是 bug、文档缺口,还是预期错了:报障前先给异常响应分类
本文给出一棵可操作的判断树,帮助你在向聚合站或模型提供方报障前,先把异常响应归类为端点缺陷、请求格式问题或文档歧义三类,从而把请求发到正确的渠道,减少无效往返。
调用 LLM API 时拿到一个看不懂的响应,第一反应往往是「这是不是坏了」。但异常响应的成因差别很大:有的是端点真的出错,有的是请求本身格式不对,还有的只是文档没说清楚而你按另一套约定理解。三者需要不同的处理路径。下面这棵判断树可以帮助你在报障前先做一次分类。
第一步:先确认响应是否可复现
在分类之前,先排除偶发因素。用完全相同的最小请求体连续发送几次,观察响应是否稳定。同时保留完整的请求(URL、方法、头部字段名、请求体结构)和完整响应(状态码、响应体、错误字段)。如果异常只在特定负载、特定并发或特定时刻出现,记录下这些条件,它本身就是重要线索。
第二步:区分「请求被拒绝」与「请求被执行但结果不对」
这是判断树的第一处分叉。
- 请求被拒绝:非 2xx 状态码,响应体里有结构化的错误对象。这类响应通常是端点在工作,只是不接受你的请求。
- 请求被执行但结果不对:2xx 状态码,但返回内容缺失、字段不符合预期、或错误对象出现在 200 的响应体里。
前者大概率指向请求侧或文档侧,后者更可能是端点行为问题。
第三步:请求被拒绝时,先自查格式
请求侧的错误里,最常见的是参数形状不对而不是参数值不对。逐项核对这些容易出错的点:
- 必填字段是否齐全:模型标识、消息数组、必要参数是否都在正确层级。
- 字段类型是否符合约定:该是数组的地方传了字符串,该是数字的地方传了字符串数字。
- 消息结构是否成立:角色字段的取值是否在允许集合内,多轮消息是否成对、顺序是否符合约定。
- 内容块格式:如果使用多模态或多段内容,确认内容块的对象结构而不是纯字符串是否符合文档要求。
- 请求体是否被额外包装:有些兼容层要求特定的外层结构,直接在顶层放参数会被拒绝。
如果按文档逐项核对后仍然被拒绝,进入第四步。
第四步:判断是文档歧义还是端点缺陷
这一步的关键是构造一个「最小合法请求」:只保留文档明确标注为必填的字段,去掉所有可选参数、自定义头部和额外包装。
- 如果最小合法请求成功,逐步加回你之前的字段,找出触发拒绝的那一个。若该字段在文档中描述含糊、示例与说明不一致、或未说明取值范围,这属于文档歧义——值得反馈,但渠道是文档反馈而不是故障报修。
- 如果最小合法请求同样被拒绝,且请求形状与文档示例逐字对齐,则更接近端点缺陷,应按故障路径上报。
第五步:2xx 但结果异常时,先排除语义层问题
返回 200 不代表结果正确。先确认问题不在你的输入侧:
- 提示词是否要求了模型无法保证的输出格式(例如未给出结构化约束却期望严格 JSON)。
- 是否把「模型没按期望回答」误当成端点错误。内容质量、拒答、风格偏离通常属于模型行为,不属于端点缺陷。
- 响应中的用量字段、结束原因字段是否与你的请求参数一致,这能帮你判断参数是否真的生效。
真正的端点异常通常表现为结构性问题:应有的字段缺失、字段类型与文档不符、错误对象混在成功响应里、或同一请求在内容分布上出现无法用模型随机性解释的偏差。
第六步:按分类选择上报对象
分类完成后,把问题发到对应的地方:
- 请求格式问题:自己修正,不需要上报。
- 文档歧义:反馈给文档维护方,附上你依据的文档段落与实际行为,说明二者不一致之处。
- 端点缺陷:上报给服务方,附最小复现请求、完整响应、复现频率与时间点。
- 模型行为差异:属于预期管理问题,可通过调整提示词或更换模型解决,不必按故障处理。
为什么先分类能省时间
把格式错误报成端点故障,会得到「请检查请求体」的回复;把文档歧义报成故障,会在来回确认中消耗双方时间。先做一次结构化分类,能让你的报障单从一开始就带着可复现的证据和明确的归属,也让真正需要修的缺陷更快被看到。
在多模型聚合的场景里,这一点尤其重要:同一个请求形状在不同模型上可能有不同的严格程度。先用最小请求定位问题出在请求、文档还是端点,再决定找谁,是最省事的做法。