OpenAI 兼容 API 返回 404 模型不存在怎么办?
简答:OpenAI 兼容 API 返回 404 model_not_found 时,优先用同一个 API Key 和同一个 Base URL 请求模型列表,再从返回的 data[].id 复制完整模型 ID;如果模型列表也 404,重点查 Base URL 和路径,如果列表成功但生成仍 404,再查接口类型、部署名和项目权限。下面这套流程适用于截至 2026-11-03 能由当前接口返回结果核验的场景。
定义:404 model_not_found 通常表示当前请求找不到可用于该请求的模型或资源,但同样的 HTTP 404 也可能来自请求路径、部署名或兼容接口地址错误,不能只凭错误文案判断。
先看这张分流表:404 到底查什么
不要先凭记忆更换模型名。先记录最终请求主机、路径、HTTP 状态码和响应体中的 error.type、error.code、error.message,然后按下面的结果分流。
| 现象 | 优先判断 | 下一步 |
|---|---|---|
| GET 模型列表也返回 404 | Base URL、路径拼接或服务端未提供该接口 | 检查最终 URL 是否重复或缺少 /v1,并查服务商兼容接口文档 |
模型列表成功,目标模型不在 data[].id | 模型 ID 不存在、已变化或当前 Key 不可见 | 复制列表中的完整 id,不要使用展示名称或旧教程别名 |
| 模型列表成功,生成请求返回 404 | 请求路径、接口类型、部署名或权限不匹配 | 核对 /chat/completions 与 messages,或 /responses 与 input 是否对应 |
| 返回 401 | 认证信息无效 | 检查 Key、请求头、项目或组织配置 |
| 返回 403 | 身份已识别但没有访问权限,或区域、项目等限制 | 检查项目、组织、区域和模型访问权限 |
| 返回 400 | 请求体或参数格式错误 | 按接口文档核对字段、类型和必填项 |
| 返回 429 | 限速、额度或用量限制 | 查看响应体和 Retry-After,不要把它当作模型不存在 |
OpenAI 的错误文档将 401、403、429 和 404 分开处理;其中 404 需要检查资源或模型标识,不能用重试代替配置核对。可参考 官方错误代码文档。
最短排查步骤:确认最终地址,再查当前模型列表
- 确认 Base URL 的真实值。打印程序最终使用的主机和路径,不要只看配置文件。重点检查是否出现
/v1/v1、漏掉/v1、把完整 endpoint 又拼接了一次,或 SDK 自动追加了路径。 - 使用同一 Key 请求模型列表。如果服务商公开兼容该接口,可请求
GET /v1/models。OpenAI 官方模型列表接口返回data数组,其中每项的id是可在 API 请求中引用的模型标识;但兼容服务是否提供此接口,仍需以该服务商文档或实际返回为准。 - 复制
data[].id,不要手打模型名。展示名称、产品名称、模型家族名称和 API 模型 ID 可能不是同一个字符串。不要把旧文章中的模型名当成当前可调用 ID。 - 用同一地址发送一次最小生成请求。先去掉工具、流式、结构化输出和复杂参数,只保留模型与最小输入。
- 对比两次请求。记录模型列表请求和生成请求的 host、path、认证方式、模型字符串及完整响应体,确认生成请求没有偷偷切换到另一套环境变量或客户端配置。
OpenAI 官方接口把模型列表定义为当前可用模型及其基本信息,并明确返回模型 id;因此“列表中看得到”只能证明该列表请求返回了这个标识,不等于所有生成接口、项目或功能都一定有权限调用。
最小诊断请求:curl、Python、JavaScript 模板
使用说明:下面是通用模板,不是某个兼容服务的已核验实例。请自行核实 Base URL、模型 ID、接口路径和服务端是否支持该接口;密钥只从环境变量读取,不要写入代码、截图或日志。
1. 先请求模型列表
curl -sS -D /tmp/models.headers "$BASE_URL/v1/models" -H "Authorization: Bearer $API_KEY"
成功判定:HTTP 状态为 2xx,响应 JSON 中存在数组字段 data,并能在其中找到目标对象的 id。如果返回 404,先不要继续改模型名,检查 Base URL、/v1 拼接和服务商是否实现模型列表接口。
2. 用 Chat Completions 做最小请求
curl -sS -D /tmp/generation.headers "$BASE_URL/v1/chat/completions" -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" -d '{"model":"从 data[].id 复制的模型 ID","messages":[{"role":"user","content":"只回复 OK"}]}'
成功判定:HTTP 状态为 2xx,响应体出现服务端定义的完成结果字段,例如标准 Chat Completions 响应中的 choices。如果服务商只支持另一种接口,必须以其文档规定的路径和请求体为准。
3. Python 与 JavaScript 的最小模板
Python 模板:
import os, requests
base_url = os.environ["BASE_URL"].rstrip("/")
api_key = os.environ["API_KEY"]
model_id = os.environ["MODEL_ID"]
r = requests.post(base_url + "/v1/chat/completions", headers={"Authorization": "Bearer " + api_key, "Content-Type": "application/json"}, json={"model": model_id, "messages": [{"role": "user", "content": "只回复 OK"}]}, timeout=30)
print(r.status_code)
print(r.text)
JavaScript 模板:
const baseUrl = process.env.BASE_URL.replace(/\/$/, "");
const r = await fetch(baseUrl + "/v1/chat/completions", { method: "POST", headers: { Authorization: `Bearer ${process.env.API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ model: process.env.MODEL_ID, messages: [{ role: "user", content: "只回复 OK" }] }) });
console.log(r.status);
console.log(await r.text());
这些示例只用于观察 HTTP 状态码和响应体,不能据此推断某个服务一定支持 Chat Completions、Responses 或模型列表接口。
为什么模型列表能看到,生成请求仍然 404?
这是最容易误判的情况。可以按以下顺序继续核对:
- 接口路径不一致:模型列表使用了一个有效路径,但生成请求可能被 SDK 拼成了另一条路径。把最终请求 URL 打印出来,确认没有重复的
/v1、错误的版本前缀或多余的部署路径。 - 接口格式不匹配:Chat Completions 使用
POST /chat/completions和messages;Responses 使用POST /responses和input。官方文档分别列出了这两种请求结构,兼容服务不一定同时实现两者,可按服务商文档选择。 - 模型只在列表中可见,但不具备当前调用资格:列表返回不应被解读为所有项目、区域、套餐或功能均已授权。继续查看响应体中的权限、项目、组织或区域提示,并在控制台核对访问设置。
- 使用了部署名规则:部分云平台不是直接使用底层模型名,而是要求在
model字段传入你创建的 deployment name。Microsoft 的官方说明明确区分了模型名称和 deployment name;使用这类 endpoint 时,应复制实际部署名称。 - 模型能力与接口不匹配:某些部署可能支持 Chat Completions,但不支持 Responses,或反过来。此时应先换成该部署文档明确支持的接口,不要仅凭 OpenAI 兼容这个标签推断能力完全相同。
如果使用 Azure OpenAI 或其他具有部署概念的云平台,先确认 endpoint、路径和 deployment name。相关官方说明见 Microsoft 的 endpoint 切换说明 与 Foundry endpoint 文档。
按 HTTP 状态码分流,而不是反复重试
| 状态码 | 典型含义 | 可执行动作 |
|---|---|---|
| 400 | 请求格式、字段或参数无效 | 核对接口路径对应的请求体;删除非必要参数后重试一次 |
| 401 | Key 无效、过期、撤销或不属于当前项目 | 重新确认环境变量和请求头,必要时在控制台创建新 Key |
| 403 | Key 已识别但无访问权限,或存在区域、项目限制 | 检查项目、组织、区域及模型授权,不要只更换模型字符串 |
| 404 | 模型、部署、资源或 URL 路径找不到 | 先查最终 URL,再查同一 Key 的模型列表和部署名 |
| 429 | 限速、额度或支出限制 | 读取错误码和 Retry-After;降低并发,处理额度或限制问题 |
| 5xx | 服务端或临时可用性问题 | 保存请求 ID、时间和响应体,按有限次数退避重试,并查看服务状态 |
OpenAI 官方错误文档还建议在持续报错时提供模型、错误信息与代码、请求数据和请求头、请求时间及时区等信息;提交前必须删除 API Key、Authorization 头和敏感输入。
安全边界:日志怎么留,哪些内容不能发
- 可以保留:HTTP 状态码、请求主机、请求路径、模型字符串、错误类型与错误代码、请求时间及时区、响应中的 request ID。
- 必须脱敏:API Key、Authorization 请求头、Cookie、完整用户输入、文件内容、组织或项目的敏感标识。
- 不要把 Key 放在前端、公开仓库、聊天截图或可访问的日志中;使用环境变量或服务端密钥管理。
- 重试只适用于明确的临时错误或限速场景。模型 ID、路径、权限错误不会因为无限重试自动修复。
- 记录“配置值”和“最终生效值”的差异,例如环境变量、SDK 初始化参数、代理层重写后的 Base URL,避免只检查未实际生效的配置文件。
如果仍无法定位,可向接口服务方提交脱敏后的请求摘要:Base URL 主机、HTTP 方法和路径、模型 ID、状态码、错误字段、时间及时区,以及是否能成功获取模型列表。不要直接提交密钥或完整请求头。
常见问题
一定要先调用 /v1/models 才能解决 404 吗?
不一定。只有当当前服务商记录或实现了模型列表接口时,才可用它核验模型 ID。若 GET /v1/models 本身返回 404,应先确认 Base URL、路径拼接和接口支持情况;不能把这个 404 直接当成模型不存在。
模型列表里有模型,为什么请求仍然返回 model_not_found?
先比较两次请求的最终 host、path、API Key 所属项目和 model 字符串。常见差异包括生成请求切换了环境变量、SDK 重复拼接 /v1、服务商要求 deployment name,或该模型不支持当前接口。用一个不带工具和流式参数的最小请求复现。
模型名称大小写或空格会导致 404 吗?
可能会。模型标识应直接复制响应中的 data[].id,避免手打、复制展示名称或带入前后空格。若复制后的字符串仍失败,继续核对当前 Key、项目和 endpoint,而不是只改大小写。
OpenAI 兼容 API 返回普通 HTML 404 页面,应该查模型吗?
优先查 URL。HTML 404 往往说明请求没有进入预期 API 路由,重点检查域名、路径、版本前缀、代理转发和 SDK 自动拼接;只有响应体明确包含模型或资源错误时,才进入模型 ID 排查。
Azure 等平台为什么不能直接填底层模型名?
因为部分云平台要求使用实际部署名称。应在对应资源或部署页面复制 deployment name,并按该平台文档确认 endpoint 与路径;不要把其他平台教程中的模型名直接照搬。
相关阅读
- 查看 Cline 接 OpenAI 兼容 API 时如何核对 /v1 与模型 ID
- 继续阅读 Dify 的 Base URL、模型名与排错步骤
- 如果状态码变成 401,按 Key 与 Base URL 继续排查
- 了解 API Key 和 Base URL 在工具中的实际配置位置