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的自动化

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

相关推荐
程序员陆业聪2 小时前
AI Bug修复与测试生成:从崩溃日志到修复PR的自动化 | AI提效Android开发(5)
android
诸神黄昏EX2 小时前
Android Google Widevine
android
HealthScience4 小时前
【Bib 2026】基因最新综述(有什么任务、benchmark、代表性模型)
android·开发语言·kotlin
夏沫琅琊6 小时前
Android拨打电话技术文档
android·kotlin
a2591748032-随心所记6 小时前
android studio gradle快速编译配置
android·android studio
一块小土坷垃6 小时前
# 《电影猎手》观影伴侣:一款支持iOS/安卓/电视盒子的全平台影视工具“电影猎手”(附自用评价)
android·ios·电视盒子
敲代码的鱼哇8 小时前
发送短信/拨打电话/获取联系人能力 UTS 插件(cz-sms)
android·前端·ios·uni-app·安卓·harmonyos·鸿蒙
用户5052372099159 小时前
Android 13/14 通知权限与前台服务适配指南
android
用户5052372099159 小时前
Android 12 适配指南:SplashScreen API 与 PendingIntent 变更
android