把工程流程沉淀为 Agent 资产:一套可交接的四层工作流

本文介绍 ai-engineering-agent——一套把软件工程全流程(需求 → PRD → 原型 → 契约 → 前后端实现 → 测试用例 → 变更日志 → 一致性核验)沉淀为文件资产的实践。
核心主张只有一句:上下文不该活在对话里,应该活在文件里。

一、起因:模型会写代码,流程却仍在靠人盯

过去一年,模型写代码的能力提升很快,但工程侧的痛点几乎没变。真正卡人的是三件事:

1. 上下文活不过一次会话。 需求边界、字段口径、命名约定、"这个地方不能改"的隐性知识,全靠对话记忆。新开一个会话,全部归零,重新交代一遍。

2. 产物不可追溯。 需求结论在聊天记录里,接口定义在另一段对话里,没人说得准"这一版为什么这么设计"。等到三个月后有人问,只能翻历史。

3. 流程纪律靠自觉。 该澄清的没澄清就开始写代码;契约没冻结就前后端各写各的;改了一个字段,十处悄悄不一致。

这些问题的解法,通常被归结为"提示词写得更好"。但提示词解决不了跨会话、跨角色、跨阶段的一致性——那是工程问题,需要工程手段。

二、设计原则:上下文不是对话,是文件

整套资产建立在五条原则上:

原则 落地方式
单一事实来源 每个概念只在一处定义,其余文件只引用。技术栈口径只写在 dev-contract.mdc 一处,命令与技能都指向它
产物交接 阶段之间不靠对话传话,靠读上游文件、写下游文件;命令明确"读什么、写什么、谁是唯一写者"
断点续跑 每个产物目录有 _meta/status.md(done / in_progress / blocked),中断后重跑跳过已完成阶段
不猜 输入缺失或口径不明时 blocked 或停下询问,禁止"合理地假设一下"
证据分级 结论分 [已确认](直读源码)/ [推断](有依据,写明依据)/ 【待验证】(静态读不出,附验证建议)

三、四层结构:命令、角色、技能、规约

为什么是四层?因为"做一件事"其实是四个不同的问题:

层 回答的问题 载体
命令 何时做、按什么顺序做 斜杠命令(/ai-require-design、/ai-dev-backend…)
角色 谁来做、边界在哪 子代理(需求分析师、PRD 作者、后端开发…)
技能 具体怎么做 方法论 + 提示词 + 模板 + 脚本
规约 什么绝对不许做 红线条款(脱敏、只读、追加式、契约先行)

切开的收益很直接:

  • 想换技术栈,只加一份画像文件,命令、角色、规约一行不用改;
  • 想加一条约束,只改规约,所有命令自动继承;
  • 想加一个环节,只加一个命令,复用已有角色与技能。

四、两条主线

0-1 新建:需求分析 → PRD → HTML 原型 → 契约 → 前后端实现 → 测试用例 → 变更日志 → 一致性核验
1+  存量:源码逆向 → PRD → HTML 原型 → 变更日志(双来源)→ 一致性核验

两条线的差别不只是方向相反:

  • 0-1 从需求出发,产出物是"设计意图"的记录;
  • 1+ 从代码与 git 历史倒推,产出物是"实现事实"的记录——所以每条结论必须带「文件路径 + 行号」证据,推不出来的必须标 【待确认】,不许用"应该是"糊过去。变更日志也要求双来源:git 提交历史 + 需求拍板记录,二者互相印证。

五、五个真正起作用的机制

1. 契约先行 + 三棒交接

前后端并行开发最大的坑是接口口径分歧。这里用"三棒"解决:

# 第 0 棒:只生成契约,不写业务代码
/ai-dev-backend --out=docs/dev --contract-only
#             → contract/{api.yaml, api.md, data-model.md, enums.md, error-codes.md}
#               状态 draft → frozen,version v1.0

# 第 1、2 棒并行:前端与测试各自吃契约
/ai-dev-frontend --out=docs/dev
/ai-test-design  --out=docs/dev

三条命令互不依赖,共用同一个 --out=docs/dev,只通过产物对齐。前端必须逐字对齐契约(路径、方法、字段名、类型、错误码),发现缺项时不自作主张补字段,而是把申请写进 contract/_requests.md,由后端裁决。

2. 单列单写者:解决"谁改的"问题

追溯矩阵是跨阶段对齐的核心,但如果谁都往里写,它很快会变成垃圾场。所以每一列只有一个命令有写权:

列 写者
需求来源 /ai-require-design / /ai-reverse-project
接口 API /ai-dev-backend
页面 P /ai-dev-frontend
后端实现 /ai-dev-backend
前端实现 /ai-dev-frontend
用例 TC /ai-test-design

同理,contract/ 的唯一写者是后端命令。这不是权限洁癖——是为了让"谁负责"永远可判定。

3. 断点续跑:状态写在文件里,不写在记忆里

每个产物目录都有 _meta/status.md。中断(关会话、断网、需求变更)后重跑同一条命令:读状态文件,跳过 done 的阶段,从 in_progress 继续;blocked 会明确打印缺什么,例如"缺少 prd/F08 的验收标准,无法冻结契约"。

命令还支持缩小范围重跑(--scope=F08)与强制重做(--fresh)。

4. 技术栈五级命中序:不硬编码,也不被默认值绑架

技术栈解析按顺序求值,命中即止:

1. --stack=<画像 id>         显式指定,最高优先
2. <DEV>/_meta/tech-stack.md  项目侧画像(缺失则回退读 0-1 落档的 <项目>/_meta/tech-stack.md)
3. 目标项目特征探测            读 pom.xml / package.json,匹配画像库的「识别特征」
4. .codebuddy/tech-stack.md   系统默认,仅在无任何工程结构可探测时使用
5. 均未命中                   停下询问,禁止猜测

系统默认排在第 4 位,这一点是踩坑之后才定下来的(见下一节)。

5. 三通道可审计证据

  • 逆向结论:必须带「文件路径 + 行号」,置信度三级;
  • 变更日志:追加式(append-only),永不覆盖与删除历史,修正只能新增条目;
  • 契约变更:version 递增 + _requests.md 记录"谁提出、影响哪些接口、如何裁决"。

三者叠加的效果是:任何一个"为什么是这样",都能顺着文件链找到出处。

六、一次完整走法

以虚构的 lab-booking(某高校实验室仪器预约系统,接手三年的存量项目)为例:

# 1) 存量逆向:出 PRD、原型、字段字典、变更日志、核验报告
/ai-reverse-project D:\work\lab-booking --out=docs/reverse-engineered --scope=reservation,instrument
#    → 产出 modules/、prd/、prototype/、dictionary/、changelog/、review/

# 2) 冻结契约(只生成契约,不写业务代码)
/ai-dev-backend --out=docs/dev --contract-only --stack=backend-java-springboot

# 3) 前端与测试并行
/ai-dev-frontend --out=docs/dev --stack=frontend-vue2
/ai-test-design  --out=docs/dev

# 4) 增量加一个功能(走契约变更流程)
/ai-dev-backend --out=docs/dev --scope=F08

第 4 步值得单独说:新功能 F08 尚未体现在契约里,命令不会直接开写,而是先把 contract/version 从 v1.0 推到 v1.1、状态走 frozen → changed → frozen,再实现,最后回填追溯矩阵的「接口 API」与「后端实现」两列。

七、踩过的坑(最值得看的一节)

这套东西不是设计出来的,是撞出来的。几个真实的修补:

坑 1:契约被下游"顺手改"。 前端发现缺个字段,直接改 api.yaml 继续写。两天后没人说得清这个字段是谁加的、要不要兼容。→ 单写者 + 变更申请:下游只能往 contract/_requests.md 写申请,后端裁决后统一落契约。

坑 2:技术栈默认值绑架存量工程。 默认栈是 Java 17 + Spring Boot 3.2。接手一个 Java 8 + Spring Boot 2.7 的项目时,若默认值先命中,骨架、依赖、API 写法全线错位。→ 把系统默认降到命中序第 4 位,只在"什么工程结构都探测不到"时兜底;存量工程一律以探测结果为准。

坑 3:0-1 阶段落档的画像,dev 阶段读不到。 需求阶段把技术栈写到 <项目>/_meta/tech-stack.md,实现阶段却去 <DEV>/_meta/tech-stack.md 找——两个路径,永远读不到项目级覆盖。→ 明确回退链:dev 侧优先读 <DEV>/_meta/,缺失则回退上游落档的文件。

坑 4:同一个概念长出四套口径。 技术栈解析在四个文件里分别是"四级""五级""级别 0""项目级优先于系统默认"。读者永远不知道该信哪个。→ 收敛到一处权威定义(dev-contract.mdc §七 第 28 条),其余文件只引用并展开同一张表,且改成按命中顺序书写(1→2→3→4→5),而不是容易误读的优先级编号。

坑 5:规约自己打自己。 一条规则把 changelog/ 列为"只读,三命令均不得修改",另一条又要求后端在契约变更时写入变更日志。→ 补一条明确的唯一例外:允许以 append-only 方式追加 decision 条目,不得删改既有内容。

坑 6:术语压缩过头。 把"技术栈命中级别 + 判定依据"压成"命中序与来源",结果谁看谁愣。→ 改回自解释写法:命中序(第几级命中)、命中来源(--stack 参数值 / 画像文件路径 / 探测依据文件)。

坑 7:文档引用会腐烂。 章节号、文件路径、脚本参数写进文档后,被引用的文件一改就失联,而且删掉一个文件不会报错——只是某处引用悄悄失效。→ 定期做机械校检:乱码字符、章节号引用可解析性、references/ 与 templates/ 引用存在性、有序列表编号连续性、产物路径一致性、同名不同义。

坑 1、2、4 是设计缺陷,坑 3、5 是一致性缺陷,坑 6、7 是沟通缺陷。三类都需要机制,而不是"下次注意"。

八、适用与不适用

适合:

  • 多人协作、需要交接的项目;
  • 交付物要评审、要留痕、要复盘的场景;
  • 接手存量代码,需要先把"它现在是什么样"讲清楚;
  • 需求会反复变,希望每次变更有记录、可追溯。

不适合:

  • 一次性脚本、临时数据处理;
  • 单人短平快的原型验证——流程开销会超过收益;
  • 只想让模型"帮我写完这个函数"的即时需求。

判断标准很简单:这件事三个月后有没有人要问"当初为什么这么做"? 有,就值得上流程。

九、三步开始

1. 把 .codebuddy/ 拷到项目根目录(或独立工作目录)
2. 用 CodeBuddy 打开该项目,新建会话(规则只在会话开始时加载)
3. 按场景执行 /ai-reverse-project(存量)或 /ai-require-design(新建)

技术栈不同不必改套件:写一份 <DEV>/_meta/tech-stack.md 覆盖即可;需要长期复用就按画像库契约新增一份画像文件,命令、角色、规约都不用动。

十、结语

这套资产本质上不是"提示词合集",而是把软件工程的流程纪律外化成了文件:

  • 流程写在命令里,不写在人的记忆里;
  • 约定写在规约里,不写在对话里;
  • 事实写在产物里,且每条结论都有出处。

模型能力的提升会让它跑得更快,但这些骨架解决的是跨会话、跨角色、跨阶段的一致性——那是另一个维度的问题。

状态说明:ai-engineering-agent 仍在持续打磨中,可能仍存在未发现的问题——规约之间口径不一致、命令 / 技能引用失效、产物路径与规约不符、表述歧义等。
使用前建议先通读 rules/ 与你要用的那条命令。发现任何问题或有改进想法都欢迎补充完善;反馈时附上文件路径 + 行号 + 现象最有效。

推荐地址

posted @ 2026-10-16 14:14  码猿手  阅读(163)  评论(0)    收藏  举报
Live2D