跳转至

供应商不支持请求的结构化输出模式,接入请求直接被拒

2026 年 9 月 11 日做一次新供应商接入实验,验证能否跑通产品的完整链路。第一个真实请求就被供应商以 HTTP 400 拒绝,错误信息说请求的输出格式类型不可用。这次拒绝没有产生费用,日志单独存档。

排查

实验记录里先后有三轮失败,先要把本地没跑起来的和请求真正到达供应商的分开:前者是环境故障,不能记成供应商的测试结果。

两轮是本地计量代理自身没启动成功,根本没有发出供应商请求,留在启动失败目录里。两次的启动日志各有直接原因:

ModuleNotFoundError: No module named 'fastapi'
AttributeError: 'Starlette' object has no attribute 'route'

一次是运行环境缺依赖,一次是代理脚本调了框架里不存在的接口。运行脚本的启动守卫发现子进程退出就直接中止整轮,所以这两轮连请求都没发出去。

剩下一轮是第一个真实请求:任务提交后标记为失败,失败位置在 runtime 阶段,不可重试,没有重试记录。要确认这个 400 是上游真实返回,看三条记录:

  • 计量代理插在产品和供应商之间,每转发一次记一条请求记录,应答原文单独存档。这一轮有对应的转发记录,请求确实发了出去,400 状态随上游应答带回。
  • 运行侧把错误归类为请求参数错误:HTTP 400、不可重试、非临时。网络抖动或供应商过载通常是临时错误,这个分类对不上。
  • 实验前后各查一次账户余额,余额没有变化。被拒的请求没有产生任何用量。

三条记录互相对上,才把问题落到请求参数本身。顺着被拒的参数查:产品请求的是 json_schema 类型的结构化输出,该供应商的网关不支持这个类型。

根因

400 出在生成之前:网关在校验请求参数时就拒绝,没有进入生成,用量为空,所以这次拒绝没有费用,和余额没变化对得上。

json_schema 和该网关支持的 json_object 差别在约束由谁保证。json_schema 要求网关按结构定义约束解码输出;json_object 只保证输出是合法 JSON,不保证符合结构定义。要用这个供应商,只能退到 json_object,把原结构定义作为指令传进去,结构约束改由产品自己的最终结果校验来保证。这也是实验变体里产品终态校验必须保持原样的原因。

实验变体

成功的一轮是一个显式的本地实验变体,没有改产品或上游代码:只在标记为实验的计量代理里,把供应商不支持的输出提示转换成它支持的类型,原结构定义作为指令传入,并关闭了思考模式。产品的最终结果校验、工具参数和扣次逻辑保持原样。

这一变体完整跑通一轮,约 26 秒,整轮 8 次外部请求,按用量和公开单价估算费用约 0.03 元。这只是估算,没做账单核对:实验结束时账户余额没有反映出相同差额。

当时的内核不会回传该供应商思考模式所需的多轮字段,所以这次不能说思考模式端到端通过;实验变体跑通,不代表原正式配置可用。输出质量也没有验收:成功样本的回答仍存在把不确定观察用于确定判断的问题,不算通过样本。

后续

正式路径后来改用该供应商支持的结构形式,有独立的发布验收(见三天三次合同缺口)。两个案例是同一类问题:声称支持的能力在实际请求里不成立,要用真实请求逐项确认。