Skip to content

AI 辅助编码工作流 ​

AI 编码工具让写代码快了很多,但也带来了一类新的问题:

  • 生成的代码调用了一个看起来很合理、实际上并不存在的方法;
  • 安装了 AI 推荐的一个依赖包,后来发现那个包名是别人抢注的恶意包;
  • 代码能编译、测试也通过了,上线后才发现逻辑是错的——因为测试也是 AI 写的,和实现错在了同一个地方;
  • AI 顺手“清理”了一段看起来多余的代码,那段代码其实是为了修复一个历史 bug。

用好 AI 编码工具的关键,不在于工具有多强,而在于给它什么任务、给它什么上下文、怎样验证它的产出。

读完这篇你会

  • 判断哪些任务适合交给 AI,哪些需要格外谨慎
  • 给出足够的上下文,用“小步改动 + 立即验证”的节奏协作
  • 识别并避免 AI 生成代码中最常见的几类问题

1. 原理:一位读过海量代码、第一天来你们项目的实习生 ​

可以把 AI 编码助手想成一位特别的实习生:

  • 他读过海量的开源代码,常见的写法、框架的用法张口就来,写得又快又工整;
  • 但他今天第一天来你们项目,不知道你们的业务规则、历史决策、团队约定,也不知道某段奇怪的代码背后有什么故事;
  • 他从不说“我不确定”,总能给出一个看起来很像样的答案。

所以 AI 生成的代码有一个典型特征:看起来是对的。结构合理、命名规范、有注释,但可能在边界条件、权限检查、错误处理这些细节上出错,而这些恰恰是 bug 最常出现的地方。

适合交给 AI需要人重点把关
样板代码、重复性的增删改查、脚手架理解项目里隐含的约定和历史决策
解释报错、查找 API 用法精确的边界条件和并发安全
测试草稿、类型定义复杂业务规则的准确性
按已有模式迁移、重构判断一段代码是否真的应该存在

2. 上下文决定质量 ​

AI 的输出质量,很大程度上取决于它看到了什么:

text
❌ 帮我写个登录功能。

✅ 这是一个 Vue 3 + TypeScript 项目,用 Pinia 管理状态,请求统一走 src/api/http.ts。
   需要实现登录:调用 POST /api/auth/login,返回 { token, user }。
   登录成功后把用户信息存入 useUserStore,401 时跳转登录页。
   请参照 src/api/user.ts 的写法新增 src/api/auth.ts,不要修改 http.ts。
   相关文件已附上。
  • 提供相关文件:要修改的文件、它依赖的类型和接口、项目里类似功能的已有实现;
  • 说清约束:用什么框架和写法、哪些文件不能动、错误怎么处理;
  • 给出参照:“照着某个现有文件的写法来”比用文字描述风格更准确;
  • 把反复出现的约定写进项目文档:比如“请求必须走统一的请求层”“状态管理只用 Pinia”。很多 AI 工具支持读取项目级的约定文件,写清楚后就不用每次重复纠正。

3. 小步改动,立即验证 ​

不要让 AI 一次生成一整个大功能。几百行的生成结果,你能看出明显的错误,却很难确认每一处细节都对。

text
① 先让 AI 说明它的方案(改哪些文件、怎么改),人确认方向
② 一次只改一小块,比如先写类型和接口定义
③ 立刻运行类型检查、lint 和相关测试
④ 自己看一遍 diff,确认改动范围和内容
⑤ 提交,再进行下一步

每一步都验证后再继续,比一次性生成再去排查错误高效得多。

4. 坑一:调用了不存在的 API,安装了不存在的包 ​

现象:AI 生成的代码调用了 dayjs().isBusinessDay(),运行时报 is not a function;或者 AI 推荐安装 vue-easy-table-pro 这样一个“很合理”的包名。

原因:模型根据“看起来最合理”的模式生成代码,会编造出名字合理但实际不存在的方法、参数和包名。

风险:编造的方法只是运行报错;编造的包名更危险——有人专门观察 AI 常编造的包名,抢先注册同名的恶意包。照着 AI 的建议安装,就把恶意代码引进了项目。

修复:

  • 不熟悉的 API,查官方文档确认它存在、用法正确;
  • 安装任何新依赖前,在包管理平台上核实:包名拼写、维护者、下载量、最近更新时间、源码仓库;
  • 能用已有依赖或几行代码解决的,不要引入新包。

5. 坑二:能编译、能运行,但逻辑是错的 ​

现象:AI 写的分页函数在大部分情况下都正常,但最后一页数据不满一页时会多显示一条空数据;优惠计算在几种券叠加时金额算错了。

原因:AI 熟悉常见情况的写法,但对你的业务边界没有概念。“能运行”只说明没有语法和类型错误。

修复:

  • 让 AI 写代码之前,先自己列出边界情况:空数据、只有一条、刚好整页、最后一页不满、重复提交、超时;
  • 用这些边界情况去测试,而不只是运行一下正常流程;
  • 关键逻辑自己逐行读一遍,如果你无法解释这段代码为什么是对的,就不要保留它。

6. 坑三:测试也是 AI 写的,和实现错在了同一个地方 ​

现象:AI 写了实现,又写了测试,测试全部通过。上线后发现逻辑有错,再看测试:测试的期望值就是照着错误的实现写的。

原因:如果让 AI 根据实现代码生成测试,它会忠实地把实现的行为(包括错误的行为)写成“期望结果”。这样的测试只能证明“代码和它自己一致”。

修复:

  • 测试的期望值来自需求,而不是来自实现:先根据需求写出(或让 AI 根据需求写出)测试用例,再写实现;
  • 人工审查测试的期望值是否符合业务规则;
  • 先确认测试在“错误的实现”下会失败(比如故意改错一处),证明测试真的能发现问题。

7. 坑四:AI 删掉了一段“多余”的代码 ​

现象:让 AI 重构一个函数,它把一段看起来多余的判断删掉了,代码变得更简洁。上线后,一个半年前修复过的 bug 又出现了。

原因:那段“奇怪”的代码是为了处理某个特殊情况而加的,AI 不知道这段历史。

修复:

  • 删除或大幅改写代码前,先用 git log -p 或 git blame 看看这段代码是什么时候、为什么加的;
  • 重要的修复要配回归测试(见 测试分层与回归保护),这样被误删时测试会立刻失败;
  • 写代码时,给“看起来奇怪但必要”的逻辑加上注释,说明原因。

8. 坑五:改动范围失控 ​

现象:只是让 AI 修一个按钮的样式,它顺手改了十几个文件:调整了格式、重命名了变量、“优化”了几个函数。diff 很大,没人能认真审查。

修复:

  • 在任务描述里明确范围:“只修改 X 文件,不要改动其他文件,不要做格式调整”;
  • 每一步都看 git diff,发现超出范围的改动就撤回;
  • 一个提交只做一件事,格式化、重构和功能修改分开提交(见 Git 协作与提交边界)。

9. 坑六:把密钥和客户数据贴给了 AI ​

现象:为了让 AI 帮忙排查问题,直接把带数据库密码的配置文件、带客户手机号的日志贴进了对话。

风险:这些内容会被发送到 AI 服务商,可能被记录、保存,违反公司的安全规定和数据保护法规。

修复:

  • 发送前删除或替换密钥、令牌、个人信息,用假数据复现问题;
  • 了解并遵守所在团队关于 AI 工具的使用规定:哪些工具可以用、哪些代码和数据可以发送;
  • 密钥不要放在代码和配置文件里(见 环境与配置管理),从源头上减少误发的可能。

10. 这些任务要格外谨慎 ​

任务风险做法
鉴权、支付、数据迁移一个细节错误就是事故AI 可以起草,人必须逐行审查并充分测试
删除和大规模重写丢失隐含的历史修复先查历史,先补测试
性能敏感的代码AI 倾向写“清晰”而不是“高效”的代码用性能测试验证
依赖隐含业务规则的代码规则不在代码里,在人脑子里由熟悉业务的人确认

排查思路:怎样审查 AI 生成的代码 ​

  1. 看范围:git diff --stat 看改了哪些文件,有没有超出任务范围的改动。
  2. 看依赖:有没有新增依赖,每个新依赖都核实过吗?
  3. 跑检查:类型检查、lint、测试全部通过;再用边界情况手动验证。
  4. 逐行读关键逻辑:特别是条件判断、循环边界、错误处理、权限检查。看不懂的地方,让 AI 解释,或者自己重写到能理解为止。
  5. 对照文档:不熟悉的 API 调用,去官方文档确认。

检查清单 ​

  • [ ] 任务描述包含了相关文件、约束和参照
  • [ ] 小步改动,每一步都运行检查并查看 diff
  • [ ] 新增的 API 调用和依赖包都经过核实
  • [ ] 测试的期望值来自需求,并确认测试能发现错误
  • [ ] 删除旧代码前查过它的历史
  • [ ] 改动范围符合任务要求
  • [ ] 发送给 AI 的内容里没有密钥和个人信息
  • [ ] 我能解释合并进来的每一段关键逻辑

延伸阅读 ​

为复用而记录,为理解而整理。