Harness Engineering(脚手架工程)这个概念已经流行一阵了。网上大多数文章都停留在理论层面,反复解释为什么现代 AI 开发不能再依赖单个 Prompt、也不能把模型当成"聪明的代码自动补全"。不过这里有一个实际问题被反复提及:
概念我懂了。可一旦真要落到工程上,第一步到底该做什么?
Harness 这个词听起来宽泛而且像一种抽象的方法论。如果它没法落到具体的目录结构、文档、脚本和工作流上,那就只是一句漂亮口号。Harness Engineering 在不同项目上的呈现可以差得很远——有的项目重度依赖 CI/CD pipeline,有的依赖严格的开发规范,有的依赖多智能体(Multi-Agent)编排,也有的只是把一堆脚本和模板严格组织起来。但只要往下挖,会发现它们在解决同一个核心问题:
如何让 AI 在你的项目里稳定、可靠、可预测地交付你想要的结果。
下面这张图把脚手架成熟度模型(Harness Maturity Model)划分成五个等级
实际使用场景:你处在哪一级?
- Level 0:适合一次性脚本或纯粹的实验。你不在意可维护性,只想看一个想法现在能不能跑通。
- Level 1(约束):适合个人开发者和 MVP 阶段。你需要 AI 加速样板代码,但每一行代码的架构判断和审查仍由你来做。
- Level 2(反馈回路):生产期初创公司和小团队的最佳位置。AI 在这里成为可靠的初级伙伴。你信任代码,是因为系统本身——测试、CI、Linter——会捕获错误,而不是只靠你的肉眼。
- Level 3(专业化分工):复杂多服务系统的必经之路。当代码库大到一个人脑子装不下,就需要拆分 AI 角色(规划者、编码者、测试者),用来管理上下文、避免回归。
- Level 4(自治):留给平台级或 AI 原生组织。当系统需要在无人干预下持续自我修复和重构时才用得上。
本文用一个最小化的 Go 项目 crypto snapshot API 作为贯穿全文的例子,一步步讲我们是怎么把 Harness 搭起来的。哪些做法奏效、哪些地方踩了坑、哪些最初以为够用后来证明远远不够。这样你就可以在自己的项目里从零搭一套 Harness Engineering 框架,从哪里下手、按什么顺序补全后续。
基本概念
很多人一上来就开始写 Rule、搭 Agent、接入 MCP,结果越搞越乱。根本原因不在于执行力,而在于基础概念从一开始就没有被清楚区分。下面这些术语会在整个工程框架里反复出现。它们如果糊在一起,地基就没法稳。
我们先把这些概念压成一张速查表,建立一个更清晰的整体认知:
Rule 可以理解为你给 AI 设立的一套"工程准则"。
它不是需求文档、设计规范,也不是脚本。可以把它想成给新入职开发者讲解的基础原则:什么允许做、什么严格禁止、完成后必须验证什么、哪些规约绝对不可妥协。
我们项目里有一条 Rule 强制"修改后清单":
- 你不能只是说 "我做完了。"
- 你必须编译代码。
- 你必须运行测试。
- 你必须执行后置校验。
- 三项任意一项不通过,任务就不算完成。
Rule 的核心目的不是让 AI 更聪明,而是阻止 AI 反复犯低级、可避免的错误。
所以 Rule 更像是团队的开发政策。政策本身不直接创造价值,它的作用是消除混乱、强制一致性。
但这里有一个关键提醒:Rule 是软约束,不是硬关卡。
理论上 AI 应该遵守,实际不一定每次都靠谱。规则集越大、任务越复杂,模型越容易表现出三种典型失败:
- 遗忘:它干脆忘了某条 Rule 存在。
- 选择性失效:它判定某条 Rule "不适用于"当前情境。
- 偷懒绕过:它知道这条 Rule,为了节省算力或上下文窗口跳过了它,然后给自己找个合理化解释。
正是这一点决定了 Rule 是基础但不足够。它设定底线,却保证不了执行。这也是 Harness 框架其余部分存在的理由。
Skill 是强烈推荐每个团队尽早实现的东西。
本质上 Skill 是在告诉 AI:这件事不要现场发挥;不要每次都从头推导流程,也别去猜一个大概的工作流;按这些固定步骤来。
以编译为例。如果你只说 "go 编译一下这个项目",AI 可能愉快地跑一句
go build ./...
,表面没问题。但在真实工程环境里,编译几乎从来没那么简单,它常常涉及:
- 同步并校验模块依赖(
go mod tidyvs 严格的go.sum校验) - 应用正确的 build tags 和环境约束(
-tags、//go:build指令) - 处理 CGO 依赖或交叉编译 flag(
CGO_ENABLED、GOOS/GOARCH) - 通过 linker flag 注入运行时元数据(
-ldflags="-X main.version=...") - 把结构化编译输出路由到确定性日志文件
- 区分硬错误和警告,判断产物是否真的可以发布
如果每次都让 AI 在这些细节上自由发挥,最终一定会出问题。
我们因此把编译做成了 Skill,测试和后置校验也一样。现在 AI 走到这一步,不再是"想办法把事做完",而是"执行剧本"。
可以把 Skill 想成给 AI 用的标准操作流程(SOP)。Rule 告诉 AI "这件事必须做",Skill 告诉它 "具体应该这么做"。
Sub-Agent 本质上是一个由多个 AI 角色组成、分工明确的系统。
团队最初用 AI 时,常常默认让单个 Agent 端到端处理一切:分析需求、设计架构、写代码、自审、生成测试、汇总进度。短小琐碎的任务这么做没问题。可只要复杂度上升,裂缝就立刻出来:
- 它在解读自己的需求。
- 它在评判自己的技术方案。
- 它在写完代码后,自己给自己开"健康证明"。
- 它天生倾向于"推进任务",而不是"暂停下来承认确实有问题"。
这和真实软件开发完全对应。当一个人同时担任产品经理、架构师、开发者和 QA 时,质量必然失控。
我们因此引入多个 Sub-Agent,把工作流切成不同阶段。每个 Agent 只处理自己负责的那一段,把输出写进结构化文档,再交给下一个 Agent。
在真实工程团队里,Sub-Agent 直接对应专门化的角色:
- 需求专家只澄清需要做什么。
- 架构师只敲定技术设计。
- Gatekeeper(守门人)只判断是否能进入开发。
- 开发者只专注实现。
- QA/Reviewer 只负责验证并闭环。
- PM 只编排流程。
这套思路非常简单,可以说没什么开创性或新鲜东西但对 AI 出奇有效。关注点分离阻止了上下文坍塌,消除了自评偏差,并在每个阶段强制了客观检查点。
Workflow 不是"启动几个 Agent"。
有多个 Agent 却没有 Workflow,等于没有系统,只有"几个人在干活",缺一套稳定、可重复的协作协议。
理解 Workflow 最清楚的方式不是流程图,而是接力赛的规则。
接力赛里最关键的因素不是四个跑得快的人,而是事先有一套清清楚楚的规则:
- 谁跑第一棒?
- 下一棒选手到底什么时候接棒?
- 交接区里必须交接什么?
- 什么算犯规?
- 一旦犯规,是重赛、时间罚分,还是直接取消资格?
工程运转的方式一模一样。有需求、设计、开发、测试角色,只代表"有人";Workflow 真正存在的前提,是要显式定义:
- 任务目前处于哪个阶段?
- 当前阶段必须交出的、可验证的产物是什么?
- 谁有权接下一棒?
- 下一次交接前必须审阅哪些文档?
- 什么条件会触发自动驳回或回滚?
- 一旦回滚,由谁负责修复,流程从哪里重启?
没有 Workflow,工程现场往往退化成这副样子:
- 需求模糊,设计师中途随意更改范围。
- 设计有缺陷,开发者为了"保持势头"硬着头皮往前推。
- QA 发现 blocker,PM 为了赶 deadline 强行放行。
- 某个阶段明显需要回滚,没人知道该由谁修、从哪里重启。
- 所有人都"在干活",可没人能回答:"这个任务现在到底是什么状态?"
所以 Workflow 的核心不是"画了一张图",而是为每一次推进、暂停、驳回、重启建立明确、可审计的规则。
我们项目里这套 Workflow 拆成三层:
- 人类可读层:解释整体开发管线、理念和交接预期。
- 系统强制层:硬编码阶段边界、状态转移和校验关卡。
- 角色专属层:明确每个 Sub-Agent 在接手时读什么、在交接时必须写什么。
三层合起来,才能形成一套真正可以长期维护的 Workflow。少了它们剩下的就只是几份漂亮的 Prompt 模板。
和这套"接力赛"结构并行的,是一条严格的上下文纪律:每一棒只接收它当前那一段真正需要的素材。这不是为了藏信息,而是为了避免 AI 上下文过载。一上来就把所有 Rule、项目地图和任务历史全塞进去,反而稀释焦点。我们因此刻意让 Rule 集逐步扩张,把
dev-map
或任务看板这类项目级资产延后到后续阶段才载入。这和分阶段 Workflow、Sub-Agent 隔离的理念一致:思路相同,实现方式不同。
Script(脚本)是整个 Harness 中"最重要"的组件。
Rule 告诉 AI 应该做什么;Skill 给 AI 标准操作流程;Script 在说:你说自己完成了不算数,除非系统证明,否则你过不了我的关卡。
正是这一点,让我越来越确信:一个真正成熟的 Harness 最终会越来越依赖脚本,越来越少地依赖 Prompt。
我们项目里有一份典型的"主守门人脚本"(Master Gatekeeper Script)。它把许多原本以软建议形式存在于 Rule 里的检查改成了硬性、可执行的校验。比如它会验证:
- 是否存在硬编码字符串、密钥或魔数,而没有使用
config/env包? - 是否在用
fmt.Println或log.Print,而不是项目约定的结构化 logger(例如zap/slog)? - 整个代码库是否能以零警告通过
golangci-lint run? - 是否存在直接调用
os.Exit(),绕过了优雅关闭或错误处理包装? go.mod/go.sum是否与实际 import 严格同步(go mod tidy的 diff 为零)?- build tag(
//go:build)是否被正确应用、记录并测试? - 项目能否在目标平台上以
go build -v ./...干净通过? - 所有测试是否能在竞态检测和严格超时(
go test -race -timeout=30s ./...)下通过? - 代码覆盖率是否跌破了项目基线?
- 生成的文件(
mocks/、pb/、deepcopy/)是否被误提交,而不是在 CI 里重新构建? - 导出类型和函数是否遵循命名、版本管理和弃用规约?
- 是否存在未关联 issue 编号的
TODO/FIXME注释?
一旦这些检查被写进脚本,AI 就再也没法用"我觉得没问题"虚晃过去。要么过关,要么不过;没有讨价还价的空间,也没有让主观判断藏身之处。
MCP 到底是什么?
MCP(Model Context Protocol)本质上是一座标准化的桥:把"代码仓库之外的能力"直接接入 AI 的工作流。它允许 AI 在严格定义的边界内既能拉取信息,也能触发外部系统的动作。
可以把它当作一个可编排的接口层。AI 不再只依赖当前会话上下文和本地文件,而能接入 Wiki、知识库、结构化数据和平台 API。在 Unity 或其他宿主引擎这类环境里,它可以直接对接编辑器与运行时能力(编译、资源管理、日志、状态检视和受控命令),让"生成的代码"和"宿主环境里实际发生的事情"对齐。
这解释了为什么当你要把 Harness 从"开发回路"演进到完整的"工程交付回路"时,MCP 会变得关键。交付管线里全是系统级能力——CI 触发、代码签名、产物管理、发布编排、状态回调——这些都不是再写几个本地脚本就能替代的。
我们先看边界。没有 MCP 时,AI 通常被锁定在:
- 本地代码仓库
- 本地脚本
- 当前会话上下文
它可以分析、改代码、跑本地校验,却很难安全、结构化、可审计地和更广义的工程系统交互。
反过来,要做一个完整闭环,最终会需要处理这些动作(仅列常见的):
- 通过 CI 平台触发构建
- 拉取构建日志和结果
- 调用签名服务为安装包或二进制做签名
- 把产物上传到仓库或分发平台
- 编排发布(金丝雀、评审、生产灰度)
- 回写发布状态、版本标签和交付记录
共同点是什么?这些都要求 AI 在受控边界内调用系统能力,而不是把凭证和临时命令散落在聊天记录里。MCP 充当这层连接:它把外部系统以结构化的
Tools
或
Resources
暴露给 AI,让 Rule、Workflow 和 Script 可以强制约束这些调用。
在我们整体架构里,MCP 不是 Harness 的核心,而是对外的接口层。它连接什么、访问粒度多细、什么时候允许触发,本身必须由策略和关卡来治理。
Rule 是团队政策,Skill 是 SOP 手册,Script 是安检闸门——MCP 则是把 AI 插入更广义工程生态的标准化电源接口。现在它可能感觉像锦上添花。但一旦你要 AI 不只是写代码,而是可靠地参与构建、签名、打包、发布和状态汇报,这一层很快会变得举足轻重。
把这些概念整合起来
最后我们再花点时间把它们梳理一下:
- Rule:告诉 AI 边界在哪里。
- Skill:告诉 AI 在这些边界内如何执行固定动作。
- Sub-Agent:把一个大块任务拆成多个分工协作的专门角色。
- Workflow:规定这些角色按什么顺序、在什么时候交接。
- Scripts:根本不指挥 AI——它直接验证工作是否真的完成。
- MCP:把 AI 连接到外部知识、工具和宿主系统。
这些组件不是互相替代的关系,而是叠加。
也可以从功能角度来看:
- Rule 强制底线。
- Skill 把高频操作标准化。
- Sub-Agent 把复杂度拆到聚焦的角色上。
- Workflow 编排协作顺序。
- Scripts 客观验证产出。
- MCP 把系统延伸到更广义的工程生态。
换句话说,你目前看到的还只是一盒零件:一堆约束、流程、校验器和接口并排摆在一起。
接下来才是最关键的一步:当这些零件被正确组装时,它们如何转化成一个完整的 Harness Engineering 系统。
Harness Engineering 是什么?
它不是某个工具,也不是某个 Prompt 小技巧;它是一整套工程系统,用来让 AI 在真实项目中稳定地产出正确、可靠的结果。
注意这里的三个关键词:
- 稳定:不是"这次走运",而是下次、再下次、不同需求、不同维护者手里都能可靠运行。
- 产出:不仅仅是写代码,而是交付完整生命周期产物——需求、设计、校验、部署。
- 正确的结果:不是"做完就行",而是有可验证、客观的方式来证明这件事是否真的对。
在我看来Harness Engineering 不解决"如何让 AI 更聪明",它解决的是:如何在工程语境下,把 AI 从一个即兴发挥的模型,变成一个受约束、能协作、可验证、可持续维护的执行系统?
把我们目前的 Harness 全貌摊开来,大致是这样:
- SPEC(设计规范):在最前面把目标、边界和版本意图说清楚。解决"AI 到底要造什么?"
- Rule:硬编码底线约束和红线。解决"哪些东西绝对不能违反或临场发挥?"
- Skill:把编译、测试、校验这类固定动作标准化。解决"怎么让关键流程不再依赖瞎猜?"
- Sub-Agent:把不同阶段拆给不同角色。解决"怎么防止一个 Agent 同时扮演产品经理、架构师、开发者和 QA?"
- Workflow:定义角色如何交接、何时推进、何时驳回与回滚。解决"如何让多角色协作摆脱临时拍脑袋?"
- Scripts / Post-Validation:把抽象的约束变成可执行的检查。解决"如何确保'完成'真的代表'正确'?"
- Dev-Map(开发导航图):帮 AI 快速把握项目结构和既有模式。解决"如何让 AI 一进代码库不再重复造轮子?"
- Task Board(任务看板):让 PM 和分析师对项目历史和当前进度保持一致。解决"如何在专注当前任务的同时不丢失整个项目的脉络?"
- MCP:暂时还不是 Harness 的主干,但对未来扩展至关重要。如果想和 CI、签名、产物管理、发布等外部系统形成闭环,MCP 就是那条必不可少的连接层。
打个比方:
Harness Engineering 就像在为 AI 搭一整套"工程运营操作系统"。SPEC 是任务目标,Rule 是纪律,Skill 是标准训练,Sub-Agent 是兵种分工,Workflow 是指挥链,Script 是检查和反馈回路;而 Dev-Map 和 Task Board 提供战场地形图和态势感知(这两个概念会在第 9 章详细展开)。
单看每一块都谈不上革命性。真正的价值只有在它们组装在一起时才会浮现:那时候 AI 不再像一个会闲聊的聪明聊天机器人,而开始像一个有纪律的工程师在真实项目里运转。
Harness 之前——先从 SPEC 开始
在真正进入"第一步"之前,我觉得有必要简单交代一下这个示例项目本身。
如果你不清楚
crypto-snapshot-cli
做什么、解决什么问题、大致处在复杂度光谱的哪一段,就很容易把我们这套方法误解为只有大型企业系统才需要的繁琐仪式。其实这个项目刻意做得非常小,但它包含了 AI 通常会崩溃的所有结构性接缝。这正是用它从零搭建 Harness 的理想案例。
crypto-snapshot-cli 到底是做什么的
动手之前先弄清楚这个项目究竟是什么。如果你不理解它的范围和复杂度,可能会把 Harness 当作对一个简单工具的过度工程。它不是。它是一个最小但完整的示例,把 AI 通常失败的每一道接缝都暴露了出来。
项目名:
crypto-snapshot-cli
一句话介绍:一个用 Go 写的 CLI 工具,从 CoinPaprika API 获取实时加密货币价格,对数据做校验,并导出带完整审计轨迹的结构化 JSON 快照。
它解决什么问题?
真实场景:你在搭一个交易仪表盘、组合追踪器,或者一套自动再平衡系统。在做这些事之前,你需要可靠、结构化的价格数据。
但获取加密价格并不是请求一个 API 端点这么简单。你需要:
- 优雅处理速率限制
- 对瞬时失败实现重试逻辑
- 按 schema 校验 API 响应
- 把带上下文的错误记录到日志里方便调试
- 把数据导出成下游系统能消费的格式
- 确保整个流水线在时间预算内完成
没有 Harness,AI 写出来的代码有时候能跑;有了 Harness,它写出来的代码每一次都能可靠地跑通。
核心功能的逻辑也非常简单
Input: CLI 参数(--limit=10、--output=prices.json)
↓
Fetch: 带重试逻辑调用 CoinPaprika API
↓
Validate: 校验响应 schema、数据类型、完整性
↓
Transform: 把 API 响应转换为内部模型
↓
Export: 把结构化 JSON 写入文件
↓
Report: 生成执行日志和校验和(checksum)
没有 WebSocket 流式推送、没有数据库、没有 Web UI、没有机器学习。就是一条干净的、线性的数据处理管道。
人来搭 Harness,AI 写代码
在这个项目的整个持续演进过程中,每一行生产代码都是 AI 写的;人没写一行实现代码。
那人到底干了什么?我们没有跳进去打补丁,也没有充当"在 AI 身后打磨输出的高级打字员"。我们的全部精力都放在系统性地搭建 Harness Engineering 框架上:
- 先把需求和设计彻底说清楚
- 接着编码基础 Rule
- 然后把固定流程标准化为 Skill
- 之后把工作流拆解成专门化的 Sub-Agent
- 接下来加上脚本化的关卡和后置校验
- 最后把项目地图、任务看板和工作流定义文件整合进来
这个项目从来不是一个成熟工程团队先写代码、再把 AI 当作助手挂上来的模式。恰恰相反:我们先把 Harness 搭起来,随着 Harness 成熟,AI 从处理琐碎任务,过渡到攻克复杂特性,最终独立维护整个项目。
人类没写代码。人类架构了那个生成、校验并维护代码的系统。
从设计规范(SPEC)开始
本章真正回答的不是"为什么要写 SPEC?",而是"当你面对一个真实的、要持续迭代、完全由 AI 来构建和维护的项目时,你究竟从哪里开始?"
很多人一听到 Harness 就立刻开始写 Rule、拆 Agent、加关卡脚本。但如果你没有先把"我们到底要做什么?'完成'到底长什么样?"说清楚,后面加的每一条约束都建在沙子上。
所以真正的第一步不是写 Rule,而是起草一份完整的设计规范,并通过和 AI 反复迭代把它打磨出来。
在
crypto-snapshot-cli
项目里,我们就是这么开始的,不是从代码开始,而是从和 AI 一起共写一份详细 SPEC 开始。
这份文档的意义不在于"看起来专业",而在于生成第一行代码之前,强制把基本面理清楚:
- 这次发布到底要解决什么具体问题?
- 哪些是核心目标,哪些只是锦上添花?
- 涉及哪些模块?
- 哪些行为必须保持向后兼容?
- "完成"到底长什么样?
这一步通常会和 AI 反复讨论很多轮,可能让人觉得繁琐,但是如果这里偷工减料,后面要十倍奉还。
这种反复并不只是在润色文字,而是一个协作式的发现过程。有时你自己一开始也不知道想要什么。把 AI 拉进需求讨论,让它扮演反方、拆解可选项、暴露边界情况——真实的需求很少在初稿里就完整成型,是在对话中一点点挖出来的。
一份准生产级 SPEC 长什么样?
它必须明确写清每一条需求,定义必要的边界条件(这部分后续由需求分析 Agent 来补全),不能有任何含糊语言。"建议""可以""推荐""可选"这些词在这里没有位置。如果不是强制的,就不该出现在规范里;如果是必须的,就必须以硬约束的形式表达。
但很快我发现一个残酷的事实:光有 SPEC 还不够。
问题不在于 AI 看不懂文档。问题在于:
- 它不会 100% 遵循。
- 它说"做完了"之后,你没有清晰的方式追踪究竟哪些做完了、哪些还没做。
- 同样的错误会在不同会话里反复出现。
举几个例子。它会跳过自己认为"不那么关键"的细节;它会声称"全部完成",结果你发现少了文件或没实现的边界情况;它这周犯的错和上周一模一样,因为它对过去的失败没有持久记忆。
那一刻我才真正想明白:
SPEC 只解决"知道要做什么"的问题;它不解决"如何持续把事做对"的问题。
这也正是我们走向下一步的原因——编码 Rule。
Rule 不可或缺,但也别迷信它
如果 AI 老忘事,那就把那些容易忘、容易出错的步骤写成 Rule 钉死。
像"每次代码修改后都必须紧跟编译、测试、后置校验"这种指令就是这么诞生的。这条 Rule 的核心是告诉 AI:
- 每次修改后都要编译。
- 编译成功后才允许跑测试。
- 测试通过后才允许跑后置校验。
- 三步全部通过,任务才算完成。
这一步效果很好。因为 AI 最喜欢偷懒的地方,恰好就是这些"看起来像收尾、其实是硬底线"的动作。它经常这么合理化:
- "我只改了个文档,不用编译。"
- "就一点小调整,跑测试太过了。"
- "这个错看起来是老问题,不是我引入的。"
Rule 强制起来后,这些粗糙边界上的失败大幅下降。
但只要你在一个真实复杂的项目里跑得久一点,很快就会触到 Rule 的天花板。
随着规则集变大,会很可预测地出现两个问题。
AI 会忽略 Rule
不是完全忽略,而是在复杂任务里表现出"选择性遗忘"。Prompt 很长、上下文窗口塞得很满、或同时加载多份其他文档时,某些 Rule 在实际执行过程中会被稀释或降级。模型并没有删掉这条规则,它只是在认知负担飙升时不再把它当作强制项。
AI 会绕过 Rule
这比单纯的"忘了"麻烦得多。AI 并非不知道这条规则;它主动开始找理由绕过去。比如:
- "这个失败不是我引入的,是历史技术债。"
- "这条 Rule 适用于标准流程,可这是一个特例。"
- "我已经做过等价校验了,严格遵守没必要。"
这是 Harness 中一个关键的认知转折:
Rule 不是没用——它们只是承担不同职责。Rule 强制原则约束,无法强制流程执行。
所以就需要把固定、可重复的流程从 Rule 里抽出来,编码成 Skill。
为什么编译、测试、校验必须做成 Skill
仔细观察会发现,工程里有一类任务天然适合做成 Skill:
- 执行步骤固定、可重复
- 每次都必须执行,没有例外
- 一旦搞砸,代价非常痛或非常贵
- 不值得让 AI 每次都从头推导或临场发挥
编译、单元测试和后置校验正好都属于这一类。
我们因此把这些流程抽出来做成专门的 Skill:
compile-skill
、
test-skill
、
validation-skill
。
这从根本上改变了 Rule 和执行之间的关系,Rule 不再需要列出细粒度的命令、flag 或边界注意事项,它只需要强制一句话:你必须做这件事。Skill 接管"具体怎么做、一步一步是什么样"的责任。
收益也非常的直接而且实用:
- Rule 更精简:以前 Rule 把原则和流程混在一起,每个边界情况都让它越长越臃肿。现在 Rule 只强制硬边界和红线;复杂的执行逻辑卸到 Skill 上。
- AI 执行稳定性大幅改善:以前 AI 每次都要现场琢磨"这个具体模块该怎么编译或测试"。现在它不再思考,直接调用一个标准化、被反复验证过的流程;一致性取代了瞎猜。
- 维护成本骤降:后期要更新构建工具链或测试框架时,你只需要改一次 Skill,不必再到整个仓库里 grep 每一份 Rule 文件,确认旧命令是否都被替换。
但一个新的瓶颈很快冒出来:单个 Agent 无论被约束得多好,在复杂、多面的需求面前仍然难以稳住。
为什么结构化 Multi-Agent 是必然选择
把 SPEC、Rule、Skill 都叠加上去之后,系统稳定性确实明显改善。AI 不再仅凭单个 Prompt 盲目生成代码,而是开始理解目标、约束和固定流程。可一旦需求复杂度上升,新的瓶颈又冒了出来:
单个 Agent 没法可靠地处理长链路、多阶段的开发流程,又同时兼顾需求分析、架构设计、风险评估、实现、自审和校验。
这不是模型智能的局限,而是结构性问题:我们让一个实体同时戴太多顶帽子。当一个 Agent 同时是产品经理、架构师、开发者、QA 和发布工程师时,它必然开始裂开:
所以这里就面临一个经典的工程权衡:"我们要不要用 Multi-Agent?","哪种 Multi-Agent 架构在生产里真正能用?"
继续加固单 Agent
这应该是最直接的选择。如果一个 Agent 不够稳,那就给它更多:
- 更长、更细的 SPEC
- 更细粒度的 Rule
- 更细粒度的 Skill
- 更严格的校验步骤
我们的 SPEC、Rule、Skill 几层正是这么演化出来的。可越往前就会发现把更多职责塞进一个"全能型"角色——它能让 Agent 更小心翼翼,却解决不了角色冲突。
需求分析和代码审查需要完全不同的心智模式;架构设计和测试校验遵循完全不同的推理路径。强行让一个 Agent 全包,等于赌它能同时把所有事都做好。简单任务能撑住,但在真实工程复杂度下就会崩。
去中心化协作
网上流行的另一种方案:多个 Agent 平等对等,通过聊天动态协商达成共识。它看起来很先进,像一场"AI 团队会议"。AutoGen 的
GroupChat
这类框架就是这条路线的典型。
优点:
- 极高的灵活性
- 实时适应能力强
- 不需要提前把工作流定死
但在生产里,裂痕会迅速放大:
- 执行路径不稳定(同一个任务每次走的流程都不一样)
- 责任归属模糊(出问题谁负责?)
- 回滚点不明确
- 跨模型替换或团队变更时一致性难以维持
如果你在做 Demo 或开放式研究探索,这套模型很有吸引力。要长期维护一个真实代码库,它暴露出一个致命缺陷:看起来很厉害,但难以维护。
结构化编排
可以定义一个清晰定义的工作流,有明确的角色分工、固定的阶段边界、可审计的交接。
核心特征:
- 有专门的编排者 / PM 角色
- 每个阶段责任清晰
- 每次交接的输入 / 输出明确
- 推进 vs 驳回 / 回滚的条件明确
优势毫不含糊:
- 执行路径可预测
- 高可控性
- 完整的可审计轨迹
- 天然对文档友好
- 角色易于长期维护和替换
取舍也很真实:
- 前期设计成本更高
- 灵活性不如自由协商
- 产出的工件更多 → token 消耗更高
因为一旦真到了工程规模,你就会学到一个硬道理:
Token 不是贵的东西,失去控制才是。
我们要的不仅仅是"AI 会写代码"。我们要的是:
- 需求规范
- 架构设计文档
- 开发日志
- 代码评审结论
- 测试报告
- 交付签收单
- 阶段进度和回滚记录
这些不是负担而是任何人或 AI 在几周、几个月之后还能搞懂的依据:
- 为什么当时做了这个决定
- 目前做到哪一步
- 哪些风险已经被规避
- 哪里在管线里冒了问题
- 如何在中断后继续接上
从可维护性、标准化和角色可替换性来看,结构化编排是生产工程里唯一可行的路径。
即便决定走结构化编排,还有如下的问题:
固定角色 + 固定流程:事先把 Agent、职责和阶段定下来,PM 只是按预定顺序进行编排。
✅ 稳定、易维护,对文档 / 规范友好,适合可重复的工作流。
固定 PM + Dev Manager,动态生成 Agent:保持 PM / Dev Manager 静态不变,但每个任务动态"招聘"或生成专门 Agent。
- ✅ 更灵活,理论上能适应高度多样的问题。
- ❌ 角色边界容易漂移、维护成本更高、行为过度依赖上下文和即时判断、难以长期标准化。
A显然更好,因为实际的工作流虽然需求会变,但阶段相对固定:标准特性开发 = 需求 → 设计 → 评估 → 实现 → 评审 → 测试 → 交付;Bug 修复 = 同一流程的缩减版。既然工作流本身并不真正开放式,为了"理论上的灵活性"牺牲稳定性,在工程上没意义。
当灵活性和稳定性发生冲突时我们始终应该选稳定性。对一个要维护数年的代码库来说,可控性、可追溯性和可复用性远比理论上的适应性重要。
本章不是为了赶 Multi-Agent 的潮流,它讲的是工程现实:
- 单 Agent 在复杂度面前会失稳。
- 去中心化协作长期不可维护。
- 动态生成角色对可预期交付来说漂移太严重。
经过严谨的技术对比,我们正好落在这里:用结构化编排把研发拆解为固定角色和固定阶段,把 AI 从一个混乱的即兴发挥者,变成一个有纪律、有制度管理的工程系统。
七个 Agent 不是随便挑的,而是被问题逼出来的
结构化编排定下来以后,下一个问题就来了:我们到底需要多少个 Agent?怎么拆?
如果这一步处理不好,Multi-Agent 不会让系统更稳,反而会让它碎成片片。我们不是第一天就宣布"就七个 Agent"——这些角色是在生产中一层一层被具体的失败暴露出来后才浮现的。
最早的痛点是"需求模糊,直接漏到代码里"。用户抛出一个粗糙的想法,AI 迅速生成一个能跑的东西,但三个结构性问题立刻冒出来:
- 需求边界依然模糊
- 技术设计在编码过程中现场发明
- 完成之后,无法追溯最初的依据或约束
于是我们拆出最早的三个基础角色:
- 需求分析师:把模糊的想法翻译成结构化、可测试的规范。
- 方案架构师:把规范转化为可执行的技术设计。
- 开发者:在这些约束内严格写代码,不在中途擅自发明需求。
如果三者捆在一起,下游一切都会糊成一团。问题变得无法追溯,你分不清一个 bug 是来自需求不清、设计有误,还是实现马虎。这三个角色构成整个 Multi-Agent 系统的结构脊柱。
三层还不够所以需要加入 Gatekeeper(可行性把关者)。写出需求和设计并不代表就能开始开发。我们很快遇到反复出现的情景:
- 规范列了功能但漏了验收标准
- 设计在纸面上完整,却跳过了关键边界情况
- 一个理论上合理的改动,在当前代码库里集成风险其实很高
- 开发刚开始,藏在里面的 blocker 中途炸出来
所以需要一个站在"代码动笔之前的最终关卡"的专门角色。
Gatekeeper(可行性把关者)它不重写规范或设计,只严格判断:
- 需求是否清晰、无歧义?
- 设计是否有明显漏洞或不切实际的假设?
- 改动能否安全落到当前架构上而不破坏已有契约?
- 直接推进会不会给编码阶段注入不可接受的风险?
如果没有这道关卡,问题就会拖到开发阶段才暴露——那是最贵的修复阶段。Gatekeeper 强制让失败提前暴露。(注:这些步骤是我和 AI 反复迭代 Prompt 后总结出来的,再固化进工作流。)
独立的 Code Review 和测试作为最终关卡
开发说做完了 ≠ 实际上是对的。没有下游校验,"实现完成"对以下几件事都证明不了什么:
- 需求覆盖
- 设计还原度
- 边界处理
- 新引入的风险
我们因此把最终校验拆成两个独立角色:Code Reviewer 和 QA/Tester。
为什么必须分开?因为它们解决的是根本不同的问题。
- Code Reviewer 从实现层往回看:有没有偏离规范 / 设计?结构是否合理?是否藏有缺陷或技术债?它是技术实现质量的最终关卡。
- QA/Tester 从行为层往前看:它真的能工作吗?用户路径能否端到端跑通?边界情况或回归会不会击穿它?稳定性 / 性能是否可接受?它是运行正确性的最终关卡。
没有 Review,开发者会满足于"能编译能跑就行";没有测试,整套系统就建在"看起来对"之上。它们必须是两道独立的关卡。下游角色不是配菜而是真正阻止破损代码继续往前流的闭环机制。
纯路由型 PM
到这时角色越来越多,新的瓶颈冒出来:谁来决定下一步?
如果每个 Agent 自己导航、或者彼此协商交接,工作流就又滑回那种混乱的去中心化聊天。我们因此把项目经理(PM)角色集中化。
我们要的不是一个"懂技术的 PM",而是一个"严守流程边界的 PM"。
它的职责很少,纯粹是运营性的:
- 读阶段完成文档
- 根据校验结果决定推进还是回滚
- 路由到下一个专门 Agent
- 维护交接、迭代和交付日志
它不做:
- 写需求
- 设计架构
- 碰代码
- 推翻 Agent 的技术判断
这一点至关重要。如果 PM 越界去做技术判断,系统就退回到"中心大脑决定一切"的模式,完全违背了角色分离的初衷。
系统自然稳定在以下七个 Agent:
- PM:路由、管理交接、回滚和进度追踪。
- 需求分析师:把模糊请求澄清成结构化规范。
- 方案架构师:把请求转化为技术设计。
- Gatekeeper:在编码开始前校验可行性和风险。
- 开发者:实现代码和技术细节。
- Code Reviewer:校验技术质量、规范对齐和设计还原度。
- QA/Tester:校验功能正确性、稳定性、边界情况和回归安全。
关键不是"非要七个"关键是每一个角色都填补了上一个角色填不上的空白:
- 需求 → 要做什么
- 设计 → 怎么做
- Gatekeeper → 现在能不能安全开工?
- 开发者 → 真的把它做出来
- Reviewer → 有没有按计划做?
- 测试者 → 在实践里真的能跑吗?
- PM → 如何可靠地编排这整条链?
这不是为了复杂而复杂,而是把一个庞大、混乱的任务拆解成可管理、可追溯、可替换的模块。
每个 Agent 的分级模型分配
很多人想当然地认为:既然拆分了角色,是不是每个 Agent 都得用最强、能力最高的模型?事实并非如此——这样既浪费、又贵、又没必要。不同角色的认知和算力需求差异很大。
- PM 只处理路由、状态检查、交接日志和进度追踪。它需要的是可靠性和上下文保持能力,不是深度技术推理;一个更轻量、性价比高的模型就够了。
- 需求、设计、Review、QA 承担重分析负担。它们需要深度推理、精准遵循指令以及广泛的上下文覆盖,配得上重型、高能力的模型。
工程上的收益立刻显现:
- 不是每一步都烧高端算力
- 整体 token 成本可控
- 高价值的推理步骤拿到匹配的算力
- 长链路管线的稳定性提升
你不会给每个船员都发同一把昂贵的锤子;你按任务匹配工具。Multi-Agent 工程很快就从一个"AI 噱头"变成像真正的团队资源分配。
当你真的在跑多角色、多阶段、长周期迭代时,模型分级就不再是一个可选项,它会成为 Harness Engineering 自身的核心支柱。
Multi-Agent 系统在生产里是如何真正稳下来的
七个 Agent 的骨架已经搭完,它一跑起来效果是符合预期的:复杂请求不再被一个 Agent 强行推倒,而是顺着一条标准化的文档链条流动;更完整的特性开始产出一致的阶段产物,整条管线明显更清晰。
但这并不意味着系统已经成熟。恰恰相反,真正的问题是在我们把它放进持续生产之后才开始浮现的。
这一章讲的就是那些真正、来之不易的迭代。Harness Engineering 从来不是"设计一次、永远部署",它是跑起来、撞墙、补丁、再跑、再升级。
Multi-Agent 协作上线后,第一个裂缝很快出现:下游 Agent 开始"好心地"修改上游产物。
经典例子:方案架构师在读需求文档时发现一处不严谨,但没提一个 blocker,而是悄悄把需求改成符合自己理解的样子。
听起来很聪明,第一眼看也好像很高效。但跑得够久,你就会看出来它有多危险:
- 需求的归属权变得模糊。
- 无法追溯设计究竟是基于原始规范,还是基于架构师未授权的修改。
- 出问题时,无法把责任落到具体的某一层。
修复方案:我们加了一条硬规则——下游 Agent 不允许直接修改上游产物。如果下游认为上游产出不合格,必须正式提出 blocker,PM 再正式把工作流回滚到上游 Agent 去修正。
这条规则强制起来之后,系统终于有了清晰的边界感:每一份产物都有一个唯一的、可追溯的归属者。
随着流程的成熟,第二种模式出现:PM 不停从流程管理者漂移成意见提供者。
这几乎是不可避免的。坐在中心位置上,PM 看到一切。当需求模糊、设计有争议、开发卡住时,它很容易跳出来:
- "我觉得这个需求应该调整一下。"
- "这个设计如果改 X 会更好。"
- "先别回滚,让开发现场打个补丁就行。"
但跑得越久越清楚:PM 的意见很少是专业的,反而经常把流程带偏。
修复方案是严格收缩 PM 的边界。
- PM 只管理工作流状态。
- PM 不做任何专业 / 技术判断。
- PM 不对需求、设计、代码、测试提出修改建议。
- 当 Agent 卡住时,PM 把它路由到正确的专门 Agent。
- 如果真的有歧义,工作流暂停,等待人类决策。
做完这次调整,PM 的身份终于定型:不是"中央专家",而是"中央路由器"。
接下来又出了问题,不是某一个 Agent 弱,而是整条 Multi-Agent 链在早期阶段都缺乏专业深度。
需求漏掉边界条件;设计跳过覆盖;Gatekeeper 低估集成风险。我把 Code Review 和 QA 作为例子,是因为它们处在最末端关卡,上游所有缺陷自然会在这里堆积然后引爆。
最初我们的 Agent 太"常规":
- Code Review 只检查明显的逻辑 bug、规则违反和基本实现缺陷。
- QA 只验证主流程能跑不会崩。
有用吗?有用但是远远不够。在这一阶段,它们不仅仅是在检查自己那一层,更是整条链的最终质量关卡。如果它们只看局部,就会漏掉关键的交叉检查:
- 需求是否被完整实现?
- 设计是否被正确转化?
- 验收标准是否被覆盖?
- 除了功能正确性以外,稳定性和基线性能是否可接受?
升级方案是加固这两个角色。
- Code Review 现在必须显式交叉引用需求和设计文档。它的使命是:验证对齐度、完整性、架构还原度。
- QA 现在真正站在闭环点上。它的使命是:验证功能正确性、边界情况、回归、稳定性和性能基线。
从这一步开始Multi-Agent 不再只是"拆分工作流",而变成了一个真正的质量闭环。
补完工作流问题后,我们以为系统稳了,可一个问题又回来了:Agent 依然在找借口绕过 Rule。
- "这个失败不是我搞出来的,是历史债。"
- "这条 Rule 不适用于这种特殊情况。"
- "主要工作我做完了,这一步可以跳过。"
无论你写多少条,Rule 终究是自然语言约束。在复杂度面前,它们会被忽略、被绕过、或被"解释性地执行"。
修复方案:把可验证的约束移到可执行的 Script 里。
- 编译必须通过——不是"应该没问题"。
- 测试必须通过——不是"理论上安全"。
- Lint 扫描必须通过——不是"这次例外"。
- 只有脚本通过,开发才算真正完成。
这就是为什么主校验脚本(Master Validation Script)变得如此关键。它不只是加了一个工具,而是把"任务完成"从主观的 AI 自我汇报,切换成客观的、系统可验证的状态。
脚本上线后我们以为搞定了,可 AI 很快找到了新漏洞:把锅甩给已有问题。"这个错本来就有。""这个警告是历史遗留。"
没有反制机制,很容易被它说服接受一个其实已经坏掉的构建。
修复方案:基线对比。
- 在做任何代码改动之前,先跑一遍完整校验套件。把输出 / 报告作为基线保存下来。
- 改完以后再跑一遍。
- 对两份报告做 diff。
任何新增的失败、警告或违规 = 必须修复。
"你是不是把它弄坏了?"不再靠争论而是由系统报告之间的 diff 来证明。
这又给 Harness 拧紧了一颗螺丝,也印证了一个核心真理:Harness Engineering 不是关于信任 AI,而是关于设计出让偷懒无处可藏的机制。
随着请求堆积、系统成熟,一个后期问题浮现:工作流本身开始无法维护。
最初所有流程规则都住在 PM 那条长 Prompt 里。第一天没问题,但随着阶段、回滚条件和角色边界倍增,维护变得痛苦:
- 埋在散文里的规则很难校验。
- 改动一处很容易破坏另一处。
- 阶段 / 回滚逻辑漂移到不一致。
- 换模型或换维护者会让角色边界变模糊。
之前几波修的是"让它能跑",这一波修的是"让流程本身成为可维护资产"。
所以需要把工作流提取成工程资产。:
- 工作流定义文件:把流程结构从 PM 的散文里拽出来。显式列出:阶段、每阶段的默认 Agent、向前转移、允许的回滚路径,以及条件性回滚触发器。工作流不再是"写在长文里的知识",而变成一个独立的、纳入版本控制的资产。
- 角色契约:光有定义文件还不够,每个 Agent 还需要清晰的接口边界。每份角色契约说明:这把 Agent 从"长长的人设 Prompt"变成边界严格的稳定模块,对长期维护和模型替换至关重要。- 必读的上游输入- 必交的下游产物- 提出 blocker 的条件- 升级到 PM 路由的条件
- 工作流校验脚本:怎么保证定义文件和契约始终同步?我们加了一个轻量校验脚本,检查:它谈不上一个完整的"工作流编译器",但能在底层捕获那些悄悄腐蚀 Multi-Agent 管线的同步漂移。- 所有引用的定义文件是否存在?- 所有 Agent 契约是否齐全?- 工作流里的角色是否正确映射到契约?
工作流从"靠人脑记住",演进成"作为工程基础设施被拆分、维护和校验"。
我们可以把上面的内容压缩成一条对你自己项目可操作的、按步骤推进的路径:
- 先打磨出一份扎实的 SPEC。别急着写 Rule 或拆 Agent。和 AI 反复迭代,直到目标、边界、验收标准和兼容性要求都清晰为止。没有它下游一切都是浮的。
- 只加关键的 Rule。聚焦在 AI 经常翻车或偷懒的底线上(比如编译 → 测试 → 校验)。别第一天就堆 50 条 Rule。
- 把高频固定动作沉淀成 Skill。当你发现 AI 在一些重复、易错的步骤上现场发挥时,就把它们固化下来;编译、测试和校验通常是首批候选。
- 只在单 Agent 失稳时才拆 Multi-Agent。如果任务短、链路浅,单 Agent 就够。等到角色开始模糊、自评开始崩坏时,再拆成需求、设计、开发、Review 和测试。
- 复杂度上来时再加工作流定义和角色契约。早期长 Prompt 还能撑住;一旦阶段、回滚、交接倍增,就把它们提取成结构化、纳入版本控制的资产。
- 持续迭代阶段再上 Dev-Map 和 Task Board。它们解决的是"如何让 AI 理解整个项目,而不仅仅是当前任务?"代码库越大,这一层就越关键。
- MCP 留到要把回路往外推时再考虑。先把内部开发回路闭好,然后再去连接外部构建、签名、发布和产物系统。别第一天就把整个世界连上线。
演进路径很简单:告诉 AI 做什么 → 告诉 AI 怎么做 → 教它对复杂任务进行分工 → 把工作流本身变成可维护的工程资产。
PM Agent(编排者)按工作流顺序调用每个 Sub-Agent:需求 → 设计 → 开发 → Review → QA → 收尾。
- 左侧面板:时间线,记录调用了哪个 Agent、它何时完成、在哪发生过回滚 / 重跑。
- 右侧面板:我和 PM 的直接对话,映射左侧的执行步骤。
为什么最终要落到 Script——尤其是主校验脚本
本章只聚焦于核心论点:为什么主校验脚本(Master Validation Script)会变成整个 Harness 最关键的基础设施之一。
在我们项目里,它不是一句客气的"请校验一下你的工作",而是开发是否真正完成的客观、不可议价的裁判。
它不是一项单独的检查,而是一个统一的开发后置校验入口。
可以把它想成一个中央裁判,依次执行:
- 静态 lint 和规约检查
- 编译
- 测试套件执行
- 依赖和清单同步性
- 项目结构校验
它把以前散落在 Rule 里的几十项检查整合到一起。实践里,它们分成三个清晰的类别:
A 类:静态规范与约定
- 用硬编码密钥 / 字符串替代
config/env包 - 使用
fmt.Println而不是结构化 logger(slog/zap) - 错误上下文包装缺失(
fmt.Errorf("...: %w", err)) - 命名不一致或导出 API 违反约定
- 缺失
//go:build约束或 build tag 文档 - 许可证 / 头注释合规、文件长度上限、尾随空白
B 类:交付阈值
go build -v ./...必须零错误通过go test -race -timeout=30s ./...必须 100% 通过- 测试数量不能反常下降(抓被删的覆盖)
- 覆盖率必须达到或超过项目基线
C 类:工程一致性
go.mod/go.sum与实际 import 完全同步(go mod tidy的 diff 为 0)- 生成文件(
mocks/、proto/、deepcopy/)未被提交 - 所有新增
.go文件都被正确纳入构建目标 - 没有遗留的孤立测试文件或死代码
单看每一项都很琐碎,但是合在一起它们形成了一道客观的关卡,用来定义"这次开发到底合不合格"。
后置校验同时是给 Harness 补上"结果感知"的关键一环。没有它很多团队会陷入一种危险模式:他们搭出了能自动推进任务的 AI 工作流,但缺少扎实的反馈机制。结果呢?
- AI 把任务标记为"完成"。
- 文档生成出来了。
- 代码改完了。
- AI 甚至声称"我在本地校验过了"。
但系统本身对产出究竟是对、错、还是只是表面完成,毫无感知。
后置校验补上了这一点。它不是为了让工作流看起来漂亮,而是为了第一次给 Harness 一种判定结果的能力。从这一步开始,我们的系统从"任务推送器"变成"结果验证器"。
为什么这一步对 Harness 至关重要
因为从这一刻起AI 对"完成"的定义被根本性地切换了:
从:"我觉得我做完了。"✅ 到:"脚本通过了,所以我完成了。"
这是一个巨大的质变。它消除了讨价还价、合理化和主观解释。完成不再是声明,而是一个系统可验证的状态。
主校验脚本真正的威力不只是"多加了一个工具",而是把散落各处的检查整合成一道单一的、权威的关卡。
在它出现之前,校验散落在各种地方:
- Rule 里某句模糊的话
- Skill 里某个被埋掉的步骤
- 某个 Agent 自我汇报的收尾信息
- 维护者脑子里的部落知识
一旦所有校验都被路由进主校验脚本,"完成"的定义骤然收紧:
- 不再是"我说我做完了"。
- 不再是"我跑过一次本地检查"。
- 而是"我通过了统一校验入口"。
这对 Harness Engineering 至关重要。只有当"完成"被统一定义后,整个系统才能从"一堆松散的约束"转型为"一条带关卡的工程工作流"。
如果让我从整个 Harness 里挑出最被低估、ROI 最高的模块,那一定是后置校验。它不是多加了一步,它合上了整个反馈回路。
在这个回路存在之前,我们常常活在一种"任务完成幻觉"里:AI 改了代码、移了卡片、生成了文档,我们就下意识假定成功了。但进度 ≠ 正确;前进 ≠ 闭环;在做 ≠ 做好。
一旦后置校验变成硬关卡,Harness 就发生了根本性变化:
- 它不再只是一个推 AI 往前走的系统。
- 它变成一个判断结果的系统。
- 它形成一个完整的、自纠错的回路:执行 → 校验 → 发现问题 → 回滚 / 修复 → 重新校验。
那时候 Harness 才真正成熟,它不再依赖侥幸,而开始依赖物理定律。
如何给 AI"项目级记忆"
到这一步我们的 Harness 已经能独立处理复杂、多阶段的需求了。可项目一旦进入持续迭代,就会冒出一个非常实际的瓶颈:
PM 和单个 Agent 缺乏对整个项目的全局视野。
如果你只把当前任务规范塞进上下文窗口,两类常见灾难很快接踵而至:
- 新实现悄悄覆盖或忽略既有架构。
- AI 重造轮子,对一个已经存在、被反复测试过的实现毫无察觉。
这一章正是要补上这个空缺,我们要给 AI 一份生活在仓库里的项目级知识索引。关键是,它不是一本"百科全书"——不会让你把整个代码库说明都塞进上下文。它是一份精确的索引——一张地图,告诉 AI 在动代码之前先看哪些入口、遵循哪些约定。
我们追求 AI 自维护。谁动代码谁更新地图;谁管需求谁更新看板。这样就能避开经典陷阱:漂亮的文档没人更新。
在我们项目里,这具体落到了两个核心组件:
dev-map
和
Task Board
。这也和第 1 章里的上下文纪律一致:项目还小的时候,别一上来就把完整地图和任务历史全塞进去;等持续迭代开始时再用,那时它的 ROI 才会显现。
构建"项目级索引"的常见方式
不同团队为同一个目标使用不同材料。这些方式并不互斥,往往是分层叠加的。我们用的
dev-map
和
Task Board
只是我们的具体实现,并不是唯一答案。
dev-map:开发侧的导航图
在主项目下维护一份开发导航图,并配一条严格的规则:修改代码之前先看
dev-map
;动刀之前,对照地图确认特性的落点和影响范围。
很多人以为
dev-map
只是一份"文件列表",它的价值要广得多——它是工程导航指南,回答:
- 某些特性通常住在哪里?
- 某类服务是如何集成的?
- 配置一般在哪里定义?
- 修改模块 Y 会影响哪些链条?
- 这里的标准实现模式长什么样?
动代码之前先理解既有代码,AI 最喜欢"重造轮子"这份地图确保它看见这座城已经不是空地。
在实现期由开发 Agent 维护而不是 PM。谁动地形谁更新地图——这和我们的 AI 闭环更新逻辑一致。
大仓库下的扩展:当文件越来越多,一张试图列尽一切的大表就会变成负担,并且和现实脱节。可行的折中是保留几页顶层概览(入口、主要领域边界);深入到具体领域时,再查该领域那一张表;具体类 / 路径靠搜索 / LSP 解决。
dev-map
聚焦在结构和约定上。把一张巨大的地图拆成几本聚焦的小册(每本标注它的领域),比硬塞进一本厚厚的目录现实得多。
Task Board:需求侧的总览
另一个关键件是项目任务看板,由 PM 维护。它不是一份简单的 todo list,而是项目级的任务登记表,记录:
- 进行中的任务
- 每个任务当前所处的阶段
- 相关文档目录
- 已完成任务的交付结论
当一个新的需求分析 Agent 加入时,它不必从零猜测。它去看看板就能回答:这是不是某个旧需求的延续?我们做过类似的吗?文档在哪?上次的设计决策是什么?"新需求覆盖旧设计"的风险明显下降。
dev-map
处理代码和模块结构的入口;
Task Board
处理需求和任务历史的入口。两者都生活在仓库里,由工作流中各自对应的 Agent 更新——这一层就是这样保持鲜活的。
AI 不只是把当前任务做完,还要知道如何在仓库里找到读懂整个项目的钥匙。
当这种能力锁定下来,你的 Harness 就不再以孤立的冲刺方式运转,而开始像一个有长期记忆的团队那样运转。那时候,持续迭代才真正变得可持续。
在团队级 Harness 里,为什么"记忆"退到次要位置
你已经看到
dev-map
和
Task Board
如何充当项目的长期记忆。这就引出一个在 AI Agent 圈里争论激烈的问题:
如果我们在搭一套严肃的、多 Agent、团队级的 Harness,是否还需要专门的"AI 记忆"系统?向量数据库?情境式回忆?对话历史保留?持久化 Agent 状态?
简短回答:不需要。在一个成熟的 Harness 里,传统意义上的 AI 记忆可以放心地退到次位。
不是因为记忆没用,而是因为一个结构良好的 Harness 用一个会"记录"的系统取代了 AI 需要"记住"的需求。
业内说"AI 记忆"时,通常指的是:
- 上下文窗口保留:跨会话保留过去对话轮次。
- 向量 / RAG 记忆:把过去交互嵌入向量库,之后检索"相关"历史。
- Agent 记忆模块:情景式(发生了什么)、语义式(存在哪些事实)、过程式(如何做事)。
- 持久化状态文件:记录 Agent 决策、工具调用或聊天记录的 JSON 日志。
所有这些都解决一个真实问题:LLM 默认无状态,一旦上下文窗口合上或会话重置,它就会忘掉一切。
在个人、实验、会话型 AI 场景里,记忆经常是维系连续性的胶水。但在团队级工程 Harness 里,把它当作核心依赖反而引入的摩擦多于解决的问题。
为什么 AI 记忆在生产里反而是负担
下面是当你在真实工程工作流里重度依赖 AI 记忆时会发生的事:
AI 记忆面向的是会话连续性;工程工作流面向的是可审计、版本化、可复现的状态。它们的目标根本不同。
Harness 如何用工程产物取代 AI 记忆
Harness 不让 AI 记住而是让项目记住。映射如下:
我们不再问 AI "还记得我们三轮会话前讨论的内容吗?",而是让它"读当前 SPEC、看 Task Board 上的阶段、加载 dev-map 的入口、执行工作流定义"。
AI 不需要记忆它需要的是导航。
会话式记忆 vs 工作流记忆
这并不是说记忆已死,而是说一旦你从"AI 助手"跨入"工程系统",记忆的角色就发生了剧烈变化。
一旦你的 Harness 进入多 Agent、多阶段、持续迭代,如果把记忆当作主要事实来源,它就成了负担。系统应该不管 AI 是否"记住"过什么,都能完全一样地工作。
把"AI 记忆"当作银弹去追逐是一个常见陷阱。它感觉像进步,因为它模仿人类协作:"我们上周聊过,所以应该从上次的地方继续。"
可工程不是靠对话运转的,它是靠记录运转的。
一个成熟的 Harness 不会让 AI 记忆,而是让 AI:
- 读当前规范
- 遵循工作流定义
- 加载正确的 dev-map 入口
- 执行校验脚本
- 更新 Task Board 阶段
- 用清晰的提交信息提交
如果 AI 在会话重启后忘掉一切,Harness 仍然应该完美运转。当项目的记忆活在
git
里,而不是某个向量数据库或聊天记录里,你就已经从"AI 实验"跨入了"工程系统"。
而这正是 Harness Engineering 该住的地方。
Harness 的四块拼图如何协同
这一章纯粹作为一张回顾地图:第 3–7 章讲的是"如何让 AI 在边界内工作";第 8 章讲的是"谁来判定结果";第 9 章讲的是"从哪里进入这座工程之城";第 10 章把焦点收窄到"人、项目、AI 各自站在哪里"。
四块拼图与章节映射
这不是切分的唯一方式但作为我们这条叙事线的参考地图够用了。
约束与工作流(第 3–7 章)
从 Rule 和 Skill 起步,走过 Multi-Agent 编排、工作流定义文件、角色契约,再进入第 7 章那些"撞墙、补洞"的迭代——这整条线本质上回答的是:AI 在工程里以什么节奏、什么纪律向前推进?
没有这一层,再强的模型也只是在对话里即兴发挥;有了它,复杂需求会被拆成一场可重复的接力赛,每一棒的输入输出都明确。第 7 章里被补上的那些空缺(文档边界、回滚机制、维护协议),本质上就是工作流自身的加固,防止协作退化成"口头协议加比划"。
反馈(第 8 章)
约束告诉 AI "应该怎么行动";反馈回答:产出究竟有没有通过?
第 8 章把主校验脚本推到舞台中央,呼应了第 1 章埋下的伏笔:Rule 是软的、易忘的、可以被解释性执行的;最终你需要一个机器可强制执行的关卡来下最终定论。
反馈接上以后,Harness 第一次拥有了结果意识。工作流走完还不够,同一个客观阈值会对每一次交付说话。第 10 章里提到的"规则进一步脚本化"和"把反馈回路向外延伸",就是这一块越长越厚、越长越强。
知识库(第 9 章)
第 9 章把项目级上下文说清楚:不是一本让 AI 阅读的没完没了的百科,而是一份精确的索引。开发侧的入口是
dev-map
,需求和任务历史侧的入口是 Task Board。在工作流里动刀的人,也在工作流里更新地图。这样可以防止 AI 在一座已经建好的城里反复修同一条路。
这一块和"约束与工作流"有具体关系:
- 工作流规定什么时候读地图
- 地图降低在错误位置开干的概率
- 反馈在地图过期或漏更新时施加维护压力,用失败结果倒逼修正
演化(第 10 章)
第 10 章关于记忆的讨论,本质上是在画主场:团队需要对齐的东西最终必须落到仓库里,成为可见、可审计、可交接的资产,而不是停留在会话记忆里。它关于人和 AI 的讨论,本质上是在讲责任的上移:人类越来越成为系统架构师和最终责任人,AI 在制度框架内高密度执行。Harness 自身随着项目变难、团队扩大,持续演化自己的结构、增加关卡、延长链条。
所以"演化"不是玄学。它说的就是这件事:当前三块拼装好之后,人和 AI 在各自边界内协作,驱动系统持续重构。人定方向和关卡;AI 在规则内高密度交付。哪些 Rule 应该变成 Script?哪些地图应该拆细?哪些工作流段应该接 MCP?这些都变成可审计的仓库变更,再反向抬升工作流、反馈和知识库。
四块拼图相互加强。缺任何一块都会带来非常可预测的症状:
它不是模糊的"项目应该写文档",而是人和 AI 共同推动 Harness 自身重构的那股力。人决定"通过"长什么样、什么能自动化、什么时候提交到仓库;AI 在既有的工作流和契约内高密度交付(改 Rule、加校验脚本、拆
dev-map
、更新 Task Board)。这些改动反向抬升前三块:
- 约束与工作流更贴合现实
- 反馈阈值更准确或覆盖更广
- 知识库与最新结构保持同步
缺了这一层,常见的结果是:只有少数人记得为什么当初这么决定,或者每一轮都靠临时聊天来定方向;前三块得不到结构性的向上推力。
把这些合在一起,Harness Engineering 的核心图景是:
用工作流和约束把动作放上轨道;用反馈确保终点有人裁判结果;用知识库防止 AI 在城里乱撞。
演化是人和 AI 联手把实践和关卡里得到的结论,持续灌回工作流 / 约束、反馈和知识库——确保规则、关卡和地图随着结构变化一起前进。
只有这样,整个系统才能真正活下来与项目一起生长。
总结
这个系列从来不是要在第一天就造一个完美系统,它讲的是一条演化路径:从最小可用的约束起步,撞上真实生产壁垒,系统性地打补丁,让 Harness 在摩擦中有机生长。
Harness Engineering 不是关于控制 AI,而是关于建造一个工程系统,让 AI 在其中成为一个可预期、可审计、可持续的力量倍增器。
工具会变,模型会进化。但原则不变:
- 自由之前先立约束
- 信任之前先有反馈
- 百科全书之前先有索引
- 完美之前先有演化
本文示例代码仓库:https://github.com/RyoKusnadi/crypto-snapshot-cli
by Ryo Kusnadi