02 - 代码生成¶
代码生成这件事,真正难的从来不是“让模型吐出代码”,而是
让它吐出正确、可控、可验证、可维护的代码。这一章会把重心从“prompt 技巧”升级到Spec-to-Code的真实工作流。
这章解决什么问题¶
很多代码生成失败,不是因为模型不够强,而是因为输入不够工程化。
常见失败原因:
- 需求描述模糊
- 没有边界和 non-goals
- 没有上下文
- 没有测试标准
- 没有分步骤执行
所以,这一章真正要练的是:
- 如何写 spec
- 如何准备 context pack
- 如何拆 plan
- 如何要求 patch 和验证输出
学习目标¶
- 从“随手问一句”升级到“按规格生成代码”
- 学会为不同任务选择不同的生成策略
- 理解生成质量背后的决定因素
- 形成可复用的代码生成模板
代码生成的正确理解¶
代码生成不是一个点动作,而是一条链。
你能控制的关键环节,不是模型内部,而是前四步和后两步。
决定代码生成质量的 6 个变量¶
| 变量 | 说明 |
|---|---|
| 任务清晰度 | 目标是否可判定 |
| 上下文质量 | 是否给了最小充分上下文 |
| 约束完整度 | 是否明确了不能做什么 |
| 分解粒度 | 是一次全做,还是拆步骤 |
| 验收标准 | 如何判断完成 |
| 验证闭环 | 是否跑测试和审查 |
你可以把这 6 个变量看成“生成成功率控制杆”。
先学会写 spec,而不是先学会写 prompt¶
差的写法¶
好的写法¶
Markdown
目标:新增邮箱登录功能
范围:
- 登录接口
- 密码校验
- JWT 签发
- 登录失败提示
约束:
- 不修改数据库 schema
- 兼容旧用户名登录
- 不新增运行时依赖
验收:
- 邮箱/密码正确时登录成功
- 错误密码返回 401
- 锁定用户不可登录
- 现有测试不回归
有了 spec,prompt 只是表达形式,不再是核心问题。
4 类高频代码生成任务¶
真正值得长期训练的,不是“让 AI 写更多”,而是先认清哪些生成任务最稳定、最有收益。
1. 样板和脚手架生成¶
适合 AI 做:
- API 路由
- DTO / schema
- CRUD
- 配置文件
- Dockerfile / CI 配置
特点:
- 结构清晰
- 模式固定
- 规则明确
这是最适合让 AI 提速的部分。
2. 在现有仓库中增量开发¶
这才是更有现实价值的场景。
要求比脚手架高得多,因为它要:
- 读懂现有结构
- 保持风格一致
- 不破坏旧逻辑
- 补齐测试
这时最重要的不是 prompt 多华丽,而是 context 是否干净。
3. 缺陷修复¶
缺陷修复要点不是“直接改”,而是:
- 先定位
- 先复现
- 先补失败测试
- 再改实现
如果让 AI 直接改,很容易只修表象。
4. 重构与迁移¶
这是高风险任务。
必须明确:
- 哪些接口不能变
- 哪些目录可以动
- 哪些行为必须保持一致
否则 agent 会“顺手优化”出很多额外改动。
最值得复用的 4 个生成模板¶
如果你只保留一小套高质量模板,下面这 4 个的复用价值通常最高。
模板 1:新增功能¶
Markdown
你先不要写代码。
任务:为订单接口增加幂等控制
范围:`src/orders`、`tests/orders`
约束:
- 不修改 schema
- 不新增外部依赖
- 保持原有 API 兼容
请先输出:
1. 涉及文件
2. 改动计划
3. 测试方案
4. 风险点
确认后再继续:
模板 2:补测试¶
Markdown
请为 `src/recommend/ranker.ts` 补齐单元测试。
要求覆盖:
- 正常排序
- 空候选集
- score 为 null
- 超时 fallback
不要修改生产逻辑,除非测试证明存在明确缺陷。
模板 3:重构¶
Markdown
目标:将支付状态判断从 controller 提取到 service
不变:
- API 协议
- 数据结构
- 现有日志字段
允许修改:
- `src/controllers/payment.ts`
- `src/services/payment-status.ts`
- 对应测试
请先列计划,再小步修改。
模板 4:小型脚手架¶
Markdown
请使用 FastAPI 生成一个最小可用的用户资料接口。
要求:
- GET /profile
- PUT /profile
- Pydantic 校验
- pytest 测试
- 代码带类型注解
输出:
- 文件结构
- 核心代码
- 测试代码
上下文比提示词更重要¶
在中等以上任务里,context > prompt wording。
推荐的 context pack 结构¶
Markdown
## 任务
为搜索服务增加 rewrite 开关
## 相关文件
- `src/search/router.ts`
- `src/rewrite/service.ts`
- `src/config/search.ts`
- `tests/rewrite.test.ts`
## 当前行为
- rewrite 默认强制开启
- 空 query 会抛异常
## 约束
- 不改接口路径
- 兼容旧配置
- 不新增依赖
## 命令
- `pnpm test rewrite`
- `pnpm lint`
不要做的事¶
- 把整个仓库全塞进去
- 给大量无关文件
- 只说要做什么,不说不能做什么
- 不写测试命令
分步生成比一次生成更稳¶
推荐流程:
planpatchverify
为什么¶
- 先看它是否理解对
- 先看改动范围是否过大
- 先看测试策略是否靠谱
一次性全做的最大问题是:你很难知道它究竟错在理解、实现还是验证。
生成代码时必须写清楚的 5 件事¶
1. 输出范围¶
例如:
- 只改 3 个文件
- 只新增 service,不改 controller
- 只补测试,不动实现
2. 非目标¶
例如:
- 不做 UI
- 不改 schema
- 不做性能优化
3. 验收标准¶
例如:
- 测试通过
- 接口保持兼容
- 空值不再报错
4. 风险提醒¶
例如:
- 涉及缓存一致性
- 涉及旧配置兼容
- 涉及权限分支
5. 输出格式¶
例如:
- 先给计划
- 再给修改
- 最后给验证结果和风险摘要
生成结果如何判断能不能收¶
建议固定用这个 checklist:
- 逻辑是否正确
- 是否处理了边界情况
- 是否和现有代码风格一致
- 是否补了必要测试
- 是否引入不必要抽象
- 是否误改了不相关文件
如果这 6 项不看,代码生成再快也只是把 review 成本后移。
2028 面试里怎么讲代码生成能力¶
不要说:
更好的表达是:
Text Only
我把代码生成任务标准化成 spec、context pack、plan、patch、verify 五段式。
在复杂任务里先规划后执行,并要求测试门禁和风险摘要,减少了大范围误改和返工。
这样表达出来的不是“会用工具”,而是“懂工程”。
最容易踩的 5 个坑¶
1. 没有 spec 就直接生成¶
最常见,也最浪费时间。
2. 上下文过多¶
模型会失焦,反而改得更乱。
3. 一次性做完整需求¶
复杂任务最好按子步骤推进。
4. 没有验证命令¶
很多任务不是生成错,而是根本没验证。
5. 只收 happy path¶
必须看空值、超时、异常、旧逻辑兼容。
本章小结¶
- 代码生成的关键不是 prompt 花样,而是
spec + context + verify - 高质量生成任务应该分阶段进行,而不是一次梭哈
- 2028 更有价值的能力,是把代码生成纳入可控交付流程
下一步¶
- 继续看 03-代码审查
- 再看 05-测试生成
- 配合 08-AI协作开发方法论 形成完整工作流