芥末
发布于 2026-04-05 / 0 阅读
0
0

用 Harness Engineering 驱动长任务 Agent:从大代码库蒸馏 Agent Skill

当任务规模大到几十万行代码时,问题就不再是“给 Agent 一个好 prompt”这么简单了。单个会话的上下文窗口有限,长时间运行容易丢失目标,多个子任务之间还会互相重复探索。想让 Agent 稳定完成这类任务,需要先设计一套外部工程环境,也就是 Harness Engineering。

Harness Engineering 可以理解为围绕 Agent 搭建的“任务运行框架”。它不只包括提示词,还包括角色分工、文件布局、任务队列、上下文索引、质量门控、权限边界、审查流程和交接协议。

一个典型目标是:面对一个 51.2 万行 TypeScript 代码库,不要求 Agent 逐文件复述实现细节,而是把其中可迁移的 Agent harness 设计原则提炼出来,整理成可安装、可复用的 Agent Skill。

这类任务的关键不是模型多强,而是:

  • 让不同 Agent 承担不同角色;
  • 让文件系统成为共享上下文;
  • 让每轮执行都从干净会话开始;
  • 让 review 和 action 形成闭环;
  • 让人工只介入方向、边界和品味判断。

Harness Engineering 解决的核心问题

普通 prompt 适合短任务,Harness 适合长任务。两者的区别可以这样理解:

维度普通 promptHarness Engineering
任务规模一次问答或短链路任务长时间、多阶段、多 Agent 任务
上下文来源当前聊天窗口文件系统、任务板、日志、索引、交接文档
状态管理依赖模型记忆依赖可读写的外部状态
质量控制靠模型自检独立 Reviewer、checklist、严重度分级
适合场景小修改、解释、生成片段大代码库分析、复杂编码、文档体系构建、研究型任务

在大代码库蒸馏任务里,直接把“请总结这个仓库的设计模式”丢给 Agent,通常会出现三个问题:

  1. 上下文爆炸:代码量远超单次会话能稳定处理的范围。
  2. 抽象层级漂移:Agent 容易陷入函数名、文件路径和实现细节,而不是提炼可迁移原则。
  3. 自我审查失效:执行者审查自己的产物时,容易漏掉事实错误和方向偏差。

Harness 的价值就在于把这些不稳定因素外置成工程结构。

flowchart TD
    A[大规模输入<br/>代码库、文档、历史决策] --> B[Harness 层]
    B --> C[角色定义]
    B --> D[上下文索引]
    B --> E[任务队列]
    B --> F[质量门控]
    B --> G[交接文档]
    C --> H[Builder Agent]
    D --> H
    E --> H
    H --> I[阶段产物]
    I --> J[Reviewer Agent]
    F --> J
    J --> K[Review 报告]
    K --> G
    G --> H

角色拆分:让 Reviewer 和 Builder 分开工作

长任务里最稳定的多 Agent 模式之一,是把“做事的人”和“审查的人”分开。

在这个实践中,可以把 Agent 分成两类:

角色适合使用的 Agent职责
Builder AgentClaude Code 一类擅长读写文件、调用工具、执行修改的 Agent扫描源码、起草参考文档、协调子 Agent、修改 Skill 内容
Reviewer AgentCodex 一类擅长审查、设计判断、事实核验的 Agent对照代码核查事实、判断抽象层级、检查产物是否可用

这个分工类似软件工程里的 code review:实现者不应该是唯一审查者。Builder 会带着前一轮决策继续推进,容易默认自己的方向是对的;Reviewer 在全新会话中启动,反而更容易发现问题。

更重要的是,每一轮 review 和 execution 都使用新的 session。这样做有两个好处:

  • 拿到完整 token 预算:不会被前几轮历史对话挤占上下文。
  • 减少上下文污染:Reviewer 不会被 Builder 的解释牵着走,Builder 也不会把未确认的 review 结论当成事实。

一次 review-action 循环可以表示成这样:

sequenceDiagram
    participant Human as 人工编排
    participant FS as 文件系统
    participant R as Reviewer Agent
    participant B as Builder Agent

    Human->>R: 启动全新 session,提供 review brief + diff + 上下文索引
    R->>FS: 读取源码、任务板、历史日志
    R-->>FS: 写入 codex_review_vX.md
    Human->>FS: 将 review 整理成 handoff_vX.md
    Human->>B: 启动全新 session,提供 builder brief + handoff
    B->>FS: 读取 handoff、源码、任务板
    B-->>FS: 修改产物并追加 progress-log.md

这里的人不负责逐字改稿,也不负责替 Agent 做所有阅读,而是负责启动下一轮、决定是否接受审查建议,以及在方向偏掉时重设边界。

文件系统是 Agent 之间的共享上下文

多 Agent 协作最怕“传话游戏”。如果一个 Agent 在聊天里总结给另一个 Agent,信息会不断压缩、丢失和扭曲。更稳的方式是让文件系统成为唯一可信状态:谁做了什么、发现了什么、下一步该做什么,都写进文件。

一个可复用的 harness 目录可以这样设计:

harness/
  briefs/
    clean-agent-brief.md
    review-agent-brief.md

  coordination/
    context-map.md
    pattern-notes.md
    task-board.md
    progress-log.md

  handoffs/
    handoff_v0_1.md
    handoff_v0_2.md

  reviews/
    codex_review_v0_1.md
    codex_review_v0_2.md

  gates/
    review-checklist.md
    execution-strategy.md
    output-format.md

  output/
    SKILL.md
    references/
      context-management.md
      multi-agent-coordination.md
      tool-permission.md

这些文件可以分成三组。

角色定义:让干净会话也能接手

文件作用
clean-agent-brief.mdBuilder 的入场说明,包括工作规则、最低输出要求、何时必须停下来问人
review-agent-brief.mdReviewer 的入场说明,包括审查优先级、输出格式、严重度分级标准

角色 brief 不应该写成超长说明书。它只需要让 Agent 明白自己的身份、边界和输出要求。细节应该放到上下文索引和任务文件里,让 Agent 按需读取。

协调层:让任务状态可追踪

文件作用
context-map.md代码上下文地图,把关键源码按 harness 层分组,说明每组为什么重要
pattern-notes.md探索笔记,记录前几轮扫描得到的关键发现
task-board.md共享任务队列,包含任务依赖、状态和退出标准
progress-log.md只追加日志,记录活动、决策和产物变更
handoff_v*.md一轮执行交给下一轮执行的行动简报
codex_review_v*.mdReviewer 的审查结果,包含严重度、证据和修复建议

progress-log.md 最好采用 append-only,也就是只追加、不重写。这样后续 Agent 能看到决策是如何形成的,也方便人工回滚错误方向。

task-board.md 可以用简单表格维护:

| ID | 任务 | 状态 | 依赖 | 退出标准 |
|---|---|---|---|---|
| P2-03 | 提炼上下文管理原则 | doing | context-map | 产出 references/context-management.md,并通过事实核验 |
| P3-01 | 标准化所有 reference 模板 | todo | P2-* | 所有章节符合 output-format.md |

质量门控:定义什么叫完成

文件作用
review-checklist.md定义阻塞问题、质量问题和措辞问题
execution-strategy.md定义并行度、子 Agent 分工和执行顺序
output-format.md定义最终 Skill 的文件结构、元数据、长度限制和章节模板

质量门控必须提前写。如果等产物已经生成完再讨论“什么叫好”,Agent 会不断局部修补,很难收敛。

一个实用的严重度分级如下:

等级含义示例
P1发布前必须修复事实错误、无源码依据的声明、Skill 运行时不可用
P2应该修复抽象不可迁移、缺少权衡、用户无法判断适用场景
P3可选优化措辞不一致、标题不够清楚、示例顺序可调整

Handoff 文档就是 Agent 之间的 API

API(应用程序编程接口)的本质是约定输入和输出。多 Agent harness 里的 handoff 文档也一样:它告诉下一个干净会话“目标是什么、该读哪些文件、必须修哪些问题、完成后写到哪里”。

一份好的 handoff 不需要塞满所有背景,它更像索引,而不是百科全书。

# Handoff v0.4 -> Builder

## 当前目标
把所有 reference 文档从“解释 Claude Code 子系统”改成“提炼可迁移 harness 原则”。

## 必读文件
- briefs/clean-agent-brief.md
- coordination/context-map.md
- reviews/codex_review_v0_4.md
- gates/output-format.md

## 必修问题
1. 修正 memory model 的事实错误,证据见 codex_review_v0_4.md#P1。
2. 所有章节去掉源码路径、函数名和实现细节。
3. 每个原则都必须回答:去掉具体产品名后是否仍然成立?

## 输出要求
- 修改 output/references/*.md
- 更新 coordination/task-board.md
- 向 coordination/progress-log.md 追加本轮决策和文件变更

这正是 Just-in-Time Context(即时上下文,JIT Context)的思路:Agent 不需要一开始获得全部上下文,只需要知道该去哪里拿到下一步所需信息。

每次 Agent 启动时,可以固定给三类上下文:

Agent Input =
  Role Brief          # 你是谁,规则是什么
+ Task Handoff        # 当前这一轮要做什么
+ Repo Filesystem     # 需要时读取的事实来源

给 Agent 一张地图,通常比给它一千页说明书更可靠。

从代码库到 Agent Skill:一条可复用流程

把大代码库蒸馏成 Agent Skill,不是简单总结代码。更合理的目标是:从具体实现里提取能迁移到其他 Agent 框架的原则。

目标定位可以用一张表说清:

不合适的目标更合适的目标
解释某个工具有哪些子系统解释构建者会遇到什么问题
罗列源码文件和函数名提炼可迁移设计原则
复述某个实现怎么做说明为什么要这么设计,以及换框架时如何迁移
只给结论给适用场景、权衡和踩坑指南

一个稳定流程可以拆成七个阶段。

flowchart LR
    P0[Phase 0<br/>搭建 Harness] --> P1[Phase 1<br/>并行探索源码]
    P1 --> P2[Phase 2<br/>起草 reference]
    P2 --> P3[Phase 3<br/>事实核验]
    P3 --> P4[Phase 4<br/>方向转向]
    P4 --> P5[Phase 5<br/>模板化重写]
    P5 --> P6[Phase 6<br/>Review 收敛]
    P6 --> P7[Phase 7<br/>UX 优化与发布]

Phase 0:先搭脚手架,再开始执行

起步阶段不让 Agent 直接读代码,而是先生成 harness 文件:角色 brief、上下文地图模板、任务板、审查清单、输出格式。

可以给 Reviewer 一个类似指令:

请为一个长时间运行的代码库蒸馏任务生成 harness 文件集合。

目标:
- 让全新 session 启动的 Agent 能快速接手;
- 所有状态通过文件系统维护;
- Builder 和 Reviewer 分离;
- 每轮 review-action 都有 handoff;
- 产物必须能被打包成 Agent Skill。

请输出:
1. Builder brief
2. Reviewer brief
3. context-map 模板
4. task-board 模板
5. progress-log 规则
6. review checklist
7. output format
8. execution strategy

这一步的产物决定了后面能否协作。如果没有任务板,无法判断进度;如果没有审查清单,无法判断产物是否合格;如果没有输出格式,多个子 Agent 写出的内容会风格混乱。

Phase 1-2:并行探索与起草

面对上千个文件,不应该让一个 Agent 从头扫到尾。更好的方式是 fan-out:多个 Explore Agent 各自负责不同源码区域,产出局部发现,再汇总到 context-map.md

例如:

Explore Agent负责范围输出
A上下文与记忆相关代码关键文件列表、核心机制、可疑事实点
B多 Agent 协作相关代码子任务调度、隔离方式、交接机制
C工具权限与生命周期权限来源、审批流程、工具调用边界
D用户界面与 Skill 触发展示限制、触发词、安装体验

随后再启动多个 Draft Agent,每个 Agent 负责一个 harness 主题,写入 references/*.md。并行不等于失控,所有子 Agent 都必须遵守同一份 output-format.md

Phase 3-4:事实核验与方向转向

第一轮 Reviewer 的价值通常不是润色,而是发现方向性问题。

常见 P1 问题包括:

  • 记忆系统描述错误;
  • 并发分类字段搞错;
  • 权限来源数量写错;
  • 某个设计被归因到不存在的源码证据;
  • 产物回答了“系统由哪些模块组成”,却没有回答“构建 Agent harness 时应该如何设计”。

其中最后一点最关键。代码蒸馏的目标不是做源码导览,而是提炼原则。判断一条原则是否合格,可以问一个问题:

去掉具体产品名、文件路径和函数名后,这条原则是否仍然有价值?

如果答案是否定的,它更可能是实现细节,不是 harness principle。

Phase 5:用统一模板重写所有章节

方向确定后,可以让多个 Agent 并行重写 reference。统一模板能显著降低风格漂移。

推荐模板如下:

1. 问题:构建者会遇到什么通用问题?
2. 黄金法则:一句可迁移的设计原则
3. 适用场景:什么时候应该使用
4. 权衡:它解决了什么,又牺牲了什么
5. 实现模式:不用源码路径描述实现方式
6. 踩坑指南:常见误用和失败模式
7. 实证说明:某个成熟实现如何体现这个原则

这里故意不要求代码片段。因为产物是 Skill,不是源码注释;它应该指导使用者设计自己的 harness,而不是绑定到某个仓库的内部结构。

Phase 6:让 Review 严重度逐轮下降

review 是否收敛,可以看严重度变化。

Review 轮次发现说明
v0.41 个 P1、多个 P2/P3仍存在事实错误,不能发布
v0.5仅 P3内容基本通过,只剩措辞级优化
UX(用户体验)审计新增 1 个 P1内容正确,但运行时展示有阻塞问题

这里有一个很容易漏掉的细节:内容审查通过,不代表 Skill 可用。Agent Skill 在列表展示时可能有描述长度限制,例如 250 字符;如果描述太长,精心设计的触发词会被截断,用户根本看不到该在什么场景调用它。

所以最后一轮必须做 UX 审计:

检查项失败表现修复方式
Skill 描述长度触发词被截断缩短描述,把关键词前置
目标读者用户不知道是否适合自己在开头写清适用对象
起步路径用户不知道先读哪一节每章增加“从这里开始”的操作指引
运行时列表Skill 名称和描述不匹配用短句说明任务边界

Phase 7:发布前做可用性收口

最终产物可以被整理成 Agent Skill,例如:

agentic-harness-patterns-skill/
  SKILL.md
  references/
    context-management.md
    multi-agent-coordination.md
    tool-permissions.md
    lifecycle.md

如果 Skill 支持通过命令安装,可以使用类似方式:

npx skills add https://github.com/keli-wen/agentic-harness-patterns-skill

发布前要确保 Skill 的入口不是“这是一个关于某代码库的分析”,而是“当你要构建长任务 Agent harness 时,该如何选择上下文、拆分角色、设置质量门控”。

人工介入应该放在哪里

Harness Engineering 不是让人完全退出流程,而是把人工介入集中到高杠杆位置。

1. 注入品味:给 Agent 一组“基向量”

从大代码库里提炼模式,有点像 PCA(主成分分析):代码是高维数据,设计原则是低维主成分。问题在于,哪些方向算“主成分”,不是纯客观的。

如果不给 Agent 任何偏好,它可能会提取 API 设计、文件组织、命名风格或内部模块关系;这些都可能正确,但不一定服务于“构建可迁移 harness 原则”的目标。

人工提供的博客、框架和判断标准,相当于一组基向量。它们告诉 Agent:

  • 更关注 Context Engineering,而不是具体函数;
  • 更关注 select / write / compress / isolate 这类上下文操作;
  • 更偏好简单可执行的规则,而不是复杂抽象;
  • 更重视跨框架迁移,而不是绑定单一实现。
flowchart TD
    A[高维代码空间<br/>文件、函数、状态机、工具调用] --> B[人工定义的基向量]
    B --> C[上下文工程视角]
    B --> D[可迁移原则视角]
    B --> E[用户可用性视角]
    C --> F[Agent 蒸馏]
    D --> F
    E --> F
    F --> G[低维原则集合<br/>可写入 Skill]

没有这些基向量,Agent 的 action space 太大,很容易产出“看起来完整但没有优先级”的内容。

2. 决定抽象边界

抽象边界不能完全交给 Agent。因为 Agent 很容易在两种错误之间摇摆:

  • 太具体:大量文件路径、函数名、内部实现,换一个框架就失效;
  • 太抽象:只剩“管理上下文”“控制权限”这类空话,无法指导实现。

一个实用判断标准是:

如果去掉具体产品名后仍然成立,并且能指导另一个 Agent 框架的设计,
它就是候选原则。

如果必须依赖某个内部函数或目录结构才能成立,
它只是实现细节。

3. 强制加入用户视角

很多 review 会盯着事实正确性,却忽略使用者能不能用。Skill 这种产物尤其需要用户视角,因为它会出现在运行时列表、触发逻辑和短描述里。

人工需要把这些规则写进 checklist,而不是靠 Agent 自觉:

## UX Gate

- Skill 描述必须在运行时列表中完整展示关键触发词。
- 开头必须说明目标读者。
- 每个 reference 必须告诉用户从哪里开始。
- 不能只解释原则,还要说明什么时候不要用。

用户视角不是润色,它可能直接发现 P1。

适合与不适合的任务

这套 harness 不应该套到所有任务上。它适合长链路、高不确定性、需要审查和沉淀的工作。

场景是否适合原因
大代码库分析适合需要上下文索引、并行探索和事实核验
复杂功能开发适合Builder/Reviewer 分离能降低实现偏差
技术文档体系生成适合多章节并行写作需要统一格式和质量门控
一次性小脚本不适合搭 harness 的成本高于任务本身
简单问答不适合文件系统协调没有必要
高度主观的创意写作谨慎使用质量门控难定义,review 容易变成风格争论

判断是否需要 Harness,可以看三个信号:

  1. 单个会话很难装下全部上下文;
  2. 任务会持续多轮,并且每轮会产生新状态;
  3. 结果需要独立审查,而不是只要“看起来还行”。

只要满足其中两个,就应该考虑用文件系统和 review-action 循环来组织任务。

常见坑

让同一个 Agent 自己审查自己

自检能发现格式问题,但很难发现方向性错误。复杂任务里应该引入 verification subagent,也就是专门负责验证的 Agent。

Handoff 写成超长总结

handoff 不是知识库。它应该指向知识库,告诉下一个 Agent 读哪些文件、修哪些问题、输出到哪里。过长的 handoff 会重新制造上下文膨胀。

没有 append-only 日志

如果日志反复被重写,后续 Agent 会看不到决策过程。只追加日志可以保留演化轨迹,也方便人工判断某个错误是从哪一轮引入的。

只做内容审查,不做运行时审查

Skill、插件、命令行工具这类产物都有运行时约束。内容正确不代表用户能触发、能看懂、能顺利安装。

抽象成空话

“提高效率”“增强可扩展性”没有指导价值。好的原则必须包含适用场景和代价,例如:

空泛说法更可执行的说法
使用文件系统提升协作把任务状态、review 结果和 handoff 写入文件,避免 Agent 之间通过聊天摘要传话
优化上下文管理给 Agent 上下文地图,而不是一次性塞入所有代码
加强质量控制用独立 Reviewer 按 P1/P2/P3 分级,P1 未清零前不发布

一个最小可复用模板

如果要把这套方式迁移到自己的项目,可以从最小 harness 开始,不必一上来就设计几十个文件。

harness/
  clean-agent-brief.md
  review-agent-brief.md
  context-map.md
  task-board.md
  progress-log.md
  review-checklist.md
  handoff_current.md

最小运行循环如下:

flowchart TD
    A[人工定义目标和输出格式] --> B[生成最小 harness 文件]
    B --> C[Builder 执行一个小阶段]
    C --> D[写入 progress-log 和产物]
    D --> E[Reviewer 独立审查]
    E --> F{是否有 P1?}
    F -- 有 --> G[写 handoff,Builder 修复]
    G --> D
    F -- 无 --> H{是否达到发布质量?}
    H -- 否 --> G
    H -- 是 --> I[做 UX Gate 和最终发布]

这套流程的核心不是“多开几个 Agent”,而是让每个 Agent 都在清晰边界内工作:Builder 负责推进,Reviewer 负责质疑,文件系统负责记忆,人工负责方向。

当输入足够复杂时,代码里真正有价值的设计模式往往不是一眼能看到的函数和模块,而是反复出现的低维原则。Harness Engineering 的作用,就是搭一个能稳定提取这些原则的环境。


评论