Harness Engineering:长任务智能体的必备架构,还是可选方案?
本文尝试回答一个在智能体工程实践中反复出现的问题:Harness Engineering 到底是不是长任务的必备解法?它的本质是什么?它与外部记忆又是什么关系?
从一个根本性的困境说起
想象一个场景:你让一个 AI 智能体去构建一个完整的 Web 应用。它开始工作,写了几个小时的代码,然后——上下文窗口满了。
新的一轮对话开始了。这个智能体对之前发生的一切一无所知。它看到了一堆代码,但不知道哪些功能已经完成、哪些还在半途、哪些已经被测试过。它只能猜测,然后继续——很可能在错误的方向上继续。
这就是长任务智能体面临的核心困境:上下文窗口是有限的,而复杂任务是无限的。
Anthropic 在 2025 年 11 月发布的工程博客 Effective harnesses for long-running agents 中,将这个问题描述得非常形象:
想象一个软件项目由轮班工程师负责,每个新工程师到来时对上一班发生的事情毫无记忆。
这不是比喻,这就是当前所有 AI 智能体在跨越上下文窗口时的真实处境。
Harness Engineering 是什么
“Harness"这个词来自工程测试领域,原意是"测试框架"或"脚手架”——一套包裹在核心系统外部、用于控制和协调其行为的结构。
在智能体语境中,Agent Harness(智能体框架) 是一个外部软件层,它包裹在 LLM 之外,负责:
- 工具调用的编排:决定智能体可以使用哪些工具、如何调用
- 上下文的管理:决定每次会话开始时注入什么信息
- 任务状态的维护:跟踪任务进度,在会话之间传递状态
- 环境的初始化与清理:为每次运行准备好正确的工作环境
一个常见的类比是:上下文窗口是 RAM(易失性内存),Agent Harness 是操作系统。操作系统负责在程序切换时保存和恢复状态;Harness 负责在智能体会话切换时保存和恢复任务状态。
Harness Engineering 是长任务的必备解法吗?
答案是:是的,这已经是业界共识——但"必备"的程度取决于任务的复杂度。
为什么是共识
Anthropic 的实验给出了明确的数据支撑。他们让 Claude Opus 4.5 在没有 Harness 的情况下,仅凭一个高层提示(“构建一个 claude.ai 的克隆”)跨多个上下文窗口工作。结果出现了两种典型失败模式:
失败模式一:一次性尝试(One-shotting)
智能体试图在一个会话内完成所有工作,导致上下文在实现到一半时耗尽。下一个会话的智能体面对半成品代码,不得不花大量时间猜测发生了什么,然后试图修复——往往越修越乱。
失败模式二:过早宣告完成
在某些功能已经实现之后,后续的智能体实例环顾四周,看到"进展已经取得",就宣布任务完成了。
这两种失败模式都不是模型能力的问题,而是架构问题:没有任何机制告诉智能体"还有什么没做"和"已经做到哪一步了"。
OpenAI 的 Codex 团队在《在智能体优先的世界中利用 Codex》中也印证了同样的结论。他们在五个月内用三名工程师、零人工编码的方式构建了一个百万行代码的产品,其核心方法论之一就是:将代码仓库本身作为记录系统,通过结构化的文档、执行计划和进度日志,让每一次智能体运行都能快速定位当前状态。
什么情况下可以不用 Harness
对于单次上下文窗口内可以完成的任务,不需要复杂的 Harness。现代模型的上下文窗口已经相当大(100K-200K tokens),很多中等复杂度的任务可以在一次会话内完成。
但一旦任务需要跨越多个上下文窗口——无论是因为代码量太大、时间跨度太长,还是需要多个专业化智能体协作——Harness 就从"可选"变成了"必须"。
Harness Engineering 的本质:外部记忆的工程化
这是问题的核心。Harness Engineering 的本质,就是通过外部记忆让任务执行可接力。
但这里需要做一个重要的区分:外部记忆不等于 Harness,Harness 是外部记忆的一种工程化实现方式。
外部记忆的四种形态
在 Harness 架构中,外部记忆通常以以下几种形态存在:
1. 任务状态文件(Task State Files)
这是最直接的外部记忆形式。Anthropic 的方案中使用了 claude-progress.txt 来记录每次会话做了什么、当前状态如何。Codex 团队则使用了结构化的执行计划文件(exec-plans/)和技术债务追踪器。
这类文件的关键特征是:它是写给下一个智能体实例读的,而不是写给人读的。
2. 功能清单文件(Feature Manifest)
Anthropic 的方案中,初始化智能体会生成一个 feature_list.json,列出所有需要实现的功能,每个功能都有一个 passes: false/true 的状态字段。
1 | |
为什么用 JSON 而不是 Markdown?Anthropic 的工程师发现,模型更不容易"不恰当地修改或覆盖" JSON 文件。这是一个微妙但重要的工程细节。
3. 版本控制历史(Git History)
Git 本身就是一种外部记忆。每次提交都是一个检查点,记录了"在这个时间点,代码处于什么状态"。Anthropic 明确要求编码智能体在每次会话结束时提交代码,并写清楚提交信息。
这样,下一个智能体实例可以通过 git log --oneline -20 快速了解最近发生了什么,而不需要阅读所有代码。
4. 环境知识文件(Environment Knowledge)
AGENTS.md、CLAUDE.md、init.sh 等文件属于这一类。它们不记录任务进度,而是记录"如何在这个环境中工作"——如何启动开发服务器、代码规范是什么、架构原则是什么。
这类文件是稳定的背景知识,而任务状态文件是动态的进度记录。两者共同构成了智能体的完整外部记忆。
Harness 的两阶段架构
Anthropic 提出的 Harness 架构有一个优雅的两阶段设计:
阶段一:初始化智能体(Initializer Agent)
第一次运行时,使用专门的提示词,让智能体完成以下工作:
- 生成
init.sh(如何启动开发环境) - 生成
feature_list.json(完整的功能需求清单,所有功能初始标记为failing) - 创建初始 Git 提交(建立基线)
- 生成
claude-progress.txt(进度日志的起点)
阶段二:编码智能体(Coding Agent)
每次后续运行时,使用另一套提示词,要求智能体:
- 运行
pwd确认工作目录 - 读取
claude-progress.txt和 Git 日志,了解当前状态 - 读取
feature_list.json,选择优先级最高的未完成功能 - 实现该功能,进行端到端测试
- 将功能标记为
passing,提交代码,更新进度日志
这个设计的精妙之处在于:每次会话的开始都有明确的"上下文恢复"步骤,每次会话的结束都有明确的"状态保存"步骤。 智能体不需要猜测,只需要按照协议执行。
为什么这个问题比看起来更难
有人可能会问:这不就是写几个文件吗?为什么需要专门的"工程"?
因为外部记忆本身也会腐烂。
Codex 团队在文章中提到了一个深刻的教训:他们最初尝试用一个大型的 AGENTS.md 文件来存储所有知识。结果:
- 上下文是稀缺资源:一个巨大的指令文件会挤占任务、代码和相关文档的空间
- 过多的指导反而失效:当一切都"重要"时,一切都不重要了
- 它会立即腐烂:随着代码库演进,文档跟不上,智能体开始基于过时信息做决策
- 难以验证:单一的大文件无法进行机械化的覆盖率检查和新鲜度验证
他们的解决方案是:将 AGENTS.md 从百科全书变成目录。一份约 100 行的 AGENTS.md 作为地图,指向 docs/ 目录下结构化的知识库。专门的 linter 和 CI 作业验证知识库的更新状况,定期运行的"文档园丁"智能体扫描过时文档并发起修复 PR。
这就是为什么叫"工程"——因为外部记忆本身需要被设计、维护和治理。
小结
| 问题 | 答案 |
|---|---|
| Harness Engineering 是长任务的必备解法吗? | 是,对于跨越多个上下文窗口的任务,这是业界共识 |
| Harness 的本质是什么? | 外部记忆的工程化:通过结构化的文件和协议,让任务状态在会话之间可传递 |
| 外部记忆等于 Harness 吗? | 不完全等于:外部记忆是 Harness 的核心机制,但 Harness 还包括工具编排、环境管理等 |
| 这个问题难在哪里? | 外部记忆本身会腐烂,需要被设计、维护和治理,这才是真正的工程挑战 |
下一篇文章,我们来看:外部记忆有没有标准的文件格式?它除了用在 Harness Engineering 里,还有哪些更广泛的用途?
参考资料
- Effective harnesses for long-running agents - Justin Young, Anthropic(2025 年 11 月)
- Engineering: Leveraging Codex in an agent-first world - Ryan Lopopolo, OpenAI
- 工程技术:在智能体优先的世界中利用 Codex - Ryan Lopopolo, OpenAI(中文官方译文)
- The Agent Harness Is the Architecture - Medium
- What is an agent harness? - Parallel AI





