程序员也有重复劳动:我让 AI 承包了代码评审和文档生成

发布时间:2026/9/5 8:24:09
程序员也有重复劳动:我让 AI 承包了代码评审和文档生成 说实话写代码这件事真正爽的部分其实没那么多。想清楚一个方案的架构、把一个藏得很深的 bug 揪出来、或者把某个接口的耗时从 800ms 压到 200ms——这些时刻是爽的。但现实是我们每天绝大部分时间根本不在写这些爽代码而是在干一堆重复到想吐的活一遍遍 review 同事提的 PR、维护那些永远对不上号的接口文档、给新人解释为什么这个字段不能叫 ​​tmp​​。这些活你说难吧真不难你说不重要吧它又挺重要。难就难在它耗人——它不费脑子纯费时间。所以当我发现 AI 其实能把这两块脏活接过去一大半的时候我的第一反应不是哇好厉害而是你怎么不早点来。这篇文章我就聊聊我是怎么把代码评审和文档生成这两件重复劳动逐步甩给 AI 的包括我踩过的坑、现在跑得比较顺的一套流程以及哪些地方我死活不敢让 AI 碰。一、代码评审让 AI 先跑第一轮我只看它漏掉的为什么是代码评审先说背景。我们团队小没有专职的 review 岗评审靠互相看。问题就来了一个 PR 动辄几百行里面一半是格式化改动、字段重命名这种机械性的东西。我 review 的时候脑子得先花十分钟把这堆噪音过滤掉才能开始看真正的业务逻辑。等看到第三个人的 PR 时耐心基本耗尽了。我后来想明白一件事review 这活其实可以拆成两层。一层是机械检查比如命名规范、空指针、资源没释放、明显的边界条件漏了——这些有明确规则不需要什么品味。另一层是逻辑判断比如这个方案是不是过度设计了、这个抽象放在这里合不合理——这些才是我该花心思的地方。第一层交给 AI 正合适。真实场景一个差点漏掉的空指针举一个我们真实踩过的例子。有个同事写了个从配置中心拉取服务地址的方法大概是这么个样子public String resolveServiceUrl(Config config) { String host config.getService().getHost(); int port config.getService().getPort(); return http:// host : port; }就这么十几行谁看都觉得没问题。但问题是我们的 ​​config.getService()​​ 在未配置场景下是会返回 ​​null​​ 的。线上就因为这个半夜告警响了一次。后来我把这段代码喂给 AI让它按我们的规范做一次 review它第一条就把这个问题点了出来【问题1】config.getService() 可能返回 null直接链式调用 getHost() 会抛 NPE。 建议先判空或使用 Optional并补充默认值兜底。当时我就一个感觉这种你明知道规则、但就是容易看走眼的问题AI 比人稳。因为它不会累也不会因为这个同事平时挺靠谱的就放过。我现在怎么跑这个流程我把整个评审流程重新搭了一下大概是这个走向核心思路就一句话让 AI 把规则类的问题在第一轮就过滤干净人只干判断类的活。具体落地我用了两种方式简单说下一种是直接把 diff 贴给 AI配一个固定的提示词模板。我把提示词调成了我们团队自己的规范让它只输出问题 位置 建议不要客套话。这个模板我贴出来你们可以参考着改你是团队的首席代码评审请按以下规则 review 这段 diff 1. 只指出确定的问题不要可能建议性的模糊表述 2. 优先级空指针/资源泄漏 并发安全 命名规范 代码风格 3. 每个问题给出位置文件:行 问题描述 修复建议 4. 没有把握的问题不要列宁可漏掉另一种是接进 CI用 AI 的 API 在 PR 创建后自动跑一遍把结果直接评论到 PR 上。第二种省事很多但有个前提——你的 AI 输出得足够干净不然评论区会被一堆废话刷屏。这块的边界哪里我坚决不撒手这里我得说句实在话AI 做 review 也不是万能的有几个地方我现在坚决不让它碰方案和设计层面的取舍。比如要不要引入一个中间层这个模块该不该拆这需要上下文和产品判断AI 给的意见经常看着有道理、实际上很飘。安全相关的关键路径。鉴权、支付、敏感数据处理这些AI 可能给你一个看起来对的改法但真正的问题在更深的语义里它抓不住。我们团队的隐性约定。有些东西是大家心照不宣的写在代码注释里反而没有AI 学不会。所以现在我的定位是AI 是第一道筛子不是终审法官。它把 80% 的机械问题挡掉剩下的 20% 我自己看这已经给我省了海量时间。二、文档生成从永远对不上号到自动同步文档的痛谁写谁知道第二块是文档。我先问一句有多少团队是代码改完了、文档还停在三个月前的我们就是。接口文档和实际代码对不上号联调的时候全靠猜新同事入职看文档看得一脸懵最后只能抓个老人问这个字段到底啥意思。这事的根源很简单——文档是额外的工作没有人天然愿意写。你代码都写完测完了谁还有劲去补文档所以文档永远是滞后、残缺、过期的。后来我想既然 AI 能读懂代码能不能让它来干这个从代码反向生成文档的活真实场景一个接口文档的自动生成拿我们一个订单查询接口举例。代码里原来是有注解和类型定义的/** * 查询订单详情 */ GetMapping(/api/order/{orderId}) public ApiResponseOrderDetail getOrderDetail( PathVariable(orderId) String orderId, RequestParam(value includeItems, defaultValue false) boolean includeItems) { return orderService.getOrderDetail(orderId, includeItems); }代码里的信息其实挺全的接口路径、参数名、参数类型、默认值、返回类型。缺的就是有人把这些信息翻译成给人看的文档。这个翻译AI 干得又快又准。我把整个类的代码喂给 AI配上一条提示词让它生成 Markdown 格式的接口文档几秒钟就出来这么一段## 查询订单详情 **接口地址** GET /api/order/{orderId} | 参数名 | 位置 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|------|--------|------| | orderId | path | String | 是 | - | 订单 ID | | includeItems | query | boolean | 否 | false | 是否返回订单明细 | **返回** ApiResponseOrderDetail你让我手写每个字段对着代码敲一遍一个接口十分钟起步。AI 干这个十秒钟。关键是它不会漏字段人反而经常漏。我用时序图梳理的完整流程但光生成一次没用文档要是不能跟着代码走还是会过期。所以我把这块也接进了自动化流程整个链路是这样的这样就把人肉补文档变成了代码一变文档自动跟着变。我现在每次合并完代码文档就自动更新一版过期问题基本根治了。文档这块也有坑我踩过的说几个我自己趟过的坑免得你们重复交学费AI 生成的描述太通用。它默认会写一些该字段用于 XXX这种废话得在提示词里逼它基于代码注释和真实语义来写写不出来的字段就明确标待补充别让它编。枚举和状态码容易翻车。这些业务含义 AI 光看代码是猜不准的我现在的做法是让它生成后标一个需人工确认的标记我再统一过一遍枚举含义。别让它碰那些没有注释的天书代码。变量全叫 ​​a​​、​​b​​、​​flag​​ 的旧代码AI 只能瞎编语义生成出来的文档比没有还害人。这种老代码要么先补注释要么干脆别生成。回头看我做这事的核心其实不是用 AI而是把重复劳动拆解成规则判断和逻辑判断两层然后把规则判断那一层果断外包。代码评审是这样文档生成也是这样。说几个我这半年下来最实在的体会AI 不是替你干活是替你把不值得人干的活干了。人该留在那些真正需要判断力、需要上下文的地方。提示词比模型重要。同样的 AI提示词写得清楚输出就干净能直接用写得含糊输出就是一堆正确的废话。我这块的提示词前前后后改了七八版。一定要留人工兜底。AI 是筛子不是法官。关键路径、安全、设计决策这些地方你撒手了迟早出事。别指望一步到位。我是先从review 跑第一轮开始试跑顺了才敢上文档自动同步。步子迈太大反而容易把流程搞乱。