编码阶段往往是团队最先感受到 AI 价值的地方,因为模型可以非常快地生成样板代码、条件分支和异常处理。但也正因为它生成得快、补得多,编码阶段也是最容易把控制器、服务、底层依赖和异常语义写乱的阶段。这一课的重点,不是禁止 AI 写代码,而是学会把它约束在正确颗粒度里。
真实研发场景
AI 最容易在“快写完了”的错觉里越界
一个很常见的场景是:你只是想让 AI 帮忙补一个业务方法,它却顺手把 Controller、Service、DTO、异常处理甚至 SQL 一起写了。表面上看,进度飞快;实际上,真正的职责边界已经被打散了。Controller 开始做参数转换和业务分支判断,Service 顺手组装响应对象,底层调用和权限判断混在一起,最后你虽然“有代码了”,却很难安全地评审和维护。
这种情况的根源,不是 AI 不会写代码,而是工程师没有先告诉它:这一步的输入输出是什么、不该做什么、边界在哪。
编码阶段真正需要的是“受约束的生成”
AI 写代码最稳的用法通常不是“补整个功能”,而是:
- 在明确方法契约后补局部实现
- 在已有分层规则下补重复逻辑
- 在已有测试或行为描述下补分支
- 在已有异常语义下补校验与错误处理
也就是说,编码阶段的核心不是放权,而是约束。
传统做法的痛点
代码返工很多时候不是逻辑错,而是职责错位
| 常见现象 | 表面问题 | 更深层的问题 |
|---|---|---|
| Controller 很胖 | 代码难看 | 边界不清,接口层承担了业务决策 |
| Service 什么都做 | 可读性差 | 后续测试和重构无法分层验证 |
| 异常处理到处复制 | 维护麻烦 | 团队没有统一错误语义 |
| AI 一次生成很多代码 | 看似高效 | 每一层都缺人工边界收口 |
如果不先控制职责范围,AI 只会把“混写”放大。
最典型的三个编码误区
- 直接让 AI “把整个功能补完”
- 没有先写清方法的输入、输出和非目标
- 只验证运行结果,不验证代码边界和可维护性
AI 能提效到哪一步
适合直接让 AI 参与的编码动作
- 样板代码生成:例如参数映射、简单分支、重复组装逻辑
- 局部实现补齐:已有方法签名和职责说明下补主流程
- 校验和异常分支草稿:前提是错误语义已经定了
- 测试辅助下的修补:先有失败用例,再补实现
不适合直接放给 AI 的动作
| 动作 | 原因 |
|---|---|
| 同时生成多层代码 | 模型会擅自跨层补全职责 |
| 设计新的分层规则 | 涉及长期维护和团队约定 |
| 决定异常体系 | 影响接口契约和调用方行为 |
| 推导隐含业务规则 | 没有上下文时极易脑补 |
一个简单判断是:如果你还说不清“这段代码不该做什么”,就不该让 AI 先生成。
推荐工作流
先写职责说明,再让 AI 补实现
在编码前,先把下面这几件事写清楚:
- 方法输入是什么
- 方法输出是什么
- 它依赖哪些已有服务或对象
- 哪些职责明确不该放进来
- 用什么测试或最小用例验证
一个适合编码阶段的最小模板
目标方法:
输入:
输出:
已有依赖:
必须遵守的分层规则:
这段代码不应该做什么:
验证方式:
五步边界守护法
| 步骤 | AI 产出 | 人工要做什么 | 验证方式 |
|---|---|---|---|
| 1. 重写职责 | 方法契约草稿 | 删掉模糊职责 | 是否能一句话说清该方法作用 |
| 2. 限定颗粒度 | 单个方法或单层代码 | 拒绝“一口气补全全链路” | 输出是否只落在约定层级 |
| 3. 边界审查 | 局部实现草稿 | 检查 Controller / Service / 底层是否串味 | 代码评审 |
| 4. 行为验证 | 测试草稿或最小调用样例 | 补关键分支 | 测试或手工调用 |
| 5. 结构收敛 | 命名、异常、返回值调整 | 保持风格统一 | diff 审查 |
与仓库代码和模板的映射
- 控制器边界:
../demo/src/main/java/com/example/ainative/chat/controller/ChatController.java适合观察接口层应该主要承担哪些职责。 - 服务边界:
../demo/src/main/java/com/example/ainative/chat/service/ChatService.java适合讨论什么属于服务层的核心逻辑。 - 只读边界示例:
../demo/src/main/java/com/example/ainative/dataassistant/controller/SqlAssistantController.java适合练习“哪些校验必须在入口就挡住”。 - 注册与执行边界:
../demo/src/main/java/com/example/ainative/agent/tool/ToolRegistry.java适合讨论职责清晰的组件为什么更适合 AI 参与局部实现。 - 对应练习:
../课后练习/第4课/练习.md
常见误用与风险
误用一:直接让 AI “补完整个功能”
这类要求最容易让模型跨层补全,最后得到一段运行可能没问题、但职责边界彻底混乱的代码。
误用二:只看运行结果,不看分层是否串味
代码能跑不代表代码是可维护的,尤其在后端项目里,坏边界会持续制造成本。
误用三:没有测试或最小样例就开始补实现
没有验证锚点时,你很难判断是逻辑错了还是边界错了。
误用四:把 AI 生成的命名、异常和返回结构原样收下
这些细节最容易暴露团队风格是否一致,也最需要人工收敛。
课后练习
建议直接在 ../课后练习/第4课/练习.md 中完成本课练习,并使用 ../课后练习/通用提交模板.md 保留 AI 输入、人工删改和验证结果。
如果你只做最小版交付,也至少保留四样东西:结构化输入、AI 产出摘要、人工判断记录、最终验证结果。
基础题
选一个你熟悉的 Service 方法,先只写职责说明和非目标,不急着写实现。
进阶题
让 AI 在该职责说明下生成一版局部实现,然后人工列出 3 个边界审查点。
挑战题
补一条覆盖主分支行为的测试,证明收敛后的实现既能工作,也没有跨层串味。