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的自动化
--- 技术博客 · 叶聪路 ---