动态:一手资料追踪

模型更强了,工具调用反而更差了:Armin Ronacher 发现的 Tool Schema 回归问题

更新 摘译
标签
llm-tool-useanthropiccoding-agentstool-use

问题

Armin Ronacher(Flask 作者,现做 AI 编程工具 Pi)发现一个反直觉的现象:更新的 Claude 模型在调用第三方工具时,反而比旧模型更容易产生格式错误的参数。

具体表现:Pi 的编辑工具接受一个嵌套的 edits[] 数组,每项含 oldText / newText。Opus 4.8 和 Sonnet 5 在调用时会凭空发明额外字段

{
  "oldText": "...",    // 内容完全正确
  "newText": "...",    // 内容完全正确
  "requireUnique": true  // 凭空发明的字段
}

Armin 在多次试验中看到了一整园"发明字段":typeidkinduniquerequireUniquematchCasein_fileforceMatchCountchildrennotescostoldText2newText2……

最烦人的是:实际的 oldText / newText 内容是字节级正确的。模型做对了编辑,只是在对象末尾加了垃圾字段,导致 Pi 按 schema 校验失败、要求重试。

而旧模型(Opus 4.5 及更早)完全没有这个问题


为什么会这样:RL 训练的隐藏代价

Armin 的核心假说:这不是随机退化,而是训练产物

Claude Code 的编辑工具是"平坦"的

Claude Code 自己的编辑工具 schema 接近 file_path + old_string + new_string + 可选 replace_all flag——不是 Pi 那种嵌套 edits[] 结构。

Claude Code 的客户端极其"宽容"

Armin 反编译了 Claude Code 的代码,发现它有一整套容错机制:

  • 检查模型输出中泄露的 <invoke 标记
  • Unicode 转义修复(修 broken \uXXXX
  • 参数别名(old_str / old_string / path / file_path 互通)
  • 静默过滤未知 key
  • 不使用 strict 模式(因为 Anthropic 对 strict 模式下的 schema 复杂度有限制)

这意味着什么

如果强化学习在这样的 harness(或其模拟)里进行,略微畸形的工具调用仍能完成任务并获得奖励。harness 完全吸收了错误,几乎没有梯度信号去惩罚"多发明一个字段"。

更糟的是:模型可能强力适配了 Claude Code 的编辑工具形状。一个语义相同但 schema 不同的第三方工具会变成off-distribution。模型越强(prior 越强),反而越难适配你的工具。

Armin 的担忧:"替代工具 schema 可能不只是不熟悉。它们可能被一个优化特定、宽容工具生态的 post-training 隐式惩罚了。而且这个生态是不公开的。"


上下文依赖与缓解措施

这个问题高度依赖上下文

  • 全新单轮 prompt("编辑这个文件")无法复现
  • 有完整 Agent 历史(读过文件、诊断过问题、再组合多行编辑)才能触发
  • 某用户的会话中,Opus 4.8 失败率约 20%
  • 从历史中剥离 thinking blocks → 失败率减半
  • 开启 strict tool invocation → 在 Armin 的测试中完全消除

这对 Agent 开发者意味着什么

维度 判断
工具 schema 不是中立的 不要假设 schema 是抽象契约、模型是通用推理器。某些工具形状更接近模型的 post-training 分布,某些更远
嵌套参数比平坦参数危险 顶层属性在 ANTML 里内联处理;嵌套对象数组需要模型在长多行字符串后写转义 JSON——错误发生在最高熵点(闭合 } 还是继续 ,"..."
strict 模式是当前解法 Anthropic 的 strict 模式(服务端拒绝采样 schema 不允许的 key)能解决,但对 schema 复杂度有限制
你的 harness 可能要适配 Claude Code 的形状 如果这种趋势持续,第三方编程工具可能不得不实现和 Claude Code 相似的编辑工具形状才能获得最佳性能

对比:OpenAI 的 harmony 格式

OpenAI 的模型(含开源的 gpt-oss)显式训练在 harmony 响应格式上。工具调用可以这样表达:

<|start|>assistant<|channel|>commentary to=functions.get_weather
<|constrain|>json<|message|>{"location":"San Francisco"}<|call|>

<|constrain|>json 标记让推理栈可以在这个边界切换到 JSON 约束采样。Armin 测试了现有 Codex 模型(除 5.6 外),没有发现这种回归


行动建议

角色 建议
做 Agent harness / 编程工具 如果用 Anthropic 模型且有嵌套参数工具,开启 strict 模式。这是目前最可靠的解法
设计工具 schema 尽量用平坦的顶层属性而非深层嵌套。嵌套越深,模型在高熵点的采样错误率越高
追踪模型回归 新模型在你的工具上不一定更好。建立自己的工具调用成功率评估,不要假设"更强模型 = 更好工具调用"
关注 Claude Code 的影响 随着越来越多 post-training 在单一主导 harness 内进行,其他 harness 将被迫继承它的怪癖。这是 Tool Use 的基础机制层面的趋势

一句话结论:模型变强了,但它在强化学习中被训练成"最擅长调用 Claude Code 那套宽容工具"。你的工具如果不是那个形状,可能要为模型的强 prior 付出代价。这不是 bug,是 RL 的隐藏副作用——对所有自建编程 Agent harness的人都是警告。