AI Code Review:让每一行代码都有AI审查员

AI提效Android开发系列 · 第4/5篇

从需求到上线,用AI重塑Android开发全流程

第1篇:AI提效Android开发全景图:从需求到上线的AI工具链

第2篇:AI驱动需求梳理与Spec编写:让PRD自动变成技术方案

第3篇:AI编码提效实战:Skill、Rule与上下文工程

第4篇:AI Code Review:让每一行代码都有AI审查员(本篇)

⏳ 第5篇:AI Bug修复与测试生成:从崩溃日志到修复PR的自动化

我们团队有个不成文的规矩:每个 MR 至少要两个人 Review 才能合并。

规矩是好规矩。但实际情况呢?周五下午提的 MR,周一才有人看。一看就是 47 个文件变更,Review 的人打开第一个文件还在认真逐行看,到第三十个文件已经变成了"LGTM"机器人。更扎心的是,那些真正藏着 bug 的地方------竞态条件、内存泄漏、空指针隐患------往往就藏在第三十一个文件里。

这不是谁不负责任。这是人类注意力的物理限制。微软的研究数据说,超过 400 行 diff 之后,人类 reviewer 的缺陷发现率断崖式下降。而我们的日常 MR,哪个不是几百行起步。

上一篇我们聊了怎么用 Skill、Rule 和上下文工程让 AI 写出风格一致的代码。但写出来只是第一步------代码最终要过 Review 这一关。这一篇的核心问题是:AI 能不能帮你 Review 代码,以及怎么帮。

一、人工 Review 到底卡在哪

先别急着上 AI。我们得先搞清楚,人工 Code Review 到底哪里出了问题。

1.1 Review 疲劳

最大的问题就三个字:看不动。

Android 项目的 MR 有个特点:一个功能改下来,ViewModel、Repository、UseCase、Entity、DTO、Mapper、UI 层 Composable 文件、Navigation、DI Module......轻松十几个文件。如果涉及多模块重构,三四十个文件是家常便饭。

人类 Reviewer 的大脑不是为这种工作设计的。你让一个人连续高专注度阅读 800 行 Kotlin diff,他一定会经历三个阶段:认真看 → 快速扫 → 直接 Approve。我管这叫 "Review 三段式衰减"。

1.2 风格争论

Review 评论里,真正有价值的 bug 发现占多少?我翻了我们团队最近三个月的 MR 评论,做了个粗略统计:

• 命名和格式类问题:约 40%

• "建议换个写法"(但原写法也没错):约 25%

• 实际逻辑缺陷或潜在 bug:约 20%

• 架构和设计层面的讨论:约 15%

也就是说,超过一半的 Review 时间花在了风格争论上。"这个变量名不够清晰"、"这里应该用 also 不是 apply"、"缩进不对"------这些东西应该让 Lint 和格式化工具干,不应该占用人类 reviewer 的注意力预算。

1.3 漏检率

最致命的问题。人工 Review 对某些类型的 bug 天然不敏感:

• 跨文件的状态不一致:A 文件改了数据类字段,B 文件的序列化逻辑没跟着改

• 协程的竞态条件:两个 Flow collect 共享可变状态,Review 时肉眼很难追踪执行序列

• 内存泄漏:在 Activity/Fragment 的回调里持有了不该持有的引用

• Android 特有的生命周期问题:配置变更后 ViewModel 的状态恢复是否正确

这些 bug 的特点是:不看完整上下文就发现不了,而 diff 视图天然是"碎片化"的。人类 reviewer 看的是一个个改动的片段,AI 可以同时"看到"整个变更集。

二、AI Review 能做什么、不能做什么

明确一点:AI Review 不是来替代人工 Review 的,是来给人工 Review 减负的。

我把 AI Review 的能力分成三个区域:

2.1 AI 擅长发现的问题

• 空安全隐患 :Kotlin 的 !!、Java 互操作时的平台类型、as 强转

• 资源泄漏:Cursor/Stream/Connection 没在 finally 或 use{} 中关闭

• 线程安全:主线程做 IO、多协程共享非线程安全集合

• API 误用:deprecated API 调用、Context 类型混淆(Application vs Activity)

• 模式违反:不符合项目约定的代码组织方式(前提是你定义了 Rule)

• 性能陷阱:Composable 里创建新对象导致不必要的 recomposition

2.2 AI 容易误报的问题

• 业务逻辑正确性:AI 不了解"满减优惠只能叠加一次"这种业务规则

• "建议式"评论过多:它会告诉你"可以用 map 替代 forEach",但这在你的场景里可能完全没必要

• 跨仓库依赖:多仓库结构下 AI 看不到被调用方的实现

2.3 AI 发现不了的问题

• 产品逻辑是否正确:这个交互流程符合 PRD 吗?

• 架构合理性:这个功能放在这一层合适吗?

• 系统性设计缺陷:整体数据流设计有没有问题?

所以最佳分工是:AI 负责扫所有机械性的、模式匹配型的问题,人类 reviewer 把注意力集中在业务逻辑和架构设计上。

三、搭建 AI Review 流水线:从 Git Hook 到评论回写

说完理论,上干货。我来分享一套我们实际在用的 AI Review 流水线,从 MR 创建到 AI 评论自动出现在代码旁边,全流程大概 2-3 分钟。

3.1 整体架构

流程很简单,就四步:

• Step 1:开发者创建/更新 MR → 触发 Webhook

• Step 2:CI 获取 diff + 相关上下文文件

• Step 3:调用 LLM 进行 Review,附带项目规则(你的 CLAUDE.md 或等效规则)

• Step 4:将 Review 结果以 inline comment 形式回写到 MR

用代码画出来:

python 复制代码
# review_pipeline.py - 核心流程(简化版)
import subprocess, json, os
from pathlib import Path

def get_mr_diff(mr_iid: int) -> str:
    """从 GitLab/工蜂 API 获取 MR diff"""
    import requests
    api = os.environ["CI_API_V4_URL"]
    project = os.environ["CI_PROJECT_ID"]
    token = os.environ["REVIEW_BOT_TOKEN"]
    resp = requests.get(
        f"{api}/projects/{project}"
        f"/merge_requests/{mr_iid}/diffs",
        headers={"PRIVATE-TOKEN": token}
    )
    return resp.json()

def get_context_files(diff_files: list) -> dict:
    """根据 diff 涉及的文件,加载完整源码
    作为上下文(只加载被改动的文件)"""
    context = {}
    for f in diff_files:
        path = Path(f["new_path"])
        if path.exists() and path.suffix == ".kt":
            context[str(path)] = path.read_text()
    return context

def build_review_prompt(
    diff: str,
    context: dict,
    rules: str
) -> str:
    return f"""你是一个 Android 代码审查专家。
请严格按照以下项目规则审查代码变更。

## 项目规则
{rules}

## 变更的文件完整源码
{json.dumps(context, ensure_ascii=False)}

## Diff 内容
{diff}

## 审查要求
1. 只报告真正的问题,不要报风格偏好
2. 每个问题必须指明文件和行号
3. 按严重程度分类:
    必须修复(bug/崩溃/安全)
    建议修复(性能/可维护性)
    可选优化(更好的写法)
4. 输出 JSON 格式:
   [{{"file","line","severity",
     "message","suggestion"}}]
"""

这里有个关键细节:不要只给 AI 看 diff,要给它被修改文件的完整源码。只看 diff 的话 AI 缺少上下文,误报率会飙升。diff 告诉 AI "改了什么",完整文件告诉 AI "改的东西在什么环境里"。

3.2 Prompt 工程:让 AI 像你团队最严格的人

Review prompt 的质量直接决定 AI Review 是"有用"还是"烦人"。我踩过的坑分享几个:

坑 1:不给规则,AI 凭自己的"常识"Review

结果就是你会收到一堆"建议使用 LiveData 观察数据"之类的评论------你项目早就全面迁移 StateFlow 了。必须把项目的 CLAUDE.md / Cursor Rules 作为 prompt 的一部分喂给 AI。坑 2:让 AI 什么都报

一个 MR 回来 30 条评论,其中 25 条是"变量名可以更好"。开发者看两次就学会无视 AI Review 了。明确要求 AI 只报 bug 级和架构级问题,风格问题交给 ktlint/detekt。坑 3:不给严重程度分级

所有评论平铺,开发者不知道哪些必须改、哪些只是建议。加了红黄绿三级之后,开发者一眼就知道先看红色。

实际效果好的 prompt 有几个原则:

• 角色明确:你是 Android 代码审查专家,熟悉 Kotlin 协程和 Jetpack Compose

• 规则前置:项目编码规范全文放在 prompt 最前面

• 负面清单:明确列出"不要报什么"------不报格式、不报 import 顺序、不建议纯风格改动

• 输出结构化:要 JSON,不要散文,方便程序解析后回写到 MR

3.3 评论回写:让 Review 出现在该出现的地方

AI 的 Review 结果不能只输出到 CI 日志里------没人会去翻。必须以 inline comment 的形式出现在 MR 的 diff 视图里,和人类 reviewer 的评论一样。

python 复制代码
# post_review_comments.py
def post_inline_comment(
    project_id: int,
    mr_iid: int,
    file_path: str,
    line: int,
    message: str,
    severity: str
):
    """将 AI Review 结果以 inline
    comment 发到 MR"""
    emoji = {
        "critical": "",
        "warning":  "",
        "info":     ""
    }
    prefix = emoji.get(severity, "")
    requests.post(
        f"{api}/projects/{project_id}"
        f"/merge_requests/{mr_iid}"
        f"/discussions",
        headers={
            "PRIVATE-TOKEN": token
        },
        json={
            "body":
                f"{prefix} **AI Review**: "
                f"{message}",
            "position": {
                "position_type": "text",
                "new_path": file_path,
                "new_line": line,
                "base_sha": base,
                "head_sha": head,
                "start_sha": start,
            }
        }
    )

这样开发者打开 MR 时,AI 的审查意见直接标注在对应代码行旁边,体验和人类 reviewer 留言完全一致。

四、自定义检查规则:Android 项目的五个高频问题

通用 AI Review 工具(比如 CodeRabbit、Qodo)开箱即用,但它们不了解你的项目。真正好用的 AI Review 需要自定义规则。以下是我们在 Android 项目里沉淀的五类高频检查。

4.1 空指针 / 平台类型检查

Kotlin 号称空安全,但只要你和 Java 交互,空安全就是摆设。最典型的场景:调用 Android Framework API 返回的"平台类型"------编译器不报错,运行时直接 NPE。

kotlin 复制代码
// AI Review 规则:检测平台类型
// 风险赋值

//  这行不会编译报错,
// 但 getSystemService 可能返回 null
val manager = context
    .getSystemService(
        Context.CLIPBOARD_SERVICE
    ) as ClipboardManager
// 配置变更后 Context 可能无效

//  AI 应该建议改成
val manager = context
    .getSystemService(
        Context.CLIPBOARD_SERVICE
    ) as? ClipboardManager
    ?: return

在 Review prompt 里加一条规则就行:

csharp 复制代码
检查所有 `as` 强转和 Android Framework
API 返回值。如果返回类型可能为 null
(getSystemService、findViewByid、
getParcelableExtra 等),标记为 。

4.2 内存泄漏检测

Android 开发者的老朋友了。2026 年了,内存泄漏的花样还是层出不穷:

kotlin 复制代码
//  典型泄漏:匿名内部类持有
// Activity 引用
class ChatActivity : AppCompatActivity() {
    private val callback =
        object : WebSocket.Listener {
            override fun onMessage(
                text: String
            ) {
                // 这里隐式持有了
                // ChatActivity.this
                updateUI(text)
            }
        }
}

//  Compose 中的泄漏:在 remember
// 里捕获了 Activity context
@Composable
fun ChatScreen() {
    val context = LocalContext.current
    // context 是 Activity 实例
    val helper = remember {
        NetworkHelper(context)
        // 被 remember 缓存,Activity
        // 销毁后仍被引用
    }
}

AI Review 规则:

markdown 复制代码
检查以下模式并标记 :
1. 匿名内部类/lambda 在
   Activity/Fragment 中作为长期回调
2. remember {} 或 LaunchedEffect 中
   捕获了 Activity-scoped Context
3. 静态/companion object 持有
   View 或 Context 引用
4. 未在 onDestroy/DisposableEffect
   中取消的注册(BroadcastReceiver、
   LocationListener 等)

4.3 协程线程安全

Kotlin 协程让异步编程简单了,但也让写出竞态条件变得更隐蔽了。人工 Review 最容易漏的就是这类问题。

kotlin 复制代码
//  竞态条件:两个协程同时修改
// mutableList
class OrderViewModel : ViewModel() {
    private val pendingOrders =
        mutableListOf<Order>()

    fun loadOrders() {
        viewModelScope.launch {
            val remote = repo.fetchOrders()
            pendingOrders.addAll(remote)
            // 如果用户同时触发了刷新,
            // 两个协程同时 addAll
            // → ConcurrentModification
        }
    }
}

//  用 Mutex 或改用 StateFlow
private val _orders =
    MutableStateFlow<List<Order>>(
        emptyList()
    )

fun loadOrders() {
    viewModelScope.launch {
        val remote = repo.fetchOrders()
        _orders.update { current ->
            current + remote
        }
        // StateFlow.update 是原子操作
    }
}

这种问题人眼特别难发现------代码看起来完全正确,只有在高并发场景才会崩。但 AI 可以通过模式匹配轻松捕获:"在 viewModelScope.launch 里操作可变集合 → 标记"。

4.4 Compose 性能陷阱

Jetpack Compose 好用,但性能坑也多。最常见的是不必要的 recomposition:

kotlin 复制代码
//  每次 recomposition 都创建
// 新的 lambda 实例
@Composable
fun ProductList(
    products: List<Product>,
    viewModel: ProductViewModel
) {
    LazyColumn {
        items(products) { product ->
            ProductCard(
                product = product,
                onAddToCart = {
                    // 这个 lambda 每次
                    // recompose 都是新对象
                    viewModel
                      .addToCart(product.id)
                }
            )
        }
    }
}

//  用 remember 或提升到
// ViewModel 层
ProductCard(
    product = product,
    onAddToCart = remember(product.id) {
        { viewModel.addToCart(product.id) }
    }
)

AI Review 规则可以写得很具体:

kotlin 复制代码
Compose 性能检查(标记 ):
1. LazyColumn/LazyRow 的 items 中
   创建未 remember 的 lambda
2. Composable 参数传入了
   unstable 的类(没有 @Immutable
   或 @Stable 注解的 data class)
3. derivedStateOf 缺失导致
   频繁 recomposition
4. remember 的 key 参数缺失或
   使用了不稳定的 key

4.5 Kotlin 最佳实践

这类不是 bug,但是能让代码质量持续提升的检查:

kotlin 复制代码
Kotlin 最佳实践检查(标记 ):
1. 可以用 sealed interface
   替代 sealed class 的场景
2. 可以用 value class 包装
   原始类型提升类型安全
3. suspend 函数可以标记
   @Throws 给 Java 调用方
4. 可以用 buildList/buildMap
   替代 mutableListOf + add 模式

五、与 CI/CD 集成:MR 自动触发 + 人工复核

AI Review 的最终形态是集成到 CI/CD 里,开发者无需做任何额外操作。

5.1 CI 配置

以工蜂 CI(.gongfeng-ci.yml)为例:

yaml 复制代码
# .gongfeng-ci.yml
ai-review:
  stage: review
  image: python:3.12-slim
  rules:
    - if: '$CI_PIPELINE_SOURCE ==
          "merge_request_event"'
  script:
    - pip install requests anthropic
    - python scripts/ai_review.py
        --mr-iid $CI_MERGE_REQUEST_IID
        --rules-file CLAUDE.md
        --max-comments 10
        --min-severity warning
  variables:
    ANTHROPIC_API_KEY: $AI_REVIEW_KEY
    REVIEW_BOT_TOKEN: $REVIEW_TOKEN
  allow_failure: true

几个实践细节:

• --max-comments 10:限制评论数量,避免"评论洪水"

• --min-severity warning:只推送黄色和红色级别,绿色的静默写入 CI 日志

• allow_failure: true:AI Review 失败不阻塞 MR 合并

5.2 人机协作流程

最终的 Review 流程变成了这样:

• 第一轮(AI,2-3 分钟):AI 自动完成,标注空安全、内存泄漏、线程安全、Compose 性能等机械性问题

• 第二轮(人类 reviewer):先看 AI 标注的红色问题是否属实,然后把精力集中在业务逻辑、架构设计、边界情况

这里有个关键的心理学因素:AI Review 的存在反而提升了人类 Review 的质量。因为人类 reviewer 知道格式和空安全这些"基础项"AI 已经扫过了,他不需要再花精力在这些上面,可以全身心投入到更高阶的思考中。就像考试的时候,如果有人帮你检查了所有计算过程,你就能把精力放在解题思路上。

5.3 误报治理:反馈闭环

AI Review 一定会有误报。关键是建立反馈机制让它越来越准。

我们的做法是给 AI Review 评论加一个 误报 反应。每周跑一次脚本,把被标记误报的评论收集起来,分析 pattern,然后更新 prompt 中的"不要报什么"列表。

markdown 复制代码
# 第1周 prompt 新增
不要报以下场景:
- Hilt Module 中的 @Provides 函数
  参数未使用(这是 DI 框架的正常模式)
- Test 类中的 !! 操作符
  (测试代码允许 force unwrap)
- BuildConfig 字段的硬编码字符串
  (这些由 Gradle 在编译期注入)

几轮迭代下来,我们的 AI Review 误报率从最初的约 35% 降到了现在的 12% 左右。

六、实战数据:接入 AI Review 之后

我们团队接入 AI Review 四个月了,分享一些实际数据。

Review 时效:从提 MR 到第一条 Review 评论出现,之前平均 4.2 小时(等人),现在 2.8 分钟(AI 自动跑)。人类 reviewer 通常在 AI Review 完成后 1-2 小时内完成第二轮复核。整体 MR 合并周期从之前的 1.3 天缩短到 0.4 天。

缺陷发现:四个月里 AI 标记了 23 个 级问题,其中 19 个被确认为真正的 bug,准确率约 83%。这 19 个 bug 中有 7 个是人工 Review 大概率会漏掉的------3 个协程竞态、2 个 Compose 内存泄漏、2 个平台类型 NPE。

线上崩溃:接入前的月均 Crash Rate 是 0.18%,接入后四个月的月均 Crash Rate 降到了 0.11%。当然不能把所有功劳归给 AI Review,同期我们也做了其他优化。但 AI 捞出的那几个竞态条件 bug,如果上了线,每个至少影响几千用户。

团队反馈:开发者最大的感受是"Review 不再是负担了"。之前提完 MR 要催人 Review,reviewer 也觉得被打断。现在 AI 先扫一轮,reviewer 的工作量少了至少一半,而且看的都是有意思的问题(架构、逻辑),不用再纠结格式和命名。

七、工具选型参考

如果你不想从零搭建,2026 年有几个现成的 AI Review 工具值得看看:

工具 特点 适合场景
CodeRabbit GitHub/GitLab 原生集成,开箱即用 外网项目,快速上手
Qodo(原 CodiumAI) 支持自定义规则集,精度较高 对准确度有要求的团队
自建(Claude/GPT API) 完全可控,规则自定义 内网环境、特殊安全需求
GitHub Copilot Review 深度集成 GitHub,上下文感知强 纯 GitHub 工作流团队

我的建议是:如果在内网环境(比如用工蜂),自建是最靠谱的选择。上面分享的架构已经足够简单,一个 Python 脚本 + CI 配置就能跑起来。外网项目用 CodeRabbit 或 Copilot Review 省心。

八、落地建议

最后给想在团队里推 AI Review 的同学几个实操建议:

• 先跑 shadow mode:AI Review 结果先不推到 MR,只发到一个内部频道。观察两周,调好误报率再开放

• 从严重问题开始:第一版只检查 级问题(bug 和崩溃)。信任建立后再加 和

• 别让 AI 阻塞合并 :allow_failure: true 永远开着。AI Review 是辅助,不是门卫

• 持续喂规则:每次发现误报或漏报,都更新 prompt。AI Review 的质量 = prompt 质量 × 迭代次数

• 量化效果:跟踪 MR 合并时间、Crash Rate、Review 评论中有效 bug 占比。用数据说话,不用感觉

AI Code Review 不是银弹。它不能替代团队里经验丰富的 reviewer 对业务逻辑的把控,也不能替代架构师对系统设计的审视。但它能把"看得完"这件事变成现实------让每一行代码真的被审查过,而不是"应该被审查但实际上被 LGTM 了"。

下一篇我们聊系列最后一个环节:AI Bug 修复与测试生成------从一条崩溃日志到一个修复 PR,能不能全自动化?

AI提效Android开发系列 · 第4/5篇

从需求到上线,用AI重塑Android开发全流程

第1篇:AI提效Android开发全景图:从需求到上线的AI工具链

第2篇:AI驱动需求梳理与Spec编写:让PRD自动变成技术方案

第3篇:AI编码提效实战:Skill、Rule与上下文工程

第4篇:AI Code Review:让每一行代码都有AI审查员(本篇)

⏳ 第5篇:AI Bug修复与测试生成:从崩溃日志到修复PR的自动化

--- 技术博客 · 叶聪路 ---

相关推荐
三少爷的鞋8 小时前
AI 时代,我们都将成为通才型开发者:只懂 Android,已经不够了
android
Dovis(誓平步青云)12 小时前
家里设备越来越多,如何用一张空间地图控制灯光和温度![
android·java·前端·javascript·人工智能·电脑
晚风叙码14 小时前
MySQL 数据类型详解:从数值到字符串,一篇讲透
android·mysql·adb
传奇开心果编程14 小时前
【Compose Multiplatform 跨端开发学与练】第3课 布局与组件
android·windows·学习·ui·ios·kotlin·composer
传奇开心果编程17 小时前
【Compose Multiplatform 跨端开发学与练】第8课 资源管理与主题
android·windows·学习·ios·kotlin·web·composer
传奇开心果编程19 小时前
【Compose Multiplatform 跨端开发学与练】第9课 测试与调试
android·学习·macos·ios·kotlin·web·composer
传奇开心果编程19 小时前
【Compose Multiplatform 跨端开发学与练】第4课 导航与路由
android·windows·学习·ui·ios·kotlin·composer
传奇开心果编程19 小时前
【Compose Multiplatform 跨端开发学与练】第6课 状态管理与架构
android·学习·ui·ios·架构·kotlin·composer
事圆则缓19 小时前
Android AOSP 定制常见概念:源码目录、系统镜像与刷机流程
android
传奇开心果编程19 小时前
【Compose Multiplatform 跨端开发学与练】第2课 Compose 基础语法
android·windows·学习·ui·ios·kotlin·composer