同步至个人站点:Harness 工程:不是新词,而是 Agent 工程终于被讲明白了

这两天,Agent 圈突然开始密集讨论一个词:Harness。
很多人第一次看到它,会觉得这是个新框架、新范式,甚至像是什么"下一代 Agent 技术名词"。
但我看了一圈后,第一反应其实很简单:
这不就是我之前在做 memo code 时,一直在做的那套东西吗?
更准确一点说:
Harness 不是一个新技术发明。它更像是 Agent 工程里那部分一直存在、但过去没有被完整命名的"软件工程现实"。
前段时间我去高校做 Agent 开发交流时,也一直在讲一个非常朴素的判断:
Agent = Loop(LLM + Context + Tools)
这个 loop 本身并不复杂。
真正难的,还是 软件工程。
现在回头看,所谓 Harness,某种意义上就是把我当时说的"软件工程"这件事,给具象化了、命名了、体系化了。OpenAI 在 2026 年 2 月发布的官方文章里,几乎就是这么描述的:工程师的工作正从"写代码"转向"设计环境、指定意图、建立反馈回路,让 agent 能可靠工作";他们甚至用小团队在几个月里借助 Codex 产出约百万行代码作为案例。
所以这篇文章,我不想把 Harness 当作一个"热词解读"。
我更想做另一件事:
把 Harness 这件事,从 Agent 工程的角度,完整讲明白。
Harness 到底是什么?
先说我的定义:
Harness 不是模型。不是 Prompt。不是 Tool Call。不是框架。 Harness 是 Agent 运行时的"工程环境总和"。
这个"环境总和"里包含什么?
至少包括这几类东西:
- 任务如何被表达
- 上下文如何被组织
- 工具如何被暴露、治理、拦截
- 状态如何被保存、恢复、裁剪
- 反馈如何回流给模型
- 错误如何被分类、重试、升级
- 安全边界如何被建立
- 系统如何验证 agent 真的把事做好了
如果你把 Agent 想成一个"会调用工具的大脑",那 Harness 就是:
你给这个大脑配的身体、传感器、护栏、操作台、流程制度、回执系统,以及出事后的保险。
所以我更愿意把它翻成:
Harness = 驾驭系统 或者更工程一点:
Harness = 让 Agent 能被稳定驾驭的环境系统
OpenAI 后续关于 Codex App Server 的文章也把这件事说得更具体:所谓 harness,不只是"用户-模型-工具"的核心 loop,还包括线程生命周期与持久化、配置和鉴权、工具执行与扩展、客户端与运行时之间的协议层。也就是说,真正的 harness 不是一个 prompt 文件,而是一个完整运行时。
为什么这个词现在突然火了?
因为行业终于开始承认一件事:
Agent 的问题,越来越不是"模型够不够聪明",而是"环境够不够好"。
同一个模型,放到不同系统里,表现会差得非常大。
有的 agent:
- 会乱调工具
- 会丢上下文
- 会把安全边界踩穿
- 会在长任务里越来越漂
- 会越来越像"有工具的聊天机器人"
而有的 agent:
- 能持续做事
- 能沿着目标推进
- 能利用反馈修正自己
- 能在复杂任务里保持结构感
- 甚至能让一个不算新的模型,也表现得很像样
这也是我当时做 memo code 时非常在意的一点。
我故意没有把测试重心放在"最新最强模型"上。相反,我很长一段时间都在用一个已经发布将近一年的 DeepSeek 模型来测。原因很简单:
我想验证的不是"模型天赋有多高",而是"环境设计能把一个普通模型托到什么程度"。
如果一个相对古早的模型,在这套环境里仍然能做成事,那说明这套工程方向是对的。 这比"换个新模型突然变强"更有价值。
这也和最近公开的一些工程经验是对齐的。OpenAI 把重点放在 scaffolding、环境约束、反馈回路和可读代码库上;OPENDEV 那篇论文则把重点放在安全控制、上下文压缩、工作负载路由、记忆系统和事件驱动提醒上。两边说法不同,但本质一致:
Agent 的能力,不只是模型能力,而是模型 × 环境。
为什么我一直说:Agent 的核心很简单,难点仍然是软件工程?
因为从原理上讲,Agent 真的不复杂。
我在分享里说过:
Agent = Loop(LLM + Context + Tools)
或者更直白一点:
在一个循环里面,提供一些工具、维护一个上下文,再调用大模型。
这件事的抽象层面,你甚至十几分钟就能给它写个最小版本。你给模型一个 system prompt,给它几个 tools,让它在循环里不断决定"要不要继续做事",这就已经是 agent 了。
所以真正的问题不在"能不能做出一个 loop"。
真正的问题在于:
一个 loop,为什么会在生产环境里烂掉?
答案通常不是因为模型突然变笨了,而是因为下面这些工程问题开始集中出现:
- 上下文越来越脏
- 工具越来越多,但没有治理
- 状态没有结构化
- 安全边界靠"相信模型懂事"
- 错误没有归类,反馈也不可消费
- 长任务没有阶段性 checkpoint
- 文档和规则堆成一坨,模型根本吃不动
- 人和 agent 的协作边界不清晰
这些问题,全部都不是"模型理论问题"。
它们是彻头彻尾的软件工程问题。
而 Harness,这个词的价值就在这里:
它提醒你,Agent 项目的真正主战场,不是模型层,而是运行环境层。
Harness 和 Context Engineering 的区别是什么?
我看到不少讨论会把 Harness 和 Context Engineering 混在一起。
我觉得可以这样区分:
1)Prompt Engineering
关注的是:怎么说
比如 system prompt 怎么写,few-shot 怎么摆,措辞怎么调。
2)Context Engineering
关注的是:给模型什么信息
比如:
- 放哪些文档
- 怎么裁剪历史
- 怎么组织 AGENTS.md
- 怎么做记忆注入
- 怎么避免 context bloat
3)Harness Engineering
关注的是:模型在什么环境里做事
它比 Context 更大一层。
因为它不只管"喂什么",还管:
- 什么时候能动手
- 动手时有哪些工具
- 工具是否需要审批
- 输出太长怎么办
- 危险操作怎么拦
- 会话如何恢复
- 中间产物如何持久化
- 任务失败后如何回路修复
- 客户端如何实时展示 agent 的状态
所以我会说:
Context Engineering 是 Harness 的一个组成部分,但 Harness 不等于 Context。
OpenAI 官方中文页里有一句话我很认同:情境是一种稀缺资源,巨大指令文件会挤掉任务、代码和相关文档,导致 agent 开始围绕错误约束优化。这个观察本身说的是 context,但他们整篇文章讲的解决方式,其实已经进入 harness 级别了:代码库结构、AGENTS.md、审阅回路、验证手段、仓库作为记录系统、熵管理。
从 memo 的实践看,Harness 具体长什么样?
如果让我用 memo code 的经验来拆,我会把 Harness 至少拆成五层。
第一层:上下文装配系统
很多人以为系统提示词就是一份大 Markdown。
其实不是。
在 memo 里,我更在意的是:提示词不是静态文档,而是动态拼装系统。
我在那篇《系统提示词架构解析》里把它拆成六层:
这个拆法的关键不是"层多",而是:
不同来源的信息,有不同优先级、不同新鲜度、不同职责。
它们不能全塞进一个大 prompt 里,然后指望模型自己理解层级关系。 你必须先在工程上把层级关系建好,再交给模型。
这就是 Harness。 因为你不是在"写提示词",你是在"设计上下文的注入机制"。
第二层:工具治理系统
一个 agent 只要开始接工具,复杂度会立刻上升。
因为工具不是"多几个 function call"这么简单。工具系统背后至少有四个问题:
- 模型如何发现工具
- 参数如何校验
- 风险如何分级
- 调用如何被统一拦截
我在 memo 的工具系统设计里,把这件事拆成三层:
- 工具定义层:声明式 DSL
- 风险与审批层:read / write / execute / critical 分级
- 编排层:统一入参校验、审批拦截、结果裁剪、错误归类
这个设计的重点不是"优雅",而是:
让工具调用成为一个可治理系统,而不是一堆裸奔接口。
很多 Agent 项目为什么一开始能跑,后来越来越不稳?
因为它们的工具系统不是"系统",只是"工具列表"。
而 Harness 的一个核心任务,就是把工具从"模型可以调用的能力"提升成"可控、可审计、可演化的运行时能力"。
第三层:安全与审批系统
只要 agent 能写文件、跑 shell、改配置,它就不再是一个"聊天模型"。
它已经是一个操作系统参与者了。
这时候安全问题不是"以后再说",而是第一天就存在。
我在 memo 的安全设计里,最后收敛成了三道防线:
- 子进程管理:会话池、数量限制、输出截断、超时终止、自动清理
- 命令守卫:命令解析、危险命令黑名单、system hint 回传
- 审批系统:风险分级、审批模式、指纹缓存、dangerous 模式兜底
这里最关键的一点是:
安全不能只靠模型自觉。
你不能把"请不要执行危险命令"写在 prompt 里,然后假装问题解决了。 真正的安全边界,必须落在运行时。
这也是 Harness 和很多"Demo Agent"的根本区别。
Demo 级别的 agent 靠的是"模型大概会听话"。 Harness 级别的 agent 靠的是"即便模型不听话,系统也有边界"。
第四层:反馈与状态系统
Agent 之所以能持续做事,不是因为它会一直"想"。
而是因为它会不断收到反馈。
比如:
- 工具执行结果
- 审批是否通过
- 输出是否被截断
- 查找结果是否过多
- 命令是否被拒绝
- 当前任务计划是否已更新
- 会话是否可恢复
在 memo 的 prompt 架构里,我专门用 XML system_hint 去承载一些异常状态,比如:
- 输出过长
- 查找结果过多
- 危险调用被拦截
很多人会觉得这只是"小技巧"。
但我不这么看。
这其实是 Harness 里非常重要的一件事:
你要把系统内部发生的事,翻译成模型能消费的反馈语言。
如果没有这层翻译,模型只能看到"失败了"。 而有了这层翻译,它才能理解:
- 失败是因为权限问题
- 失败是因为输出被裁剪
- 失败是因为查找范围太大
- 失败是因为命令危险而被拒绝
这直接决定了 agent 是否能做出下一步正确行动。
第五层:熵管理系统
这是我觉得很多人会忽略,但其实特别关键的一层。
Agent 一旦持续运行,系统一定会逐渐"变脏"。
表现形式包括:
- prompt 越来越长
- rules 越来越旧
- AGENTS.md 越来越像垃圾场
- 工具定义越来越多但没人维护
- 会话历史越来越重
- memory 里混入大量无效信息
OpenAI 在那篇文章里其实已经非常明确提到了这件事:当一切都重要时,一切都不重要;大而全的说明文件会迅速腐烂。
所以 Harness 不是"搭完就完了"。
Harness 还有一个长期任务:
持续做熵管理。
也就是:
- 让过期规则失效
- 让长上下文压缩
- 让低价值历史退出上下文
- 让项目知识以可维护方式沉淀
- 让系统不断回到"对模型友好"的状态
如果没有这层意识,再强的 agent 也会越跑越歪。
所以,Harness 的本质到底是什么?
如果一定要让我用一句话概括,我会这么说:
Harness 工程,就是把 Agent 从"会调用工具的模型",变成"能在约束中稳定完成任务的系统"。
这里面最重要的词不是 Agent,也不是模型。
是三个词:
- 约束
- 反馈
- 稳定
因为真实世界里的 agent,不是靠"聪明"活下来的。
是靠:
- 有边界
- 有结构
- 有状态
- 有反馈
- 有兜底
活下来的。
所以我一直觉得,Agent 的重点从来都不在模型。
模型当然重要。 但模型更像发动机。
真正决定这台车能不能上路、能不能跑长途、会不会翻车的,是底下那整套工程环境。
也就是 Harness。
一个我更愿意推广的公式
如果以前我会说:
Agent = Loop(LLM + Context + Tools)
那现在我会更进一步,把它升级成:
Agent = Loop(Model + Harness)
为什么我要这么改?
因为 Context 和 Tools 其实都已经属于 Harness 的一部分了。
真正决定 agent 上限的,越来越不是"你有没有这些组件",而是:
你有没有把这些组件工程化成一个可以长期运转的环境。
同样是:
- 一个模型
- 一个工具列表
- 一个上下文窗口
有人做出来的是玩具。 有人做出来的是生产系统。
差别就在 Harness。
如果你要开始做 Harness 工程,先抓什么?
我给一个非常实用的落地顺序。
1. 先别急着追最强模型
先把环境搭起来。
因为环境是可复用资产,换模型能继承; 但只靠换模型,通常不能替你补环境债。
2. 先把工具系统做成"系统"
至少做到:
- 可发现
- 可校验
- 可分级
- 可拦截
- 可审计
3. 上下文不要写成一坨
把 prompt 当成装配系统,不要当成单文件。
4. 安全边界必须在运行时
不要把安全寄托在提示词上。
5. 所有失败都尽量可解释
让系统错误能回流成模型能理解的反馈。
6. 给长任务设计状态与恢复机制
没有状态管理,就没有真正的持续执行。
7. 定期做熵管理
规则、记忆、会话、文档,都会腐烂。 你不清理,系统就会慢慢失控。
为什么我会说:Harness 不是新东西,但它是一个重要命名
我很少会因为一个新词本身而兴奋。
但这次我觉得 Harness 这个词是有价值的。
因为它终于把很多 Agent 开发者长期在做、但总说不清的事情,命名清楚了:
- 为什么 prompt 调半天没用
- 为什么换模型只能解决一部分问题
- 为什么工程化之后效果会突然稳定
- 为什么长任务能力往往取决于环境,而不是参数量
- 为什么真正的瓶颈常常是软件工程,不是模型 API
它把这些零散经验,收束成了一个更明确的讨论入口。
所以我不认为 Harness 是什么"横空出世的新发明"。
我更愿意说:
Harness 让 Agent 工程这门课,终于有了一个更准确的词。
最后说回 memo,也说回我自己的判断
回头看 memo code,我越来越确认一件事:
我当时真正做的事情,不只是"做一个 coding agent"。
我其实一直在做一套 Harness。
我做的那些看起来很"工程琐事"的东西:
- prompt 分层装配
- AGENTS.md / SOUL.md
- skills 自动发现
- 工具 DSL
- 风险分级
- 审批缓存
- 危险命令拦截
- 子进程管理
- system hint 反馈
- 输出裁剪
- 多 workspace / web 控制台
这些东西单拿出来都不性感。
但正是这些东西,决定了一个 agent 最后到底是:
- 一个 demo
- 一个玩具
- 一个会写几段代码的聊天机器人
- 还是一个真的能在环境里持续做事的系统
所以如果今天再让我用一句最简短的话来讲 Agent,我可能会这么说:
Agent 的核心很简单,真正难的是 Harness。
或者更直白一点:
Agent 的重点不在模型,而在环境。
这句话,我之前是这么想的。 现在我只是终于有了一个更流行的词,来把它说得更完整一点。
(完)