AI 工程实践

Agent 越快,越需要硬门禁

用可观察验收条件、风险测试、硬门禁和独立 Review 控制 Coding Agent 的高速推进。

Kane约 8 分钟阅读
  • Coding Agent
  • 阶段门禁
  • 验收
  • 测试策略

如何正确推进

当我们有了 Agent 能高质量运行的环境之后,我们就该去控制 Agent 如何去运行了。

经常用 coding agent 的人应该能体会到它总是推进太快,总是想一口气就把活干完,这是 Agent 的底层设计造成的问题。

推进太快就容易出错,为了确保它没有在错误方向上高速推进,我们必须重新编排 coding 的 workflow。

首先,我们必须接受的一个现实:agent 编码速度超过人的阅读速度,随着 Agent 编程能力提升,最终会简化为简单的 /goal 命令。

所以我们必须接受黑箱运营,然后通过各种手段去控制生成质量。手段包括(单元测试 / Gherkin / QA / 变异测试 / 覆盖率 / TDD / SDD)

先说我设计的结论:人和强推理的 LLM 侧重于设计、审阅,在关键节点 gate 设置硬约束,具体写代码的 LLM 可以用便宜的模型。

但是,为了保证软件长期迭代时需求没有由于偏差而被破坏,需要“能够准确校验需求的测试用例”。

当 Agent 的实现速度超过人的阅读速度,确保它没有在错误方向上高速推进。

代码生成速度为什么改变了质量控制方式

  • 人无法继续把“逐行理解全部实现”作为主要控制手段;
  • Agent 最危险的状态往往不是做得慢,而是未经确认就连续推进;
  • 质量控制需要从阅读代码转向三个问题:
    1. 目标是否明确且可观察;
    2. 实现是否满足有效规格;
    3. 失败能否及时暴露、定位和回退。

为了解决这些问题,就需要我们在设计任务(spec)的时候,把需求做成可执行事实,把功能拆成可运行的小版本,把问题送回产生它的层级,再用自动反馈、人工门禁和独立 Review 控制推进。

这样我们就能控制 coding agent 在实现需求的同时,生成的结果是可观测的高质量的测试用例。

具体 coding 的 workflow 是这样的。

机会判断(前置)
  → 需求确认
  → 设计确认
  → 实现就绪
  → 开发与反馈闭环
  → 验收与独立 Review
  → 清理与提交

先决定做不做

由 Agent 结合现状罗列技术路径与可行性评估,人依据产品定位与直觉选择最优解,避免沉没成本。

先做可行性分析,从产品价值和技术可行性角度去分析需求是否有价值,开发一个功能不仅仅是 token 成本的问题,通常也会影响产品的整体设计,做了再砍掉,除非是回滚,要不然结果就是“你大妈已经不是以前那个大妈了”。

在这个阶段,Agent 负责调查项目现状、罗列方案、暴露不确定性和验证技术实现,然后出 3 个技术方案并分别给出推荐度。人负责价值判断和最终选择,没有被选中的方案也要保留原因,可以简短些,避免后续重复讨论。

写设计文档

在确定可行、有了初步的技术方案之后,先写设计文档。和 AI 协作写的设计文档更像是产品设计和技术设计的结合体。主要回答三个问题:

  1. 产品解决什么问题;
  2. 这一版做什么;
  3. 暂时不做什么。

如果使用 matt pocock skills 的朋友们可以选择用 /grill-with-docs 去完善信息,完善好之后,别忘了让 agent 出一份简报,如果你愿意看那一串文档的话自然最好,我不乐意看,所以就让 Agent 出一份简报,而且是 html 格式的(新开会话去做这件事)。这样能清楚知道这个功能是怎么回事,他打算怎么去实现。

要注意,每个需求要有可观察的验收条件:

  • 用用户能够观察到的行为描述结果;
  • 覆盖成功、失败、空状态、权限和边界条件;
  • 区分产品要求、技术约束和实现建议;
  • 每项交付都能映射到验证命令或实际操作路径。

新开会话让 agent 出一个 md 文档,方便产出后面测试用例的文档。

原型设计

界面型产品

选择正确的设计表达,有设计规范的这时候就享福了,直接把设计的规范文档作为物料提供给 AI,可以是 mcp、md、ui lib storybook,甚至所使用的组件库的页面链接,都行。

这里需要注意的是:用模拟数据去串联权限、空状态、禁用状态和异常反馈,能够通过模拟数据和交互状态表达的规则,尽量直接放进原型。

API、CLI、库和数据任务

这主要是数据结构文档,比如 API 契约和请求响应示例、Schema 这些。等业务稳定之后,可以单独做个迭代让 AI 优化性能,它很擅长。

让 Agent 在实现阶段形成反馈闭环

以文档和原型为输入,Agent 自动按里程碑编码、运行测试并截图自查。写代码不再是瓶颈,人无需过度介入。

配合 /goal,把文档一起发给 agent 去实施,它会按照文档规划的 Spec 一个个去实现,还会自己验证结果。

Spec → Task → 可观察验收条件 → AI Coding → Run & Check
                                  ↑               │
                                  └── Fix & Retry ┘
  • 按里程碑完成可运行切片;
  • 每个阶段运行与改动相称的验证;
  • 失败时修复根因,不通过放宽断言或屏蔽错误制造通过;
  • UI 改动由 Agent 打开实际页面并截图或操作自查。

这个阶段需要注意的是:让问题回到产生它的层级。

  • 需求问题修改需求;
  • 设计问题修改设计或原型;
  • 规格问题修改规格;
  • 实现问题修改代码;
  • 测试问题修复验证方法。

避免在代码层持续为上游错误打补丁。

如果有什么情况就 /fork, /handoff, /compact. 自己考量应该用什么指令去保证生成的质量。

按风险选择测试,而不是只追求测试数量

风险类型 主要验证方式
复杂、稳定的核心逻辑 单元测试:边界、状态转换、不变量
模块与真实依赖协作 集成测试
前后端或服务间字段一致性 契约测试
关键用户路径 E2E 或浏览器自动化
界面和体验 人工实际操作、截图和状态观察

单元测试、集成测试和 E2E 不是只能选择一种。 项目越接近核心业务、逻辑越复杂,越需要核心单测;越是跨模块、CRUD 和页面密集场景,越应该提高集成、契约和 E2E 的比重。

静态检查、类型检查和测试输出还要让 Agent 自己看见。 反馈越短、错误越具体,它在当前会话内闭环的问题越多。 关键用户路径必须真的运行过,不能只因为代码编译或测试文件存在,就推断功能已经可用。

测试跑完也不代表工作结束。 Agent 应该生成可复查的报告,并清除测试产生的账户、文件和数据库记录。

在资源有限的本地环境里,完整浏览器回归和重型设计工具同时运行可能影响反馈速度。

tips: E2E 浏览器自动化测试可以使用 kimi-webbridge/browser-skill 这类插件,如果是 mac 可以使用 codex computer use plugin 或者 ego lite 浏览器。

独立 Review

这部分建议用 不同模型和不同 Agent 来作为 reviewer 这个角色。对抗性测试对产品质量有帮助。我们需要提供给 reviewer:

  • 原始需求与生效规格;
  • 最终差异;
  • 测试和 smoke test 结果;
  • 运行日志、截图或性能数据;
  • 已知风险和非目标。

不要把完整的对话历史,比如 handoff 或者 export 生成的报告作为材料给他,避免继承相同假设,尽量提供新的信息,这样有助于他的独立判断。

它需要做这些工作:

  • 寻找会导致当前实现失败的条件;
  • 检查边界是否完整;
  • 检查测试发现的是否是真实缺陷;
  • 区分真实问题、偏好建议和无证据推测。

最终用户视角的黑盒验收

产品的责任人还是人,所以最后还是得由人来验收。

我们需要以普通用户身份走完完整的用户旅程。发现问题后送回正确层级,再由 Agent 修复和重新验证。

只验证体验与逻辑闭环,发现问题扔回给 Agent 修复。

提交前完成清理和可回退记录

Agent 在开发和测试过程中会产生大量数据垃圾,所以在提交之前清理测试创建的账户、文件、数据库记录和后台进程。对电脑和人的心理健康很重要。

建议用团队提供的 skill 进行 git commit 和 push 这个步骤。

用硬门禁控制 Agent 的推进速度

Coding Agent 最危险的时候往往不是做得慢,而是推进得太快。

它可以在几分钟内完成实现、测试、重构和下一阶段拆解,而人还没有判断上一阶段的方向是否正确。

仅在提示词里写“请等待确认”并不稳定。阶段的推进应该依赖文件和交付物。比如:

  1. 对应文档已经存在,内容达到当前阶段要求;
  2. 状态文件允许进入下一阶段;
  3. 需要人工判断的节点保留了用户确认原话。

这一块可以让 AI 设计自己的 workflow,只需要强调必须要有交付物或者状态改变才允许进入下一个阶段。通过 hooks 让越界操作无法通过。

比如需求没有确认就不生成实现计划,方案没有选定就不拆任务,验收没有通过就不提交或发布。

这样我们就只需要在可行性、设计、和最终验收几个关键节点做判断就行了。Agent 负责高速探索和执行,人负责方向、边界和放行。