Skip to content

模型 vs 骨架:为什么 Harness 决定上限

先从一个让整个行业困惑过的现象说起。

2024 年初,SWE-bench(一个用真实 GitHub issue 衡量 AI 修 bug 能力的基准)上的最好成绩是 1.96%——100 个真实 issue 里解决不了 2 个。2024 年 3 月,Cognition 发布 Devin,自报成绩 13.86%,七倍提升。几个月后,SWE-agent 论文用 GPT-4 Turbo 拿到 12.47%(完整集)/ 18%(Lite 集)。到 2024 年 10 月,Anthropic 用一个刻意极简的 scaffold 把 Claude 3.5 Sonnet 推到 49%

这期间模型确实在进步,但每一次跳变的幅度,都远超模型迭代的幅度。真正发生的事情是:大家逐渐搞明白了怎么给模型「搭骨架」

本页的论点一句话说完:

核心论点

在模型能力相同时,harness(骨架)是智能体能力的主要变量。一个二流模型配上一流 harness,通常胜过一个一流模型配上二流 harness。而「harness 重要」和「模型终将内化 harness 技巧」这两件事同时成立——理解这两股力量的博弈,是 agent 工程的基本功。

一、先把两个词钉死

模型(model):一个静态的权重文件。给定一段 token 序列,输出下一段 token 的概率分布。它本身没有循环、没有工具、没有记忆、不知道自己在执行任务。模型是「潜力」。

骨架(harness / scaffold):围绕模型的那套可执行系统——决定模型每一步看到什么上下文、能调用什么工具、输出如何被解析成动作、失败后如何恢复、何时停下来。骨架是「把潜力兑现成能力」的机制。

text
┌────────────────────────────── Harness(骨架)─────────────────────────────┐
│                                                                          │
│   上下文装配      工具层         控制循环        记忆         人在回路      │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌────────┐  ┌──────────┐      │
│  │ 仓库地图  │  │ bash     │  │ plan →   │  │ 笔记/  │  │ 权限审批 │      │
│  │ 相关文件  │  │ 文件编辑 │  │ act →    │  │ 检索   │  │ 中断/接管│      │
│  │ 截断/压缩 │  │ 测试运行 │  │ observe  │  │        │  │          │      │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └───┬────┘  └────┬─────┘      │
│       └──────────────┴──────┬─────┴────────────┴────────────┘            │
│                             ▼                                            │
│                    ┌─────────────────┐                                   │
│                    │   LLM(模型)    │  ← 只负责「下一步输出什么」      │
│                    └─────────────────┘                                   │
└──────────────────────────────────────────────────────────────────────────┘

行业里对 scaffold 这个词有过精确定义。Anthropic 在 SWE-bench 技术博客里写道:scaffolding「负责生成喂给模型的 prompt、解析模型输出以采取行动、管理交互循环——模型上一步动作的结果会被并入下一个 prompt」,并且明确指出:「即使使用相同的底层模型,agent 在 SWE-bench 上的表现也会因 scaffolding 的不同而显著变化。」 这句话是整个 agent 工程领域少有的、被厂商亲手写进技术博客的共识。

二、证据:同一模型,骨架造成的差距有多大

空谈「骨架重要」没有说服力,直接看数据。下面四组证据,全部满足「模型相同(或同时代),骨架不同」的控制条件。

证据 1:SWE-agent 的 ACI 消融实验(最干净的对照实验)

SWE-agent 论文(NeurIPS 2024)做了 agent 工程史上最经典的一个消融实验:固定 GPT-4 Turbo 不变,只改模型与计算机的交互接口——作者称之为智能体-计算机接口(ACI, agent-computer interface)。

配置模型SWE-bench Lite 解决率
检索增强生成(RAG,非交互式)GPT-4 Turbo约 3.8%
裸 shell(只给原始终端)GPT-4 Turbo显著低于 ACI 版
SWE-agent(精心设计的 ACI)GPT-4 Turbo18.00%(54/300)

关键数字是两个:

  • 相比 RAG 方案,交互式骨架带来 6.7 倍的解决率提升(代价是成本高 8–13 倍);
  • 相比「只给一个裸 shell」,为模型量身设计的 ACI(专用编辑命令、格式化的反馈、对长输出的截断保护)带来 64% 的相对提升

模型一个权重都没动,只改了「模型看到的界面」,性能提升 64%。这就是 harness 的杠杆率。

什么是「为模型设计界面」

SWE-agent 发现,给人类设计的工具(比如 vim、交互式命令)对模型是灾难;模型的强项是一次性输出完整、格式严格的内容。于是 ACI 把「编辑文件」设计成专用的 edit 命令、把长输出强制截断并标注、把错误信息格式化成模型容易解析的样子。接口设计的对象从人换成了模型,这是整个领域的范式转换。

证据 2:SWE-bench 榜单本身就是一个大型自然实验

对 SWE-bench 官方榜单的系统性分析(Dissecting the SWE-Bench Leaderboards)发现:榜单上的条目绝大多数使用同一批模型——在 Lite 和 Verified 两个榜单上,Claude 3.5 Sonnet 分别被 21 个和 24 个条目使用

这意味着什么?榜单上那些挂着不同团队名字、分数相差十几个百分点的条目,背后经常是同一个模型。它们之间的分数差,几乎完全是 harness 之差:上下文怎么塞、工具怎么设计、轨迹怎么控制、提交前怎么自检。SWE-bench 在无意中变成了一个测量「骨架工程学」水平的仪器。

证据 3:Devin 的 7 倍跳变

2024 年 3 月 Cognition 发布 Devin 时,自报在 SWE-bench 上解决 13.86% 的 issue,而当时无辅助状态下的最好成绩是 1.96%。注意时间点:Devin 发布时用的是同时代的 GPT-4 级模型,并没有独家模型。从 1.96% 到 13.86% 的跳变,几乎全部来自 harness——完整的沙箱环境、自己的 shell/编辑器/浏览器、多步规划与执行循环。这个案例后来被广泛讨论(包括对其评测子集选择的方法论批评),但它立住了一个事实:在模型不变的前提下,工程化的骨架可以把基准成绩拉高一个数量级

证据 4:Anthropic 的「极简骨架」49%

最耐人寻味的证据来自 Anthropic 自己。2024 年 10 月的技术博客里,他们公布了升级版 Claude 3.5 Sonnet 在 SWE-bench Verified 上 49% 的成绩(当时的 SOTA 是 45%),然后完整公开了自己的 scaffold:

  • 一段不到 300 词的 prompt;
  • 两个工具:一个 Bash 工具,一个文件编辑工具(str_replace_editor);
  • 没有规划模块、没有多智能体、没有复杂的检索管线,循环跑到模型自己说「完成了」或者 200k 上下文耗尽为止。

同一篇博客里还有一张表,四个模型用同一个 scaffold 跑:Claude 3 Opus 22% → 旧版 3.5 Sonnet 33% → 前代 SOTA 45% → 新版 3.5 Sonnet 49%。这张表同时展示了两个方向的结论:骨架相同时模型进步有用(22% → 49%),而同一时期榜单上五花八门的 scaffold 让同模型的分数散布在很大区间里。

更值得抄下来的是他们在骨架里做的「防错设计」:

  • 文件编辑工具强制要求绝对路径——因为模型在 cd 离开根目录后经常把相对路径搞错;
  • 编辑采用字符串替换(old_strnew_str),且仅当 old_str 在文件中恰好出现一次才执行,否则返回明确的错误信息让模型重试;
  • 工具描述写得像产品文档:预先堵住他们实测中发现的所有模型误用方式。

注意这些细节的性质

「强制绝对路径」不是模型能力,也不是 prompt 技巧,它是用确定性代码消除模型的一个已知故障模式。这类「模型容易在哪摔倒,就在哪修栏杆」的工作,是 harness 工程的核心日常,也是模型厂商自己都在认真做的事情。

三、Harness 补偿模型短板的三种机制

把上面案例里的手法抽象一下,harness 对模型短板的补偿无非三条路径。

1. 上下文管理:解决「看不到」和「装不下」

模型的第一短板是上下文窗口有限,且注意力在超长上下文中会劣化。一个中型代码仓库轻松超过任何模型的窗口。harness 的解法是替模型做「信息节食」:

  • 检索与导航:仓库地图(repo map)、符号索引、按调用关系展开,而不是把文件一股脑塞进去;
  • 截断与摘要:长工具输出强制截断、旧轨迹压缩成摘要(Claude Code 的 compaction 就是典型);
  • 子智能体隔离:把「探索」这类高token、低信息密度的任务丢给子智能体,只把结论返回主上下文。

这套做法现在有个专门的名字:上下文工程(context engineering)。详见上下文工程

2. 错误恢复:解决「会犯错」和「不自知」

模型会幻觉、会写错语法、会在死循环里打转。裸模型对此无能为力,harness 则可以:

  • 即时反馈环:每次工具调用把真实执行结果(编译错误、测试失败、exit code)原样喂回去,让模型在下一轮自我修正——SWE-bench 上成功的 run 普遍要跑几十上百轮;
  • 防错工具设计:像 Anthropic 那样,把已知故障模式消灭在工具层(唯一匹配校验、绝对路径、超时保护);
  • 外部校验:用确定性程序(linter、类型检查、测试套件)做裁判,而不是相信模型的自我评估。模型说「修好了」不算数,测试绿了才算数。

3. 工具兜底:解决「做不到」

有些事模型本质上不擅长:精确计算、长字符串的逐字节处理、记住三天前的状态、访问实时信息。harness 的原则是凡是能用确定性代码做的,绝不让模型用概率生成去做

  • 算数交给计算器/代码执行,不让模型口算;
  • 文件 diff 交给 str_replace 工具做精确匹配,不让模型重写整个文件;
  • 跨会话状态交给文件系统和记忆模块,不依赖模型的「记性」。

一个粗略但好用的判断标准:每当你发现自己在 prompt 里「恳求」模型仔细做某件机械的事(「请务必逐字符核对……」),多半说明这件事应该从模型手里拿走,变成工具。

四、反向的箭头:模型进步如何改写 Harness

如果故事只讲到「harness 很重要」,那只是个静态结论。真实的历史是一条双向道:模型每一代进步,都会内化掉一批昨天的 harness 技巧。这个现象常被称作能力外溢(capability overhang)的消化过程——模型里早已存在、但需要外部技巧才能激发出来的能力,被下一代模型直接训练进了权重。

几个已经发生的内化:

昨天的 harness 技巧今天的模型能力
在 prompt 里写「让我们一步步思考」(CoT prompting)推理模型(o1、DeepSeek-R1 等)把长链思考直接训练进模型,思考过程成为原生输出
手写 ReAct 循环,用正则解析 Thought/Action/Observation原生工具调用(function calling),结构化输出由模型直接生成,解析器消失
精心维护少样本示例(few-shot examples)指令遵循能力强化后,零样本 + 清晰指令通常足够
多智能体辩论/投票来减少错误单模型 + 长思考的可靠性提升,很多「自我辩论」被一次前向推理吸收

Anthropic 在「Building effective agents」(2024 年 12 月)里给出的建议正是这种动态观的体现:最成功的实现不是用复杂框架堆出来的,而是「简单、可组合的模式」;并且「给模型尽可能多的控制权,骨架保持最小」。模型越强,harness 越应该做减法——因为复杂的预设流程会束缚一个本来有能力自己规划路径的模型。

这对你意味着什么

不要把 harness 里的技巧当成永久资产。设计每个机制时问一句:**「这是在补模型的短板,还是在替模型做它其实已经会做的事?」**前者(沙箱、权限、测试校验、防错工具)会长期保值;后者(繁琐的输出格式约束、硬编码的工作流)大概率在下一代模型发布时变成负债——它不但没用,还会限制新模型的发挥。

五、「套壳」之争的再认识

理解了上面两节,就可以重新审视那个自 2023 年以来争论不休的问题:「不就是个套壳(wrapper)吗?」

这个嘲讽隐含的前提是:价值全部在模型层,外围系统只是肤浅包装。历史给过这个嘲讽两次相反的判决:

判决一:纯 prompt 套壳确实死了。 那些只做「把用户输入包进一段精心写的 prompt」的产品(早期的写作助手、角色扮演聊天),在模型迭代中被成片碾过——因为它们的价值恰好是「模型暂时做不到的事」,而模型进步专门消化这类价值。

判决二:但系统级 harness 活了下来,而且越来越值钱。 Claude Code、Cursor、Devin 这些产品和「调一次 API」之间的距离,是沙箱隔离、权限系统、工具生态、上下文装配、可观测性、团队工作流——这些是软件工程资产,不随模型换代而贬值,反而因为模型变强而增值(更强的模型让同一个 harness 产出更高的上限)。

所以「套壳」之争的正确提法不是「壳有没有价值」,而是:

判别标准

一个 harness 的价值 ≈ 它积累的不会随模型进步而蒸发的工程资产——环境、工具、数据飞轮、工作流集成——减去它依赖的将被模型内化的临时技巧。前者越厚,护城河越深;后者越厚,越危险。

SWE-bench 榜单是这层道理最直白的注脚:几十个团队用同一个模型,分数天差地别。如果壳不重要,这些分数应该挤在一起;它们没有,说明壳里装的根本不只是 prompt,而是完整的、难以复制的系统工程。

六、对工程师的启示:在模型层还是 Harness 层投入

落到决策上。假设你资源有限,该往哪层投?

你的处境建议理由
做产品/业务落地的团队坚定投 harness,模型用最好的商用 API模型层是万亿美元军备竞赛,你玩不起;harness 层是你唯一能积累的差异化资产
做模型训练的团队投模型,但用 harness 反哺训练agentic 能力本身就是训出来的(工具使用、长程任务);harness 产生的轨迹数据是训练燃料
研究者把 harness 当一等研究对象,而非附属工程ACI、上下文管理等方向已经证明能发顶会(SWE-agent 是 NeurIPS 论文)
个人开发者先精通 1–2 个成熟 harness,再尝试造轮子理解 Claude Code / Aider 的设计决策,比从零写一个脚手架学到的多得多

三条更具体的行动准则:

  1. 换模型前先榨干 harness。 模型迭代每季度一次,harness 迭代可以每周一次。榜单证据表明,同一模型下 harness 优化动辄带来两位数百分点的提升——这比等下一代模型便宜得多。
  2. 建评测,再谈优化。 没有自己的任务评测集,你无法区分「这次提升来自模型升级还是骨架改动」,也无法发现「新模型让某个旧技巧变成了负优化」。
  3. 为「模型换代」做架构准备。 把 harness 中「补模型短板」的部分(格式约束、分步引导)设计成可拆卸的模块;当新模型发布时,你的第一反应应该是尝试删掉它们,而不是叠加新的。

延伸阅读

参考资料