本文参考 OpenAI 官方博客 Harness engineering: leveraging Codex in an agent-first world、LangChain 博客 The Anatomy of an Agent Harness 以及 Martin Fowler 博客 Harness Engineering 三篇权威来源,系统梳理 Agent 优先时代的软件工程新范式。
为什么我们需要 Harness Engineering
过去几个月,AI 编程领域发生了深刻的范式转移。当人们还在讨论”AI 能写多少代码”时,前沿团队已经在探索一个更本质的问题:如何让 AI 持续、可靠、规模化地维护复杂软件系统?
OpenAI 团队给出了一个大胆的答案。在过去五个月,他们运行了一项惊人的实验:从零构建并发布了一款内部 Beta 产品,全程没有一行人工编写的代码。五个月后,这个仓库包含了约一百万行代码,涵盖应用逻辑、基础设施、工具链、文档和内部开发工具。在此期间,仅由 3 名工程师驱动 Codex 就完成并合并了约 1500 个 PR,平均每个工程师每天产出 3.5 个 PR。
这不是关于”AI 取代程序员”的故事。恰恰相反,这是对软件工程本质的重新思考。OpenAI 团队将其总结为一句简洁有力的原则:
Humans steer. Agents execute.(人类掌舵,Agent 执行。)
LangChain 团队则用更技术化的语言定义了这个新范式:
Agent = Model + Harness
如果你不是模型,你就是 Harness。 一个 Harness 是除模型本身之外的每一块代码、配置和执行逻辑。原始模型不是 Agent,但当一个 Harness 赋予它状态、工具执行、反馈循环和可执行约束时,它就变成了一个 Agent。
本文将系统性地解析 Harness Engineering 的完整框架,从核心概念到实践组件,从知识管理到架构约束,从当下实践到未来展望。
Agent = Model + Harness
要理解 Harness Engineering,首先需要建立一个清晰的认知框架。LangChain 团队提出的 Agent = Model + Harness 公式,是这个领域最简洁而准确的定义。
什么是 Harness?
一个 Harness 包括:
- System Prompts:系统提示词,定义 Agent 的行为边界和工作方式
- Tools, Skills, MCPs:工具、技能、MCP 及其描述,扩展 Agent 的能力边界
- Bundled Infrastructure:捆绑的基础设施(文件系统、沙箱、浏览器)
- Orchestration Logic:编排逻辑(子 Agent 生成、交接、模型路由)
- Hooks/Middleware:钩子/中间件,用于确定性执行(压缩、续接、Lint 检查)
为什么模型本身不足以成为 Agent?
模型(主要是)接收文本、图像、音频、视频等数据,输出文本。仅此而已。开箱即用的模型无法:
- 在交互间保持持久状态
- 执行代码
- 访问实时知识
- 搭建环境并安装包以完成工作
这些都是 Harness 级别的功能。LLM 的结构需要某种机制来包装它们以完成有用的工作。
从期望的 Agent 行为推导 Harness 设计
Harness Engineering 帮助人类注入有用的先验知识来引导 Agent 行为。随着模型能力增强,Harness 被用于精确地扩展和纠正模型,以完成以前不可能的任务。
我们可以遵循一个模式:
期望的行为(或想要修复的问题)→ 帮助模型实现这一点的 Harness 设计
这个框架将贯穿本文,帮助我们理解每个 Harness 组件存在的根本原因。
OpenAI 的实践:从零到百万行代码
OpenAI 团队的实验是 Harness Engineering 领域最具里程碑意义的实践案例。他们不仅证明了可行性,更重要的是,他们发现了一套全新的工程方法论。
实验设置:空仓库的起点
2025 年 8 月底,第一个 commit 提交到了一个空仓库。
初始的项目骨架——仓库结构、CI 配置、格式化规则、包管理器设置、应用框架——全部由 Codex CLI 基于 GPT-5 生成,仅参考了少量现有模板。甚至指导 Agent 如何在仓库中工作的 AGENTS.md 文件本身也是 Codex 写的。
整个系统从一开始就没有人工编写的代码作为锚点,从诞生起就是由 Agent 塑造的。
惊人的数据
五个月后:
- 代码规模:约一百万行代码
- PR 数量:约 1500 个 PR 被合并
- 团队规模:从 3 名工程师扩展到 7 名
- 产出效率:平均每个工程师每天产出 3.5 个 PR,且效率随团队扩张持续提升
- 用户采用:数百名内部日常使用用户,包括重度用户
最重要的是:在整个开发过程中,人类从未直接贡献过任何代码。
工程师角色的重新定义
不需要人工写代码带来了一种完全不同的工程工作模式,核心聚焦于系统、脚手架和杠杆效应。
早期进展比预期的要慢,不是因为 Codex 能力不足,而是因为环境没有被充分定义。Agent 缺乏实现高层目标所需的工具、抽象和内部结构。工程团队的核心工作变成了赋能 Agent 完成有用的工作。
实践中,这意味着采用深度优先的工作方式:将大目标拆解成更小的构建块(设计、编码、评审、测试等),提示 Agent 构建这些模块,再用这些模块解锁更复杂的任务。
当某个环节失败时,解决方案几乎从来不是”让 Agent 再试一次”。人类工程师总会退一步思考:“缺少了什么能力?我们如何让 Agent 既能理解这种能力,又能遵守相关约束?”
人类几乎完全通过**提示(prompt)**与系统交互:工程师描述任务,运行 Agent,让它自动打开 PR。Codex 使用标准开发工具直接获取上下文,不需要人类复制粘贴到 CLI。
人类可以评审 PR,但这不是必需的。随着时间推移,几乎所有评审工作都交给了 Agent 之间互相完成。
Harness 的核心组件
基于 LangChain 的系统性分析,我们可以将 Harness 的核心组件归纳为以下几个关键领域。每个组件都是为了解决一个特定的 Agent 能力缺口。
文件系统:持久存储与上下文管理
核心问题:我们希望 Agent 拥有持久存储来与真实数据交互、卸载不适合放入上下文的中间信息,并在会话间持久化工作。
模型只能直接操作其上下文窗口内的知识。在文件系统之前,用户必须将内容直接复制粘贴给模型——这种 UX 很笨拙,对自治 Agent 不起作用。
世界已经在使用文件系统来完成工作,模型自然在数十亿 tokens 的数据上训练了如何使用它们。
Harness 解决方案:Harness 内置文件系统抽象和文件操作工具。
文件系统是最基础的 Harness 原语,因为它解锁了:
- Agent 获得一个工作空间来读取数据、代码和文档
- 工作可以增量添加和卸载,而不是将所有内容保存在上下文中
- Agent 可以存储中间输出并保持超出单个会话的状态
- 文件系统是自然的协作表面。多个 Agent 和人类可以通过共享文件协调。Agent Teams 等架构依赖于此
Git 为文件系统添加了版本控制,使 Agent 可以跟踪工作、回滚错误和分支实验。
Bash + 代码执行:通用目的工具
核心问题:我们希望 Agent 能够自主解决问题,而不需要人类预先设计每一个工具。
今天的主要 Agent 执行模式是 ReAct 循环,模型推理、通过工具调用采取行动、观察结果,并在 while 循环中重复。但 Harness 只能执行它们有逻辑的工具。与其强迫用户为每一个可能的动作构建工具,不如给 Agent 一个像 Bash 这样的通用目的工具。
Harness 解决方案:Harness 内置 Bash 工具,使模型能够通过编写和执行代码自主解决问题。
Bash + 代码执行是朝给模型一台计算机并让它们自主完成其余工作迈出的一大步。模型可以通过代码动态设计自己的工具,而不是被限制在一组固定的预配置工具中。
Harness 仍然附带其他工具,但代码执行已成为自主问题解决的默认通用策略。
沙箱与工具执行环境
核心问题:Agent 需要一个具有正确默认值的执行环境,以便安全地行动、观察结果并持续取得进展。
我们已经给模型存储能力和执行代码的能力,但所有这些都需要在某个地方发生。在本地运行 Agent 生成的代码是有风险的,单一本地环境无法扩展到大型 Agent 工作负载。
Harness 解决方案:沙箱为 Agent 提供安全的操作环境。
与其在本地执行,Harness 可以连接到沙箱来运行代码、检查文件、安装依赖和完成任务。这为代码创建了安全、隔离的执行环境。为了更高的安全性,Harness 可以允许列表命令并强制执行网络隔离。
沙箱还解锁了规模,因为环境可以按需创建,分散到许多任务中,并在工作完成后销毁。
良好的环境配备良好的默认工具。Harness 负责配置工具,使 Agent 能够完成有用的工作。这包括预安装语言运行时和包、git 和测试的 CLI、浏览器用于 Web 交互和验证。
浏览器、日志、截图和测试运行器等工具为 Agent 提供了一种观察和分析其工作的方式。这帮助它们创建自验证循环,可以编写应用代码、运行测试、检查日志和修复错误。
模型开箱即用不会配置自己的执行环境。决定 Agent 在哪里运行、什么工具可用、它可以访问什么以及如何验证其工作,这些都是 Harness 级别的设计决策。
内存与持续学习
核心问题:Agent 应该记住它们看到过的东西,并访问在训练时不存在的信息。
模型除了其权重和当前上下文中的内容外,没有额外的知识。如果不访问编辑模型权重,“添加知识”的唯一方式是通过上下文注入。
对于内存,文件系统再次成为核心原语。Harness 支持内存文件标准如 AGENTS.md,在 Agent 启动时被注入上下文。当 Agent 添加和编辑此文件时,Harness 将更新的文件加载到上下文中。这是一种持续学习的形式,Agent 在一个会话中持久存储知识,并将该知识注入未来会话。
知识截止日期意味着模型不能直接访问新数据,如更新的库版本,除非用户直接提供它们。对于最新知识,Web 搜索和 MCP 工具如 Context7 帮助 Agent 访问超出知识截止日期的信息,如新的库版本或训练停止时不存在的当前数据。
Web 搜索和查询最新上下文的工具是内置于 Harness 的有用原语。
对抗上下文腐烂
核心问题:Agent 性能不应随着工作进展而下降。
上下文腐烂描述了随着上下文窗口填满,模型在推理和完成任务方面变得 worse 的现象。上下文是一种宝贵且稀缺的资源,因此 Harness 需要管理它的策略。
Harness 今天很大程度上是良好上下文工程的交付机制。
压缩解决了当上下文窗口接近填满时做什么的问题。没有压缩,当对话超出上下文窗口时会发生什么?一个选项是 API 错误,这不好。Harness 必须使用某种策略来处理这种情况。因此压缩智能地卸载和总结现有上下文窗口,使 Agent 能够继续工作。
工具调用卸载帮助减少大工具输出的影响,这些输出可能嘈杂地混乱上下文窗口而不提供有用的信息。Harness 保留超过阈值 token 数的工具输出的头部和尾部 token,并将完整输出卸载到文件系统,以便模型可以在需要时访问它。
技能解决了在 Agent 启动时将太多工具或 MCP 服务器加载到上下文中会损害性能的问题,在 Agent 能够开始工作之前就降低性能。技能是一种 Harness 级别原语,通过渐进披露解决这个问题。模型没有选择在启动时将技能前言加载到上下文中,但 Harness 可以支持这一点来保护模型免受上下文腐烂。
知识管理:让仓库成为事实唯一来源
OpenAI 团队在知识管理方面的实践是 Harness Engineering 中最具启发性的部分之一。他们发现,当整个代码库都由 Agent 生成时,传统的知识管理方式完全失效了。
为什么超大 AGENTS.md 失败了
他们最早尝试的是”一个超大 AGENTS.md”的方案,但很快就以可预见的方式失败了:
-
上下文是稀缺资源:巨大的说明文件会挤占任务、代码和相关文档的空间,导致 Agent 要么遗漏关键约束,要么开始优化错误的目标。
-
过多指导等于没有指导:当所有内容都”重要”时,就没有什么是重要的了。Agent 最终只会进行局部模式匹配,而不是有意图地导航。
-
内容会立刻过期:单体手册会变成过时规则的坟场。Agent 无法分辨哪些规则仍然有效,人类也停止维护它,这个文件最终会成为一个吸引人的麻烦。
-
难以验证:单一 blob 不适合机械检查(覆盖率、新鲜度、所有者、交叉链接),所以漂移是不可避免的。
渐进式披露:AGENTS.md 作为目录
Open 渐进式披露:AGENTS.md 作为目录
解决方案是将 AGENTS.md 从百科全书转变为目录。
仓库的知识库保存在结构化的 docs/ 目录中,作为事实的唯一来源。一个简短的 AGENTS.md(约 100 行)被注入到上下文中,主要作为地图,指向其他地方更深层的事实来源。
AGENTS.md
ARCHITECTURE.md
docs/
├── design-docs/
│ ├── index.md
│ ├── core-beliefs.md
│ └── ...
├── exec-plans/
│ ├── active/
│ ├── completed/
│ └── tech-debt-tracker.md
├── generated/
│ └── db-schema.md
├── product-specs/
│ ├── index.md
│ ├── new-user-onboarding.md
│ └── ...
├── references/
│ ├── design-system-reference-llms.txt
│ ├── nixpacks-llms.txt
│ ├── uv-llms.txt
│ └── ...
├── DESIGN.md
├── FRONTEND.md
├── PLANS.md
├── PRODUCT_SENSE.md
├── QUALITY_SCORE.md
├── RELIABILITY.md
└── SECURITY.md
结构化知识库的设计原则
设计文档被编目和索引,包括验证状态和定义 Agent 优先运营原则的核心信念集。架构文档提供了领域和包分层的顶层地图。质量文档为每个产品领域和架构层打分,随时间跟踪差距。
计划被视为一等 artifact。小变更使用临时的轻量级计划,复杂工作则被记录在执行计划中,包含进度和决策日志,并提交到仓库。活跃计划、已完成计划和已知技术债务都被版本化并放在一起,使 Agent 能够在不依赖外部上下文的情况下运行。
这实现了渐进式披露:Agent 从一个小而稳定的入口点开始,学习下一步去哪里查找信息,而不是一开始就被信息淹没。
机械化的强制执行
OpenAI 团队用机械方式强制执行这一知识管理结构:
- 专用的 linter 和 CI 任务验证知识库是否是最新的、交叉链接正确且结构正确
- 一个定期运行的”文档园艺”Agent 会扫描不符合实际代码行为的过时或废弃文档,并打开修复 PR
Agent 可理解性是核心目标
因为仓库完全是 Agent 生成的,所以它首先是为 Codex 的可理解性 优化的。就像团队致力于提高代码对新工程师的可导航性一样,人类工程师的目标是让 Agent 能够 直接从仓库本身推理完整的业务领域。
从 Agent 的角度来看,任何它在运行时无法在上下文中访问的东西实际上都不存在。存在于 Google Docs、聊天线程或人们头脑中的知识对系统来说是不可访问的。只有仓库本地、版本化的 artifact(例如代码、markdown、schema、可执行计划)是它能看到的。
这个框架澄清了很多权衡取舍。团队倾向于使用能够在仓库中被完全内化和推理的依赖和抽象。通常被描述为”无聊”的技术往往更容易被 Agent 建模,因为它们具有可组合性、API 稳定性,并且在训练集中有充分的代表性。
架构约束与质量保证
仅有文档不足以让完全由 Agent 生成的代码库保持一致性。OpenAI 团队发现,通过强制执行不变量,而不是微观管理实现,可以让 Agent 能够快速交付而不破坏基础。
分层领域架构
Agent 在有严格边界和可预测结构的环境中效率最高。OpenAI 团队围绕严格的架构模型构建应用。每个业务领域被划分为固定的层集合,有严格验证的依赖方向和有限的允许边缘。
规则是:在每个业务领域(例如应用设置)内,代码只能按照固定的层顺序”向前”依赖(类型→配置→仓库→服务→运行时→UI)。横切关注点(认证、连接器、遥测、功能开关)通过单一明确的接口进入:Provider。其他任何方式都是不允许的。
这种架构通常是等到有数百名工程师时才会考虑的事情。但对于代码 Agent 来说,这是早期的先决条件:这些约束使得能够在没有衰减或架构漂移的情况下保持高速开发。
自定义 Linter 与结构测试
这些约束通过自定义 linter(当然也是 Codex 生成的!)和结构测试以机械方式强制执行。
实践中,团队用自定义 linter 和结构测试,加上一小组”风格不变量”来执行这些规则。例如:
- 静态强制执行结构化日志
- Schema 和类型的命名约定
- 文件大小限制
- 平台特定的可靠性要求
因为 lint 是自定义的,团队编写的错误消息会将修复指令注入到 Agent 上下文中。
在以人为先的工作流中,这些规则可能显得迂腐或约束性强。但对于 Agent 来说,它们成为了倍增器:一旦编码完成,它们会立刻应用到所有地方。
黄金原则与垃圾回收
完全的 Agent 自治也带来了新的问题。Codex 会复制仓库中已经存在的模式——即使是不均衡或次优的模式。随着时间推移,这不可避免地会导致漂移。
最初,团队每周五(每周 20% 的时间)清理”AI 垃圾”。不出所料,这种方式无法扩展。
相反,团队开始将”黄金原则”直接编码到仓库中,并构建了定期清理流程。这些原则是明确的、机械的规则,保持代码库对未来 Agent 运行的可理解性和一致性。例如:
- 更喜欢共享工具包而不是手工编写的辅助函数,以保持不变量集中化
- 不”YOLO 式”探测数据——验证边界或依赖类型化的 SDK,这样 Agent 就不会意外地基于猜测的结构构建功能
定期运行一组后台 Codex 任务扫描偏差,更新质量评分,并打开针对性的重构 PR。大多数这些 PR 可以在一分钟内评审完毕并自动合并。
这就像垃圾回收。技术债务就像高息贷款:持续小额偿还几乎总是比让它复利累积再痛苦地一次性解决要好。
产出效率改变合并哲学
随着 Codex 产出效率的提升,很多传统的工程规范变得适得其反。
仓库采用最小化的阻塞合并门控。PR 生命周期很短。测试不稳定通常通过后续运行解决,而不是无限期阻塞进度。在 Agent 产出效率远远超过人类注意力的系统中,修正成本很低,而等待成本很高。
这在低产出环境中是不负责任的。但在这里,这通常是正确的权衡。
未来展望:Harness 会走向何方
Martin Fowler 在 Thoughtworks 的博客文章中,从行业视角对 Harness Engineering 的未来提出了深刻的洞察。
Harness 会成为未来的服务模板吗?
大多数组织只有两到三个主要技术栈——并非每个应用都是独特的雪花。OpenAI 的文章让我们想象一个未来:团队从一组针对常见应用拓扑的 Harness 中选择开始。这让人想起今天的服务模板,帮助团队在”黄金路径”上实例化新服务。
Harness——带有自定义 linter、结构测试、基本上下文和知识文档以及额外上下文提供者——会成为新的服务模板吗?团队会将它们作为起点,然后随着时间的推移为应用的特定需求塑造它们吗?
技术栈会收敛吗?
随着编码变得越来越少关于打字代码,越来越多关于引导其生成,AI 可能会推动我们走向更少的技术栈。框架和 SDK 的可用性仍然重要——我们反复看到对人类有益的东西对 AI 也有益。但在那种细节层面上,开发者的口味会变得不那么重要。接口中的小效率和不规则性会变得不那么烦人,因为我们不直接处理它们。我们可能会选择有良好 Harness 可用的栈,并优先考虑”AI 友好性”。
这可能不仅适用于技术栈,也适用于代码库结构和拓扑。我们可能会默认选择更容易用 AI 维护的结构,因为它们更容易被 Harness。OpenAI 团队讨论了架构刚性和强制执行规则。我能看到的主要关注领域是保持数据结构稳定和定义及强制执行模块边界。这听起来合理——但没有具体例子,我仍然难以想象”我们要求 Codex 在边界处解析数据形状”在他们的 Harness 中实际是什么样子。
但如果我们能弄清楚如何广泛地 Harness 代码库设计模式,这些拓扑会成为新的抽象层,而不是像许多 AI 爱好者希望的那样是自然语言本身吗?
两个未来世界:Pre-AI 与 Post-AI 应用维护
假设我们开发了良好的 Harnessing 技术,将 AI 自主性调到 9 并提高我们对结果的信任。哪些技术可以应用于现有应用,哪些只对从一开始就考虑 Harness 构建的应用有效?
对于较旧的代码库,我们需要考虑改造 Harness 是否值得努力。AI 可以帮助我们更快地完成,但这些应用通常如此非标准化且充满熵,以至于可能不值得。这让我想起在一个从未有过静态代码分析工具的代码库上运行它,然后淹没在警报中。
你的 Harness 今天是什么?
这个团队花了 5 个月时间在他们的 Harness 上,表明这不是你可以为了快速结果而跳入的东西。但反思你今天的 Harness 是什么是值得的。你有 pre-commit 钩子吗?里面有什么?你有自定义 linter 的想法吗?你想对你的代码库强制执行什么架构约束?你是否尝试过像 ArchUnit 这样的结构测试框架?
核心收获与行动建议
核心收获
1. 范式转移:从写代码到设计 Harness
软件工程的核心工作正在从编写代码转向设计 Harness——那些让 AI 能够可靠、持续、规模化地完成工作的系统、脚手架和反馈循环。
2. 核心公式:Agent = Model + Harness
模型提供智能,Harness 让智能变得有用。如果你不是模型,你就是 Harness。
3. 关键原则:人类掌舵,Agent 执行
人类的工作是排列优先级、定义意图、设计环境、建立反馈循环。Agent 的工作是执行。
4. 知识管理:仓库是事实的唯一来源
任何不在仓库中的知识对 Agent 来说都不存在。使用渐进式披露,让 AGENTS.md 成为目录,而不是百科全书。
5. 架构约束:强制执行不变量,而非微观管理
通过自定义 linter、结构测试和黄金原则来强制执行架构约束。这让 Agent 能够快速交付而不破坏基础。
6. 质量保障:垃圾回收模式
不要等待技术债务累积。通过持续的、小规模的清理(垃圾回收)来保持代码库健康,而不是周期性的痛苦重构。
如何开始你的 Harness 之旅
如果你是一名工程师:
- 审计你当前的 Harness:你有什么 pre-commit 钩子?CI 流程?文档结构?
- 从 AGENTS.md 开始:创建一个简短的 AGENTS.md 文件作为目录,而不是长篇手册。
- 添加一个自定义 linter:找一个你最关心的代码规范,用 linter 强制执行。
- 实验 Codex/Claude Code:在一个小项目中尝试”零人工代码”的约束。
如果你是一个团队负责人:
- 识别重复模式:你的团队在哪些任务上反复花费时间?这些可能是 Harness 的机会。
- 投资于文档结构:建立一个结构化的 docs/ 目录,作为团队知识的事实来源。
- 建立黄金原则:定义 3-5 个不可妥协的工程原则,用自动化工具强制执行。
- 分配 Harness 时间:像 OpenAI 团队那样,为 Harness 建设和维护分配专门的时间预算。
如果你是一个组织:
- 建立 Harness 卓越中心:一个专门负责设计、维护和传播 Harness 最佳实践的团队。
- 开发服务模板:为常见应用拓扑创建 Harness 模板,作为”黄金路径”。
- 投资于可观测性:确保你的 Harness 有适当的指标和日志来持续改进。
- 培养实验文化:鼓励团队尝试新的 Harness 技术,并从成功和失败中学习。
最后的话
Harness Engineering 不是关于 AI 取代工程师,而是关于重新定义工程师的角色。在未来最优秀的工程师可能不是那些写代码最快的人,而是那些最擅长设计 Harness 的人——那些让 AI 能够释放其全部潜力的系统。
正如 OpenAI 团队所发现的,最大的挑战现在集中在设计环境、反馈循环和控制系统。这些恰恰是软件工程师最擅长的领域。
未来属于那些能够驾驭这场范式转移的人。你的 Harness 之旅,从今天开始。
参考资源
原始来源:
- OpenAI: Harness engineering: leveraging Codex in an agent-first world
- LangChain: The Anatomy of an Agent Harness
- Martin Fowler: Harness Engineering
相关概念: