模型越强,工具越差
速览
尽管AI大模型能力不断增强,但相应的工具链、开发平台和用户体验却未能同步升级,甚至出现倒退。这导致开发者难以充分发挥模型潜力,行业面临效率瓶颈。该现象反映出AI领域重模型轻工具的倾向,可能阻碍技术落地。
AI 深度解读
背景
2026年7月,知名开发者Armin Ronacher(Flask、Jinja2等项目的作者)在博客中记录了一个令他困惑的发现:在使用Pi(一款依赖AI工具调用的编程助手)时,新版Claude模型(Opus 4.8和Sonnet 5)在调用Pi的编辑工具时,会频繁在工具调用参数中发明额外的、不符合schema的字段,导致Pi拒绝调用并要求重试。而旧版模型(如Haiku、Opus 4.5等)却没有这个问题。这一现象引发了作者对当前AI模型训练范式——尤其是后训练(post-training)阶段如何影响工具调用能力——的深入思考。
核心内容
问题的具体表现
Pi的编辑工具接受一个包含path和edits数组的JSON参数,其中edits数组中的每个对象只应包含oldText和newText两个字段。但在新版Claude模型(Opus 4.8和Sonnet 5)的调用中,模型有时会在edits数组的对象里添加额外的键,例如:
requireUnique: trueoldText2: "",newText2: ""type,id,kind,unique,matchCase,in_file,forceMatchCount,children,notes,cost,oldText_2,newText_2,甚至出现event.0.additionalProperties这样的嵌套键。
作者检查了这些出错的调用,发现oldText和newText的实际内容字节正确,说明模型已经正确生成了要替换的文本,只是在对象末尾添加了无意义的额外字段。Pi的验证器发现这些字段不符合schema,于是拒绝调用,要求模型重试。
失败的条件依赖性
这个问题并非总能复现。作者在单轮对话中直接要求“编辑这个文件”时无法触发。只有在具备历史上下文的Agentic场景中(模型已读取文件、诊断问题、然后构造多行编辑)才可能复现。而且并非所有用户都会遇到:作者需要借助另一位开发者Petr Baudis的会话记录才能复现。在Petr的会话中,Opus 4.8在连续会话中失败率约20%。如果从历史中移除思考块(thinking blocks),失败率降低一半。如果开启严格工具调用(strict tool invocation),则完全消除。
技术背景:LLM工具调用如何工作
LLM工具调用并非魔法,而是通过一种相当粗糙的带内信号(in-band signalling)实现。模型收到一个对话记录、系统提示和可用工具列表。服务器将这些信息合成一个带有特殊标记令牌(marker tokens)的大型提示。模型经过训练(在特定格式的例子上强化学习),在生成过程中会输出一些被API或客户端解释为“调用这个工具,参数如下”的内容。
以编辑工具为例,预期的调用负载是JSON格式,包含path和edits数组。在Anthropic的模型中,实际序列化输出可能看起来像XML(但并非真正的XML),例如:
<antml:function_calls>
<antml:invoke name="edit">
<antml:parameter name="path">some/file.py</antml:parameter>
<antml:parameter name="edits">
[
{
"oldText": "text to replace",
"newText": "replacement text"
}
]
</antml:parameter>
</antml:invoke>
</antml:function_calls>
注意:顶层字符串参数是内联的,而对象数组则通过JSON序列化实现。这种格式只是Anthropic选择便于分词和训练的产物。
两种控制模型输出的方式
- 无约束生成:模型仅凭学习到的惯例来生成格式,然后由外部验证器检查JSON是否匹配schema。如果不匹配,验证器报错,模型重试。
- 约束解码(Grammar-aware decoding):在采样过程中直接屏蔽违反语法的令牌,例如规定对象内只允许
oldText和newText,则模型无法输出其他键。这可以保证语法正确性,也能强制枚举值或键名。
Pi当前没有使用约束解码,而是依赖第一种方式。因此模型只是模仿它见过的格式。
作者的核心假设:这不是随机退化,而是训练痕迹
作者认为,新版Claude模型之所以表现更差,不是因为能力下降,而是因为它们在post-training阶段被暴露于一个特定的、宽容的tool-using harness——很可能就是Claude Code(Anthropic自家闭源的编程助手)。
- 旧版模型(如Opus 4.5)训练时,使用的工具集相对通用,没有针对某个特定harness进行过拟合。因此它们在面对不同schema的工具时适应良好。
- 新版模型(Opus 4.8, Sonnet 5)的post-training很可能包含了Claude Code或类似的环境。在这个环境中,Claude Code自己的工具是扁平的(例如
file_path,old_string,new_string,replace_all),而且Claude Code的客户端非常宽容:它会自动修复类型错误、参数别名、Unicode问题,并过滤未知键。换句话说,模型在Claude Code的harness中学习到“稍微偏离schema的调用仍然可以完成任务并获得奖励”,因为harness消化了错误,没有产生惩罚梯度。
因此,当模型面对一个更严格的工具schema(如Pi的edits数组要求精确的键)时,它已经习惯了“添加一些额外字段也没关系”的行为,导致工具调用失败。更好的模型(SOTA)反而因为更强的先验而更顽固地偏离新schema。
作者对Claude Code的观察
Claude Code虽然是闭源,但通过查看其混淆后的代码,可以推断它非常宽容:它会检查模型输出中的可见文本,并尝试提取工具调用,甚至允许参数别名、类型强制转换等。这种容错设计虽然方便了用户,但也让模型在训练中学会了“可以犯错”。
关键要点
- 新版Claude模型(Opus 4.8, Sonnet 5)在调用Pi的编辑工具时,会频繁在
edits数组中添加不符合schema的额外字段,导致调用被拒绝,而旧版模型(包括Opus 4.5)没有此问题。 - 问题有上下文依赖性:仅出现在多轮Agentic场景中,且不同用户会话表现不同;
