AI API 返回 400 怎么排查?从请求体、模型到 Base URL 逐项定位
简答:AI API 返回 400,优先把它当作“请求已到达,但请求内容或格式未通过校验”,不要先盲目重试。先保存响应体中的 error.type、error.code、error.message 和 error.param,再用同一 Base URL、同一模型发送只含文本的最小请求;最小请求成功后,再逐项恢复工具、图片、结构化输出、思维参数和流式选项。本站不是任何 API 厂商的官方文档,本文按 2026-11-04 核验到的公开资料整理通用排查方法。
定义:400 Bad Request 是服务器认为客户端请求存在格式、内容、参数或消息结构问题而拒绝处理的 HTTP 客户端错误;原请求不修改而重复发送,通常仍会失败。
先做这一步:看响应体,再发最小请求
三行结论:400 不等于 Key 一定失效;先看响应 JSON 中的错误字段;把复杂请求缩减为“固定模型、单条文本、非流式、无工具”的最小请求,再按项恢复。
| 现象 | 优先检查 | 处理动作 |
|---|---|---|
| 响应明确指出字段或参数 | error.message、error.param、字段类型 | 按错误消息修正名称、类型、枚举值或格式 |
| 请求体解析失败 | JSON 括号、引号、转义、编码、Content-Type | 用 JSON 校验器或命令行重新生成请求体 |
| 只有某个模型失败 | 模型 ID、模型能力、供应商参数 | 查该模型接口文档,暂时删除不兼容参数 |
| 复杂请求失败,纯文本成功 | tools、图片、文件、结构化输出、思维配置 | 一次恢复一个功能,记录是哪一项触发 400 |
| 所有请求都失败且响应来自网关 | Base URL、路径、模型映射、网关转换规则 | 确认接口版本只出现一次,并查看网关透传的上游错误 |
OpenAI 的错误文档将请求缺少必需参数、拼写或格式错误、编码、格式和请求数据大小列为 BadRequestError 的检查方向,并建议用 curl 或类似工具验证最小请求;参见 OpenAI API 错误码文档。MDN 也说明,400 通常表示请求语法、消息 framing 或路由信息存在客户端错误,未修改请求直接重试通常仍会失败;参见 MDN 对 400 Bad Request 的定义。
最短主流程:四步把问题缩小
- 记录完整响应。保存 HTTP 状态码、响应头中的请求 ID、响应 JSON,以及客户端实际发送的 URL、方法和请求体。API Key、Cookie、Authorization 值必须脱敏。
- 确认请求边界。检查方法是否为接口要求的 POST,
Content-Type是否为application/json,字符是否为 UTF-8,Base URL 与路径是否重复拼接版本目录。不要凭经验把/v1追加两次。 - 发送最小请求。只保留一个已在目标服务文档或模型列表中确认的模型、一个短文本、必要认证头和非流式设置。这里的模型名、Base URL 和 Key 都是占位符,不能直接照抄运行。
- 逐项恢复。最小请求成功后,按“历史消息→较长输入→参数→tools→图片或文件→结构化输出→stream”顺序,每次只恢复一项。出现 400 时,最后恢复的项目就是第一嫌疑。
最小复现请求模板如下。这是占位模板,不代表任何具体服务的真实地址或模型 ID。
curl -i "$BASE_URL/v1/chat/completions" -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" --data '{"model":"<已确认的模型ID>","messages":[{"role":"user","content":"请回复 OK"}],"stream":false}'
成功标准不是“HTTP 请求发出去了”,而是返回 2xx,并且响应体符合该接口文档定义的成功结构;任何非 2xx 都应先保存响应体再判断。若服务使用的不是 Chat Completions 路径,应以该服务的 API Reference 为准,不要把上述路径强行套用到其他接口。
按错误证据检查 JSON、字段和参数
1. JSON 与请求头
- 确认 JSON 使用双引号,字符串中的换行、反斜杠和引号已正确转义。
- 确认没有尾逗号、未闭合括号、数组与对象层级错误,或把 JSON 字符串误传成表单数据。
- 检查
Content-Type: application/json、请求编码和实际发送的请求体;不要只检查代码里的对象,因为 SDK 或代理可能在发送前重新序列化。 - 如果经过反向代理或网关,同时记录代理收到的请求体大小和上游返回体,避免把中间层生成的 400 误判为模型接口错误。
2. 必填字段、字段名和数据类型
- 核对必填字段是否缺失、拼写是否正确,数字是否被错误地传成字符串,布尔值是否写成
"true"。 - 检查枚举值、空字符串、
null、负数和超出范围的数值;“字段存在”不代表字段值合法。 - 先删除无法确认的可选参数。未知参数、旧 SDK 生成的字段、某模型不支持的参数,都可能触发请求校验失败。
- 如果错误响应提供
error.param或字段路径,优先修改该字段,不要同时改动整段业务逻辑。
3. 模型、路径和部署名称
确认模型 ID 是目标服务当前可用且有权限调用的名称。使用云平台部署时,还要区分资源 endpoint、deployment name、API version 和模型名称;Azure 的错误表将错误 endpoint、部署名不存在和不支持的 API version 归入 404,而不是一概归为 400,参见 Microsoft Foundry 的 HTTP 错误排查表。
使用 OpenAI 兼容网关时,兼容的是请求外形,不代表所有参数、模型能力和错误码都完全相同。对照网关文档确认:Base URL 是否已经包含版本路径、接口是否映射到正确上游、模型名是否需要映射、网关是否会改写 messages、tools 或其他参数。无法从公开资料确认的网关行为,应标记为“需核实”,不要当作平台通用机制。
复杂场景:上下文、工具、图片和模型能力
如果短文本最小请求成功,而原请求返回 400,重点比较请求大小和功能字段。Azure OpenAI 的官方排查表把无效 payload、上下文长度超限、不支持的参数和内容过滤列为 400 的常见原因;其中内容过滤也可能在错误码中明确出现 content_filter,参见 Azure OpenAI 错误排查文档。
- 上下文过长:减少历史消息、工具定义和输入附件,确认输入与输出预算符合目标模型限制。不要只减少
max_tokens,因为输入本身也可能已经超限。 - 工具调用:先移除
tools和tool_choice,验证纯文本;再检查工具名称、参数 JSON Schema、必填字段和嵌套类型。 - 图片或文件:核对媒体类型、编码格式、大小、数据 URI 或文件引用方式。若服务商文档没有确认某种格式,不要假定 OpenAI 兼容就一定支持。
- 结构化输出:检查
response_format、JSON Schema 或同类字段是否被当前模型和接口支持;先改回普通文本输出。 - 思维或推理配置:这类参数通常与模型能力绑定。以 Claude API 为例,官方文档列出不同模型对 thinking 配置、预填 assistant 消息和工具选择的限制,发送不支持的组合会返回 400;参见 Claude API 错误文档。其他服务应以各自模型文档为准。
- 流式请求:先将
stream设为 false,确认非流式响应成功后再启用流式。若非流式也失败,问题通常不应先归因于 SSE 连接。
错误分流:不要把 400 当成所有 API 故障
| 状态码 | 通常优先检查 | 是否适合盲目重试 |
|---|---|---|
| 400 | 请求格式、字段、模型能力、内容和大小 | 不适合;先修改请求 |
| 401 | Key、Token、组织或项目认证配置 | 不适合;先修认证 |
| 403 | 权限、区域、网络策略或资源访问控制 | 不适合;先查授权 |
| 404 | URL、路径、部署名、API 版本 | 不适合;先核对地址 |
| 413 | 请求体超过中间层或服务限制 | 不适合;缩小请求或查限制 |
| 422 | 服务定义的语义校验失败 | 通常不适合;读字段错误 |
| 429 | 速率、并发、额度或支出限制 | 按响应头和官方策略退避 |
| 500/503 | 服务端或暂时容量问题 | 可按官方建议退避重试并查状态 |
不同平台对状态码的具体使用可能不同。例如 Claude 文档说明 400 代表请求格式或内容问题,同时某些支出限制也可能返回 400;因此最终判断应结合响应中的错误类型和消息,而不能只看数字。
安全边界与工单信息清单
排查时只记录必要信息,不要把完整 API Key、Cookie、用户隐私、原始文件或未脱敏对话发送给服务商。建议保存以下脱敏字段:
- 核验时间:2026-11-04;客户端名称与版本;运行环境。
- 请求方法、脱敏后的 Base URL、接口路径、是否经过网关或代理。
- HTTP 状态码、响应头中的请求 ID、
error.type、error.code、error.param和完整错误消息。 - 模型 ID、请求字段清单、输入长度的大致范围;删除真实提示词、密钥和个人数据。
- 最小请求是否成功,以及恢复哪一个参数后开始失败。
如果问题只在组织网络、企业代理或受控环境中出现,应联系管理员核对授权范围、出站策略和日志,不要通过绕过组织控制来验证请求。
发布前自查卡:把 400 排查结果写成可复现证据
- 是否能用一条短文本复现?如果不能,先固定环境、模型和请求体。
- 是否保存了错误响应,而不是只记录“接口返回 400”?
- 是否确认了 Base URL、版本路径和 endpoint 没有重复拼接?
- 是否把复杂请求拆成了消息、参数、工具、文件、结构化输出和流式六类变量?
- 是否分别验证了模型 ID、部署名、API version 和网关模型映射?
- 是否避免把 401、403、404、429 或 5xx 的问题混称为 400?
- 是否在日志中删除了 Key、Cookie、原始隐私内容和完整附件?
最有效的判断通常不是“换一个模型再试”,而是比较一条成功的最小请求和一条失败请求的差异。保留差异清单,后续升级 SDK、切换网关或迁移模型时也更容易定位兼容性问题。
常见问题
AI API 返回 400,是不是 API Key 失效?
不一定。400 更常见于请求格式、缺少字段、参数类型、模型能力或请求大小问题;Key 失效通常应先按 401 方向检查,但具体仍要看响应体中的错误类型和消息。核验动作是脱敏保存响应 JSON,再用同一 Key 发送最小请求。
为什么同一个请求反复重试还是 400?
因为 400 通常是确定性的客户端请求问题,原请求不修改而重试往往不会改变结果。先删除可选参数,确认 JSON、模型和路径,再按一次一个变量的顺序恢复。
OpenAI 兼容接口返回 400,应该先查什么?
先查 Base URL 是否已包含版本路径、接口路径是否匹配、模型 ID 是否被网关识别,以及网关是否支持你发送的参数。兼容请求格式不代表所有模型能力和参数完全一致,无法确认的行为应查看该网关文档或日志。
只有启用 tools 或结构化输出时才返回 400,怎么定位?
先确认纯文本非流式请求成功,然后只恢复 tools 或结构化输出中的一项。重点检查 Schema 类型、必填字段、工具选择方式和当前模型是否支持该能力;不要同时更换模型、SDK 和请求路径。
400 和 404、429 有什么区别?
400 主要指请求内容或格式未通过校验;404 更应先查地址、部署名和 API 版本;429 更应查限速、并发、额度或支出限制。最终以目标服务的错误响应和官方文档为准。
相关阅读
参考资料
- OpenAI API Error codes
- Microsoft Foundry:Troubleshoot common HTTP errors for Azure OpenAI
- MDN:400 Bad Request - HTTP
- Cloudflare Support:Error 400
- Claude Platform Docs:Claude API errors(platform.claude.com)