Harness 工程:必要组件、核心工作与任务流转

所有内容以 Anthropic 官方 Agent 设计指南、Claude Code 实际行为(--verbose 可观察)及 Claude Code 内置 CLAUDE.md 行为约束为依据。


一、一句话理解 Harness 工程

提示词工程管"怎么说",上下文工程管"给什么",Harness 工程管"怎么跑"。

它是套在 AI Agent 外面的那层管理框架,决定 Agent 如何被约束、如何运转、如何交付结果。

graph TD A[AI 工程体系] --> B[提示词工程\nPrompt Engineering] A --> C[上下文工程\nContext Engineering] A --> D[Harness 工程\nHarness Engineering] B --> B1["关注:怎么说话\n写出好的指令让模型理解"] C --> C1["关注:给什么信息\n管理放入窗口的内容"] D --> D1["关注:怎么运转\n构建驱动模型的整套框架"] style D fill:#f9a,stroke:#c66 style D1 fill:#ffd,stroke:#c66

二、必要组件

graph TD A[Harness 工程] --> B[1 多 Agent 架构] A --> C[2 AGENTS.md] A --> D[3 可测试的验收标准] A --> E[4 Linter 架构守卫] B --> B1["Orchestrator 规划\nGenerator 执行\nEvaluator 评审\n三者职责分离"] C --> C1["Agent 的地图\n100-200行作为索引\n指向具体规范文档"] D --> D1["每个功能写成\n可被工具验证的行为\n而不是模糊描述"] E --> E1["架构规范编码进 Linter\n报错信息包含修复指令\nCI 强制执行"]

组件 1:多 Agent 架构

依据:Anthropic 官方指南 ------ "In agentic contexts, Claude will sometimes act as an orchestrator of multi-agent pipelines and sometimes as a subagent within those pipelines, and sometimes as both."

核心思想:让同一个 Agent 又规划又执行又评审,它会对自己的作品过度宽容。把"规划者""运动员""裁判"彻底分开。

flowchart TD User[用户任务] --> Orch subgraph Orchestrator Agent 编排层 Orch[接收任务] Orch --> P1[读取 AGENTS.md] P1 --> P2[探索代码库\n只读不写] P2 --> P3[拆解子任务\n写入 plan.md] P3 --> P4[识别风险点\n确定验收标准] end subgraph Generator Agent 执行层 P4 -->|下发 plan.md| G1[读取 plan.md] G1 --> G2[按 TODO 执行] G2 --> G3[Edit / Bash 工具调用] G3 --> G4[每步轻量自检\nnpx tsc] G4 -->|局部有误| G3 G4 -->|计划有误\n回报 Orchestrator| P3 end subgraph Evaluator Agent 评审层 G4 -->|子任务完成| E1[读取 plan.md\n对照验收标准] E1 --> E2[跑测试 + Linter] E2 --> E3{是否通过?} E3 -->|通过| Done[ PR Ready] E3 -->|不通过 + 原因| P3 end

三个 Agent 的职责边界:

Agent 阶段 核心职责 不做什么
Orchestrator Plan 读规范、探索、拆任务、输出 plan.md ❌ 不写业务代码
Generator Execute 按 TODO 执行、工具调用、轻量自检 ❌ 不评审质量
Evaluator Verify 对照需求评审、跑 CI ❌ 不修改代码

注意:Evaluator 不是必须一直存在的。任务简单时是多余的开销,超出模型能力边界时才真正有价值。模型升级后要重新判断是否还需要它。


组件 2:AGENTS.md(给 Agent 的地图)

不是手册,是索引。控制在 100-200 行,告诉 Agent 去哪找规范,而不是把所有规范都堆在里面。

markdown 复制代码
# AGENTS.md 结构示例

## 项目概览
这是一个 React + TypeScript 的电商项目

## 核心规范(按需读取)
- 组件规范 → /docs/components.md
- API 规范  → /docs/api-conventions.md
- 测试规范  → /docs/testing.md

## 架构约束(必须遵守)
- 禁止在组件内直接调用 API,必须通过 hooks 层
- 状态管理统一使用 Zustand,禁止 Redux

## 常见错误(血泪教训)
- 修改 auth 相关代码前先读 /docs/auth-flow.md
- 环境变量不要硬编码,统一在 /config/env.ts 管理

关键原则:只存在于口头、聊天记录、脑子里的决定,对 Agent 来说不存在。


组件 3:可测试的验收标准

错误示范 → "界面要好用"

正确示范 → "点击删除按钮后,selectedEntityId 应该被清空"

markdown 复制代码
## 功能:用户登录
验收标准:
- [ ] 输入正确账号密码后,localStorage 中存在 auth_token
- [ ] 输入错误密码后,页面显示文字"密码错误,请重试"
- [ ] 登录成功后,URL 跳转到 /dashboard
- [ ] token 过期后访问 /dashboard,自动跳转回 /login

## 功能:删除商品
验收标准:
- [ ] 点击删除按钮,调用 DELETE /api/products/:id
- [ ] 删除成功后,列表中该商品消失
- [ ] selectedProductId 状态被清空

组件 4:Linter 架构守卫

把不能违反的架构规范写成 Linter 规则,让 Agent 读到报错就知道怎么改。

javascript 复制代码
// 自定义 ESLint 规则:禁止在组件里直接 fetch
module.exports = {
  rules: {
    'no-fetch-in-component': {
      create(context) {
        return {
          CallExpression(node) {
            if (node.callee.name === 'fetch') {
              context.report({
                node,
                message: `
                  ❌ 不允许在组件中直接调用 fetch
                  ✅ 修复方法:将请求逻辑移至 src/hooks/ 目录下
                  📖 参考规范:/docs/api-conventions.md#hooks-pattern
                `
              })
            }
          }
        }
      }
    }
  }
}

三、Coding 中的任务流转:Plan → Execute → Verify

依据:Anthropic 官方指南 ------ "For complex tasks, invest in upfront planning. Have the model explore and understand before acting."

3.1 完整三阶段流转图

flowchart TD Input["用户任务"] --> P1 subgraph plan["Plan 阶段"] P1["读取 AGENTS.md + 相关规范"] P2["探索代码库结构\n只读 不修改任何文件"] P3["拆解子任务\n写入 plan.md"] P4["识别风险点\n写入验收标准"] P1 --> P2 --> P3 --> P4 end subgraph execute["Execute 阶段"] E1["读取 plan.md"] E2["按 TODO 顺序执行"] E3["Edit / Bash 工具调用"] E4["每步轻量自检\nnpx tsc"] E1 --> E2 --> E3 --> E4 E4 -->|"局部有误"| E3 end subgraph verify["Verify 阶段"] V1["层1:自动化\nnpm test + tsc + eslint"] V2["层2:验收标准核对\n逐项检查 plan.md 中的标准"] V3["层3:Evaluator Agent\n独立评审逻辑与架构合规"] V4["层4:人工确认\nReview PR + 关注风险点"] V1 --> V2 --> V3 --> V4 end P4 --> E1 E4 -->|"计划有误"| P3 E4 -->|"所有任务完成"| V1 V4 -->|"不通过 + 原因"| P3 V4 -->|"通过"| Done["PR Ready"]

3.2 Plan 阶段:只读,不写业务代码

Claude Code 在 Plan 阶段的实际行为(--verbose 可观察):

markdown 复制代码
Phase: PLAN
─────────────────────────────────────────
  → read_file: AGENTS.md                  ✓
  → read_file: /docs/api-conventions.md   ✓
  → glob: src/**/*.ts                     ✓  (探索结构)
  → grep: "UserService"                   ✓  (找依赖)
  → read_file: src/services/user.ts       ✓

  输出 plan.md:
  TODO:
  [ ] 1. 拆分 UserService → AuthService + ProfileService
  [ ] 2. 更新 src/controllers/ 下的 import(共 4 个文件)
  [ ] 3. 补充 AuthService 单元测试
  [ ] 4. 跑 npm test 验证无回归

  ⚠️ 风险点:ProfileService 依赖 legacy UserDAO,需要兼容层
─────────────────────────────────────────

Plan 阶段工作清单:

工作 工具 目的
AGENTS.md read_file 加载项目约束
探索目录结构 glob / ls 理解全局,防止遗漏
查找依赖关系 grep 知道改哪里会影响哪里
plan.md write_file 外置状态,供后续 Agent 读取
标注风险项 写入 plan.md 让 Verify 阶段重点检查

3.3 Plan 产物必须外置到文件

原因:Generator 和 Evaluator 是独立的新 Agent,无法读取 Orchestrator 的上下文,产物必须写入文件才能传递。

markdown 复制代码
# plan.md(Orchestrator 写,Generator 和 Evaluator 读)

## 任务目标
给用户列表页加"按注册时间排序"功能

## 代码探索结果
- 入口:src/pages/UserListPage.tsx
- Hook 层:src/hooks/useUserList.ts
- API 层:src/api/users.ts
- 约束:状态管理用 Zustand,禁止组件内直接调 API

## 执行 TODO
[ ] 1. api/users.ts 加 sortBy 参数
[ ] 2. hooks/useUserList.ts 加排序状态
[ ] 3. UserListPage.tsx 加排序按钮 UI

## 风险点(Evaluator 重点检查)
- API 是否真实支持 sortBy,需要 bash 确认
- Zustand store 命名是否符合规范

## 验收标准
- [ ] 点击排序按钮,列表顺序变化
- [ ] 不刷新页面,排序状态保持

3.4 三 Agent 完整协作时序

sequenceDiagram participant User as 👤 用户 participant O as 🎯 Orchestrator participant F as 📁 文件系统 participant G as ⚒️ Generator participant E as 🔍 Evaluator User->>O: 下达任务 Note over O: PLAN 阶段 O->>F: read AGENTS.md O->>F: glob / grep 探索代码库 O->>F: write plan.md O->>G: 启动,传入 plan.md 路径 Note over G: EXECUTE 阶段 G->>F: read plan.md G->>F: Edit / write 执行变更 G->>G: npx tsc 轻量自检 G->>F: 更新 plan.md 进度 G->>E: 启动,传入 plan.md 路径 Note over E: VERIFY 阶段 E->>F: read plan.md E->>G: bash npm test E->>G: bash eslint alt 验证不通过 E->>O: 返回失败原因 O->>F: 更新 plan.md O->>G: 重新执行 else 验证通过 E->>User: ✅ PR Ready end

3.5 上下文重置机制(长任务关键)

sequenceDiagram participant O as Orchestrator participant A1 as Generator 第1轮 participant F as 文件系统 participant A2 as Generator 第2轮 O->>F: 写入 plan.md(完整计划) O->>A1: 启动,传入 plan.md A1->>F: 执行子任务 1、2、3 A1->>F: 更新 plan.md 进度 Note over A1: ⚠️ 上下文即将满 A1->>F: 写入当前状态\n已完成:1、2、3\n下一步:4 A1-->>O: 上下文重置,需要新 Agent O->>A2: 启动新 Agent A2->>F: read plan.md Note over A2: 知道了:已完成1-3\n接下来做4、5 A2->>F: 继续执行子任务 4、5

plan.md 进度更新格式:

markdown 复制代码
# plan.md(执行中持续更新)

## 任务目标
重构用户模块

## 执行 TODO
[x] 1. 拆分 UserService → AuthService + ProfileService
[x] 2. 更新 src/controllers/ 下的 import 路径
[x] 3. 补充 AuthService 单元测试
[ ] 4. 补充 ProfileService 单元测试  ← 当前位置
[ ] 5. 更新 API 文档

## 遇到的问题(新 Agent 接力时必读)
- ProfileService 依赖 legacy UserDAO
- 已在 src/services/compat/user-dao-adapter.ts 建立兼容层
- 新 Agent 继续时不要删除这个文件

## 验收标准
- [ ] npm test 全部通过
- [ ] npx tsc 无报错

四、需要做的具体工作清单

graph LR Step1["第一步\n裸跑 Agent\n观察失败点"] --> Step2["第二步\n写 AGENTS.md\n建立基础索引"] --> Step3["第三步\n把验收标准\n写成可测试行为"] --> Step4["第四步\n加 Linter 规则\n守住架构边界"] --> Step5["第五步\n视复杂度\n引入多 Agent"] --> Step6["第六步\n模型升级后\n重新审视每个组件"]
工作项 做什么 判断是否需要
裸跑观察 直接把任务给 Agent,读日志找失败点 永远先做这步
AGENTS.md 写 100-200 行的项目索引 任何项目都需要
规范文档目录 按需建立 /docs 下的具体规范 项目复杂度超过一般时
验收标准 把功能需求翻译成可验证的行为 有功能性任务时
Linter 规则 把架构约束编码进 CI 有反复出现的错误模式时
plan.md 机制 Orchestrator 输出计划文件 任务预计超过 30 分钟时
上下文重置 plan.md 记录进度 + 新 Agent 接力 任务预计超过 1 小时时
Evaluator Agent 加评审层 任务超出单 Agent 能力边界时
三 Agent 架构 Orchestrator + Generator + Evaluator 任务非常复杂时才值得开销

五、一个完整的真实示例串联全流程

任务:给用户列表页加"按注册时间排序"功能

markdown 复制代码
════════════════════════════════════════
PLAN 阶段(Orchestrator 执行)
════════════════════════════════════════

→ read_file: AGENTS.md
  发现约束:状态管理用 Zustand,禁止组件内直接调 API

→ glob: src/**/*.ts
→ grep: "UserList"
  找到:
  - src/pages/UserListPage.tsx   ← UI 入口
  - src/hooks/useUserList.ts     ← Hook 层
  - src/api/users.ts             ← API 层

→ write_file: plan.md
  内容:
  TODO:
  [ ] 1. api/users.ts 加 sortBy 参数
  [ ] 2. hooks/useUserList.ts 加排序状态
  [ ] 3. UserListPage.tsx 加排序按钮 UI

  风险点:API 是否支持 sortBy,需 bash 确认

  验收标准:
  [ ] 点击排序按钮,列表顺序变化
  [ ] 不刷新页面,排序状态保持

════════════════════════════════════════
EXECUTE 阶段(Generator 执行)
════════════════════════════════════════

→ read_file: plan.md

→ bash: curl -s /api/docs | grep sortBy
  确认 API 支持 sortBy 参数 ✓

→ edit: src/api/users.ts
  old: getUsers()
  new: getUsers(sortBy?: 'createdAt')

→ npx tsc --noEmit   ← 轻量自检
  通过 ✓,更新 plan.md: [x] 1

→ edit: src/hooks/useUserList.ts
  加入 sortBy 状态和传参逻辑

→ npx tsc --noEmit
  通过 ✓,更新 plan.md: [x] 2

→ edit: src/pages/UserListPage.tsx
  加入排序按钮,调用 hook

→ npx tsc --noEmit
  通过 ✓,更新 plan.md: [x] 3

════════════════════════════════════════
VERIFY 阶段(Evaluator 执行)
════════════════════════════════════════

→ read_file: plan.md (读取验收标准)

层1 自动化验证:
→ bash: npm test
  ✓ 32 passed

→ bash: npx eslint src/
  ✓ 无报错(Linter 守卫通过)

层2 验收标准核对:
→ 点击排序按钮列表顺序变化?
  read_file: UserListPage.tsx
  确认 onClick 正确绑定 ✓

→ 不刷新页面排序状态保持?
  read_file: useUserList.ts
  确认状态存入 Zustand store ✓

层3 架构合规:
→ 组件内是否有直接 fetch 调用?
  grep: "fetch" src/pages/UserListPage.tsx
  无结果 ✓(符合 Linter 规则)

结论:全部通过 → ✅ PR Ready

六、最重要的一条原则

依据:Anthropic 官方指南 ------ "Invest in the right amount of scaffolding. More structure is not always better."

先跑裸 Agent,再决定加什么。

Harness 的每个组件应该针对真实观察到的失败模式,而不是理论上的风险。

graph LR A["🟢 裸跑\n观察失败"] -->|发现问题再加| B["🟡 最小 Harness\nAGENTS.md + 验收标准"] B -->|发现问题再加| C["🔴 完整 Harness\n多 Agent + Linter + plan.md"] A -. 不要跳过 .-> C

七、常见误区与解法

依据:Anthropic 官方指南 ------ "Mistakes in agentic contexts may be difficult to reverse, and could have downstream consequences within the same pipeline."

graph TD subgraph 常见误区 M1[Plan 和 Execute 混在一起\n边想边改] M2[验收标准写得模糊\n无法被工具验证] M3[plan.md 只存在于上下文\n没有写入文件] M4[Evaluator 和 Generator\n用同一个 Agent] M5[一上来就搭三 Agent 架构\n任务其实很简单] end subgraph 正确做法 S1[Plan 阶段严格只读\nExecute 阶段才动文件] S2[验收标准写成\n工具可执行的检查项] S3[所有状态外置到文件\n新 Agent 能独立接力] S4[两个独立 Agent\n职责完全分离] S5[先裸跑\n发现真实失败点再加组件] end M1 --> S1 M2 --> S2 M3 --> S3 M4 --> S4 M5 --> S5

八、快速参考卡片

判断用哪种架构

flowchart TD Start[新任务来了] --> Q1{任务能在\n10分钟内完成?} Q1 -->|是| A1[ 单 Agent 裸跑\n无需 Harness] Q1 -->|否| Q2{任务有明确的\n可验证验收标准?} Q2 -->|否| A2[先把验收标准\n写清楚再开始] Q2 -->|是| Q3{预计超过\n30 分钟?} Q3 -->|否| A3[ 单 Agent\n+ AGENTS.md\n+ 验收标准] Q3 -->|是| Q4{预计超过\n1 小时?} Q4 -->|否| A4[ 单 Agent\n+ plan.md\n+ 上下文重置机制] Q4 -->|是| Q5{任务超出\n单 Agent 能力?} Q5 -->|否| A5[ 单 Agent\n+ plan.md 接力] Q5 -->|是| A6[ 三 Agent 架构\nOrchestrator\n+ Generator\n+ Evaluator]

三阶段检查清单

markdown 复制代码
════════════════════════════════════
PLAN 阶段 检查清单
════════════════════════════════════
□ 读取了 AGENTS.md?
□ 用 glob/grep 探索了代码库?
□ TODO 列表写入了 plan.md?
□ 风险点标注了?
□ 验收标准写成了可验证的行为?
□ 本阶段没有修改任何业务文件?

════════════════════════════════════
EXECUTE 阶段 检查清单
════════════════════════════════════
□ 读取了 plan.md?
□ 按 TODO 顺序执行,没有跳步?
□ 优先用 Edit 而非整文件 Write?
□ 每个子任务后跑了 npx tsc?
□ plan.md 进度实时更新了?
□ 发现计划有误时回到 Plan 重规划?

════════════════════════════════════
VERIFY 阶段 检查清单
════════════════════════════════════
□ 层1:npm test 全部通过?
□ 层1:npx tsc 无报错?
□ 层1:eslint 无报错?
□ 层2:plan.md 验收标准逐项核对?
□ 层3:Evaluator 独立评审通过?
□ 层4:风险点已告知人工 Review?

文件结构参考

markdown 复制代码
project/
├── AGENTS.md              ← Agent 的地图(100-200行)
├── docs/
│   ├── components.md      ← 组件规范(AGENTS.md 指向)
│   ├── api-conventions.md ← API 规范(AGENTS.md 指向)
│   └── testing.md         ← 测试规范(AGENTS.md 指向)
├── .eslintrc.js           ← 含自定义架构守卫规则
├── plan.md                ← 当前任务计划(任务结束后删除)
└── src/

九、全文总结

graph TD A[Harness 工程] --> B[四个组件] A --> C[三个阶段] A --> D[一条原则] B --> B1[多 Agent 架构\nOrchestrator+Generator+Evaluator] B --> B2[AGENTS.md\n项目地图索引] B --> B3[可测试验收标准\n行为可被工具验证] B --> B4[Linter 架构守卫\n错误信息含修复指令] C --> C1[Plan\n只读探索 输出plan.md] C --> C2[Execute\n按TODO执行 实时更新进度] C --> C3[Verify\n四层验证 不通过回到Plan] D --> D1[先裸跑观察真实失败点\n再决定加哪个组件\n不要过度设计] style D fill:#ffd,stroke:#c66 style D1 fill:#ffd,stroke:#c66

最后一句话:Harness 工程的本质不是给 Agent 加更多限制,而是给它一套可靠的运转轨道,让它在正确的时间做正确的事,出错时能被发现,能被纠正,能被接力。

相关推荐
洛卡卡了2 小时前
Claude Code进阶:用Superpowers打造靠谱的AI开发工作流
aigc·ai编程·claude
嵌入式小企鹅2 小时前
RISC-V爆发、AI编程变天、半导体涨价潮
物联网·学习·ai编程·开发工具·risc-v·芯片·工具链
非科班Java出身GISer3 小时前
国产 AI IDE(Agent) 颠覆传统开发方式:codebuddy 介绍,以及简单对比 trae、lingma、Comate
人工智能·ai编程·ai agent·ai ide·ai 开发工具·ai 开发软件
马丁玩编程3 小时前
历时半年,开源了一套企业级 Agentic RAG 系统!
aigc·openai·ai编程
IT 行者3 小时前
Web逆向工程AI工具:Integuru,YC W24孵化的API逆向神器
人工智能·ai编程·web逆向·mcp
github.com/starRTC3 小时前
AI写需求系列之PM Skills
ai编程
花千树-0103 小时前
IndexTTS2 在 macOS 性能最佳设置(M1/M2/M3/M4 全适用)
人工智能·深度学习·macos·ai·语音识别·ai编程
好多渔鱼好多4 小时前
【AI编程工具】Copilot详解
copilot·ai编程
小程故事多_805 小时前
Harness实战指南,在Java Spring Boot项目中规范落地OpenSpec+Claude Code
java·人工智能·spring boot·架构·aigc·ai编程