报错是这么冒出来的。微调完成后拿到 ft:gpt-4o-mini:myorg:abc123:xyz 这个名字,写进 chat.completions 的 model 字段,接口返回 404 model_not_found,可控制台里这个微调模型的状态是 succeeded。

中间走过弯路,把「微调模型只在创建它的项目下可调用,跨项目就是查不到」当成主因,改完现象没变。

真正麻烦的地方在于,几个原因的现象几乎一样。名字中间的组织段和当前 key 所属组织对不上,服务端按不存在处理。少数情况下是冒号在 shell 或 yaml 里被当成特殊字符,名字被截断成前半段。

不容易想到的是,复制的是 job 输出里的模型名,少抄了最后一段后缀。

从模型列表里筛出所有 ft 开头的完整 id

curl -s https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY" | jq -r '.data[].id' | grep '^ft:'

随后用单引号包住带冒号的名字再请求

curl https://api.openai.com/v1/chat/completions -H "Authorization: Bearer $OPENAI_API_KEY" -H "Content-Type: application/json" -d '{"model":"ft:gpt-4o-mini:myorg:abc123:xyz","messages":[{"role":"user","content":"hi"}]}'

单查这个模型确认归属组织

curl -s "https://api.openai.com/v1/models/ft:gpt-4o-mini:myorg:abc123:xyz" -H "Authorization: Bearer $OPENAI_API_KEY" | jq '.id,.owned_by'

代码里改成从环境变量读模型名

python -c "import os;print(os.getenv('FT_MODEL'))"

怎么算真的好了,看的是同一批现象。模型单查返回 200 且 owned_by 与当前组织一致,chat 请求拿到 200 和正常 choices,日志里模型名五段完整没有被截断。

提醒一点。带冒号的名字在 shell、yaml、.env 里都容易断,统一放进环境变量再读,比每次手抄安全,也方便灰度时整段替换。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。

作者 9823189