AI 编程验证优先工作流
AI 编程验证优先工作流
AI 编程真正拉开差距的不是“提示词写得更长”,而是能否把模型输出放进一个可验证、可回滚、可复用的工程循环。验证优先不是每次都跑最重的全量测试,而是在动手前先定义:这次改动最可能错在哪里,用什么最小证据证明它没有错。
核心判断
把 AI 当成能快速产生候选方案的搭档,而不是替你承担结果责任的黑盒。一个验证优先的工作流要同时回答三个问题:
| 问题 | 不合格做法 | 合格做法 |
|---|---|---|
| 目标 | “让它优化一下代码” | 写清要改善的行为、文件范围和完成标准 |
| 风险 | “看起来没问题” | 列出最可能破坏的接口、状态、链接或数据 |
| 证据 | “AI 说通过了” | 保存真实命令、构建、测试或人工复核结果 |
一轮最小闭环
读上下文 → 定风险 → 改一小块 → 跑最小验证 → 记录证据 → 再决定下一步1. 读上下文
不要让 Agent 或 AI 助手直接从空白处生成改动。至少先读:
- 项目 README、约定文件和最近的计划文档;
git status,确认哪些改动已经存在;- 目标文件附近的命名、结构、测试风格;
- package/script 配置,找出项目推荐的验证命令。
这一步的收益是避免两类常见浪费:把内容写到错误目录,以及把别人尚未提交的改动混进自己的提交。
2. 定风险
每次只给当前小任务写 1-3 个风险点。例如:
| 任务 | 主要风险 | 最小验证 |
|---|---|---|
| 新增文档 | frontmatter 错、链接断、目录未收录 | git diff --check,本地构建或人工检查目录链接 |
| 修改 React 组件 | 状态分支遗漏、交互回归 | 单元测试、类型检查、关键路径 smoke test |
| 改后端接口 | schema 不兼容、错误码变化 | 针对接口测试、最小 curl/fixture |
| 写脚本 | 误删文件、路径假设错误 | dry-run、小样本目录、输出快照 |
风险点越具体,AI 越容易被用来生成测试、检查边界和修复失败,而不是泛泛“再检查一下”。
3. 改一小块
适合 AI 编程的改动粒度通常满足:
- 可以在一次 diff 中看完;
- 可以用一个命令或一个人工检查点验证;
- 出错时能快速回滚;
- 不需要同时改业务规则、样式、依赖和目录结构。
如果一个任务不得不跨很多模块,先让 AI 帮你拆出“第一个可运行切片”,而不是一次性生成大改。
4. 跑最小验证
验证命令应覆盖本轮核心风险,而不是为了显得严谨机械跑全量命令。
常用顺序:
git diff --check:先排除空白、冲突标记和低级格式问题。- 类型检查或 lint:覆盖静态接口和风格约束。
- 相关单元测试:只跑受影响模块附近的测试。
- 构建或 smoke test:覆盖集成和产物生成。
- 人工复核:对文档结构、视觉布局、产品语义做最后判断。
如果验证失败,先把失败输出喂回 AI,让它基于真实错误修复;不要让它凭印象重写一遍。
验证失败后还要先判断“失败归属”,再决定下一条动作:
| 失败归属 | 下一条动作 |
|---|---|
| 本轮改动 | 复跑最小失败命令,确认失败稳定;只改相关文件或回滚本轮切片 |
| 启动前已有改动 | 重新记录 git status --short,只读判断归属;不要把它混进本轮提交 |
| 环境依赖 | 先检查版本、安装或缓存状态;把可重跑命令和原始错误留下 |
| 外部服务 | 先做凭据、网络或服务健康检查;必要时改用 dry-run / mock 验证 |
| 信息缺口 | 先读权威文档、配置或入口文件;仍缺失时停止有副作用动作 |
这张表的作用是把“测试失败”从情绪信号变成路线选择器:失败不是一定要继续改代码,也可能意味着缩小范围、补环境证据或显式交接未验证项。
如果本轮无法修完失败,至少留下一个最小交接块,避免下一轮重新考古:
已验证:<已经通过的最小命令或人工检查>。
未验证:<失败命令、未覆盖交互或缺失依赖>;原因是 <失败归属>。
结论措辞:本轮只能说 <有证据的结论>,不能说 <被失败阻断的结论>。
下一步:先 <第一条可复制命令/文件读取/人工检查路径>;仍失败则 <缩小或交接规则>。
证据位置:<命令输出、diff、notebook 段落或相对路径>。这份块状记录可以复用 books/tech-cards-handbook/samples/ai-agent-verification-failure-handoff-template.md 的字段:先判断失败归属,再把下一条动作压缩成一个能执行的命令、文件读取或检查路径。
5. 记录证据
每轮结束至少留下这四项:
改动文件:docs/...
核心风险:目录链接和 frontmatter 是否正确
验证方式:git diff --check;人工检查 README catalog 链接
结果:通过;未运行完整 VuePress build,因为只新增一页 markdown 且未改配置这份记录可以写进 commit message、PR 描述、项目 notebook 或工作总结。它的价值在于下一次接力者能立刻知道“哪些已经被证明过,哪些还没证明”。
6. 收尾报告字段
真实项目里的 AI 编程通常不是 clean room:工作区可能已有别人改动,验证可能只覆盖本轮切片,甚至某些命令会失败。为了不让下一轮被误导,收尾报告要固定写这六类字段:
本轮选择:为什么选这个小任务,为什么没有接管其他脏文件
实际推进:改了哪些文件,完成了什么可复核资产
验证证据:真实命令和结果;失败或未覆盖项也写清
状态证据:启动/收尾 git status 摘要,说明未接管边界
提交读回:项目提交和 notebook/PR 记录分别读回 hash 与标题
下一步:下一轮第一条动作,而不是泛泛“继续优化”关键原则是“证据先于结论”。如果只运行了 git diff --check 和局部单测,就只能说这些范围已验证;如果全量构建没有跑,要把原因和风险留下。提交后再用 git log -1 --oneline 读回,不要从计划、commit 命令输出或记忆里复制 hash。
一个简短例子:
验证证据:`git -C docs diff --check -- documents/trending/ai/verification-first-ai-coding.md` 通过;人工检查 README catalog 已包含该页。
状态证据:启动时 `loom` 有非本轮改动,未接管;收尾时 `docs` clean,`loom` 仍未 stage。
项目提交:docs 1a2b3c4 docs(ai): add verification-first coding workflow doc(提交后读回)
未验证:未运行完整 VuePress build;本轮只改单页 markdown,下一步如改 sidebar 再跑 build。这能把 AI 编程从“我感觉做完了”改成“我知道哪些结论有证据,哪些需要交接”。
提示词模板
把验证前置到提示词中,可以显著减少 AI 的无效发挥:
目标:在 docs/... 新增一页关于 AI 编程验证工作流的文档。
范围:只允许新增该文档并更新同目录 README catalog。
风险:frontmatter 必须符合 VuePress 约定;链接不能断;不要修改生成产物。
执行:先读现有 README 和相邻文章风格,再写文档。
验证:运行 git diff --check,并人工检查 catalog 相对链接。
输出:列出变更文件、验证命令和未覆盖项。关键是让 AI 在开始写代码前就知道验收标准,而不是写完后再补一句“请检查”。
团队落地规则
可以把下面几条写进项目的 Agent 指南:
- 修改前必须检查
git status,避免混入他人改动。 - 每轮只做一个可验证切片,除非用户明确要求大范围重构。
- 每个提交说明至少包含“改了什么”和“怎么验证”。
- AI 生成的测试必须真实运行,不能只展示看起来合理的输出。
- 无法验证时要明确写出原因和剩余风险。
自检清单
提交前问自己:
- 这次改动的目标能否用一句话说清?
- 我是否读过相关上下文,而不是直接生成?
- 这次最可能出错的 1-3 个点是什么?
- 我是否拿到了真实验证结果?
- notebook、PR 或 commit 中是否留下了可接力的证据?
如果这五个问题都能回答,AI 编程就从“快但不可控”变成了“快且可复盘”。