AI 写代码最危险的时候,往往是它看起来没问题的时候

1. AI 写代码最危险的时候,往往是它看起来没问题的时候

AI 写代码最危险的时候 ▲ AI 写代码最危险的时候

我以前以为,测试通过就说明 AI 这次写得差不多了。

diff 看起来很干净,AI 还很自信地告诉我「已完成」。

但真正 review 的时候,我经常说不清一件事:它为什么这样改?这个判断条件从哪来的?有没有替我偷偷补了一个业务假设?

注:此文配图源自本人开源 skill:「卷卷整理研究所:内容插画 Skill」,https://github.com/dososo/juju-content-illustrations

插画:AI 交付的代码需要人工验证

后来我给 Coding Agent 加了一条规矩:写完代码,不只交 diff,还要交一份「可验证解释」。

这份解释不追求写得好看,重点是让人能检查:它改了什么、基于什么假设、跑了哪些测试、哪些场景没覆盖、出问题怎么回退。

我看了一篇 2026 年 7 月 2 日刚挂到 arXiv 的论文,题目叫《Guiding Human Validation of LLM-Generated Code via Verifiable Literate Programming》。里面提出了一个很好用的方向:让 AI 生成代码时,同时生成一份可以被验证的解释。

VLP 论文页面

我更愿意把它翻译成一句日常工作里的话:别只让 Agent 交代码,也要让它交一张「验收路线图」。

这件事对普通使用者很有价值。你不需要马上理解论文里的模型检查、形式化属性、trace link 这些术语。

先把它拆成一个今天就能用的工作流:代码、假设、测试、验证说明一起交付。

1.1. 这篇论文真正提醒我的一件事

论文研究的是 VLP,也就是 Verifiable Literate Programming。Literate Programming 这个概念来自 Donald Knuth,核心是让程序面向人来阅读。VLP 往前推了一步:解释不能只好读,还要能拿来验证。

arXiv 页面显示,这篇论文由香港大学的 Ziqi Yuan、Wenhao Lu、Hao Wu、Dunhong Jin、Chuan Wu 提交,时间是 2026 年 7 月 2 日。

论文里有两组数字很说明问题:

  1. 在他们的 bug study 里,81.7% 到 83.3% 的失败,可以用自然语言表达成具体的「意图级行为」。这说明很多错误并非只有程序员才能发现,只要 AI 把行为写清楚,需求方也能参与判断。
  2. 在 QuantCodeEval 和 BigCodeBench 的评估里,VLP 把 pass@1 从 28.7%~73.2% 提升到 65.4%~93.5%。这说明「让人参与验证」不是形式主义,它确实能提升代码正确率。

我看完后的第一反应是:这不就是我们日常用 Codex、Claude Code、Cursor 时最缺的一层吗?

现在我们用 AI 写代码,流程大概是:提需求,等它改,跑测试,看 diff,没红字就合并。

问题是,测试只能覆盖你想到的路径,diff 又太细,需求和实现之间缺一张中间层。

这张中间层就应该叫「可验证解释」。

可验证解释作为需求与实现之间的中间层

1.2. 普通解释没用,可验证解释才有用

我以前也会让 AI「解释一下你改了什么」。结果经常拿到一段丝滑的总结:优化了逻辑、增强了健壮性、提升了可维护性。读起来挺舒服,审查时几乎帮不上忙。

但是我发现,解释要有用,至少要满足三个条件:

  1. 能对照需求:它要说明哪一段需求被哪一处代码处理了。
  2. 能对照测试:它要给出具体命令、测试文件、测试用例,方便你复跑。
  3. 能暴露假设:它要说清楚 AI 自己补了哪些判断,哪些地方需要人确认。

举个例子。如果你让 AI 修一个「登录按钮连续点击会重复提交」的问题,普通解释可能写成:

我增加了 loading 状态,避免用户重复提交。

这句话又过于简单了。

你根本不知道它处理了哪些细节。

可验证解释应该长这样:

需求目标:用户连续点击登录按钮时,只允许产生一次登录请求。

实现假设:前端负责阻止重复点击,后端接口仍保留幂等保护。

代码路径:LoginForm.tsx 在提交开始时设置 isSubmitting=true,请求结束后在 finally 中恢复。按钮在 isSubmitting=true 时禁用。

验证方式:新增测试 LoginForm.test.tsx,模拟连续点击两次,断言 loginApi 只调用一次。

人工确认点:如果产品希望第二次点击展示提示文案,需要补一条交互规则。

这就不一样了。

审查者先读这段,就知道自己该看什么:finally 有没有覆盖异常路径,测试是不是真的连续点了两次,产品有没有提示文案要求。

1.3. 我现在会让 Agent 每次多交四样东西

Agent 交付的四样东西

如果你想马上用,不用等任何新工具。直接改提示词就行。

我现在会要求 Agent 在交付代码时,同时输出这四样东西:

1.3.1. 假设清单

AI 写代码时一定会补全很多没明说的细节。它不写出来,人就很难发现。

比如「导出订单」这个需求,AI 可能默认只导出当前页,也可能默认导出全部搜索结果。

这两种实现都能跑,业务含义完全不同。

所以我会让它明确写:

请列出你在实现中做出的假设,每条假设后面标注:
1. 来自用户明确要求
2. 来自现有代码约定
3. 由你推断,需要人工确认

审查时优先看第三类。

这里最容易出现需求不一致。

1.3.2. 需求到代码的映射

只看 diff 会被文件结构牵着走。你看到的是代码如何变化,未必能看出需求如何被满足。

我会让 Agent 这样写:

请把本次需求拆成 3 到 7 条可检查行为,并为每条行为标注:
1. 涉及文件
2. 涉及函数或组件
3. 对应测试或验证命令
4. 如果没有测试,说明原因

这一步很像论文里的 trace link 思路。论文做得更完整,会把 prompt 和 documentation 建立链接,再用 LLM 标出可疑片段。

我们日常不必做得那么重,先让 Agent 把「需求、代码、测试」串起来,已经能省掉很多审查时间。

1.3.3. 测试证据

「我已经测试过了」这句话没有价值。我要的是能复跑的证据。

我会要求它给出:

请提供本次验证证据:
1. 执行过的命令
2. 命令结果摘要
3. 新增或修改的测试文件
4. 覆盖的正常路径
5. 覆盖的异常路径
6. 仍未覆盖的场景

这里有个小技巧:不要只让它写「测试通过」。

让它写「哪些场景没有覆盖」。这比成功信息更有用。

1.3.4. 回滚和风险说明

AI 改代码很快,但上线后出现问题,真正花时间的是定位和回退。

所以我会加一段:

请说明本次改动的风险和回滚方式:
1. 可能影响哪些旧流程
2. 哪些配置或环境变量发生变化
3. 如果线上异常,最小回滚动作是什么
4. 哪些日志可以帮助确认问题位置

这部分对小团队尤其有用。你不一定有完整 QA,也不一定有专门运维,但你可以让 Agent 在交付时先把逃生路线写出来。

1.4. 可以直接复制的 3 个模板

三个可复用模板

下面这三段我建议直接放到你的工作流里。

用 Codex 可以写进 AGENTS.md,用 Claude Code 可以写进 CLAUDE.md。如果是临时任务,直接复制到对话里也能用。

1.4.1. 模板 1:开工前先别动代码

你先不要修改文件。请先输出一份可验证计划,格式如下:

一、我理解的用户目标
用 3 到 5 条可检查行为描述,不写抽象口号。

二、我准备修改的范围
列出可能涉及的文件、函数、组件、测试文件。

三、实现假设
按三类列出:用户已明确、代码约定可推断、需要人工确认。

四、验证标准
每条标准必须能通过命令、测试、页面操作或日志确认。

五、需要确认的问题
只问会影响实现方向的问题,不问无关细节。

这段适合需求还不够清楚的时候。

它能把 AI 的脑补提前摊开,避免它直接开改。

1.4.2. 模板 2:交付时必须带可验证解释

请在完成代码修改后,按下面格式交付:

一、改动摘要
说明改了什么,每条不超过两句话。

二、需求到代码映射
表格列出:需求行为、涉及文件、核心函数或组件、验证方式。

三、可验证解释
解释关键判断为什么这样写,每条解释都要绑定到代码位置或测试证据。

四、测试证据
列出执行命令、结果摘要、新增测试、未覆盖场景。

五、风险和回滚
说明可能影响的旧流程、配置变化、最小回滚动作。

这段适合日常小需求。

你会发现,同样一份 diff,只要多了这层说明,review 会轻很多。

1.4.3. 模板 3:让另一个 Agent 做审查

你只做代码审查,不修改文件。

请先阅读交付方提供的可验证解释,再检查 diff。
重点检查:
1. 解释里的每条需求是否真的有代码实现
2. 测试是否覆盖解释里的关键行为
3. 是否存在解释没提到的额外改动
4. 假设清单里是否有需要人工确认的内容
5. 回滚方式是否足够具体

最后按三类输出:必须处理、建议处理、可以接受。

这段很适合 Codex、Claude Code 这种支持多 Agent 或多会话的工具。

一个 Agent 写,一个 Agent 审,你自己看最终分歧点。

1.5. 放进 AGENTS.md,可以这样写

如果你不想每次复制提示词,可以把规则写进项目根目录的 AGENTS.md。

OpenAI Codex 官方文档也明确说明,Codex 会在开始工作前读取 AGENTS.md,并且可以通过项目级规则保持任务期望一致。

可以直接加这一段:

### 5.1 代码交付规则

每次修改代码后,必须附带 Verifiable Explanation:

1. 本次需求被拆成哪些可检查行为
2. 每个行为对应哪些文件、函数、组件
3. 哪些测试或命令验证了这些行为
4. 哪些假设来自推断,需要人工确认
5. 哪些场景没有覆盖
6. 最小回滚动作是什么

如果没有执行测试,必须说明原因,并给出建议执行命令。
如果发现需求和现有代码约定冲突,先停下说明冲突,不要直接自行选择。

如果你用 Claude Code,还可以把「测试、lint、typecheck」这类确定性动作放进 hooks。

Anthropic 官方 hooks 文档说明,hooks 是在 Claude Code 生命周期特定节点执行的用户自定义 shell 命令,用来强制执行项目规则和重复动作。

我的理解很简单:提示词适合约束判断,hooks 适合执行命令。

1.6. 一个小任务怎么跑完整流程

拿一个很常见的需求举例:给订单列表增加「导出 CSV」。

我会这样给 Agent:

请为订单列表增加导出 CSV 功能。

先不要改代码。请先输出可验证计划:
1. 你理解的用户目标
2. 需要确认的业务假设
3. 计划修改的文件
4. 验证标准
5. 可能影响的旧流程

如果它返回:

假设:导出范围为当前搜索条件下的全部订单。
需要确认:是否导出当前页,还是导出全部搜索结果。

这时你就赚到了。

因为这个问题如果等代码写完才发现,可能前端、接口、分页逻辑都要重改。

确认后再让它执行:

按确认后的方案修改代码。完成后必须输出:需求到代码映射、测试证据、未覆盖场景、回滚动作。

交付后你先不急着看 diff,先看它的可验证解释。

如果解释写「导出全部搜索结果」,测试却只覆盖当前页,这就是明确问题。

如果解释写「后端新增 exportOrders 接口」,diff 里还改了无关的订单详情页,也要单独拎出来问原因。

这个流程不复杂,但能把 AI 写代码从「看起来完成」推进到「可以检查」。

1.7. 它最适合这几类场景

适合使用可验证解释的场景

我不建议每个小改动都搞成论文级流程。改一个文案、调一个颜色,没有必要写太长解释。

更适合用可验证解释的,是下面几类任务:

  1. 涉及钱的逻辑:支付、退款、账单、优惠券、订阅。
  2. 涉及权限的逻辑:登录、角色、后台管理、数据可见范围。
  3. 涉及状态变化的逻辑:订单状态、任务流转、异步队列。
  4. 涉及数据迁移的逻辑:字段变更、脚本、批处理。
  5. 涉及多人维护的代码:你今天能理解,三周后同事也要能接住。

这些地方,AI 多写 300 字解释,比你事后花 3 小时排查划算得多。

1.8. 也别把它用歪了

这里有三个常见问题,我自己也遇到过。

第一,解释写成作文。可验证解释不追求漂亮文字,只追求能检查。

看到「提升体验」「优化逻辑」「增强健壮性」这类句子,直接让 AI 改成具体行为。

第二,只验证成功路径。比如导出 CSV 成功了,但空数据、无权限、接口失败、超大数据量都没看。

让 Agent 主动列「未覆盖场景」,审查价值会高很多。

第三,把验证交给 AI 自己评分。AI 说「逻辑正确」没有意义。

它要给命令、测试文件、操作步骤、日志关键词,人再抽查。

1.9. 我的建议:从下一次小需求开始试

如果你已经在用 Codex、Claude Code 或 Cursor,我建议从下一次小需求开始试,不需要改团队流程,也不需要引入新平台。

1.9.1. 你只做两件事

  1. 开工前,让 Agent 先写「可验证计划」。
  2. 交付时,让 Agent 附带「可验证解释」。

几次之后,你会很明显地感受到变化:你不再只是被动看 diff,而是在检查「需求、代码、测试、风险」有没有对上。

这也是我觉得 VLP 这篇论文有意思的地方。它没有停在「让 AI 多解释几句」,而是把解释变成验证入口。

未来 AI 写代码越快,人的审查方式也得升级。

我们不可能逐行盯住所有代码,但可以要求 AI 把它的假设、证据和风险摆到桌面上。

1.10. 参考资料

  1. arXiv:《Guiding Human Validation of LLM-Generated Code via Verifiable Literate Programming》,2026 年 7 月 2 日提交:https://arxiv.org/abs/2607.02333v1
  2. arXiv PDF:https://arxiv.org/pdf/2607.02333v1
  3. OpenAI Developers:Codex 使用 AGENTS.md 自定义项目指令:https://developers.openai.com/codex/guides/agents-md
  4. OpenAI Developers:Codex Best Practices,提到可通过 code_review.md 和 AGENTS.md 保持 review 规则一致:https://developers.openai.com/codex/learn/best-practices
  5. Anthropic Claude Code Docs:Automate actions with hooks:https://code.claude.com/docs/en/hooks-guide
  6. Donald Knuth:Literate Programming 相关资料:https://www-cs-faculty.stanford.edu/~knuth/lp.html

1.11. 历史文章

  1. 别把 Codex 只当代码助手,它正在变成工作流系统
  2. Codex 的 Pinned Threads,到底该怎么用?
  3. Codex App 不折腾上手指南:先会这几个命令就够了
  4. AGENTS.md 完全指南 2026:规范、工具、示例
  5. Codex 最佳实践:入门指南与提升效果的经验法则
  6. Codex App 线程调度指南:当前线程、新对话、派生、工作树、Subagents 到底怎么选?
  7. 复杂需求先别让 AI 写代码:多 Agent 并行 Plan 实操
  8. 让 Codex 排查 Codex:手机端和桌面端协同踩坑复盘
  9. MacBook 合盖后,Codex 手机远程不断线的方法
  10. 知识库最缺的不是更多笔记,而是一个 500 字符的热缓存
  11. Codex 的「批注」功能,把 AI 改代码变得像改 Word 文档
  12. 三 Agent 工作流实操:双 Agent battle 用久了,我加了一个裁判
  13. 从需求到部署:这 10 个 Codex App 插件,让 AI 编程真正跑完整个项目
  14. Agent 记忆不是 RAG:给 Codex 和 Claude 做长期记忆的最简方式
  15. MacBook 合盖不断线进阶版:Codex 手机远程 + Amphetamine + 任务交接
  16. Agent 会话历史别浪费:把 Claude Code 和 Codex 的历史变成本地知识库
  17. 用 Claude Code / Codex 复现论文:AI 现在能不能当研究助理
  18. Claude Code / Codex 多 Agent 并行:小白也能用的分工方法
  19. Agent 找不到你的工具?给它写一张 ARD 能力地图
  20. Codex 和 Claude Code 写完代码后,我先看这 6 件事
  21. Claude Code / Codex / Grok 长任务工作流:只读计划、按计划执行、单独验收
  22. Agent 部署卡在 OAuth 和 API Token?Cloudflare 临时账号操作指南
  23. giffgaff eSIM 保姆级激活教程:国行 / 非 eSIM 手机也能用
  24. Codex 不断线进阶篇 | Adrafinil 安装与使用指南:让 MacBook 合盖后只在该醒的时候醒
  25. AI 编码工具入职手册:4 个可直接复制粘贴的模板,搞定 CLAUDE.md 和 AGENTS.md
  26. AI Agent 到底是什么?用 DeepSeek 和 Telegram 搭一个小号 Hermes 就懂了