Harness 工程说白了,就是围着模型搭系统,把它变成能真正干活的引擎。模型本身是有智能的,但得靠 Harness,才能让这份智能真正用起来。

这篇文章先跟大家说清楚什么是 Harness,再从模型这个最基本的出发点,一步步推导出现在以及未来 Agent 最核心的组成部分。

01

有没有人能把 Harness 讲明白?

其实特简单,Agent = Model + Harness。要是你没在做模型训练,那你干的活儿,多半都属于 Harness 的范畴。说白了,Harness 就是:所有不属于模型本身的代码、配置,还有执行逻辑,都算。

一个光秃秃的模型,可算不上 Agent;只有等 Harness 给它配上状态管理、工具调用能力、反馈循环,还有可执行的约束,它才算真正的 Agent。

说得再具体点,Harness 一般包括这些东西:系统提示词、工具与技能(还有 MCP)以及它们的说明、封装好的基础设施(比如文件系统、沙箱、浏览器)、编排逻辑(像子 Agent 的生成和交接、模型路由这些),还有用来保证执行稳定的 Hook(钩子机制)或者中间件(比如上下文压缩、续写机制、Lint 检查之类的)。

在实际的系统里,模型和 Harness 的边界其实有好多种划分方式,而且往往没那么清晰。

但从做工程的角度来看,咱们刚才给 Harness 下的定义,区分度是最高的——因为它逼着我们从“怎么围绕模型的智能来设计系统”这个角度去思考问题。

接下来,咱们就从模型这个最基础的抽象概念入手,一步步说说这些 Harness 组件到底为啥会存在。

图片

02

为啥需要 Harness 呢?

因为我们希望 Agent 能做到的很多事,模型本身其实根本做不到,这就是 Harness 存在的意义。

大多数情况下,模型就是接收文本、图像、音频、视频这些输入,然后输出文本(或者结构化的调用结果),就这么点事儿。默认情况下,它做不到这些:

在多次交互之间,维持持久的状态;执行代码;获取实时信息;搭建运行环境,还要安装依赖。这些能力,全都是 Harness 层来提供的。LLM 的结构就决定了,必须有一层外部机制把它包起来,它才能真正参与到实际工作里来。

举个简单的例子,咱们平时用的聊天产品,其实就是用一个 while 循环来保存历史消息,然后不断追加新的用户输入。几乎所有人都用过这种形式的 Harness,本质上,我们做的就是把希望 Agent 表现出来的行为,变成 Harness 里的具体实现。

03

从目标行为反推 Harness 设计

Harness 工程的作用,就是帮我们把有用的先验知识加进去,从而引导 Agent 的行为。

随着模型能力越来越强,Harness 也慢慢被用来以更精细的方式,扩展或者修正模型,让它能完成以前很难做到的任务。

咱们不打算把所有可能的 Harness 功能都列出来,这里的目标是,从“让模型能完成实际工作”这个出发点,推导出一组关键能力。

核心思路很简单:我们想要(或者需要修正)的行为,决定了对应的 Harness 该怎么设计。

图片

04

用文件系统实现持久存储和上下文管理

我们希望 Agent 能有持久化存储的能力,用来处理真实的数据、转移那些装不下上下文的信息,还能在不同的会话之间继续推进工作。

但模型只能直接处理它上下文窗口里的信息。在引入文件系统之前,用户只能靠复制粘贴,把内容提供给模型,既麻烦又低效,也不适合自动化的 Agent。

现实世界里,我们本来就是靠文件系统来组织工作的,而且模型在训练的时候,也学到了这种模式。所以一个很自然的解决方案就是:让 Harness 提供文件系统的抽象,还有相关的操作工具。

文件系统可以说是最基础的 Harness 原语之一,它能带来好几个关键能力:

Agent 有了一个工作空间,可以读取数据、代码和文档;信息可以一步步写入或者转移,不用全都堆在上下文中;中间结果能保存下来,这样就能维持跨会话的状态;文件系统还是个天然的协作界面,多个 Agent 或者人和 Agent 之间,都能通过共享文件来配合工作,比如 Agent Teams 这种架构,就离不开这一点。

要是再加上 Git,文件系统还能拥有版本控制的能力,Agent 就能跟踪工作进度、回滚错误,还能做分支实验。后面咱们还会提到文件系统,因为它其实是很多其他能力的基础。

05

用 Bash 和代码执行作为通用工具

我们希望 Agent 能自己解决问题,而不是每一步都要依赖我们预先定义好的工具。

现在主流的 Agent 执行模式是 ReAct 循环:模型先思考推理,然后通过调用工具执行动作,观察结果,再进入下一轮循环。

问题在于,Harness 只能执行我们事先定义好的工具。与其给每一种可能的操作都写一个专用工具,不如直接提供一个通用工具,比如 Bash。

所以,Harness 通常都会提供 Bash 能力,让模型通过编写和执行代码来解决问题。

Bash 加上代码执行,就相当于给模型配了一台“通用计算机”。模型可以通过写代码临时搭建工具,再也不用被固定的一组预配置工具限制住。

当然,Harness 还是会提供一些其他的专用工具,但代码执行正慢慢变成 Agent 自主解决问题的默认方式。

06

用沙箱和工具完成执行与验证

Agent 得有个合适的环境,才能安全地执行操作、观察结果,还能持续推进任务。

咱们已经给模型提供了存储能力和代码执行能力,但这些都得在具体的环境里才能实现。直接在本地运行模型生成的代码,风险挺高的,而且单一的环境也很难支持大规模的任务。

沙箱就提供了一个隔离又安全的执行环境。Harness 可以把执行过程放到沙箱里,让 Agent 在里面运行代码、访问文件、安装依赖,完成任务。

为了进一步提高安全性,还可以引入命令白名单机制,限制网络访问。与此同时,沙箱还能带来很好的可扩展性:环境可以按需创建,能并行运行多个任务,任务完成后还能销毁。

一个完善的环境,通常还需要预先配置好常用的工具,比如语言运行时、依赖包、Git、测试工具,还有用来做网页交互的浏览器。

浏览器、日志、截图、测试运行器这些能力,能让 Agent 观察并分析自己的行为,从而形成一个自验证循环:写代码 → 运行测试 → 分析结果 → 修复问题。

要注意的是,这些环境配置,模型本身是不会做的。Agent 在什么地方运行、有哪些工具可用、能访问哪些资源、怎么验证结果,这些全都是 Harness 层的设计决策。

07

用记忆与搜索实现持续学习

我们希望 Agent 能记住自己的经历,还能获取到它训练之后才出现的信息。

模型本身只有权重和当前的上下文,没有额外的记忆。在不修改权重的前提下,增加知识的主要方式,就是把知识注入到上下文中。

在记忆这方面,文件系统又一次成为了核心。Harness 可以支持类似 AGENTS.md 这样的记忆文件,在 Agent 启动的时候,把这些文件加载到上下文中。

随着 Agent 不断更新这些文件,系统就会持续注入最新的内容,这样就形成了一种“持续学习”的机制。

另外,模型有个问题,就是有知识截止期,没法直接获取训练之后的数据,比如那些更新后的库版本。所以,得靠 Web 搜索和 MCP 工具(比如 Context7),让 Agent 拿到超出训练范围的信息。

所以说,Web 搜索以及动态获取最新上下文的能力,也是 Harness 里特别关键的一类基础能力。

08

对抗 Context Rot(上下文退化)

我们不希望 Agent 在执行过程中,性能越变越差。

所谓 Context Rot(上下文退化),就是说随着上下文窗口被越填越满,模型在推理和完成任务时的表现会慢慢变差。上下文是有限又宝贵的资源,所以 Harness 必须好好管理它。

其实从某种角度来说,现在很多 Harness 相关的工作,本质上都是在做“上下文工程”。

当上下文快到上限的时候,就得进行压缩。要是不处理,一旦超过上下文限制,API 可能就直接报错了,这在工程上是绝对不能接受的。所以 Harness 通常会通过总结和转移的机制,让 Agent 能一直运行下去。

如果工具调用产生了大量输出,全都放进上下文里,会引入很多没用的噪声。常见的做法就是,只保留开头和结尾的一部分内容,剩下的都写到文件系统里,需要的时候再读出来。

除此之外,要是在启动的时候加载太多工具或者 MCP 服务,一开始就会拖慢模型的表现。

Skills(按需加载的能力模块)就是通过渐进式加载,来缓解这个问题的。模型本身不会主动选择加载哪些能力,但 Harness 可以用这种方式保护上下文,避免它过早退化。

09

长时间尺度上的自主执行

我们希望 Agent 能在比较长的时间里,自动、稳定地完成复杂任务。

自动化软件开发,算是编码类 Agent 的一个重要目标。但现在的模型还有些局限,比如容易提前停止、不会拆解复杂任务,还有在跨多个上下文窗口的时候,表现不稳定。

所以,一个好的 Harness,必须围绕这些问题来设计。

到这时候,前面提到的那些能力就开始协同发挥作用了。长时间的任务,需要持久的状态、规划能力,还有观察和验证机制,才能跨多个上下文持续推进。

文件系统和 Git 是用来跨会话跟踪工作的。长期任务可能会产生几百万个 token,文件系统能稳定记录这些过程,而 Git 能让新的 Agent 快速搞懂当前的状态和历史情况。

对于多 Agent 协作来说,文件系统也是一个共享的“账本”。

Ralph Loop 是用来让任务持续执行的。这是一种 Harness 模式:通过 Hook 拦截模型的“结束”行为,然后在新的上下文窗口里,重新注入原始目标,逼着任务继续推进。

这里面文件系统起到了关键作用,因为每一轮都能在新的上下文中,读取之前的状态。

规划和自验证是用来保持方向的。规划就是把目标拆成好几个步骤,Harness 可以通过提示词和文件机制,支持这个过程。每完成一步,就通过测试或者自评来验证;要是失败了,就通过 Hook 把错误反馈给模型,进入下一轮迭代。

验证不仅能提高结果的可靠性,还能给模型提供持续改进的信号。

10

Harness 的未来

模型训练与 Harness 设计正在逐渐耦合

有些 Agent 产品(比如 Claude Code、Codex),已经在训练阶段就把 Harness 纳入了闭环,让模型在文件系统操作、Bash 执行、规划以及多 Agent 协作方面,表现得更好。

这就形成了一个反馈循环:先在 Harness 里找到有效的模式,再把它加到训练里,进而进一步增强模型的能力。

但这种共同演化也带来了问题,比如泛化能力下降。当工具逻辑发生变化时,模型的性能可能会明显下降,这说明模型在一定程度上,“过拟合”了训练时用的 Harness。

不过,这并不意味着某个模型对应的 Harness,就是最好的选择。实际上,在不同的 Harness 下,同一个模型的表现可能差别很大。

比如在 Terminal Bench 2.0 上,我们就看到了明显的性能波动;甚至只要调整一下 Harness,就能把一个编码 Agent 的排名,从 Top 30 提升到 Top 5。

这说明,Harness 还有很大的优化空间。

图片

Harness 工程会走向哪里?

随着模型能力不断增强,一些现在属于 Harness 的能力,可能会慢慢被模型吸收,比如规划、自验证以及长程一致性,这样就能减少对上下文注入的依赖。

这看起来好像是说,Harness 会变得没那么重要。但就像 Prompt 工程到现在依然重要一样,Harness 工程大概率也会长期存在。

因为它不只是在弥补模型的不足,更重要的是围绕模型的智能,搭建完整的系统。好的环境配置、合适的工具、持久的状态以及验证机制,不管模型智能水平怎么样,都能让它变得更高效。

目前,Harness 工程还是一个非常活跃的研究方向。比如在 LangChain 的 deepagents 项目中,人们正在探索:

如何让上百个 Agent 在同一代码库上并行协作

如何让 Agent 分析自身执行轨迹,从而发现并修复 Harness 层问题

如何根据具体任务动态组装工具与上下文,而不是预先配置一切

这篇文章本质上就是在回答两个问题:什么是 Harness,以及它如何被我们对模型能力的期待所塑造。

模型提供智能,而 Harness 让这种智能真正发挥作用。

愿我们能搭建出更好的 Harness、更完善的系统,还有更强大的 Agent。

如果你已经看到这里,其实你已经踩进门槛里了。剩下的,就是把这些“理解”,变成“能做出来”的东西。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐