最近我们用这套流程跑通了一个原本预估 6 PD 的需求。人只用了约 0.5 PD 澄清需求、补齐边界并确认技术方案;后续约 0.5 PD 由 Claude Code 完成开发,人没有持续介入。Claude Code 根据技术方案拆分和实现任务,Hooks 在修改过程中检查代码是否符合仓库规范,编译通过后继续调试;它读取异常、日志和测试结果,带着具体证据修改实现,直到达到交付条件。
这里的重点不是 Claude Code 一次生成了多少代码。需求澄清、技术方案、仓库规则、Hooks、编译、调试和异常信息组成了一个循环:每一步产出都成为下一步的输入。失败不会只得到一句“重试”,而是回到实现阶段并附带可定位的问题。人的工作也没有消失,而是集中在定义需求边界、技术决策和最终确认上。
后来再看这类实践,我发现它与 Harness Engineering 的描述高度一致:围绕模型补齐上下文、工具、约束和反馈,使 Agent 能够稳定执行任务。但从实际运行形态看,它首先是一个 Loop。Harness 提供循环得以运行的环境和规则,Loop 则描述一次需求如何在“实现 → 检查 → 调试 → 修复 → 再检查”之间持续收敛。
下面把这次实践中可复用的经验整理一下。
Claude Code 是执行端,Harness 是工程系统
本文的实践使用 Claude Code,但 Harness Engineering 不是某个编码产品的使用技巧。Claude Code 提供了代码浏览、编辑、命令执行、子任务、Hooks 和会话上下文等执行能力;项目仍要决定它应该读取什么、哪些动作允许执行、什么结果才算完成,以及失败后如何处理。换成其他 Coding Agent,这些工程问题依然存在。
我在 2024 年做 Agent 时遇到的工具描述、结构化错误、状态外置、上下文压缩、权限边界、运行验证和评估问题,正是这次 Claude Code 实践的前置积累。它们不是两套方法:早期是自己搭建 Agent 运行时,需要显式设计每个环节;现在 Claude Code 已经提供了部分通用运行时,工程团队仍要把项目事实、约束和反馈接入其中。本文会聚焦这种衔接,而不是把 Claude Code 当作独立于既有 Agent 实践的新范式。
过去的软件工程默认开发者是人:人能从代码、文档、口头约定和历史经验中补齐上下文,也能在评审时识别不合适的实现。Agent 不具备这些默认前提。它可以在几分钟内生成大量代码,却未必知道既有架构、领域规则和依赖边界;当团队仍以人工评审承接所有检查时,代码生成速度也会迅速超过人工吞吐量。
这篇文章整理我对 AI 友好型工程系统的理解:工程师的重点逐渐从直接编码,转为设计 Agent 获取信息、执行任务和接收反馈的运行环境。
人的工作从写代码转向设计执行系统
这里的变化不等于“人不需要工程能力”。相反,人仍然要对需求边界、架构取舍和交付风险负责,只是工作的重心发生了迁移。
第一层迁移是从直接实现转向工程设计。当 Claude Code 的实现不符合预期,先问的不是“换一个 Prompt 能不能写对”,而是:它缺少什么完成任务所需的知识、工具或约束?这些能力能否被表达成 Agent 可读取、可执行且可验证的形式?实践中,研究与实现也值得拆开:先由一个会话调查代码库、比较方案并形成技术路径;确认路径后,再用干净的执行会话只处理实现,避免调研过程的噪声混入编码上下文。这延续了早期 Agent 中“规划与执行分离”的做法,只是现在由 Claude Code 的会话和子任务能力承接。
第二层迁移是从逐行审查代码转向设计反馈。代码生成量增加后,人逐个阅读 PR 会成为瓶颈。更可持续的做法是把能确定的检查交给系统,把 UI 状态、日志、网络请求和测试结果交给 Claude Code 作为反馈;人则处理产品取舍、异常风险和无法通过规则判定的问题。不是取消 Review,而是把 Review 前移为规则和检查,并让独立 Agent 或确定性工具承担重复验证。这与早期 Agent 实践中“工具返回应包含可修复证据”的要求一致,只是反馈对象从自建编排器中的模型调用,变成了 Coding Agent 的下一轮执行。
三个阶段:Prompt、Context 与 Harness
这三个概念不是替代关系,而是作用范围逐层扩大。
- Prompt Engineering 解决“怎么说”。它通过任务描述、角色和示例改善一次调用的输出,但难以覆盖复杂任务中的工具使用、状态变化和跨会话协作。
- Context Engineering 解决“看什么”。它将文档、记忆、RAG、工具结果和工作状态组织为上下文,使 Agent 能基于项目事实工作。
- Harness Engineering 解决“怎么运行和控制”。它围绕模型建立任务拆分、工具权限、质量门禁、观测和反馈回路,使 Agent 能在约束下持续完成工作。
模型能力提高后,影响交付质量的变量会更多地落到模型之外:Agent 是否拿得到正确的知识,能否调用必要工具,违反架构时是否会被拦截,失败后能否获得可操作的反馈。Harness 就是把这些条件组织成工程系统。
OpenAI 在 Harness engineering 中给出的经验很直接:人负责引导和决策,Agent 负责执行。团队不应只把任务交给 Agent 后等待代码,而应不断把 Agent 失败时缺少的信息、工具或约束,回写为可复用的系统能力。
从面向人到面向 Agent
传统工程资产大多面向人阅读:长文档、网页操作、会议纪要和散落的注释都依赖读者自行拼接上下文。对 Agent 而言,关键不是再增加一个聊天入口,而是让工程资产具备机器可读、可发现和可执行的形态。
这要求至少完成三类转换:
- 结构化表达知识。 架构原则、领域模型、接口契约和依赖边界不应只存在于经验中。它们需要以规则、Schema、元数据、ADR 或版本化文档表达出来。
- 提供机器接口。 原本只能通过 GUI 完成的查询、诊断和操作,应尽量提供 CLI、API 或受控工具调用,让 Agent 能稳定发现和使用能力。
- 按任务提供上下文。 一次性塞入所有文档会增加噪声。更有效的方式是让 Agent 从项目总览进入,再按目录、模块和任务逐层读取所需规则。
Harness 的三个部分
把早期 Agent 实践映射到 Claude Code,可以更清楚地看出 Harness 的边界:原先要自己实现的检索与记忆,对应仓库规则、专项知识和按任务加载的上下文;原先的工具 Schema、权限与状态机,对应受控命令、Hooks、工作区和人工确认;原先的工具返回、测试与轨迹,对应类型检查、CI、浏览器、日志和运行指标。产品形态变了,但 Harness 仍然要回答同样的问题:Agent 基于什么事实行动,哪些动作必须受限,如何根据证据继续或停止。
我把 AI 友好型架构归纳为三个相互依赖的部分:可读性、受控执行和反馈回路。
1. Agent 可读性
仓库不再只是代码存储位置,也应是一张可导航的知识地图。Agent 先读取项目级说明,再根据正在修改的目录加载局部规则、领域知识和接口说明。这样可以避免全量上下文带来的噪声,也让规则的作用范围更清晰。
可以从分层上下文开始:
| 层级 | 加载时机 | 适合放置的内容 |
|---|---|---|
| 会话常驻 | 每次会话 | 项目概览、运行命令、安全约束 |
| 目录规则 | 进入对应目录 | 模块边界、依赖方向、代码约定 |
| 专项知识 | 调用特定能力时 | 接口文档、研究结论、历史决策、Skill |
AGENTS.md、CLAUDE.md 或目录级规则文件的价值不在于文档数量,而在于让 Agent 能从任务位置找到足够小、足够准确的上下文。架构决策可用 ADR 记录,并随着系统变化维护;否则旧决策会成为错误上下文的一部分。
ADR 不只是“曾经为什么这样选”的档案。在 Agent 参与方案设计、PRD 对齐和架构检查时,它应成为可查询的架构事实来源:记录决策背景、可选方案、约束、结论和失效条件。相应地,也需要定义更新与清理机制。已废弃的决策、与实现不一致的规则和过期的接口说明,都会让 Agent 在正确地读取错误上下文。
2. 受控执行
人工 Code Review 无法单独承担 AI 时代的质量控制。对于规则明确的约束,应优先把检查变成自动化门禁,而不是让评审者反复发现同类问题。
常见的边界包括:
- 静态检查:依赖方向、命名、禁止 API、Lint 规则;
- 类型检查:严格 TypeScript 配置、减少
any和未声明的边界; - 自动化测试:单元测试、集成测试和端到端测试;
- 权限与隔离:将读取、修改、部署等工具能力分开,避免 Agent 因任务数据间接获得更高权限;
- 独立审查:由不同上下文或不同 Agent 检查设计一致性、代码风险和测试覆盖,而不是让编码 Agent 自行验收。
约束需要具备确定性:Agent 可以探索实现方案,但一旦违反依赖、类型或安全规则,就应由系统直接阻止进入下一阶段。错误信息也应包含修复线索,使失败结果成为下一轮执行的输入。
3. 反馈回路
约束回答“哪些事不能做”,反馈回答“下一步如何调整”。Agent 需要获得的不是一句“失败了”,而是可以定位问题的证据。
反馈可以按距离分为三层:
- 开发反馈:Lint、类型错误、单元测试和本地浏览器验证;
- 交付反馈:CI 中的集成测试、性能回归、冲突检测和预览环境;
- 运行反馈:日志、追踪、指标、异常和真实用户链路。
Chrome DevTools Protocol、日志查询和指标平台的意义,在于让 Agent 可以检查代码运行后的状态。对 Agent 来说,截图、DOM 快照、网络请求、错误堆栈和指标变化都是比自然语言更可靠的反馈。没有这些通路,Agent 只能根据代码猜测结果。
在无 UI 或逻辑与视图分离的场景中,反馈不必等待端到端页面测试。可以把业务状态、Service 方法和调试能力以受控工具暴露给 Agent:它先发现可用能力,再执行业务动作、读取状态、注入必要的调试信息,并根据实际状态或异常继续修改。这种接口的作用不是替代端到端测试,而是在功能尚未完成、页面用例难以编写时,为开发阶段提供更早的运行时反馈。完成逻辑验证后,仍应由集成测试、端到端测试或人工验收覆盖真实用户路径。
用专业化 Agent 组织反馈
一个拥有全部上下文和全部工具的通用 Agent,不一定比职责受限的多个 Agent 更可靠。专业化同时是一种上下文管理:每个 Agent 只携带当前阶段需要的信息,并只拥有完成该阶段所需的权限。
一个可行的分工是:
| 角色 | 主要职责 | 输入与产出 |
|---|---|---|
| 需求评审 Agent | 发现歧义,给出需要确认的选项 | PRD → 可执行需求 |
| 研究与规划 Agent | 探索代码库、拆分任务、选择实现路径 | 需求 → 技术方案与任务列表 |
| 执行 Agent | 在受限工作区完成单个任务 | 任务 → 代码与变更说明 |
| 审查 Agent | 检查方案一致性、风险和遗漏 | 变更 → 问题清单 |
| 测试 Agent | 用独立测试与真实交互验证功能 | 构建产物 → 缺陷与证据 |
| 清理 Agent | 定期发现过期文档、重复实现和规则偏差 | 仓库状态 → 小范围修复 PR |
角色拆分不代表每个任务都要走完整流水线。低风险改动可以直接执行并跑确定性检查;涉及多个模块、运行时行为或外部副作用的任务,才需要研究、审查和测试等独立阶段。
长任务需要把工作状态留在仓库中
一次会话能完成的任务,可以直接使用上面的闭环。任务跨多个上下文窗口时,新的 Agent 并不知道上一轮做到了哪里;只靠对话历史,状态会随着会话结束而丢失。因此,长任务需要把状态外置为版本化的工程资产,而不是依赖模型“记住”。
一个实用的最小组合是:统一启动方式、任务清单、进度记录和可回滚的提交。初始化阶段先建立运行环境和验收基线;后续每轮只领取一个可独立完成的任务,先检查当前工作区和已有验证结果,完成后更新任务状态、记录遗留风险并提交变更。任务清单适合使用结构化字段描述优先级、完成条件和验证证据,避免只用自然语言写“差不多完成”。
这套状态管理还有两个作用:一是让下一轮从可验证的工作状态继续,而不是重新探索整个项目;二是让失败能够恢复。提交、检查点、幂等操作和明确的重试上限,都是 Loop 的组成部分,而不是交付结束后再补的流程。
熵管理:让清理能力跟上生成能力
Agent 会模仿仓库已有模式,包括过时或低质量的部分。如果代码生成吞吐量不断提高,而规范更新、文档校验和冗余清理仍依赖人工临时处理,系统复杂度会持续上升。
因此,Harness 还需要持续维护机制:定时检查过期知识、在发布后校验文档与代码的一致性、通过小 PR 修复可自动确认的问题、对重复或违反架构的实现进行周期性审查。目标不是让 Agent 大规模重写代码,而是让清理吞吐量与新增代码吞吐量相匹配。
对于并行任务,还要额外管理共享工作区。任务应有明确所有者或锁,修改应在独立分支或工作区完成,再通过测试和合并流程汇合。并行化适合彼此独立的调研、测试和问题定位;多个 Agent 同时修改同一处核心逻辑时,冲突协调成本可能高于收益。
从哪里开始
不需要先搭建一个完整的多 Agent 平台。可以选择一个已有交付流程,按下面顺序补齐:
- 将项目结构、目录边界和运行命令写成短小的分层规则;
- 把已有的类型检查、Lint、测试和架构检查接入 Agent 的可执行反馈;
- 为日志、浏览器验证和指标查询提供受控工具入口;对逻辑层可额外暴露查询状态和执行受限业务动作的工具;
- 将编码、审查和测试分成独立步骤,先在中低风险需求上验证;
- 为跨会话任务维护版本化的任务清单、进度记录、验证证据和可回滚提交;
- 记录重复出现的失败原因,把它们转成规则、测试或工具能力;
- 对自动循环设置停止条件,例如最大重试次数、预算上限和必须转人工的异常类型,避免错误路径无限运行。
工程师的角色并没有消失,而是更集中在定义目标、设计边界、选择反馈信号和处理无法机械化的判断。Agent 可以加快实现速度,但长期交付质量取决于工程系统是否能让它读懂约束、在边界内行动,并根据真实结果收敛。
参考资料
- OpenAI: Harness engineering
- Martin Fowler: Harness Engineering
- Anthropic: Effective harnesses for long-running agents
- Anthropic: Building a C compiler with a team of parallel Claudes
- Architecture Decision Records: adr.github.io

