当依赖项损坏时,你的构建会失败。当临时规避方案变得不再必要时,什么都不会发生。这种不对称性正是为什么每一个运行超过一年的生产级 LLM 系统都带有它不再需要的脚手架——重试编排、输出修复解析器、强制思维链、复杂的任务分解、分块启发式方法——每一个都是为了弥补特定模型的特定弱点而构建的,而且每一个都在无声无息中比它所补偿的弱点活得更久。
令人不安的是,这不仅仅是一个像过期的特性标志(feature flags)那样的卫生问题。过时的脚手架不仅仅是消耗你的延迟和 Token。在最坏的情况下,它会主动将新模型限制在旧模型的上限内:你的分解逻辑将一个任务切分为六个步骤,是因为 2024 年的模型无法处理整个任务,而 2026 年的模型本可以一次性完成,现在却继承了六个在你构建的缝隙中丢失上下文的机会。
临时规避方案在变得不再必要时并不会报错
想想脚手架是如何添加的。一名工程师看到模型输出了带有尾随逗号的 JSON,于是写了一个修复解析器并上线。模型在长任务执行中途会发生偏移,于是有人每隔十轮添加一个“检查点并总结”的循环。模型拒绝了合法的请求类别,于是系统提示词(system prompt)中加入了一条“你被允许讨论……”的条款。每一次添加都是理性的、经过测试的,并与观察到的失败案例紧密相关。
现在想想脚手架是如何移除的。事实是,它们根本不会被移除。没有信号会提示你移除它。修复解析器仍然在每次响应中运行——它只是不再修复任何东西,因为供应商提供了限制性解码(constrained decoding),JSON 现在从构造上就符合 schema。在原生结构化输出出现之前,团队通常会将 20-30% 的 LLM 集成代码用于解析和验证;而在有了限制性解码之后,对于新代码来说,这个数字实际上是零。但是,旧的防御性代码在变得多余时并不会抛出错误。它只是永远地安静执行,悄无声息。
这就是结构性陷阱:脚手架因“尸检”而添加,却因“虚无”而移除。失败会产生提交(commits);过时则产生沉默。沉没成本和惯性完成了剩下的工作——编写重试编排的工程师记得促成它的那次事故,没有人愿意成为那个删除“保护生产环境”的东西的人。
死重(Dead Weight)的三个层级
并非所有过时的脚手架带来的成本都是一样的。将你的辅助框架分为三个层级会有所帮助。
第一层:纯开销。 临时规避方案除了消耗延迟和 Token 之外没有任何作用。在 schema 强制响应上运行输出修复解析器就是典型的例子。同样,在已经从解码器层面强制执行 schema 的 API 调用旁,放一个“仅以有效的 JSON 响应,不要包含任何其他文本”的提示块也是如此。这虽然恼人且可衡量,但大多无害。
第二层:扭曲。 临时规避方案改变了模型的行为,这种改变以前是纠正性的,现在则是降级性的。强制思维链(CoT)是最明显的例子:“一步步思考”在 2023 年代的模型上几乎是免费提升准确率的手段,但推理模型(reasoning models)会产生自己的内部审视,在上面叠加显式的 CoT 指令会导致过度推理——对 o1 类模型的研究发现,正是因为过度的推理,它们在相当一部分简单任务上的表现反而不如预期。同样,为过度谨慎的旧模型编写的拒绝规避方案(“不要拒绝关于……的请求”)对于阈值已经重新校准的新模型来说,可能会被解读为对抗性上下文——Anthropic 自己的迁移指南明确指出了这种模式需要审计并通常需要删除。
第三层:能力上限。 临时规避方案从结构上阻止了新模型执行它现在有能力完成的任务。任务分解就是其中的重头戏。如果你的编排器因为旧模型的可靠视野很短而将每个作业拆分为五个子任务,那么你就硬编码了那个视野。METR 的测量显示,模型能够自主完成的任务长度大约每七个月翻一倍——这意味着你选择的任何分解粒度都注定会成为一个牢笼。为一代模型的智力构建的脚手架,成了下一代模型的囚笼。子任务之间的每一次转接都是你人为设计的上下文损失,而模型永远没有机会向你展示它其实不需要这些转接。
这些层级之所以重要,是因为它们决定了审计的优先级。第三层项目是模型升级静默失败的地方:团队更换了模型 ID,看到微弱的增长,然后得出结论认为这次发布被过度吹捧了——而事实是,他们的框架从未让新模型施展拳脚。
为每个临时规避方案标注它所补偿的弱点
解决方法始于编写代码时,而非审计时。纪律很简单:任何临时规避方案在进入代码库时,必须带有机器可检索的注释,指明它所补偿的模型弱点以及你观察到该弱点的模型版本。
类似于一种注释约定——COMPENSATES: gpt-4-turbo 在长 JSON 中会丢失数组尾随元素,观察于 2024-03——附加在修复解析器、重试策略、提示词条款或分解规则上。具体的格式并不重要,重要的是它具备以下三个属性:
- 它命名的是弱点,而不是修复方法。 “对错误格式的输出进行重试”描述了代码做了什么;而注释必须记录模型为什么需要它,因为这才是会过时的事实。
- 它是可搜索(Greppable)的。 当新模型发布时,你希望通过一次搜索就能返回系统中的所有补偿方案,这样迁移清单就能自动生成。
- 它锚定了模型版本。 标注给两代前模型的临时规避方案是首选的删除候选对象;标注给当前模型的则假定仍然有效。
这将脚手架从“基础设施”重新定义为它本来的样子:一份关于特定模型的过时投诉清单。基础设施是永久性的,而投诉会过期。当你升级数据库时,你的负载均衡器不会变得不再必要;但当你的上下文窗口增长 8 倍时,你的分块启发式方法绝对可能变得不再必要。
尽管并不总是如此——这正是为什么要通过测试而不是假设来验证。长上下文研究不断发现,即使所有内容在技术上都能装入窗口,检索和分块对于质量仍然至关重要。标注的目的不是预判答案,而是确保问题被提出。
每次升级都进行消融实验:将审计作为一等迁移步骤
标记好权宜之计(workarounds)后,模型迁移就不再只是“更换 ID 并运行评估”那么简单,而是变成了一个双阶段的过程。
第一阶段,基准测试(Baseline): 在不改变 Harness 的情况下运行新模型。这是每个人的常规操作,它只回答一个问题——在保留旧模型“拐杖”的情况下,新模型是否至少和旧模型一样好?
第二阶段,消融实验(Ablation): 在禁用每个已标记权宜之计的情况下,单独或按主题分组重新运行评估。关闭修复解析器(repair parser)。取消强制思维链(CoT forcing)。将六步分解简化为两步,甚至一步。将重试预算从五次降到一次。每一次消融都在回答基准测试无法回答的问题:新模型是否还需要这些东西?
结果一目了然。如果关闭权宜之计后质量保持不变,你就找到了冗余重量——删掉它,以此降低延迟并节省 Token。如果质量反而提升了,说明你发现了一个二阶或三阶失真,原本的权宜之计正在消耗你支付高价使用的新模型的性能。如果质量下降了,说明这种缺陷在代际更新中依然存在——保留该权宜之计,并将其标签更新为新模型版本,因为现在你确定它是凭实力留下的,而不是盲目继承下来的。
跳过第二阶段的团队会系统性地低估新模型。这也是为什么“Harness 比模型更重要”的发现——这些发现是真实的且有据可查,在 SWE-bench 上,同一个基础模型根据 Harness 的不同,解决率可能从 5% 波动到 30% 以上——常被误读。是的,在模型固定的情况下,Harness 起主导作用。但适用于模型 N 的最佳 Harness 并不等同于适用于模型 N+1 的最佳 Harness。寻找新最优解的唯一方法是做减法,而不仅仅是加法。
删除是交付成果,而非事后清理
这一策略在文化层面上的阻力比技术层面更大。大多数工程团队将代码删除视为“保洁工作”——只有在功能开发的空隙才会去做,而这意味着永远不会做。对于 LLM Harness 来说,这种直觉恰恰相反。最接近前沿模型的从业者已经开始明确指出:Agent 构建的艺术正在从“叠加”转向“战略性删减”,从“引导一个不可靠的推理引擎走过你亲手设计的迷宫”转向“别挡住一个强大引擎的路”。
具体来说,这意味着模型迁移的“完成定义(Definition of Done)”应该包含如下内容:“删除了 11 个标记权宜之计中的 4 个,p50 延迟降低了 340ms,输出 Token 减少了 18%,评估表现持平或更优。”删除脚手架(Scaffolding)是一个具有可衡量收益的交付成果,应该在展示新模型能力的 Demo 中一并庆祝——因为这就是新模型能力的体现。
还有一个复利层面的论据。你带入下一代模型的每一个权宜之计都会与其他策略产生交互——重试逻辑包裹着修复解析器,后者又为分解循环提供输入——如果你不进行审计,这种过时补偿机制之间的组合交互面会随着每次发布而扩大。在每次升级时都进行消融实验的团队,能保持其 Harness 足够精简以便于理解。而那些不这样做的团队,最终会陷入一种无人能说清流水线中哪些部分是核心支撑(load-bearing)的境地。Harness 变得不可证伪:删除任何东西都太危险,信任任何东西都太模糊。
模型的迭代是有时间表的。能力飞跃每隔几个月就会出现,每一次都会悄无声息地将你精心构建的 Harness 中的一部分变成冗余重量——而且没有失败的测试会告诉你具体是哪一部分。一套标记规范、每次升级时的消融实验,以及一种将删除视为交付的文化,是成本极低的保险。否则,你就是在以 2026 年的推理价格,运行一个被包裹在 2024 年各种“牢骚”里的模型。
会员专享
余下内容仅对会员开放。
会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。
- —完整文章,包含未公开存档的部分
- —可落地的工作框架,附带权衡与决策依据
- —新文章抢先看,先于公开发布
随时取消 · 一次订阅,畅读全部