
说实话,写代码这件事,真正爽的部分其实没那么多。想清楚一个方案的架构、把一个藏得很深的 bug 揪出来、或者把某个接口的耗时从 800ms 压到 200ms——这些时刻是爽的。但现实是,我们每天绝大部分时间根本不在写这些"爽代码",而是在干一堆重复到想吐的活:一遍遍 review 同事提的 PR、维护那些永远对不上号的接口文档、给新人解释为什么这个字段不能叫 tmp。
这些活你说难吧,真不难;你说不重要吧,它又挺重要。难就难在它"耗人"——它不费脑子,纯费时间。所以当我发现 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 是"第一道筛子",不是"终审法官"。它把 80% 的机械问题挡掉,剩下的 20% 我自己看,这已经给我省了海量时间。
第二块是文档。我先问一句:有多少团队是"代码改完了、文档还停在三个月前"的?我们就是。接口文档和实际代码对不上号,联调的时候全靠猜,新同事入职看文档看得一脸懵,最后只能抓个老人问"这个字段到底啥意思"。
这事的根源很简单——文档是"额外"的工作,没有人天然愿意写。 你代码都写完测完了,谁还有劲去补文档?所以文档永远是滞后、残缺、过期的。
后来我想,既然 AI 能读懂代码,能不能让它来干这个"从代码反向生成文档"的活?
拿我们一个订单查询接口举例。代码里原来是有注解和类型定义的:
/**
* 查询订单详情
*/
@GetMapping("/api/order/{orderId}")
public ApiResponse<OrderDetail> 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 | 是否返回订单明细 |
**返回:** `ApiResponse<OrderDetail>`你让我手写,每个字段对着代码敲一遍,一个接口十分钟起步。AI 干这个,十秒钟。关键是它不会漏字段,人反而经常漏。
但光"生成一次"没用,文档要是不能跟着代码走,还是会过期。所以我把这块也接进了自动化流程,整个链路是这样的:

这样就把"人肉补文档"变成了"代码一变,文档自动跟着变"。我现在每次合并完代码,文档就自动更新一版,过期问题基本根治了。
说几个我自己趟过的坑,免得你们重复交学费:
a、b、flag 的旧代码,AI 只能瞎编语义,生成出来的文档比没有还害人。这种老代码,要么先补注释,要么干脆别生成。回头看,我做这事的核心其实不是"用 AI",而是把重复劳动拆解成"规则判断"和"逻辑判断"两层,然后把规则判断那一层果断外包。 代码评审是这样,文档生成也是这样。
说几个我这半年下来最实在的体会:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。