Skip to main content

模块三:输出校验能力

快速判断 AI 输出是否正确

AI 写的代码"看起来对"和"真的对"之间可能隔着一个生产事故。五层校验金字塔(可运行性 / 规范性 / 类型 / 架构 / 业务)+ 2 分钟快速校验清单 + AI 自检技巧。

为什么校验能力不可或缺

AI 写代码有一个危险的特点:它输出的代码看起来总是很对。语法正确、结构清晰、甚至还有注释解释。但"看起来对"和"真的对"之间可能隔着一个生产事故。

AI 最常犯的错误类型:

  • 幻觉型错误:调用一个不存在的 API、引用一个不存在的包
  • 语义型错误:语法完美但逻辑相反(比如该用 === 写成了 !==
  • 遗漏型错误:主干逻辑对了,但遗漏了边界条件、错误处理、资源释放
  • 过时型错误:用了旧版 API 或已废弃的写法
  • 上下文冲突型错误:代码本身没问题,但和项目现有代码的风格、约定、架构不一致

你不需要逐行阅读 AI 的每一行输出,但你需要知道去哪里看、看什么

校验金字塔


/ \
/ 5 \ 业务逻辑正确性
/─────\ (最难验证,依赖领域知识)
/ 4 \ 架构一致性
/─────────\ (是否符合项目架构和模式)
/ 3 \ 类型安全性
/─────────────\ (TypeScript 编译能否通过)
/ 2 \ 代码规范性
/─────────────────\ (ESLint / Prettier 能否通过)
/ 1 \静态可运行性
/─────────────────────(语法正确,依赖存在,文件路径对)

从底向上校验——底层的问题用工具自动检测,顶层的问题靠你的判断力。


五层校验方法

第一层:静态可运行性(工具自动化)

检查项

  • 文件路径是否正确
  • import 的模块是否存在
  • 函数调用的参数类型和数量是否匹配
  • 是否引入了项目没有安装的依赖

方法

# TypeScript 编译检查(最有效的一步)
cd frontend && npx tsc --noEmit

# 如果项目有 build 命令
npm run build

这一步能抓住大部分"幻觉型错误"。

第二层:代码规范性(工具自动化)

检查项

  • 是否符合 ESLint 规则
  • 是否符合 Prettier 格式
  • 是否有未使用的变量/导入

方法

cd frontend && npx eslint src/**/*.{js,ts,jsx,tsx}
cd frontend && npx prettier --check src/**/*.{js,ts,jsx,tsx}

第三层:类型安全性(半自动)

检查项

  • TypeScript 类型是否正确(不是 any 万金油)
  • 泛型参数是否合理
  • 可选类型是否做了空值处理
  • 枚举值是否用了具名常量而非魔数

方法:读 AI 输出的类型声明部分,重点关注:

// 警惕这些信号:
data: any; // AI 偷懒用 any
result!.value(
// 非空断言可能掩盖真实的 null
data as SomeType,
); // 类型断言可能不安全

第四层:架构一致性(人工判断)

检查项

  • 是否符合项目现有模式(MobX store 的写法、组件的组织方式)
  • 新增的函数放在了正确的文件/模块中
  • 依赖方向是否正确(utils 不应该依赖 store)
  • 是否复用了已有的工具函数而非重新实现

方法

问自己一个问题:"如果这是团队成员提的 PR,我会在 Code Review 时指出什么?"

常见的架构违规:

  • 在组件中直接写业务逻辑(应该放 store)
  • 在 utils 中引用了具体的 store(循环依赖风险)
  • 新建了一个功能雷同的工具函数(项目里已经有了)
  • 没有更新 MobX store 的 makeObservable 装饰器声明

第五层:业务逻辑正确性(人工判断)

检查项

  • 核心逻辑是否正确(不只是"能跑",而是"跑得对")
  • 边界条件处理:空数组、null/undefined、极大极小值
  • 异步时序:竞态条件、Promise 链顺序
  • 资源管理:事件监听是否解绑、定时器是否清除、流是否关闭
  • 安全性:是否暴露了敏感信息、XSS 风险

方法

重点检查 AI 代码中这些高风险区域:

// 1. 资源释放 —— AI 经常忘记
useEffect(() => {
const timer = setInterval(...);
return () => clearInterval(timer); // AI 是否写了清理函数?
}, []);

// 2. 异步竞态 —— AI 很少主动处理
useEffect(() => {
let cancelled = false; // AI 是否处理了组件卸载后的异步回调?
fetchData().then(data => {
if (!cancelled) setState(data);
});
return () => { cancelled = true; };
}, []);

// 3. 空值保护 —— AI 常假设数据一定存在
const name = data.user.profile.name; // 如果 user 或 profile 是 undefined?

// 4. 事件监听清理 —— AI 经常注册但不清理
window.addEventListener("resize", handler);
// 组件卸载时是否 removeEventListener?

快速校验清单

拿到 AI 输出后,按这个顺序过一遍(2分钟内完成):

□ 1. import 了哪些东西?有没有项目中不存在的包?
□ 2. 新增/修改的函数签名对不对?参数类型和返回值类型?
□ 3. 跑一遍 tsc --noEmit 和 eslint
□ 4. 有没有 any / as / ! 这些"偷懒"写法?
□ 5. 如果改了 MobX store,makeObservable 里更新了吗?
□ 6. 有没有新增 useEffect?清理函数写了吗?
□ 7. 有没有新增事件监听?解绑了吗?
□ 8. 有没有新增定时器?清除了吗?
□ 9. 核心逻辑的 if/else 分支,每个分支都合理吗?
□ 10. 整体风格跟周围代码一致吗?

让 AI 自检

一个强大的技巧:让 AI 审查自己刚写的代码。

你刚才写的代码,帮我 review 一下:
1. 有没有边界条件没处理
2. 有没有资源泄漏(事件监听、定时器、流)
3. 类型安全性如何
4. 和项目现有代码风格一致吗

AI 在 "review 模式"下比"写代码模式"更严格——因为 review 不需要创造,只需要挑错,这是 AI 更擅长的任务。


反模式 vs 正确做法

反模式一:看一眼就接受

AI 输出 50 行代码,你扫一眼"看起来差不多"就全盘接受。

正确做法:至少跑 tsc 和 eslint,重点看 import、类型声明、资源清理三个区域。

反模式二:逐行通读

200 行输出逐行阅读,费时费力。

正确做法:用校验金字塔——先用工具过前两层,人工只聚焦后三层。
重点看"高风险区域"(异步、资源管理、边界条件)。

反模式三:只在本地验证不考虑集成

代码在本地跑通了就行?

正确做法:想一下这段代码合入后对其他模块的影响。
比如改了 store 的某个 observable,
所有使用这个 observable 的组件都会受影响。

实战练习

练习 1:找 Bug 训练

让 AI 帮你写一个带有 useEffect 的组件(比如"窗口 resize 时更新图表尺寸")。拿到输出后,不运行,先自己找出所有潜在问题。然后跑 lint 和 tsc 验证你的判断。

练习 2:校验计时

在你下一次使用 AI 写代码时,计时你从"拿到输出"到"确认可以接受"花了多久。目标:对于 50 行以内的代码变更,校验时间控制在 3 分钟以内。

练习 3:AI 自检实验

让 AI 写一段中等复杂度的代码(比如"实现一个带防抖的搜索输入框"),然后在同一个对话中让 AI review 自己的代码。记录:

  • AI 自检发现了多少问题?
  • 你自己还能发现多少 AI 没提到的问题?
  • AI 自检 + 你的补充 vs 你独立 review,哪个更全面?

练习 4:构建自动化校验流水线

在你的项目中设置一套命令,让你一键完成前两层校验:

# 在 package.json scripts 中加一个 check 命令
"check": "tsc --noEmit && eslint src/**/*.{js,ts,jsx,tsx}"

然后在 .trae/rules/project_rules.md 中注明:"每次修改代码后运行 npm run check"。


思考题

  1. 信任校准:你对 AI 不同类型输出的信任度应该不同。排序一下:生成工具函数、生成 React 组件、修改现有业务逻辑、修改构建配置、修改数据库 schema——从最可信到最不可信,为什么?

  2. review 的收益递减:校验粒度越细花的时间越多。存不存在一个"最优校验深度"——超过这个深度,花的时间多但额外发现的问题极少?你怎么判断这个临界点?

  3. 测试作为校验:有人说"写测试就是最好的校验"。你怎么看?让 AI 写代码 + AI 写测试,能不能替代人工 review?如果测试本身也有 bug 呢?

  4. 架构违规的长期代价:前三层校验(语法、规范、类型)都能用工具自动化,但第四层(架构一致性)只能靠人。如果团队长期不做架构层面的 review,会发生什么?

  5. 校验能力和编码能力的关系:有一种说法是"AI 时代,review 代码的能力比写代码的能力更重要"。你同意吗?一个不会写代码但很会 review 的人,能在 AI 时代生存吗?