Agent瓶颈不在模型而在harness:从运行结果反馈迭代与迁移
1. 为什么我觉得这篇论文值得读两遍:Agent 的瓶颈往往不在模型,而在 harness
最近把 Johns Hopkins 和 CMU 合作的那篇关于“小模型通过运行结果改进 Agent harness 代码并迁移到新任务”的工作认真读了几遍。说实话,我一开始是被标题吸引的,因为我自己做 Agent 应用开发时,最头疼的不是模型推理能力不够,而是外面那层 harness 总在关键时刻掉链子。所谓 harness,简单说就是 Agent 与外部世界之间的脚手架代码:工具调用怎么定义、上下文怎么拼、动作输出怎么解析、失败怎么重试、日志怎么埋点。模型再强,把这层代码写烂了,Agent 照样跑不出结果。我自己就见过不少项目,换了更强的模型后表现没提升多少,反而是把 harness 里一个解析 bug 修掉之后,成功率直接上一个台阶。
这篇论文真正戳中我的点是它把问题反过来看了:与其让工程师手工去调 harness,不如让模型自己去改 harness,而且特意强调用小模型而不是 GPT-4 级别的大家伙。原因是 harness 的迭代优化是一个非常消耗 token 的过程,一轮实验可能要跑很多次完整 Agent 轨迹,如果用大模型在循环里反复改代码,成本会迅速失控。小模型虽然写复杂业务代码吃力,但 harness 代码往往结构性强、模式固定,改起来反而是小模型能够胜任的活。更让我觉得有价值的是“迁移”这层:作者团队不只是想在单个任务上把 harness 调好,而是希望模型从运行结果里学到一种“怎么改 harness”的通用方法,换到新任务时能直接复用。这个思路如果成立,意味着我们能从“针对每个任务手工调 harness”升级成“用一套自动化的 harness 优化机制去适配任意新任务”。
所以这篇博文,我会从论文的核心机制讲起,再拆解迁移能力为什么值钱,最后落到我们日常做 Agent 开发时能借鉴的实操方法。适合的人有两类:一类是正在做 Agent 框架、编排层、工具接入的工程师,这类人应该能在论文里看到自己踩过的坑;另一类是对模型自我改进、自动机器学习感兴趣的读者,论文里“从运行结果反推代码修改”的实验设计也相当有代表性。
1.1 Agent 真正的隐性短板:harness 才是性能分水岭
很多人对 Agent 有个误解,觉得只要模型够聪明,Agent 就能自动干好活。但实际开发中你会发现,模型只是决策大脑,真正让决策落到行动上的是 harness。我举一个最常见的例子:模型已经知道要调用一个天气查询工具,但工具 schema 里把参数名写成了location,模型输出的是city,如果 harness 没有做别名映射或者模糊匹配,这一次调用就直接失败了。又比如模型返回了一段带 markdown 的 JSON,harness 如果用严格解析器去解,大概率抛异常;如果用宽松解析器配合错误重试,就能救回来。这些细节既不影响模型本身的推理能力,又对最终成功率有决定性影响。
论文对 harness 的理解比我们日常说的还要宽一点。它不只是工具封装层,还包括系统提示词的组装逻辑、Agent 循环的执行顺序、上下文窗口的裁剪策略、出错后的重试机制、甚至日志格式。这些代码决定了模型每走一步能看到什么信息、能做什么动作、出错时能不能自我纠正。作者团队之所以把优化目标定为 harness,是因为在大量实验里发现:给定同一个模型,harness 写得好不好,可能直接造成数十个百分点的成功率差距。这和我们做工程时的体感完全一致——同一套大模型底座,有人能用出 80 分的效果,有人只能跑出 30 分,差别往往不在模型,而在外面这层“缰绳”。
还有个工程上的原因让 harness 成为瓶颈:模型能力是外部给定的,很难在项目周期内快速提升,但 harness 是我们自己代码仓库里的东西,想改就能改。把优化火力集中在 harness 上,本质上是在“自己可控的范围内”做性能挖潜。这也是我觉得论文工作“接地气”的原因,它没有要求你去微调模型、重训底座,而是把功夫花在 Agent 外围的代码上,这对绝大多数团队来说才是可行的路径。
1.2 论文的出发点:小模型也能干 harness 优化的活
为什么专门强调“小模型”?这里有个现实约束:harness 的自动优化需要反复执行“生成修改 → 跑验证任务 → 看结果 → 再修改”的循环。每一轮迭代都要消耗不少 token,如果用大模型来当“优化器”,一次实验跑下来成本很高。更麻烦的是,大模型 API 往往有并发限制和延迟,会让整个迭代过程变得又慢又贵。而 harness 代码的特点是结构套路化、修改点集中,很多时候就是改改工具描述、调调重试逻辑、换换提示词格式,并不需要很强的创造力。小模型在这类“局部修改”任务上完全够用。
论文里有个我印象很深的设计细节:它不是让小模型凭空生成一版新 harness,而是让小模型基于当前运行轨迹,做差异化的修改。也就是说,模型只需要给出“哪里不对、改成什么”的修改说明,而不是重写整个文件。这大大降低了任务难度,也让小模型的成功率高了很多。这和咱们写代码时“在旧代码基础上打补丁”而不是“推倒重写”是同一个道理。
当然,小模型也有明显的短板,比如上下文长度受限、推理深度不足、容易在复杂逻辑里绕晕。论文对此的处理方式是把迭代过程拆得很碎:运行结果里的反馈信号被结构化地提取出来,模型只需要看一小段关键信息,而不是把整条轨迹都塞进去。这种“把复杂问题拆成小步”的设计,既是工程实践里的常用手段,也恰好是让小模型能上的关键前提。
1.3 适合谁读、读完能拿去干什么
如果你是 Agent 应用开发者,这篇工作最直接的启发是:你的 harness 值得被当成“一等公民”来看待,而不是随便糊弄过去的胶水代码。读完你可以照着论文的迭代思路,给自己项目加一个“harness 自动优化”的实验脚本:跑一批任务、收集失败轨迹、让模型分析原因并输出修改建议、人工确认后合入代码。这套流程不需要复现论文的全部实验,哪怕只把“从运行结果反推 harness 问题”这一步用起来,就能在日常开发里省下大量排查时间。
如果你是做 Agent 框架、平台层的人,论文对“迁移”的处理值得仔细琢磨。它展示了一种可能性:把在源任务集上优化 harness 的经验,沉淀成可复用的知识,让新任务不用从零开始调。迁移能力如果做好了,等于给 Agent 平台装了一个“自适应优化”的引擎,新任务接入时的初始效果会好很多。这一点对需要同时维护大量 Agent 应用的团队来说尤其有价值,因为手工为每个任务调 harness 的成本实在太高了。
2. 论文核心机制:从运行结果里提炼反馈信号,驱动 harness 迭代
论文的整个机制可以浓缩成一句话:让 Agent 跑起来,把运行结果变成“修改说明书”,再让模型照着说明书改 harness。听起来简单,但每个环节都有不少讲究。我按自己的理解把它拆成几个关键步骤来看。
2.1 看运行结果找线索:失败轨迹里藏着修改方向
先说“运行结果”到底是什么。它不只是最终成功或失败这个二元结果,而是整条执行轨迹:Agent 在每一步看到了什么观察、输出了什么动作、工具返回了什么内容、在哪一步开始偏离、上下文是否被截断、重试机制有没有生效。论文里的做法是把这些轨迹做结构化整理,重点提取几类信号。
第一类是失败点定位,也就是动作序列里第一次出错的位置。是工具调用格式错了?还是模型生成了不存在的动作?还是观察太长把上下文撑爆了?不同错误类型对应不同的 harness 修改方向。比如格式类错误,可能需要调整输出解析器的宽容度;上下文溢出,则要改压缩策略或裁剪逻辑。
第二类是中间状态评估。即使最终任务失败,Agent 也可能已经完成了部分子目标。论文会记录这些中间进展,比如在网页操作类任务里已经填好了某个表单字段,但在提交时出错。这类信息能帮助模型判断:是 harness 阻碍了某类动作,还是任务本身太难。
第三类是稳定性信息。同一任务跑多次,可能有时成功有时失败,论文会用多次运行的统计来过滤噪声。单次失败可能是随机性导致的,但如果一个特定类型的错误反复出现,就说明 harness 里大概率存在系统性缺陷。这个思想跟工程里的稳定性测试很像,我平时排查 Agent 问题时也会反复跑同一任务来确认是不是偶发问题。
2.2 迭代循环怎么一步步落地:生成、评估、沉淀
论文的迭代循环可以拆成四个阶段。第一阶段是初始化:给 Agent 配一套初始 harness,可以来自模板、人工编写或者模型生成。第二阶段是执行与收集:用这套 harness 在验证任务集合上跑,采集完整轨迹和结果,按上一节说的方式提取信号。第三阶段是修改生成:把提取出的信号、当前 harness 代码、失败的轨迹片段打包,交给小模型,让模型输出针对 harness 的修改补丁。这里关键是把信息组织得足够清爽,模型不需要看完整轨迹,只需要看到和失败强相关的片段。
第四阶段是验证与保留:新的 harness 在同样的验证任务上重新评估,如果成功率提升或者成本下降,就保留这次修改,否则回退。这里有个细节:论文强调修改要“小而明确”,每次只改一个点,这样归因才清楚。如果一次改动堆了很多变化,出了问题根本不知道是哪个环节引起的。这种“单变量实验”的思维,和我日常调 Agent 时的习惯完全一致。
这里我可以顺带提一个工程上的注意点:任何自动优化 harness 的流程,都必须有代码回退机制。小模型给出的补丁不一定能直接合入,可能是语法错误、逻辑冲突,甚至和项目其他部分不兼容。论文的实验里那些能跑的补丁,背后一定有大量的合入校验和回退兜底。我们自己在项目里借鉴这套思路时,也一定要把 harness 的版本管理做起来,每次修改都留快照,迭代坏了能一键退回。
2.3 为什么这种迭代比“换更强的模型”更划算
其实这背后有个容易忽略的经济账。假设我们用一套 harness 跑 100 个任务,发现成功率只有 40%,常见思路是换一个更强的大模型,指望推理能力提升能带来收益。但大模型 API 的单价通常是几十倍差距,如果 100 个任务里大部分失败都源于 harness 的格式解析、工具定义、重试策略问题,那换模型是“用高成本掩盖低层缺陷”。论文的方式是让模型在循环里小步修改 harness,每次改动只花小模型的生成费用,而评估时用的还是现有底座模型。这样就把优化成本从“全部任务的推理费用”压缩到了“少量修改迭代的生成费用”。
另一个划算的地方是积累效应。换强模型是一次性的,下次任务还是得继续烧钱用强模型;而 harness 优化产生的代码和知识是沉淀在仓库里的,越迭代越完善。这和咱们常说的“复用”本质一致,一次优化的产出可以反复使用,长期来看边际成本很低。论文的实验里也提到,优化后的 harness 不仅在目标任务上表现更好,还能作为新任务的初始版本,相当于把一次迭代的成果变成了后续所有任务的起跑线。
3. 迁移能力:从“调好一个任务”到“掌握调 harness 的方法”
单任务优化已经很实用了,但论文真正让我兴奋的是迁移部分。如果只是把某个任务的 harness 调到最优,那价值还是有限的;能把“调 harness 的方法”本身学到手,换到新任务也能快速上手,才是自动化优化的终局形态。
3.1 迁移是怎么实现的:从任务级优化到元技能沉淀
我理解的论文设计思路是这样:先在多个“源任务”上执行上一节说的迭代循环,让模型在大量“运行结果 → harness 修改”数据上积累经验。这些经验不是某个任务的特定答案,而是一种模式识别能力:看到这类的失败轨迹,就知道大概率是哪种 harness 问题,应该往哪个方向改。比如反复出现“工具返回 JSON 但模型输出被截断”,模型就能学会“加大输出 token 上限或者启用流式解析”这类通用的修改策略。
迁移到新任务时,论文把源任务上学到的这种“调试知识”作为上下文示例注入给模型,再结合新任务的少量运行结果,让模型在初始 harness 基础上直接做出有针对性的修改。这种做法本质上就是少样本学习:与其让模型在新任务上重新摸索错误模式,不如把已经总结好的错误模式示例直接递到它面前。这就好比一个老工程师换到新项目,虽然具体业务不熟,但“看到登录超时就查会话管理、看到解析报错就看序列化配置”这类经验能直接平移过去。
还有一个细节是:论文并没有把迁移做成一个黑盒模型,而是保持了解释性。每次迁移修改都能说明是根据哪个经验、针对哪个现象做的。这种可解释性在实际工程里很重要,因为我们不可能完全信任自动生成的代码,总归要有人去 review。如果系统能给出“为什么这么改”的说明,review 成本就低很多。
3.2 实验中看到的跨任务效果:不是玄学,是真能落地
论文的实验设置大致是:在多个公开的 Agent benchmark 和自建任务上训练迭代,然后拿这些经验去初始化新任务的 harness,再跑少量迭代。我看到的几个关键结论很有参考价值。第一,迁移后新任务的初始成功率明显高于从零开始,说明源任务积累的经验确实起了作用。第二,达到同等成功率所需要的迭代轮数大幅减少,这等于节省了最消耗资源的那部分试错过程。第三,跨任务迁移在任务类型越相似时效果越明显,比如同为网页操作类任务,但网站结构不同,迁移收益非常大;而如果从网页操作迁移到代码生成类任务,收益就会打折扣。
这几个结论其实揭示了迁移的适用边界,也让我对“Agent 通用性”有了更务实的理解:完全的零样本跨域迁移还很遥远,但同域内的快速适配已经在论文里被验证可行。这个“同域适配”的能力在业务场景中特别有用。举个例子,如果一个平台要接入十家不同电商网站的数据抓取 Agent,每家网站的页面结构都不同,手工适配成本极高;论文的方法可以让系统先在一个网站上积累 harness 调试经验,然后快速适配到剩下九家,把每个网站的适配周期从几天压缩到几小时。
3.3 迁移的边界:什么情况下会失效
任何方法都有边界,论文也没有回避这一点。我总结下来,迁移失效主要有三种场景。第一种是任务形态差异过大,源任务都是“多轮工具调用类”,新任务却是“纯文本生成类”,harness 要处理的核心问题完全不同,迁移自然没效果。第二种是反馈信号稀疏,新任务如果只能拿到成功/失败标签,而拿不到中间轨迹和部分进展,模型很难定位 harness 问题,迁移就成了无米之炊。所以论文反复强调结构化运行结果的价值,这也是为什么做 Agent 工程一定要把日志和 trace 埋点做扎实。第三种是harness 抽象层次不匹配,如果两个任务的 harness 结构本身差异太大,迁移过去的知识可能根本不适用。
考虑到这些限制,我对迁移能力的定位是:它是一个“加速器”而不是“万能引擎”。它能让新任务的起点更高、迭代更快,但不能保证一步到位。在做工程规划时,把迁移当作一个降低冷启动成本的手段,而不是替代人工 review 和最终验证的方案,是比较现实的预期。
4. 这套思路对日常 Agent 开发的实操启示
论文看完了,回到我们自己项目里,最值得借鉴的不是“复现整套实验”,而是把几个关键思想拆出来,用在日常开发中。这里我结合自己做 Agent 应用时踩过的一些坑,给出几条可以直接上手的思路。
4.1 先把自己的 harness 变成“可观测”的
论文的一切都建立在高质量运行轨迹之上,没有轨迹就没有反馈信号,没有反馈信号就不可能自动优化。但现实是很多项目的 harness 几乎没有观测能力:Agent 跑挂了,只能看到一句“任务失败”,不知道中间每一步发生了什么。我自己早期做 Agent 项目时就吃过这个亏,排查问题只能反复在代码里加 print,效率极低。
现在我做 Agent 项目,harness 里一定会埋三类日志。第一是动作轨迹:每一步的输入和输出都记录,包括工具调用参数和返回结果;第二是状态快照:上下文长度、重试次数、当前已消耗 token 这些环境变量;第三是异常事件:解析失败、超时、格式不匹配这类 harness 层错误,必须单独标记。这些日志在平时是排查利器,在论文的框架下就是自动优化的反馈数据源。不用全量存,存最近几百条就够用,关键是结构化和可查询。
4.2 用 7B 级别模型小成本迭代 harness 的落地姿势
论文里用的小模型,落到国内开发者的现实场景里,就是 7B、13B 这类开源小模型,或者便宜的 API 中间档。用它们做 harness 优化,我建议走这样一条流程。先用一套基线 harness 在验证集上跑出一批结果,把失败轨迹按错误类型分组;然后挑几类高频错误,把对应的轨迹片段和 harness 代码片段一起喂给小模型,让它给出修改建议;再人工 review 一下建议,挑合理的部分合入;最后重新跑验证集对比效果。
这个过程要注意的是,别把小模型当成自动代码生成器。它更适合做“错误分析员”和“修改建议器”,而不是“代码编写器”。我试过让小模型直接改一个复杂的重试逻辑,结果改得一塌糊涂;但让它先分析“这类错误是什么原因造成的、应该改哪一块”,再输出简要的修改要点,这些要点反而经常能直接给我指出正确方向。所以落地姿势很重要:合理分工,小模型做分析和建议,人类做决策和关键代码编写。
另外,迭代的评估集合不能太小。至少要保证每个任务类型有代表性的场景覆盖,否则很容易调出只在测试集上有效的 harness,一换数据就露馅。论文里做实验时对评估集的选择也很讲究,这个思路我直接搬过来了。
4.3 几个可以立刻用起来的工程抓手
如果不想搞得太复杂,论文里至少有四个点可以立刻在自己的 harness 工程里落地。
第一,给 harness 修改流程加“单变量验证”纪律。一次只改一个点,改完立刻跑回归,用数据说话。这条看似朴素,但能救回大量被“多个改动叠加导致问题定位不清”折磨的调试时间。第二,建立错误类型标签体系。先跑一批任务,把错误归类成“动作格式错误”“上下文截断”“工具返回解析失败”“重试策略失效”等几个高频类型,再针对每个类型积累对应的修改方案。这套标签体系本身就是知识资产,论文里的迁移就是把这种资产复用到新任务。第三,把“从运行结果到修改建议”沉淀成固定模板。我现在的做法是:每条失败轨迹都自动生成一个结构化摘要,包含失败步骤、期望结果、实际输出、初步定位方向,直接存进团队的知识库。新项目遇到类似问题时,先搜知识库再重新排查,效率高很多。第四,给 harness 的每次改动做版本快照,支持一键回退。论文里的小模型迭代天然需要一个安全的修改环境,我们的工程环境也一样,改 harness 最怕的是一通操作后项目跑不起来了,回退机制是底线保障。
这里我也想特意提一下热词里频繁出现的“harness 工程”“Agent 框架与编排”。很多开发者找这方面的资料,说明大家其实已经意识到 harness 不是可有可无的胶水,而是 Agent 系统的骨干。论文提供的价值在于,它给这种直觉提供了一个系统化的方法论:把 harness 当成一个可以持续优化的对象,用反馈驱动的方式让它越变越好,而不是写完就丢在角落。
5. 常见误读与避坑指南
读这篇论文时我也看到不少社区里的讨论,有些理解存在偏差。整理几个典型的误区和实操中的大坑,给大家排排雷。
5.1 别把 harness 当成万能药
有一类观点是“模型不重要,harness 好就一切都好”,这跟“harness 无用论”一样危险。论文的实验背景是模型已经具备一定能力的情况下,harness 的改进能显著提升效果,但它不等于模型能力可以无限压缩。如果一个模型本身的指令跟随能力很差,连基本工具调用都做不好,harness 写得再精致也只能兜底到一定程度。我在实践中会把模型能力和 harness 当成一个整体来调优:先确认模型在当前任务上有基本能力下限,再投入精力优化 harness。否则可能花了大力气调 harness,最后发现还不如直接换一个更强的模型来得快。
5.2 反馈信号质量差时,迭代会原地转圈
这是我在借鉴论文思路时踩过最深的坑。如果运行结果记录不完整,或者反馈信号里混杂了大量噪声,模型从里面学不到有效规律,迭代就会在原地转圈。我有一次尝试自动优化一个 Agent 的提示词模板,跑了五轮迭代,成功率都没动。后来排查发现,是埋点代码本身有 bug,导致所有失败轨迹都记成了同一种错误类型。所以做自动优化前,先花时间把观测层做扎实,这比优化本身更重要。论文里能迭代得动,是因为它把轨迹信号做得非常细致,各种中间状态都记录在案,绝对不是只靠一个最终成功率的数字。
5.3 迁移不是玄学:注意任务同质性假设
“迁移到新任务”听起来很美,但如果不注意任务之间的同质性,很容易产生预期落差。论文实验里迁移效果好的场景,是任务核心结构相似的情况,比如同样是“多步工具调用 + 外部环境反馈”的任务形态。如果硬要把一个对话类任务的经验迁移到一个纯代码生成任务上,基本等于白搭。我的建议是:在项目里做迁移时,先按任务形态画一个谱系图,把任务分成几大类,迁移只在同类别内部进行。这样既可控,又容易判断迁移是否成功。另一个提醒是,迁移效果的好坏要用“初始成功率提升幅度”来衡量,而不是看最终能不能达到 100%。它的定位是帮你缩短冷启动时间,不是保证一步到位。
论文里关于“从运行结果学会改进”的核心思想,其实和我平时调 Agent 时最朴素的习惯一脉相承:先看失败日志,再反推代码问题。只不过论文把这个过程系统化、自动化,让小模型在循环里扮演了分析员的角色,还把积累下来的调试知识搬到了新任务上。读完之后我最深刻的体会是:harness 值得被当成产品一样持续打磨,而不是一个写完就再不管的附属品。我现在的项目里,已经按照“可观测、可迭代、可回退”的标准来重构 harness,并且开始用一套小脚本辅助分析失败轨迹和生成修改建议。虽然离论文里全自动的形态还有距离,但光是“把失败归类和修改方向沉淀成知识库”这一步,就已经让我在新任务接入时省了不少力气。最后分享一个小习惯:所有 harness 的调整,我都要求配一条“修改前 → 修改后 → 效果对比”的记录,这既是给自己积累调参经验,也是将来做自动化优化时最好的训练数据。