Android工程师的AI开发实战系列 · 第4/4篇(完结篇)

用Android思维理解RAG、Agent和微调,从移动端老兵到AI开发者的跨界之路

第1篇:RAG:给大模型装一个靠谱的「本地数据库」

第2篇:Agent智能体:让AI自己调API干活

第3篇:微调:让通用大模型变成你的「专属定制ROM」

第4篇:RAG+Agent+微调组合拳(本篇·完结)

上周五下午四点半,我跑了一个小时的Lint检查,日志里哗哗往外喷Warning,我盯着屏幕想:要是有个AI助手能帮我查文档、跑命令、还能按团队代码风格给建议,那该多爽?

这不是幻想。经过前三篇的铺垫——RAG让大模型能查知识、Agent让大模型能动手干活、微调让大模型懂你的风格——今天我们把三块拼图合到一起,搭一个真正能用的AI Android开发助手。

说实话,单用任何一个技术都有明显短板。就像你不可能只用Activity写出一个复杂App——你需要Fragment管UI、Service跑后台、BroadcastReceiver响应事件。RAG、Agent、微调各司其职,组合起来才是完整能力。

为什么必须组合?单一技术的天花板

先快速回顾一下各自的能力边界:

技术 擅长 短板
RAG 查知识、引用文档 只能读,不能动手
Agent 调工具、执行操作 没有领域知识沉淀
微调 风格统一、领域精准 知识冻结、不会用工具

想象一个场景:你问AI助手「我们项目里怎么处理Token过期刷新的?」

纯RAG:能从文档里找到Token刷新的相关代码,但给的建议可能和你们团队风格不一致。纯Agent:能帮你搜代码、跑命令,但它不知道该搜什么关键词、该去哪个模块找。纯微调:风格对味了,但知识可能过时——上个月才改的刷新策略它不知道。

组合起来就不一样了:RAG从最新代码库检索出Token刷新的实现;Agent调grep/git log拿到变更历史;微调后的模型用团队风格组织回答。这才是一个靠谱的回答链路。

架构设计:用MVVM思维理解三层融合

做Android的都熟悉MVVM三层分离。巧的是,RAG+Agent+微调的组合恰好可以用这个框架类比:

用户提问

微调模型(View层·表现)

作用 → 理解意图、统一输出风格、团队用语

Agent(ViewModel层·逻辑)

作用 → 编排工具调用、决策执行路径

RAG(Model层·数据)

作用 → 提供知识检索、文档引用、代码搜索

输出回答

这个类比不只是方便理解——它还指导了我的实现策略:就像MVVM里ViewModel不直接操作View、Model不关心展示逻辑一样,三个模块的职责要清晰隔离,通过接口通信。

实战项目:AI Android开发助手

别光说理论,我们来真的。目标:搭一个能在日常开发中实际派上用场的AI助手。它要能:

• 查官方文档和项目Wiki(RAG)

• 执行Gradle命令、跑Lint、搜代码(Agent)

• 用团队代码风格给出建议(微调)

知识库搭建:三种数据源的RAG索引

知识库是地基。我的方案是分三层建索引:

第一层:Android官方文档。把developer.android.com的核心文档抓下来做chunk,每个chunk 512 token,overlap 64。重点索引API Reference、Architecture Guide、Performance部分。

第二层:项目Wiki和技术设计文档。从Confluence/飞书/企业微信文档导出Markdown,同样切片入库。这部分是团队私有知识,价值最高。

第三层:项目源码和Git历史。这个最tricky——不是把整个代码库塞进去,而是索引函数签名、类声明、关键注释。配合git log里的commit message做关联检索。

// 知识库索引构建配置
data class IndexConfig(
    val sources: List<
        DataSource>,
    val chunkSize: Int =
        512,
    val overlap: Int =
        64,
    val embedding: String =
        "text-embedding-3-small"
)

sealed class DataSource {
    data class OfficialDocs(
        val baseUrl: String,
        val sections: List<
            String>
    ) : DataSource()

    data class ProjectWiki(
        val exportPath: String,
        val format: String =
            "markdown"
    ) : DataSource()

    data class SourceCode(
        val repoPath: String,
        val includeGitLog:
            Boolean = true,
        val indexLevel:
            IndexLevel =
            IndexLevel.SIGNATURE
    ) : DataSource()
}

踩坑提醒:源码索引千万别用全量文本。一个中型Android项目动不动几十万行代码,全塞进向量库不仅慢,而且检索精度反而下降。只索引「声明级」信息(函数签名+docstring+关键注释),细节靠Agent实时grep。

工具集设计:Agent的Function Calling武器库

Agent需要工具才能干活。就像Android里的Intent能启动各种组件一样,我们给Agent设计一组工具接口:

val tools = listOf(
    // 代码搜索
    Tool(
        name = "search_code",
        desc = "在项目中搜索代码",
        params = mapOf(
            "query" to
                "搜索关键词",
            "file_pattern" to
                "文件过滤,如*.kt"
        )
    ),
    // Gradle命令
    Tool(
        name = "run_gradle",
        desc = "执行Gradle任务",
        params = mapOf(
            "task" to
                "任务名如:app:lint",
            "args" to
                "额外参数"
        )
    ),
    // Lint检查
    Tool(
        name = "run_lint",
        desc = "对指定模块跑Lint",
        params = mapOf(
            "module" to
                "模块路径"
        )
    ),
    // Git操作
    Tool(
        name = "git_log",
        desc = "查看Git提交历史",
        params = mapOf(
            "path" to
                "文件或目录路径",
            "count" to
                "条数,默认10"
        )
    ),
    // 文件读取
    Tool(
        name = "read_file",
        desc = "读取文件内容",
        params = mapOf(
            "path" to
                "文件路径",
            "lines" to
                "行范围如1-50"
        )
    )
)

关键设计决策:工具粒度要适中。太粗(一个"执行任意shell命令")会让模型乱来;太细(每个gradle task单独一个工具)会让工具列表爆炸。我的原则是:每个工具对应一个你会在Terminal里执行的命令类别

微调数据集:从团队历史中挖金矿

微调的目标是让模型「说话像我们团队的人」。数据从哪来?三个金矿:

1. Code Review记录。每条CR评论天然就是一对 (代码context, 审查建议),直接转成instruction-response格式。质量极高,因为都是高级工程师写的。

2. 技术群聊中的Q&A。从IM记录里提取「有人问问题→有人给出好答案」的对话对。需要人工筛选,但量不用太大,500-1000条就有明显效果。

3. 好的Commit Message和PR描述。这些反映了团队的表达习惯和技术用语。

// 微调数据条目示例
data class TrainingSample(
    val system: String =
        "你是团队的Android技术顾问",
    val instruction: String,
    val response: String
)

// 从CR记录生成训练样本
fun crToSample(
    cr: CodeReview
): TrainingSample {
    return TrainingSample(
        instruction = """
请审查这段代码:
```kotlin
${cr.codeSnippet}
```""",
        response = cr.reviewComment
    )
}

端云协同:轻量推理放端侧

这是我觉得最有Android特色的部分。做App的人天然理解「不是所有逻辑都要走网络」——能本地处理的就别打接口。AI助手同理:

场景 执行位置 理由
代码补全提示 端侧(小模型) 低延迟要求、隐私敏感
意图分类 端侧(分类器) 极简模型就够用
RAG检索+生成 云端 需要大模型+向量库
Agent工具调用 云端编排+本地执行 决策在云,执行在本地
结果缓存 端侧SQLite 相同问题秒回

这不就是WorkManager决策「本地跑还是推到服务端」的翻版吗?标准是一样的:延迟敏感度、计算量、数据隐私、网络条件。

// 路由决策器
class InferenceRouter(
    private val localModel:
        OnDeviceModel,
    private val cloudClient:
        CloudAIClient,
    private val cache:
        ResponseCache
) {
    suspend fun route(
        query: UserQuery
    ): AIResponse {
        // 1.先查缓存
        cache.get(query)?.let {
            return it
        }
        // 2.端侧意图分类
        val intent = localModel
            .classify(query)

        return when (intent) {
            Intent.SIMPLE_COMPLETE ->
                localModel.complete(
                    query)
            Intent.NEED_KNOWLEDGE ->
                cloudClient.ragQuery(
                    query)
            Intent.NEED_ACTION ->
                cloudClient.agentRun(
                    query)
            else ->
                cloudClient.chat(
                    query)
        }.also { cache.put(
            query, it) }
    }
}

生产部署:复用Android发版经验

把AI助手当成一个「服务」来运维,你会发现很多经验可以直接迁移:

灰度发布——先给5%的团队成员用新版模型/新RAG索引,观察一周没问题再全量。和App灰度逻辑一模一样。

A/B测试——同一个问题,让base模型和微调模型各答一次,让用户选哪个好。收集到的偏好数据还能回馈到下一轮微调。

监控告警——响应延迟P99、Token消耗量、工具调用失败率、用户满意度评分。和App的崩溃率、ANR率、用户留存是一个思路。

回滚机制——微调后的模型表现不好?一键切回base model。RAG索引有问题?回退到上一个版本的索引快照。就像App热修复。

// 部署配置 - 很Android味道的写法
data class DeployConfig(
    // 灰度比例
    val rolloutPercent:
        Int = 5,
    // 是否开启A/B
    val abTestEnabled:
        Boolean = true,
    // 模型版本管理
    val models: ModelVersions =
        ModelVersions(
            base = "gpt-4o",
            finetuned = "ft:gpt-4o:
    team-android:v3",
            fallback = "gpt-4o-mini"
        ),
    // 告警阈值
    val alerts: AlertThresholds =
        AlertThresholds(
            p99LatencyMs = 5000,
            errorRate = 0.05,
            dailyTokenBudget =
                1_000_000
        )
)

成本优化:和App性能优化一脉相承

AI服务最大的开支是Token消耗。但如果你做过Android性能优化,这些策略你会觉得似曾相识:

缓存策略 = OkHttp Cache。相同或相似问题的回答直接从缓存返回。用语义相似度(cosine > 0.95)判断是否命中缓存,而不是精确字符串匹配。

请求合并 = Coil的请求去重。多人同时问类似问题时,合并成一个请求,结果广播给所有等待者。

模型量化 = APK瘦身。端侧部署的小模型用INT4量化,精度损失可接受,推理速度翻倍。和PNG转WebP、SO裁剪是同一个trade-off思维。

分级响应 = 懒加载。简单问题用小模型快速回答,复杂问题才调用大模型。就像RecyclerView先加载文字,图片异步填充。

成本参考:一个10人团队每天产生约200次查询,按GPT-4o定价,纯云端每月约$300-500。加上缓存+分级响应,实测可以压到$80-120。这钱省出来够请团队吃两顿火锅了。

完整调用链路:一次问答的生命周期

来看一个完整的例子。用户问:「帮我看看NetworkModule里的Retrofit配置,超时时间是不是太短了?」

用户提问

Step1: 意图分类(端侧)

结果 → NEED_KNOWLEDGE + NEED_ACTION

Step2: RAG检索

查到 → OkHttp超时最佳实践文档 + 项目Wiki网络配置说明

Step3: Agent执行工具

search_code → 找到NetworkModule.kt第42行

read_file → 读取具体配置:connectTimeout=10s

git_log → 上次修改是3个月前,改小了超时

Step4: 微调模型生成回答

输出 → 用团队风格组织:问题分析+建议+代码示例

返回用户

整个链路下来,用户得到的不是泛泛而谈的「建议增加超时时间」,而是:「你们项目NetworkModule.kt第42行connectTimeout是10s,三个月前小明从30s改成10s(commit: abc123),结合最近上报的超时率上升,建议改回15-20s。参考OkHttp官方建议,对于移动网络场景,15s是比较合理的值。要不要我帮你提个MR?」

这才是一个真正有用的AI开发助手。

未来:端侧大模型的可能性

写到这里,我不得不提一个让我特别兴奋的方向:端侧大模型。

Google的Gemini Nano已经跑在Pixel上了,MediaPipe LLM Inference API让端侧推理变得越来越easy。想象一下:如果端侧模型足够强,整个RAG+Agent+微调的链路可以完全在本地跑——零延迟、零成本、完全隐私。

当然现在还早。端侧模型的能力大概在GPT-3.5水平,对于复杂的推理和代码生成还差点意思。但趋势很明确:两年前我们觉得手机跑LLM是天方夜谭,现在已经可以跑7B参数的模型了。再给两年时间?

作为Android工程师,我们是最有资格去探索这个方向的人。我们懂端侧性能优化、懂内存管理、懂电量控制、懂异构计算(NPU/GPU/CPU调度)。这些能力在AI Native App时代会变得极其值钱。

系列完结:从这里开始,路在脚下

四篇文章写下来,我想传达的核心观点很简单:Android工程师学AI开发没有想象中那么难,因为你已经有了大量可迁移的思维框架

RAG就是给大模型加了个「本地数据库」,和Room/SQLite是一码事——你在管数据的存取和检索。Agent就是个升级版的Service——它监听指令、调用能力、返回结果。微调就是「定制ROM」——基于通用系统,适配你的特定需求。组合起来,就是一个完整App的架构。

接下来怎么走?我的建议是:

• 先搭一个最小版本的RAG助手(一个下午就能搞定)

• 加几个工具让它变成Agent(一两天)

• 收集团队数据做一次微调(一周)

• 部署给团队用,收集反馈迭代(持续)

不要追求完美。先让它跑起来、用起来,然后在实际使用中发现问题、改进迭代。这不就是我们做App的方式吗?MVP先行,数据驱动,快速迭代。

这个系列到这里就结束了。感谢一路读到这里的你。如果这四篇文章让你觉得「嗯,AI开发好像也没那么遥远」,那我的目的就达到了。

下一步,动手吧。代码不会骗人。

系列回顾

第1篇:RAG——给大模型装一个靠谱的「本地数据库」

第2篇:Agent智能体——让AI自己调API干活

第3篇:微调——让通用大模型变成你的「专属定制ROM」

第4篇:三大技术组合拳(本篇)

感谢关注,我们下个系列见

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐