AI与Agent · 2026-07-03

AI写代码为什么要先建验证门禁

把 AI coding 的风险讲成验证门禁问题:模型可以快速生成代码,但每次改动都要经过本地检查、CI 状态、测试层级、代码审查、关键路径 smoke test 和失败恢复路径,才能进入可合并状态。

AI 写代码最容易让人上头的地方,是它真的很快。你描述一个需求,它能补函数、改样式、写接口、迁移文件、补文档,甚至顺手把测试也写出来。问题是,代码生成速度越快,错误进入主分支的速度也会越快。

过去一个开发者一天改几十行,很多问题会被人的节奏自然挡住。现在一个 AI coding agent 几分钟就能改十几个文件,风险不再只是“它会不会写错”,而是“团队有没有机制及时发现它写错”。所以,AI 写代码的第一件事,不是挑模型,也不是写更长提示词,而是先建验证门禁。

验证门禁不是一个单独工具,而是一组能拦住错误的检查点:本地测试、类型检查、lint、格式化、单元测试、集成测试、端到端测试、代码审查、依赖扫描、CI 状态检查、发布前 smoke test、失败后的恢复路径。它们共同回答一个问题:这次改动,能不能进入下一步?

AI写代码验证门禁图

AI 不是不可信,而是太快了

讨论 AI 写代码时,很多人会把问题说成“模型会幻觉”。这当然存在,但工程上更实际的问题是:模型的产出速度超过了团队原来的验证能力。

一个人类开发者写错一行代码,可能会在本地运行时发现;AI 一次性改了多个模块,错误可能藏在跨文件调用、边界条件、类型约束、权限判断、构建配置或 UI 交互里。它生成的代码越完整,越容易让人误以为“已经能用了”。

OpenAI Codex best practices 把完成任务前的检查写得很直接:写或更新测试、运行正确的测试套件、检查 lint、格式化或类型检查、确认最终行为符合请求、审查 diff 中的 bug、回归或风险模式。这个清单说明,AI coding 的收尾不是“看起来写完了”,而是要经过一组可执行验证。

GitHub Copilot cloud agent 文档也把流程描述为:Agent 可以研究仓库、制定实现计划、在分支上改代码,开发者可以 review diff、iterate,并在准备好时创建 pull request。这里的关键词是 branch、diff、review、pull request。AI 可以独立工作,但它的结果仍然应该进入软件工程原有的门禁链条。

什么是验证门禁

验证门禁可以理解为代码流动中的关口。每个关口都问一个小问题。

语法能过吗?类型能过吗?格式符合项目规则吗?关键函数有测试吗?旧行为有没有被破坏?UI 流程还能跑吗?安全扫描有没有报出高风险项?CI 状态是不是绿色?审查者有没有看到可疑改动?发布前最重要路径有没有 smoke test?

GitHub status checks 的官方文档说,status checks 用来告诉你提交是否满足仓库设置的条件;pull request 页面里的 Checks tab 会显示自动化测试、构建或其他 CI 工作流状态。GitHub protected branches 文档还说明,可以要求特定 status checks 通过后才能合并。换句话说,门禁不只是开发者自觉,它可以被仓库规则强制执行。

对 AI 写代码来说,这一点尤其重要。因为 AI 不会天然知道你的业务底线,也不会天然知道哪些测试必须跑。门禁把“团队经验”变成系统规则,让每次 AI 改动都必须经过相同标准。

第一层:本地快速门禁

第一层门禁应该离代码最近,越快越好。它不追求覆盖所有风险,而是尽早拦住低级错误。

常见组合是:格式化、lint、类型检查、受影响模块的单元测试。ESLint 官方说明它用于识别和报告 ECMAScript/JavaScript 代码中的模式,目标是让代码更一致并避免 bug。TypeScript 官方文档里的 --noEmit 选项可以在不输出文件的情况下做类型检查。pytest 文档强调它能让小而可读的测试变得容易,并能扩展到复杂功能测试。它们不是 AI 专用工具,但正好适合做 AI coding 的第一道门。

如果一个 AI agent 每改完一个小目标,都能自动跑这些检查,它会更容易自我修正。错误越早暴露,修复成本越低。反过来,如果等到最后才跑全量 CI,Agent 可能已经在错误假设上叠了很多改动,修起来更费力。

一个实用做法是把本地门禁写进项目说明里:修改 TypeScript 代码后必须跑 tsc --noEmit,修改前端交互后必须跑对应 Playwright 用例,修改 Python 模块后必须跑目标 pytest,修改公共 API 后必须补契约测试。不要只写“请确保代码正确”,要写具体命令和通过标准。

第二层:CI 与必需状态检查

本地检查解决的是“这台机器上看起来没问题”。CI 解决的是“在团队统一环境里是否也能通过”。

GitHub Actions、GitLab CI、CircleCI、Buildkite、Jenkins 都可以做这件事。本文不讨论具体工具优劣,重点是把验证变成 Pull Request 的必经环节。GitHub protected branches 支持要求 pull request 在合并前通过 status checks,也可以要求分支保持最新后再合并,避免基于旧主分支测试的结果被误用。

对 AI 写代码来说,CI 至少应该包含四类检查。

第一类是构建检查:项目能不能安装依赖、编译、打包。

第二类是测试检查:单元测试、集成测试、关键端到端用例。

第三类是质量检查:lint、格式、类型、静态分析、依赖审计。

第四类是变更检查:生成文件是否更新、数据库迁移是否成对、API schema 是否兼容、文档是否随行为改动更新。

如果团队允许 AI 直接开 PR,那么必需状态检查就更重要。它的作用,是把“不管这个 PR 是人写的还是 AI 写的,都要经过同一组检查”变成仓库规则。这比让审稿人凭感觉判断 AI 代码可靠得多。

测试金字塔与门禁层级

第三层:代码审查不是形式

AI 生成代码之后,代码审查仍然有价值。只是审查重点要变。

人类审查者不必逐行把 AI 当学生批改,而要看几类风险:需求有没有被误解,边界条件有没有漏,权限和数据流有没有异常,改动范围是否过大,是否引入隐性依赖,测试是否只覆盖了 happy path,是否把临时逻辑写成长期设计。

GitHub Copilot code review 文档说明,Copilot 可以审查 pull request,识别问题并提出可应用的修复建议;它还支持 custom instructions,让组织把编码标准和审查偏好写进仓库。这个能力可以作为辅助审查,但不能替代仓库自己的验证门禁。AI review 可以帮你发现问题,CI 才能稳定执行规则,人类 owner 负责最终判断。

一个更稳的做法是三层审查:AI 自检先跑,自动化门禁再跑,人类审查最后看意图和风险。这样人不用被低级格式问题拖住,能把注意力放在系统行为上。

第四层:端到端与用户路径

很多 AI 改动不会在单元测试里失败,但会在真实用户路径里出问题。比如按钮文案改了导致选择器失效,接口字段名改了导致页面空白,权限判断改了导致普通用户看到管理员入口。

Playwright 官方 best practices 强调测试应尽可能隔离,每个测试应独立运行,拥有自己的 local storage、session storage、数据和 cookies;测试隔离能提升可复现性、简化调试并避免级联失败。对 AI coding 来说,这很关键。AI 生成的 UI 改动经常看起来合理,但只有自动化浏览器测试能较稳定地检查关键路径。

端到端门禁不一定要覆盖所有页面。建议从“业务不能坏”的路径开始:登录、下单、支付、发布、保存、搜索、权限切换、关键数据展示。AI 改动触碰这些路径时,必须跑对应 smoke test 或 E2E test。

这层门禁的目标不是覆盖所有页面,而是让最重要的路径不被轻易破坏。

第五层:失败恢复路径

验证门禁不仅要告诉你“能不能过”,还要告诉你“没过怎么办”。

很多团队的 AI coding 问题不在于没有测试,而在于测试失败后继续往前堆改动。Agent 为了修一个失败,又改了三个文件;三个文件引入更多失败;最后 diff 变大,审查成本升高。

更好的策略是小步提交、分段验证、失败停下。OpenAI Codex 的 code migration 用例建议按 milestone 工作,并在每个 milestone 后运行 lint、type-check 和 focused tests;如果验证失败,先修好再继续。这个思路可以推广到所有 AI coding 任务。

失败恢复路径可以写成四条规则:

第一,失败时先读错误,不要立刻大范围重写。

第二,只改与失败相关的最小范围。

第三,修复后重跑同一个门禁,再跑上一级门禁。

第四,如果连续失败,收缩任务或交给人判断。

这里用“恢复路径”而不是“回到旧状态”,是因为生产工程里更重要的是可追溯:知道哪一步失败、改了什么、如何验证,而不是靠感觉撤销一堆文件。

失败恢复与验证循环

门禁要按风险分层

不是所有改动都需要同样重的验证。改一个文档错别字,不需要跑全量端到端;改支付逻辑,不能只跑格式化。

可以把 AI 改动分成四级。

L1,低风险:文档、注释、样式微调、低风险文案。门禁是格式化、相关预览、轻量检查。

L2,中低风险:单个函数、单个组件、小范围 bug fix。门禁是 lint、类型检查、目标单元测试、相关快照或组件测试。

L3,中高风险:接口、数据库、权限、状态管理、跨模块行为。门禁是目标单元测试、集成测试、契约测试、相关 E2E。

L4,高风险:支付、账号、隐私、安全、生产配置、数据迁移、正式发布流程。门禁是全量 CI、人工审查、回放或灰度、发布前 smoke test、可追溯恢复方案。

风险分层的好处是避免两种极端:小改动被门禁拖死,大改动却只有轻量检查。AI coding 的验证系统应该既能快,也能在关键处重。

把门禁写进 Agent 指令

很多团队把验证门禁放在 CI 里,但没有写进 Agent 指令。结果 AI 写完代码后不知道应该跑什么,也不知道哪些失败可以忽略。

项目里的 AGENTS.mdCONTRIBUTING.md.github/copilot-instructions.md、README 或内部任务模板,都可以写清楚验证规则。GitHub Copilot code review 文档提到,Copilot review 可以使用仓库 custom instructions;OpenAI Codex best practices 也强调要让 Codex 知道如何验证变更、运行哪些测试、如何确认最终行为。

一份实用指令可以这样写:

这类指令越具体,AI 越容易把验证当作工作的一部分,而不是最后一句“请自行检查”。

什么时候不要让 AI 继续改

验证门禁还有一个作用:判断什么时候该停。

如果 AI 连续三次修同一个测试都失败,如果它开始为了通过测试而削弱断言,如果它删除了关键校验,如果 diff 越修越大,如果它解释不清楚为什么改这个文件,就应该停下来。

这不是否定 AI,而是正常工程纪律。人类开发者遇到复杂失败也会停下来重读需求、缩小范围、找同事看一眼。AI 也需要这种停顿。

门禁不只是“通过/失败”的机器判断,也是一套行为边界:失败可以修,但不能无限扩散;验证可以补,但不能为了变绿而降低质量;自动化可以快,但高风险节点必须有人确认。

一份 AI coding 门禁清单

如果你要把 AI coding 放进团队工作流,可以从下面这份清单开始:

第一,给每类改动定义最小验证命令。

第二,把验证命令写进 Agent 指令和仓库文档。

第三,要求 AI 在每个小阶段后运行目标测试,而不是最后一次性验证。

第四,把 lint、typecheck、unit test、build 放进 CI。

第五,用 protected branches 或 rulesets 要求关键 status checks 通过后才能合并。

第六,为关键路径建立 smoke test 或 E2E test。

第七,让 AI review 作为辅助,但保留人类审查和自动化门禁。

第八,测试失败时先最小修复,连续失败就停下来重新评估。

第九,记录验证命令和结果,让 PR 审查者知道哪些已经检查、哪些没覆盖。

第十,高风险动作进入人工确认,不让 AI 单独决定发布或生产变更。

AI coding提交前清单

结论:让 AI 快,但让门禁硬

AI 写代码会把开发节奏推得很快,但速度本身不是质量。没有验证门禁,AI 越快,团队越难知道哪些改动可信;有了验证门禁,AI 的速度才有机会变成可控的生产力。

最好的 AI coding 工作流,不是让模型一次写出完美代码,而是让它在清晰规则下小步前进:改一点,测一点,审一点,再继续。每一步都有证据,每个失败都能定位,每次合并都经过同一套门禁。

未来的开发团队不会只比谁的模型更强,也会比谁的验证系统更稳。模型负责加速,门禁负责守住边界。两者配合起来,AI 写代码才不只是演示效果,而是能进入团队日常工程。