扩张 Harness,而不是堆上下文:从无策略脚手架到可复用专家 Agent
Agent 产品里有一种很常见的惯性:任务一复杂,就往上下文里再塞一轮提示、再塞一段历史、再塞一份「经验摘要」。短期看,模型似乎更懂事;中期看,token 账单和注意力都被拉长。中科院深圳先进院与合著者在 arXiv:2609.26760 提出的 Growing Harness,把问题换了个方向——别让模型在每一次任务里重新发明同样的控制决策;把反复出现的控制长成可执行代码,把上下文留给任务特有的证据与语义判断。
这篇不是热榜软新闻,而是一条可以和站内既有 harness / Skills / 确定性流水线对照的机制文。论文主张可以压成一句话:扩张 harness,而不是堆上下文。
为什么值得单独写长文?因为 2026 年公开讨论里,「上下文」几乎成了默认扩容旋钮:窗口更大、摘要更勤、记忆更长、Skills 往 system prompt 里塞得更多。这些旋钮都能买到短期收益,却很少强迫团队回答一个更硬的问题——哪些控制决策其实已经稳定到不该再占用模型上下文? Growing Harness 用可复现实验把这个问题钉住:在两个任务族、三档部署模型上,把控制沉进代码之后,成功率可以不掉(多数设定还升高),调用与成本却大幅下降。长期主义内容要的就是这种「机制 + 边界 + 可核对数字」,而不是又一条「Agent 又变强了」的标题党。
问题不在「会不会调工具」,而在「同样的控制为什么每次都要再推一遍」
部署里的 Agent 很少只跑一次孤立任务。更常见的是:同一任务族、同一工具接口、同一模型后端,反复处理目标不同、观察不同的实例。目标与观察会变,但外围控制往往重复——改查询、过滤观察、校验进度、从错误恢复、决定何时停下。
标准做法是把这些决策继续委托给 LLM:每次轨迹里再推理一遍。灵活,但每一步都要再付一次推理成本,并把提示、观察、输出继续堆进越来越长的执行历史。站内 Claude Code Agent Harness 已经从生产循环里拆过一层:真正让 Agent 活下来的,往往不是教科书里的五步 ReAct,而是上下文压缩、流式执行、错误恢复、权限与中断——也就是 harness。Growing Harness 把同一条线索推得更远:如果控制本身是可学习对象,能不能从任务反馈里长出来,而不是事先写死,也不是每次都塞回 prompt?
论文的中心问题因此很具体:在固定模型与工具接口下,一个不预先编码任务求解控制器的脚手架,如何从任务反馈中增长,使它不再要求 LLM 去重建本可以用代码执行的行为?
无策略脚手架:低先验承诺,而不是「空程序」
作者把起点叫 strategy-free scaffold(无策略脚手架)。它暴露任务入口、固定的 LLM 与工具接口,但不编码完整的任务求解控制器——例如不自带 ReAct 式工具调用循环。模型与工具仍可被调用,因此 LLM 中介的 Agent 仍在假设空间内;真正要学习的对象只有 harness 程序 (h)。
低先验承诺有两个含义。第一,不把「正确控制结构」写死在初始化里;BrowseComp-Plus 最终长成共享检索与证据校验流水线,WebArena-Verified 最终长成带确定性解析器、学习型控制例程、回退浏览器控制与完成态校验的分层程序——同一类种子,不同任务族,结构可以分叉。第二,优化器不被要求在既有控制器上打补丁;它可以从弱初始化增长可执行控制。
这和「先手写一个很强的 agent loop,再靠 prompt 微调」不是一条路。也和「把经验存成自然语言 workflow,下次再检索进上下文」不同:持久化产物是共享 harness 本身,被接受的修复变成后续任务直接跑的程序路径,而不是再解释一遍的文本。
Growing Harness 怎么长:失败窗口、函数级轨迹、闸门回滚
方法可以看成三条互相咬合的机制(论文 Algorithm 1)。
第一,失败窗口课程。 训练时维护容量为 (K) 的当前失败窗口,而不是反复优化已经解决的任务。优化器对窗口内失败联合修复,以鼓励跨任务可复用行为;修好的离开,未解决的保留新轨迹并累加尝试次数,超过 (R_{\max}) 则退役。窗口迫使模型看到「一类失败」,而不是「这一题的特例补丁」。
第二,函数级轨迹定位编辑面。 每次失败执行记录函数级执行图:哪些 harness 函数、模型调用、工具调用与错误参与了轨迹。优化器只允许改入口函数与失败轨迹中出现过的函数,并可新增少量可复用 helper,编辑预算 (L) 限制改动规模;未触及函数保持不变。方向也很明确:把解析、校验、状态更新、条件化查询 refinement、错误恢复、停止条件等确定性、可复用控制写成代码;把解释、综合、模糊比较、答案生成等任务依赖语义留给 LLM。
第三,成功优先的持出闸门与事务式回滚。 候选先在失败窗口上重跑;修好不够就丢弃。更关键的是:相对最近接受检查点,若闸门集成功率下降,则整段修复序列回滚——不仅回滚代码,也回滚任务游标、失败窗口与训练记录。论文明确写了 success-first:更低在线成本不能补偿更低闸门成功率。这正是持续优化 harness 时最容易踩的坑——局部修好、整体退化。
三条合起来,对应三个技术挑战:什么该变代码、什么该留模型调用;如何在程序变大时仍只优化活跃执行切片;如何避免脆性规则与能力回退。
数字只报告论文里有的:成功、调用次数、成本与消融
实验在 BrowseComp-Plus(深检索)与 WebArena-Verified(多步网页)上,各用 200 / 50 / 50 的训练、闸门、终评划分;部署模型为 gpt-oss-120b、gpt-oss-20b、Qwen3.5-4B。基线按基准适配:浏览检索侧含 Tool-Calling、Self-Ask、IRCoT;网页侧含 Tool-Calling、WebDreamer、AgentOccam。指标是三次独立终评的均值,不挑多试最优。
主结果可以诚实概括如下(均来自论文 Table 1 与正文,不外推):
- 六个「基准 × 模型」设定里,Growing Harness 在五个上取得最高平均成功率;剩下一个平均成功率只比最佳低 0.7 个百分点。
- 相对 Tool-Calling,LLM 调用次数下降 76.0%–91.8%,部署 Agent 推理成本下降 74.4%–98.6%。
- 在 WebArena-Verified 上,其成功率在三个模型尺度间保持 44.7%–45.3%;同一设定下 Tool-Calling 在 4B 模型上落到 6.7%。论文据此强调:把反复出现的浏览器控制沉到代码里,对小模型与资源受限部署尤其有价值。
消融(BrowseComp-Plus、部署模型 gpt-oss-20b、单次优化 10 步)把机制拆开:完整方法终评成功 36%;去掉函数级引导降至 18%;去掉闸门验证降至 22%;把失败窗口容量设为 1 降至 28%。去掉闸门时,闸门成功率曾升到 30% 再掉到 16%——正是「修好当前失败、毁掉既有能力」的轨迹。这些数字说明:轨迹局部编辑、联合修复、闸门回滚不是装饰,而是互补。
收敛形态也不同:BrowseComp-Plus 更像共享检索与校验流水线的早期跃升;WebArena-Verified 更像在通用浏览器回路周围逐步挂上 Shopping / Reddit / Map 等专用处理。任务族塑造控制器——这正是低先验承诺想要的结果。
学到的程序长什么样:流水线 vs 分层控制器
附录里的事后抽象(Figure 6)值得单独读一遍,因为它说明「无策略」不是「无结构」,而是结构由任务反馈涌现。
BrowseComp-Plus 一侧,学到的 harness 更像一条共享检索与证据校验流水线:查询生成、证据收集与压缩、答案核对走同一条主干。于是对主干的修复会迁移到闸门任务,而不是给每道题长出私有分支——这也解释了训练早期闸门成功率为什么跳得快。WebArena-Verified 一侧则不同:在通用 LLM 引导的浏览器回路周围,挂上确定性解析器、学习型控制例程、回退浏览器控制,以及显式的完成态校验;Shopping、Reddit、Map 等任务类型可以增加专用处理,而不必重写其他类型还在用的路径。
对产品经理,这句话翻译过来是:你不必先赌「全公司统一一个超级 Agent 循环」。如果你服务的是稳定任务族,让控制器从失败里长,往往比先开一场架构委员会更贴近数据。对工程师,这句话翻译过来是:观察最终代码的控制图,比只看成功率更重要——你要确认增长出来的是共享主干还是特例森林。特例森林在训练集上也好看,一换分布就碎。
论文还提醒:两个基准的训练配置不同,因此「流水线 vs 分层」应理解为这两次运行的描述,而不是对任务难度的严格对比。读法保持克制,反而更有用:同一套增长算法,在不同反馈结构下会收敛到不同可执行形态。
相关工作放在哪一层:提示优化、技能库、Harness 搜索
把 Growing Harness 塞进「又一个 agent 框架」会低估它。更准确的坐标是:
- 推理时控制(ReAct、Self-Ask、IRCoT、Reflexion)证明控制很重要,但循环结构通常事先指定,许多决策仍以文本历史形式反复计算。
- 跨任务经验(ExpeL、Agent Workflow Memory、Voyager、LATM、CRAFT)证明经验可以摊销;文本洞见要检索再解释,技能/工具则常挂在既有 Agent 结构之后。Growing Harness 的持久化对象是共享控制器本身。
- 语言模型程序优化(DSPy、MIPRO、TextGrad、GEPA、AFlow、ADAS)把提示、模块与工作流结构当作可学习对象。Growing Harness 强调的是从无策略脚手架出发的持续程序增长:失败指出缺什么,轨迹局部编辑补什么,接受的更新在任务流上累积。
- 直接优化 harness(AutoHarness、Meta-Harness、VeRO 等)已经把「模型外围的代码与配置」当成优化面。本文区分点不在「会不会合成代码」,而在:开放式全局增长 + 失败条件化的局部优化 + 从无策略脚手架起步,并用闸门事务挡住连续更新里的能力回退。
如果你已经在用 Skills 或跨 harness 运营系统,不必二选一。Skills 解决「人写好的流程如何被多运行时加载」;Growing Harness 解决「机器如何把反复失败变成可执行控制资产」。一个偏分发与治理,一个偏从反馈中生长控制器。
对照一:「再塞一点上下文」为什么不是同一条路
堆上下文的隐含假设是:只要模型看见更多历史、更多规则、更多经验摘要,它就会在下一次轨迹里「自己想起来」该怎么控制。Growing Harness 的反驳是结构性的——
- 重复控制不该占用语义带宽。 长历史抬高输入成本,也可能让真正相关的证据更难用上;论文引用了长上下文利用困难的既有讨论。把查询 refinement、停止条件、错误恢复写成代码,等于从上下文里拿走不必再推理的部分。
- 文本经验仍要被再解释。 ExpeL、Agent Workflow Memory 一类方法把洞见或 workflow 存起来再检索;下次执行仍要把它们读进模型上下文。Harness 增长把已接受行为变成程序路径,边际成本接近普通函数调用。
- 压缩与路由是降成本,不是换结构。 LLMLingua、FrugalGPT、RouteLLM 让调用更短、更便宜或选择性调用贵模型;它们改善的是「怎么打这次电话」。Growing Harness 问的是「这次电话本来就不该打」。
对工程团队,实用判断可以更直白:如果你发现 Agent 在同一任务族里反复犯同型控制错误,优先候选不一定是更大的上下文窗口,而是——这段控制能不能变成可测试、可版本化、可回滚的代码?
对照二:Skills / ECC / 确定性流水线——同向,但层位不同
站内已经有几条相关叙事,最好把层位说清楚,避免把所有「可复用」混成一种东西。
Agent Skills 入门 讲的是能力包如何分发与触发:何时启用、产出什么、怎样验收。Cloudflare 的 security-audit-skill 把安全审计做成可安装 Skill——阶段硬、产物结构化、校验脚本齐全;它甚至自称是内部漏洞发现 harness 的单仓库起点。阿里 Open Code Review 则把「哪些文件必须审、评论落在哪一行」从自然语言里拆出,交给确定性工程。Addy Osmani 的 agent-skills、affaan-m/ECC 这类公开 skill / harness 产品,进一步把可移植 SKILL.md、规则、钩子与跨 harness 适配做成运营系统——它们解决的是工作流如何被安装、触发与在多运行时之间复用。
Growing Harness 不替代这些层。它回答的是另一层:在固定工具与模型下,控制器程序本身能否从失败反馈中增长,并把控制从「每次塞进上下文的策略」变成「共享可执行资产」。 Skills 通常是人类(或团队)编写、按需注入的工作流说明书;OCR / security-audit 强调确定性门禁与校验;Claude Code 式 harness 强调生产循环存活。论文的贡献是:从无策略脚手架出发,用失败引导的程序综合,长出可复用专家 Agent,并在小模型上仍能稳住成功率。
Jev × Claude Code 里「生成与判断拆开」的思路,和这里「语义留给模型、控制沉到代码」是同构的:不是所有决策都值得付一次完整 LLM 调用。差别在于 Jev 讨论的是结构化判断服务如何接入编码 Agent;Growing Harness 讨论的是整段控制器如何被训练成程序。
一句话对照:
| 层位 | 典型产物 | 主要解决什么 |
|---|---|---|
| Skills / 工作流包 | SKILL.md、阶段清单、校验脚本 | 分发、触发、人工可维护的流程复用 |
| 确定性工程门禁 | 文件筛选、定位、schema 校验 | 不能错的步骤别赌模型心情 |
| 生产级 Agent Harness | 压缩、流式、权限、恢复 | 循环在真实环境里别挂 |
| Growing Harness | 从失败长出的共享控制器代码 | 反复控制别每次再推理一遍 |
工程上你能抄什么(以及不能抄什么)
论文结论写得很克制:价值取决于学到的 harness 被复用得够不够,以抵消离线优化成本;真实部署还需要沙箱、明确权限边界,以及对生成代码的验证。结合站内 Agents of Chaos 的失败案例,这一点不能当附录跳过——能改 harness 的优化器,本质上是「会写生产代码的 Agent」;没有沙箱与闸门,增长就是在放大执行面。
可执行的抄法,建议压成清单:
- 先定义任务族,再谈增长。 Growing Harness 假设训练与终评来自同一分布。跨域乱拼失败窗口,学到的多半是特例补丁。
- 把「可沉代码」和「必须留模型」写进优化约束。 解析、状态机、停止条件、schema 校验优先代码;开放解释与综合保留 LLM。这和 OCR「确定性管不能错的、Agent 管必须活的」同频。
- 失败要能定位到函数,而不是只给一个 0/1。 没有执行切片,程序一长大,优化就会退化成整文件乱改。
- 联合看一组失败,而不是一题一补丁。 窗口 (K>1) 是为了逼出共享行为。
- 闸门必须能整段回滚。 局部成功率上升而持出集下降时,默认不该合并。Success-first,而不是 cost-first。
- 离线优化与在线部署模型可以分离。 论文允许优化器用更强模型,部署用更小模型;这正好解释 WebArena 上小模型仍稳住成功率的现象。
- 把生成代码当不可信输入。 沙箱、权限、静态检查、闸门评测,缺一就不要上生产循环。
不能直接抄的,也要说清楚:你没有他们的优化器提示、数据集划分与工具封装,复现的是范式,不是开箱即用的产品。也不要把论文数字当成「任意 Agent 换 Growing Harness 就能降九成成本」的营销句——降幅是相对 Tool-Calling、在两个基准与三套部署模型上的实验结果。
也有几类反模式,建议显式写进团队笔记:
- 把实例答案写进 harness。 论文约束优化器不得编码任务标识、期望答案或固定解。一旦「增长」变成背题,复用就假了。
- 用成本下降为回退辩护。 闸门成功率掉了,却因为调用更少而合并——这直接违反 success-first。
- 没有函数级轨迹就整库重写。 消融里去掉函数级引导后终评腰斩,训练还长时间停滞;程序越大,这个坑越深。
- 窗口永远等于 1。 一题一补丁最容易长出 brittle 规则;联合失败是在逼优化器找共享结构。
- 把离线优化器的工具权限直接接到生产。 能改 harness 的 Agent,攻击面接近「能写部署代码的人」。沙箱与权限边界不是礼貌用语。
若你的系统已经有 Skills,一个务实接法是:Skills 继续承载人类维护的阶段与验收;Growing Harness 一类机制只允许改「被标记为可学习控制」的模块,并且每次接受都要过与业务相关的持出闸门。不要让「自动长程序」与「人工技能包」抢同一块无版本管理的目录。
长期主义意味:上下文是工作区,Harness 才是资产
过去一年,Agent 工程的公开讨论常常围着三件事转:更长的上下文、更强的模型、更多的 Skills。三件事都有用,但它们回答的问题不完全一样。更长上下文扩大的是当次工作区;更强模型提高的是语义上限;Skills 加速的是流程分发。Growing Harness 补的是第四件事:把反复出现的控制从工作区搬进资产表。
资产表意味着:可 diff、可测试、可回滚、可在小模型上复用。当部署从 120B 挪到 4B,Tool-Calling 在 WebArena-Verified 上塌得很厉害,而学到的 harness 仍大致稳住——这不是「小模型突然变聪明」,而是聪明被要求的次数变少了。对端侧、私有化与成本敏感场景,这条路径比「再买一档上下文」更值得长期押注。
它也提醒产品团队:如果你的护城河只写在 system prompt 里,竞争对手复制提示词就能跟上;如果护城河写在经过闸门验证、持续增长的 harness 代码里,复制成本完全不同。Skills 与确定性流水线仍然重要——它们是人类可维护的接口与门禁;Growing Harness 指出,接口背后的控制器本身也可以成为学习对象。
结语
Grow the Harness, Not the Context 给出的不是又一个「多 Agent 编排口号」,而是一套可检验的训练范式:从无策略脚手架出发,用函数级失败轨迹做局部监督,用失败窗口逼出可复用修复,用持出闸门挡住回归,最终把反复控制沉进代码,把模型上下文留给任务特有的证据与语义。
对站内读者,最有用的读法也许是三连:用 Claude Code Agent Harness 理解生产循环要补什么;用 Skills / security-audit-skill / Open Code Review 理解流程如何分发与锁死;再用本文理解——当同一任务族要跑很久,增长对象或许不该是 prompt,而该是 harness。
扩张 harness。别再默认把控制堆回上下文。