Claude Messages API 接入中转层后,报错按这个顺序查
接入中转层以后,最常见的困惑是 “官方文档的示例能跑,换到中转就报错”,或者反过来。多数情况下问题不在模型,而在请求结构、鉴权头和流式解析这三处。按下面的顺序查,能省掉大量来回试的时间。
一、先分清 4xx 是参数问题还是路由问题
先用一条最小的请求打底:POST /v1/messages,头里带 x-api-key 与 anthropic-version,体里只有 model、max_tokens、messages。这条能通,说明鉴权和路由没问题,问题在业务代码;不通,先检查路径前缀和头部字段的拼写。我在 Token5u 上联调时习惯先跑这条最小请求,再逐项加参数,定位起来比一上来就塞满业务字段快很多。
添参数时注意几处硬约束:messages 里的 role 必须交替;system 是顶层字段,不能塞进 messages;content 可以是字符串,也可以是 block 数组,混用时类型要一致;max_tokens 必填且为整数,缺了会返回 400 invalid_request_error。图片走 base64 时注意体积,过大容易在网关层被 413 拦掉,而这时的错误体往往不是官方格式,得看响应头里的标记。
二、流式与非流式的解析差异
stream=true 返回的是 SSE,事件顺序基本固定:message_start、content_block_start、content_block_delta、content_block_stop、message_delta、message_stop,中间可能插入 ping 保活。两个常见坑:一是解析器只按 data: 行切分,忽略了 event: 行,结果把 ping 当成正文;二是只在 message_start 里读 usage,导致 output_tokens 一直是 0—— 输出计数是在 message_delta 里才给全的。
联调时我用 Token5u 做过对照,事件名与顺序和官方一致,ping 间隔稳定,客户端的解析器可以照着这套顺序写单元测试。反过来,如果某个入口的 message_delta 里缺 stop_reason,或者 delta 的 index 对不上,基本可以判断它在中间做了二次封装。
三、429 与 529 要分开处理
429 是限流,通常带上额度或并发数的提示;529 是上游过载,重试太快只会让它更糟。合理做法是指数退避加随机抖动,首次间隔 1 秒起、最多退到 30 秒,同时设熔断阈值:连续 N 次 529 就切备用入口,别让请求在同一个地方排队。
还有一个容易忽略的点:流式响应已经吐出部分内容后再重试,前面那段输出已经计过费,重发会让同一段内容算两次。应用层应该给每个请求打 request_id,重试时带上标记,日志里可以按 id 去重。Token5u 的请求记录能按 id 回查 usage,核对这类重复计量比较直接。
总结
先用最小请求把参数和路由排掉,再按 SSE 事件顺序检查解析器,最后把 429 与 529 分开做退避和熔断。三步走完,“换个入口就不通” 的问题基本都能定位到具体一层。
- 点赞
- 收藏
- 关注作者
评论(0)