AI 实用 03|用 AI 写代码:一套能落地的流程

先说结论

AI 写代码的效果差异,几乎不在模型,而在**"你怎么给它任务、怎么验收"**。同一个模型,有人用得像个高级实习生,有人用出十年前的复制粘贴水平,区别在流程。

下面是这套流程,每一步都能单独用。

第一步:把需求拆到"一次能看清"

不要这样提:

帮我写一个用户管理系统的后端

这样提:

第一轮只做这个:
实现一个 HTTP 接口 POST /api/users,
输入 JSON:{"name": "string, 1-50 字符", "email": "string, 合法邮箱"}
输出:成功 {id, name, email},失败 {error, field}
约束:用 FastAPI + Pydantic,不接数据库,先用内存字典存。
不要写认证、日志、分页,这些后面再说。

判断标准:这个任务的正确性,你能不能在三分钟内验证完? 能,就拆对了。

第二步:先要接口,再要实现

对稍大的任务,让它先输出"骨架":

不要写实现。先给我:
1. 文件结构(每个文件负责什么)
2. 每个函数/类的签名(参数、返回类型)
3. 数据如何在模块之间流动

我确认后再写具体代码。

这样做的好处很实际:结构错了改起来只要一分钟,代码写完了发现结构错了要重写。AI 特别擅长"写得很完整但结构不合理",先用一轮把它按在结构上。

第三步:一次只让它改一个文件

大段代码一次性生成的常见问题:它自己编了不存在的函数、引用了没定义的变量、import 了不存在的模块。

只生成 src/services/parser.py 这一个文件。
它可以使用 src/models/schema.py 里已定义的 Document 类(见下面粘贴的代码)。
不要修改其他文件,如果需要新依赖,先告诉我。

把"它需要知道的已有代码"贴进去,比让它"猜"可靠得多。上下文不是越多越好,是越准越好——贴三个相关文件比贴整个仓库有效。

第四步:必须自己跑一遍

这条没有例外。AI 生成的代码,运行通过率远低于"看起来通过率"。

最小验证三件套:

1. 正常输入,输出对不对
2. 边界输入(空、超长、非法类型),有没有崩
3. 异常输入(网络失败、文件不存在),错误处理走没走对

如果它没给你测试,直接要:

为上面的代码写 5 个测试:2 个正常、2 个边界(空字符串、超长输入)、1 个异常(模拟数据库抛异常)。
用 pytest,不依赖外部服务。

一个真实的对比

需求:把 "2026-11-08" 解析成日期对象

AI 第一版给的:
datetime.strptime(s, "%Y-%m-%d")
—— 遇到 "2026-2-8" 直接抛异常

问题:输入格式没约束清楚。补一句"允许 2026-2-8 这种不带前导零的格式",
它才会想到用更宽松的解析或先做规范化。

大部分"AI 写得不对",本质是需求里有隐含假设没说出来。

第五步:审查——重点查五类问题

不用逐行看,按这五类扫:

1. 幻觉 API(最常见)

它可能编出一个"看起来很像"的方法:

# AI 可能写出
df.filter_by(column="age", value=18)      # 没有这个方法

处理方式:所有没见过的 API,去官方文档确认一遍。这是用 AI 写代码唯一不能省的动作。

2. 过时写法

模型的知识有截止时间,它可能给你:

  • 已经被弃用的库版本写法
  • 已改名的函数
  • 已停止维护的方案

处理方式:涉及"版本敏感"的部分(依赖、框架 API),让它标注版本,然后自己核。

3. 静默的错误处理

try:
    do_something()
except Exception:
    pass                      # ← AI 很爱写这个

它为了让代码"跑得通",会把异常吞掉。这在生产里是灾难——问题是没了,但你也不知道出过问题。

审查要求:except 里必须有日志或重新抛出。

4. 性能陷阱

# 循环里查数据库 —— AI 也常这么写
for user_id in user_ids:
    user = db.query(f"SELECT * FROM users WHERE id = {user_id}")

处理方式:看到"循环 + IO"(数据库、HTTP、文件)就警觉,要求改成批量。

5. 安全

  • SQL 拼接(不是参数化查询)
  • 用户输入直接拼进命令
  • 缺权限校验
  • 密钥硬编码

处理方式:涉及外部输入的代码,必须专门问一句:

这段代码里,哪些地方直接使用了外部输入?逐处列出,并说明如何防止注入/越权。

第六步:让它自己找问题

一个非常好用的收尾动作:

现在以"严格的代码审查者"身份审查上面这段代码,按严重程度列出问题:
- 会导致运行失败的
- 会导致数据错误的
- 会导致性能问题的
- 会导致安全问题的

每条给出具体行和修改建议。不要夸,只列问题。

模型在"找茬模式"下的表现,往往比"生成模式"更好——因为它不需要保证一致性,只需要挑毛病。这一步经常能自己抓出前面漏掉的 bug。

上下文管理的三条经验

  1. 给相关文件,不给整个项目。三个相关文件 + 一段说明,胜过全仓库。
  2. 长对话会变差。超过二三十轮,模型容易记混之前的设计。换任务就开新会话,把必要的结论复述一遍。
  3. 报错信息要原样贴。不要概括成"报错了",把完整堆栈贴进去,它定位问题的准确率会明显提高。

提示模板(可直接用)

【环境】
语言/版本:Python 3.12
依赖:仅标准库 + requests
运行:Linux 容器,无网络访问权限(除指定域名)

【任务】
在 src/ingest/fetch.py 中实现 fetch_pages(urls, concurrency=5):
- 并发抓取,最多 5 个并发
- 单个 URL 失败不影响其他(返回该 URL 的错误信息,不抛出)
- 超时 10 秒
- 返回 list[dict],每项 {url, status, body_len, error}

【约束】
- 完整可运行,不要省略号
- 用 urllib 或 requests,不要引入新依赖
- 类型注解写全
- 注释用中文,只解释"为什么这么做"

【验收】
给出 3 个测试:全成功、部分失败、全部超时(用 mock 模拟)。

【禁区】
不要加日志框架、不要写重试逻辑、不要改其他文件。

团队落地:让 AI 生成的代码可维护

三件事,团队规模超过三个人就该做:

  1. CI 必须跑:lint + 类型检查 + 测试。AI 生成的代码最容易在类型检查上翻车。
  2. review 规则写清楚:哪些位置禁止 AI 直接生成(鉴权、支付、加解密),必须人工逐行看。
  3. 提交信息里标出来:哪些是 AI 生成后修改的。不是为了追责,是为了让后来的人知道"这块可能没被充分理解"。

不要交给 AI 的部分

  • 安全边界的实现(认证、加解密、签名校验)
  • 涉及资金的逻辑(哪怕只是算个手续费)
  • 你不理解的技术方案。看不懂的代码进了仓库,就是未来的债。

用 AI 写代码的正确心态是:它能帮你把"想清楚的事"快速实现,但不能替你"想清楚"。判断和验收,永远是你的活。

一份 30 秒自检清单

在合入之前问自己:

  • 我完整读过这段代码吗?
  • 所有不熟悉的 API 我都核对过吗?
  • 正常/边界/异常三种输入都跑过吗?
  • 有没有 except: pass 这种吞异常?
  • 循环里有没有 IO 操作?
  • 有没有直接拼接外部输入?

六条都过,这段代码才算"能用"。