AI 生成的前端代码应该怎样审查和验证?
把模型输出当成不可信的候选补丁,建立需求约束、类型检查、测试、依赖和安全审查的验证链,区分代码能运行与代码适合合并。
简答
- 把模型生成的代码当作不可信的候选补丁。
- 审查前先把需求写成可检查的约束,再读差异和数据流。
- 类型检查和 lint 只能证明一部分事实,测试要覆盖失败、取消和竞态。
- 还要审查新增依赖的真实性和许可证,以及提示词注入带来的安全风险。
AI 可以很快生成一个表单、请求封装或 React 组件,但“代码看起来像对的”不等于它符合项目约束。模型可能使用过时 API、遗漏取消和清理、引入未经批准的依赖,甚至把用户输入直接插入 HTML。
因此生成代码的正确流程不是复制到仓库,而是把它当成一个外部贡献者提交的候选补丁:先明确需求和边界,再用自动化检查和人工审查共同验证。
先把需求写成可检查的约束
“写一个搜索组件”太宽泛。审查前至少要明确:
- 输入变化是否防抖,旧请求是否取消或丢弃;
- 结果接口的状态码、数据结构和错误文案;
- 组件卸载时要清理哪些监听、计时器和请求;
- 是否允许新增依赖、目标浏览器和 TypeScript 版本;
- 用户输入是否能进入 HTML、URL、命令或权限接口;
- 哪些行为必须通过键盘、读屏和窄屏验收。
没有这些约束,审查者只能判断代码是否“像一个实现”,无法判断它是否解决了真实问题。
先读差异和数据流,不先看演示截图
AI 生成代码应以小提交或补丁进入分支,先看它修改了哪些文件、引入了哪些包、改变了哪些入口。重点追踪数据从哪里来、经过什么转换、最终进入哪个副作用:DOM、网络请求、存储、日志、权限或第三方 SDK。
例如下面这种代码可能能显示文字,但把不可信输入送进了 HTML 解释器:
preview.innerHTML = modelOutput;
改成 textContent 可能是正确方向;如果产品确实需要富文本,还要使用明确允许标签和协议的净化流程,并检查后续插件是否重新插入危险节点。仅仅让模型补一句“请注意 XSS”不能替代代码审查。
URL、命令参数、SQL、文件路径、模板和权限判断都要做同样的数据流审查。AI 输出的变量名叫 safeHtml 或 trustedUrl,不代表它已经经过验证。
类型检查和 lint 只能证明一部分事实
TypeScript 可以发现参数类型、缺失字段和部分错误分支,但不能证明服务器真的返回了声明类型,也不能证明权限、取消、内存或 XSS 处理正确。ESLint 可以发现规则问题,却不知道“这个请求是否能覆盖新搜索结果”。
生成代码应运行项目已有的类型检查、lint、格式检查和构建,并把新增依赖锁进正确的 lockfile。不要为了让 AI 代码通过而大面积关闭规则、加入 any 或删除测试;这通常只是隐藏了问题。
测试要覆盖失败和竞态,不只测成功截图
一个异步组件至少应测试:成功、HTTP 错误、格式错误、用户取消、快速切换输入、组件卸载后迟到响应、重复提交和空结果。对浏览器 API 还要测试不支持、权限拒绝和用户未激活等分支。
如果模型只生成了“点击按钮后显示成功”的测试,不能据此认为实现可靠。Mock 要匹配真实接口契约,关键流程还要有集成或端到端测试;视觉截图通过也不能证明键盘、读屏和网络失败正确。
依赖和许可证同样要审查
模型可能为了一个很小的功能引入一套大型库,或生成一个实际上不存在的包名。安装前应确认包的官方仓库、版本、维护状态、许可证、传递依赖和发布内容;执行安装脚本和构建脚本时还要考虑供应链风险。
“网上常见的代码”也可能复制了带限制的商业代码、过时的 polyfill 或包含不明许可证的片段。项目需要保留依赖变更记录,不要把模型引用来源当成许可证证明。
安全审查要关注模型特有的输入路径
如果 AI 根据 issue、网页、文档或用户提示生成代码,外部文本可能包含提示词注入,诱导模型关闭校验、泄露环境变量或添加恶意依赖。工具调用型代码还可能获得文件、终端或网络权限。
模型输出应先放在隔离分支或临时目录,限制可访问的文件和命令,禁止把秘密、生产令牌或完整私有数据直接放入提示。任何自动修改、执行测试或创建 Pull Request 的 Agent 都应有明确的工具权限、审批和日志。
人工审核不能只看功能是否通过
审查者要比较项目现有的状态管理、错误处理、无障碍、性能和安全约定,确认新代码没有引入一套风格和生命周期完全不同的做法。尤其要检查:
- Effect 或事件监听是否成对清理;
- 请求是否有过期结果和幂等处理;
- loading、空数据、错误和取消是否被区分;
- 受控组件、焦点和键盘操作是否保持一致;
- 是否把客户端配置误当成秘密;
- 是否扩大了 CSP、CORS、权限或文件访问范围。
AI 适合帮助探索实现和生成测试草稿,但最终合并依据应是需求、源码、验证结果和团队约束。只有“代码运行了”说明语法和一条路径成立;能够解释数据流、失败路径、权限和维护成本,才达到可合并的质量。