ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

移动端AI Agent实战:从OpenMinis看Android端部署与工具调用

移动端AI Agent实战:从OpenMinis看Android端部署与工具调用 上个月我把 OpenMinis 这个开源项目拉到了 Android 真机上跑。从配环境、编工程到把天气查询、闹钟设定、日程备忘这几个工具串进对话里前后花了两个晚上。跑通之后我最大的感受是把 AI Agent 塞进手机真正的难点根本不在模型能不能跑起来而是怎么让一个具有自主规划能力的智能助手在手机这种内存、电量、权限都有限的环境里稳定地干活。OpenMinis 这类项目解决的正是这个问题。它不是又一个聊天应用而是一套能在移动端承载 AI Agent 的工程底座有 Agent 运行时、工具注册机制、模型接入层也处理了工具调用、权限审批和上下文管理。这篇文章我会按实际部署顺序拆一拆它的整体结构、两条模型接入链路、端侧性能账本以及我二次开发过程中踩过的几个坑给准备拿它做点东西的人一份可参考的记录。1. 手机里的 AI Agent 不是“能聊天的模型”先看清它要拆解多少动作先抛一个具体场景。你对着手机说一句明天上午 10 点的会如果下雨就提前 15 分钟提醒我没下雨就正常提醒。普通 App 收到这句话顶多识别出设置提醒这个意图然后弹一个表单让你手动填时间。但如果是一个 Agent它要拆出来的动作远比你想象的多先确认用户有没有日历日程再调用天气工具查询明天的降雨概率根据结果算出提醒时间然后分别执行创建提醒或修改日程这类的工具。Chatbot 到 Agent 的分界线就在这里。聊天模型的任务是生成下一段文本Agent 的任务是把一句自然语言变成一串可执行的动作并且在这些动作执行完之后还要能根据结果决定是否继续下一步。我把两者的差异拉了一张表方便对照着理解。能力维度普通 Chatbot移动端 Agent输出目标生成自然语言回答生成自然语言加结构化工具调用任务处理单轮问答多步规划、执行、观察、再规划系统集成通常无权限可调用日程、闹钟、短信、文件等能力失败处理答错就重答需要识别执行失败并尝试修复运行环境服务器或云端内存、联网、电量都受限的移动设备OpenMinis 的价值是把这个从文本到动作的闭环在手机端做了工程化落地。你用一句话发起任务它内部会把这句话连同历史上下文、可用工具的描述、系统指令一起发给模型模型返回的不只是一段话还可能包含一个类似query_weather(cityShanghai, date2026-07-14)这样的函数调用请求。Agent Runtime 解析这个请求才真正去调 Android 的日历接口或闹钟接口。1.1 移动端 Agent 最核心的三个模块规划、工具、记忆如果只从功能层面看一个能用的移动端 Agent 至少要包含三个引擎。第一个是规划。模型拿到用户请求后要决定先调哪个工具、调完怎么判断结果。OpenMinis 默认用的思路和目前主流 Agent 基本一致ReAct 循环也就是思考 - 调用 - 观察结果 - 再思考的循环。系统提示词里会明确要求模型当一次工具调用没有解决问题时不要重复同样的调用要根据返回信息调整策略。第二个是工具。模型本身是没有任何执行能力的它只会返回一个我想调用 set_alarm参数是早上七点这样的意图。真正去创建闹钟是工程代码里注册的 Tool Handler 来做。所以工具注册表的设计好坏直接决定了 Agent 能做多少事。第三个是记忆。这里要区分短期上下文和长期记忆。短期上下文是当前任务里已经产生的人机对话和工具返回结果长期记忆则更像是用户的偏好和习惯。移动端场景里长期记忆通常存在本地数据库需要时再通过向量检索找回来。OpenMinis 默认做的是短期上下文管理因为移动端内存太紧多轮工具调用会把上下文撑爆必须有裁剪和压缩策略。讲到这里你应该明白了把它当成一个套壳聊天软件来看肯定看不明白把它当成一个带执行能力的移动端机器人框架来看架构就清晰了。1.2 为什么一定要在手机端跑而不是继续用服务端方案一个很自然的疑问是服务器有算力、有内存Agent 跑在云端不香吗为什么非要把这套东西塞进手机。答案和手机本地数据有关。AI Agent 真正发挥作用的基础是我们愿意让它访问日程、位置、通讯录、健康数据这些高度私密的信息。如果这些数据必须上传到云端才能做规划隐私风险会直线上升。OpenMinis 这类移动端 Agent 最吸引我的一点是它把和你个人数据相关的计算留在了本地把需要的部分以最小权限传给模型。另一个原因则是响应链路。很多生活场景下的需求只有几十毫秒的交互窗口比如你在路上说了句十分钟后提醒我下车。如果这句话要先经过网络、在云端做一次推理再传回来整条链路慢且不说断网就完全不可用。手机端跑 Agent至少保证了基础任务在本地也能闭环。不过这里必须提醒一句把 Agent 放到手机端等于把以前服务器上的稳定性问题转移到了移动环境里。后面我会细说内存和耗电的账那是和 PC 端完全不同的世界。2. OpenMinis 的模块地图从 UI 到模型运行时的一次任务闭环先说结论OpenMinis 这个项目在架构上不算复杂但它把移动端 Agent 最容易写成一锅粥的部分拆得很干净。我把它分成四层来看基本可以解释代码仓库里绝大多数目录的作用。2.1 四大分层与目录职责第一层是表现层也就是手机上的 UI。它负责接收用户的文字或语音输入展示中间步骤、工具调用状态和最终结果。这一层的核心任务是把人机交互过程中的不确定性可视化因为 Agent 执行任务会有延时如果你不告诉用户我正在查天气、马上就好体验会很差。第二层是 Agent Runtime这是整个项目的灵魂。它维护当前任务的状态机、对话历史、工具调用的循环逻辑。你可以把它理解成一个大脑的调度中心模型负责出主意Runtime 负责安排执行计划并控制节奏。它不关心某个具体工具是怎么实现的只关心模型提出了什么调用请求这个请求是不是被允许应该交给哪个 Handler。第三层是工具层也叫 Tool Registry。所有手机能力都以插件方式注册到这里。工具层的每个模块都遵循同一个接口对外提供名称、描述、参数 JSON Schema、执行函数对内接收模型传入的参数调用系统 API 完成动作并返回结构化的执行结果。这个设计是我觉得 OpenMinis 做得最舒服的地方——你不需要理解 Agent 内部逻辑也能往里面加一个新能力。第四层是模型适配层。它把各种模型来源统一成一个 Provider 接口。不管是本地 llama.cpp、局域网里的 Ollama还是云端兼容 OpenAI API 的 DeepSeek在这个层里都能被抽象成输入 Prompt、输出文本和工具调用。配置不同模型只需要改配置文件不用改业务代码。2.2 完整走一遍OpenMinis 执行“帮我看看明天天气再定闹钟”时的内部状态这部分建议所有准备改源码的人认真看因为理解了任务闭环你才知道哪些地方该改、哪些地方千万不能乱动。系统收到明天早上如果下雨就 7 点叫我没下雨就 8 点叫我后会按下面的顺序流转前端把用户输入和当前会话 ID 交给 Agent Runtime。Runtime 会先判断这次请求是否需要新建任务。如果用户之前已经在聊相关话题它会带上历史记录形成多轮上下文。Runtime 组装 Prompt。到这一步模型看到的不是一个裸提问而是经过填充的模板系统指令 用户偏好 可用工具描述 历史对话 当前请求。工具描述越长消耗的 Token 越多这个细节后面性能部分还会展开。调用模型。模型根据工具描述决定调哪个函数。OpenMinis 的配置一般会要求模型输出 JSON而不是 Markdown 或者其他文本格式以便解析。模型返回的典型结构长这样{ tool_calls: [ { id: call_001, type: function, function: { name: query_weather, arguments: {\city\:\Shanghai\,\date\:\2026-07-14\} } } ] }Runtime 解析 tool_calls把 arguments 字符串用 JSON 解析成对象然后去工具注册表里找叫query_weather的 Handler。找不到就直接返回错误找到则调用执行函数。工具执行完后返回结构化结果Runtime 把这个结果拼进对话上下文再次发给模型。模型看到天气结果是有雨于是开始规划下一步它很可能再次请求调用 set_alarm参数是明天早上 7 点。循环直到模型认为任务完成返回final_answer前端把它渲染给用户。这段链路里绝大多数 Agent 跑飞的问题都出在第 3 到第 5 步之间。模型输出的 JSON 经常带多余的引号、换行甚至代码块标记工具返回的错误信息如果不够结构化模型会陷入反复调用同一个工具的循环。所以 OpenMinis 在 Runtime 里专门做了工具调用的错误兜底这一点从工程设计角度看非常值得学。2.3 两条模型接入通道为什么默认配置既接本地模型也接云端 API看 OpenMinis 的默认配置时你会发现它有两条模型通道一条走本地方案一条走云端 API。这不是为了凑功能而是两套互补的部署策略。本地通道适合处理隐私敏感且任务简单的操作。比如打开勿扰模式记一条只有我自己能看到的笔记这些操作的特征是上下文短、不需要复杂推理上云反而增加泄露风险。实测下来本地 1.5B 级别的量化模型对这类请求的响应速度也够用。云端通道则用在你需要复杂推理的任务上。比如帮用户做行程规划、分析一份文字材料再生成总结这些任务对模型能力要求高端侧小模型很难做好。OpenMinis 的云端通道支持任何兼容 OpenAI 格式的 API因此搭配 DeepSeek 这类模型时只需要把 provider 指到对应的 base_url 就行。仓库里常见的配置思路大概长这样model: provider: openai_compatible base_url: http://192.168.1.10:8000/v1 model: deepseek-chat api_key_env: OPENMINIS_API_KEY temperature: 0.2 tool_server: enabled: true host: 0.0.0.0 port: 8090注意这里有个非常有用的工程点OpenMinis 把模型和工具执行拆成了两个进程。模型可以跑在云端工具执行器跑在本地两者通过网络通信。即使将来你想把 Agent 接到某个非移动端系统上只要有这个工具服务器层整层逻辑都可以复用。3. Android 真机部署记OpenMinis 的两套模型接入链路与配置细节我这次部署的基准环境是Android Studio Koala、JDK 17、一台骁龙 8 系测试机、一台局域网内的 Ubuntu 开发机。下面这些步骤是我反复折腾后整理出的最小可运行路径照着走能少踩很多坑。3.1 编译前必须确认的三件事先说最容易被忽略的。OpenMinis 这种带 C 推理模块的开源工程和普通 Android App 构建不太一样它的 native 代码依赖特定 NDK 版本。不少人在导入工程后第一件事就是报 NDK 版本不一致因为工程里 build.gradle 和 CMakeLists 引用的 NDK 版本跟本机已安装的对不上。建议先看仓库根目录的构建说明或 gradle 配置确认版本再决定要不要让 Android Studio 自动下载。别一上来就点 Sync Now等它默认选了一个不兼容的 NDK后面会浪费很多时间。第二件事是 Gradle 依赖下载。国内网络环境拉 Maven 依赖时经常超时建议直接在项目的 settings.gradle 里配好阿里云镜像仓库把 google、mavenCentral 的仓库地址放在镜像地址之后或者直接替换。这一步能省掉大量反复等待的时间。第三件事是子模块。OpenMinis 的代码仓库里可能有子模块或者需要单独拉取的模型下载脚本如果你只 git clone 主仓库就编译部分工具模块会是空的。建议执行的时候留意一下仓库说明有子模块就补拉有模型脚本就先跑一次模型下载。3.2 本地方案把 Ollama 跑在局域网内手机端作为客户端接入我实际第一轮跑通的其实是手机 App 通过局域网连接 Ollama的模式而不是把模型完整塞进手机。手机内存毕竟有限而且 Ollama 官方客户端在 Android 上并不是开箱即用的方案。更务实的做法是在开发机上装 Ollama然后用手机去连它的局域网 API。这套模式的配置逻辑是手机端不承担模型推理只承担 Agent Runtime 和工具执行。我建议你第一次调试也这样做把变量减少到最少。因为一旦把 Agent 卡顿或工具调用失败的原因归结到模型推理慢排查起来会很痛苦。我在开发机上下载的是 Qwen2.5 1.5B 的量化版本模型参数不大但足以测试工具调用链路是否通顺。在 OpenMinis 的配置里指向局域网 Ollama 时需要小心地址开发机上如果开了防火墙要先允许TCP 11434 端口的局域网访问手机和开发机必须在同一个网段。模拟器里跑的话则有些不同Android 模拟器访问宿主机要用 10.0.2.2而不是 localhost。3.3 云端方案用 DeepSeek 这类模型的 API 接入本地方案的好处是零成本但 1.5B 模型在两三步工具调用后经常出现理解力不足的问题。比如它会把日期格式搞错把明天换算成错误的具体日期或者工具名称引用错乱。所以第二套方案我接了云端推理用的办法也很简单在 OpenMinis 的 model provider 里配 OpenAI 兼容的 API把模型名换成 DeepSeek 的 chat 版本。配云端通道有个细节接口地址末尾必须带 /v1 还是不带不同服务商不一样填写之前先翻一下服务商的文档。OpenMinis 代码里一般会在构造 client 时拼接 base_url如果已经带了 /v1 的路径后面再加就可能变成重复路径直接 404。我开始就犯过这个错浪费了大半个小时排查请求日志。云端通道配好以后你几乎能立刻感受到模型智能度的提升模型理解如果下雨就提前这种条件句式要准确得多工具参数的生成也更规范。这说明了一个很现实的道理Agent 的聪明程度上限还是取决于你接的模型本身。工程框架只能保证流程不崩没法弥补模型能力不足。3.4 验证步骤先关掉所有工具再从空 Agent 开始逐步加能力我给第一次上手的人一个建议不要一上来就开全部工具去测那会把自己绕晕。我的验证路径分三步。第一步把工具数量清零只保留纯对话能力。发一句你好测试模型通道是否连通、流式响应是否正常。这个阶段如果出错基本和 Agent 无关纯粹是网络、密钥或模型配置的问题。第二步只开启一个最简单、无副作用、不需要系统权限的工具比如查当前时间或掷骰子。这样能验证 Agent Runtime 的工具调用闭环同时不用担心误操作搞坏系统数据。让模型执行现在几点了如果它回答的是调用工具后的结果而不是自己的幻觉说明工具链路是通的。第三步再开启闹钟、日历这类真实影响的工具并且把目标设备设置好提醒权限。到这一步才算真正开始接触移动端 Agent 的复杂性。4. 跑通只是开始端侧推理的性能、内存与耗电账本如果只是做一个能在手机上运行的 Demo前面三步已经足够了。但凡是打算把 OpenMinis 做成自己天天用的工具就必须面对一个终极问题手机的资源兜不兜得住 Agent 的这堆操作。4.1 内存不是只装模型权重就够KV Cache 往往会给你惊喜很多人在评估端侧模型时只看模型权重大小比如3B 模型量化后大概 2GB我的手机 12GB 内存没问题。这种算法有两个遗漏。第一个是运行时的 KV Cache。模型推理过程中内存里不止保存权重还会保存每一层计算出的 Key 和 Value。上下文越长KV Cache 占用越大。不同模型结构的计算公式有差异但你可以按这个粗粒度口径估算KV Cache 字节数 ≈ 2K和V × 层数 × KV Head 数 × Head 维度 × 上下文长度 × 每值字节数举例来说一个层数 28 层、每个 Token 的 KV Cache 大约在几百 KB 量级的小模型跑到 4096 上下文时KV Cache 就可能占用两三百 MB 甚至更多。内存小的手机在长对话时会明显感到越来越卡然后可能直接被系统杀掉。第二个是移动端系统本身的内存压力。Android 系统并不会把你的所有物理内存都留给 App后台进程、相机、地图都会抢占内存。在 12GB 手机上跑 2GB 模型似乎绰绰有余但如果系统只给 App 分配七八百 MB 可用空间模型一加载就 OOM。测试时一定要关注 Android 开发者选项里的内存占用曲线别只看编译期能否过。4.2 一次任务调用要消耗多少 Token做个小学数学题我们平时用云端模型很少算 Token 成本。但端侧推理的速度瓶颈非常直接算一笔账会给你不少启发。假设一个三步工具调用任务用户问明天上海下雨吗如果下就提醒我带伞。第一步模型要拿到历史上下文、工具定义和用户问题这可能已经消耗 800~1200 Token 的输入输出可能是一条 query_weather 调用又产生约 80~150 Token。天气结果返回给模型后第二步又要重新把结果拼进去再推理一次如果模型觉得天气信息不够详细还会多轮追问。整个任务跑下来累计消耗常常超过两千 Token。在端侧 1.5B~3B 模型上量化后速度按旗舰手机每秒 15~25 Token 计算推理两千 Token 需要两三分钟。用户等一次天气查询等两分钟这在手机上根本没法接受。所以做移动端 Agent 有一个隐藏要求减少模型推理次数。能一次并联调用多个工具的就不要拆成两次能在 Prompt 里说清楚输出格式的就不要让模型靠试错理解。OpenMinis 这类框架通常会支持一个 Prompt 里返回多个 tool_calls这是很实用的设计。4.3 手机发热和后台限制一个容易被忽略的体验大坑我之前在开发机上跑模型从没想过手机发热会成为使用体验的一部分。部署到真机后才发现连续几轮调用端侧模型中框就会明显升温。手机厂商为了控制发热会直接对处理器降频导致越用越慢、越慢越热形成恶性循环。更麻烦的是后台保活。Agent 的任务流程不是一瞬间完成的一次调度可能需要十几秒甚至更久期间用户可能把 App 切到后台。Android 的后台限制会直接冻结或杀死 App 进程导致任务中断。所以如果你要把 OpenMinis 做成一个常驻级助手至少要把它设计成前台服务并且用一条持续通知告知系统这个 App 正在工作。但这会加剧耗电和用户的这 App 怎么一直占着通知栏的抱怨需要在产品层面做取舍。这里我也给一个优化方向把工具调用尽量拆成轻量动作。凡是本地就能快速完成的能力比如设置闹钟、查日历不要让模型一步一步思考而是识别出意图后直接用代码执行只有遇到真正的决策场景才走完整的 Agent 推理链路。混合式流程比所有请求都让模型循环推理的体验好得多。4.4 几个实测有效的移动端性能优化手段OpenMinis 自身的代码已经做了一部分优化但真要压榨性能以下几点建议结合自己的机型去尝试。第一调整上下文窗口。默认全量对话历史都发给模型非常奢侈。在端侧建议把上下文裁剪成最后几轮历史摘要单独存。第二工具描述精简。工具描述越短输入 Token 就越少模型越不容易被干扰。不要给工具写长篇小说式的说明把关键参数说清楚就好。第三考虑量化等级。Q4_K_M 是最常用的平衡点Q8 更准但吃内存IQ4 系列更省但要确认设备的算子支持。另外必须强调CPU 跑模型和 GPU/NPU 跑模型在性能上差别很大。有些手机支持 NPU 加速但 OpenMinis 并不一定默认打开。调试时可以查一下当前是否真正启用了 GPU delegate千万别在日志里看到一句 llama.cpp loaded 就以为已经用上了所有硬件加速。5. 让 Agent 在手机上真正干活工具注册、权限审批与安全边界部署和性能是地基。地基打好之后真正需要花心思的其实是工具层的设计。一个只会在对话框里回话的 Agent 没有价值能真正帮你把闹钟定了、日程安排了、文件归档了的 Agent 才是工具。5.1 工具注册让模型知道它能用什么比让它自己发明工具更重要模型生成本身是不可控的但你可以通过设计工具注册表来缩小它的选择范围。我在扩展 OpenMinis 的工具层时总会遵守一个原则每个工具必须有清晰的名字、描述和参数约束让模型一眼就能判断什么时候该用、不该用。一个典型工具的注册描述长这样{ name: set_alarm, description: 在指定时间创建或修改设备上的闹钟。当用户表达想要被叫醒、定时提醒、按条件提醒时使用。, parameters: { type: object, properties: { time: { type: string, description: 闹钟时间24小时制格式 HH:mm, pattern: ^([01]\\d|2[0-3]):[0-5]\\d$ }, label: { type: string, description: 闹钟备注例如“开会提醒” } }, required: [time] } }这段 JSON 表面上是在描述参数实际上有两个作用。一方面它作为模型生成 tool_call 时的参照模型会照着 JSON Schema 的字段来生成 Python 字典或 JSON 对象另一方面执行层拿到参数后也要依据 Schema 做一次实际校验防止模型生成了不合法的参数导致程序崩溃。工具函数的实现代码通常长这样。OpenMinis 的工具层一般用接口类约束统一签名下面是 Kotlin 里一个工具执行器的大致骨架class AlarmToolHandler(private val context: Context) : ToolHandler { override val name set_alarm override suspend fun execute(arguments: JsonObject): ToolResult { val time arguments[time]?.asString ?: return ToolResult.failure(缺少time参数) val label arguments[label]?.asString ?: // 调用 AlarmManager 创建闹钟的具体实现 val alarmId AlarmScheduler.create(context, parseTime(time), label) return ToolResult.success(mapOf(alarm_id to alarmId)) } }这里我把核心注册过程简写了但你应该能看出来工具注册表的逻辑边界很纯粹它不关心模型为什么调用只关心能不能执行、执行得对不对。新加一个工具对工程的大部分代码是无侵入的。5.2 危险操作必须加审批闸门模型不该有“直接删数据”的权力真正的移动端 Agent 项目里最容易被一股脑加进去的就是各种系统权限。授予 App 读取日程、定位、通讯录权限后Agent 就能调用相应工具。但一定要冷静想一个问题模型的输出是概率性的它有概率把关闭闹钟理解成删除全部闹钟也有概率在错误的上下文里访问不该访问的数据。我实际做二次开发时给 OpenMinis 的工具层加了一个风险等级字段。低风险查询当前时间、读取天气、读取本地笔记这类无副作用操作允许 Agent 直接执行。中风险创建闹钟、添加日程、发送通知这类会产生数据变更但可撤销的操作在通知栏提示用户Agent 已执行。高风险发送短信、删除日程、读取通讯录、涉及支付的任何操作必须有用户明确的确认步骤。确认方式一般是在前端弹一个对话框显示模型准备执行的动作和参数用户点头才放行。这个设计思路我建议所有人都保留。因为安全不是靠模型很聪明不会出错来保证的而是靠系统架构把错误的影响限制在可控范围。5.3 移动端权限与沙箱的适配要点Android 的权限模型和桌面系统相比严格不少大多数危险权限都需要运行时动态申请。Agent 在处理工具调用时不能假设权限一定已经授予了。比如用户第一次让 Agent 创建日程时应用未必已有日历权限这时工具执行器应该返回缺少日历权限需要用户授权的结构化错误而不是直接崩溃。正确的做法是在工具执行失败前检测权限状态然后向 Agent Runtime 返回一个权限缺失的标记由 Runtime 通知 UI 层发起权限请求。权限请求完成后用户需要再说一次同样的话。这种重试逻辑看着不优雅但它是保证移动端稳定性的必要代价。还有一点容易被忽视Agent 工具一定不要申请对整个存储或通讯录的全量读取权限。你完全可以把读取最近联系人封装成一个工具在模型需要的时候返回必要的字段而不是把整张通讯录表交给模型。授出最少权限既是对用户数据负责也是让 Agent 的行为更容易被审计。6. 我实际遇到的坑、以及不建议让 Agent 做的事最后这部分不是理论推演是我在这两三天实测里真实遇到的问题还有我在设计任务边界时踩过的坑。把这些问题记录下来能帮后续接手的人少走一些弯路。6.1 本地小模型工具调用的“幻觉”问题比想象中严重先说现象。用 Qwen 1.5B 这类端侧小模型时它经常会在没有定义工具的情况下硬编一个比query_weather更朴素的函数名比如get_weather。它会一本正经地返回一个工具调用但参数表里根本没有这个函数。Runtime 查找注册表发现不存在返回错误给模型模型反而可能换成另一个不存在或更奇怪的函数名继续试。这类问题在 PC 上不太明显因为你通常会接 70B 甚至更强的模型函数调用能力已经训练得很扎实。但端侧小模型不行它对函数调用的理解并不稳定。解决思路有两个一是在 Prompt 末尾显式强调只能使用下面列出的函数其他函数不存在二是在 Runtime 里做容错一个小模型多次调用同一个不存在工具时不要让它无限循环而是直接中止并询问用户是否需要换更强的模型。6.2 “自动执行一切”是最危险的产品定位给 OpenMinis 加工具那一阵我一度很想把所有系统能力都暴露给 Agent让它什么都能干。还好在一开始就给自己设了限制没有碰短信和支付。相信我的判断Agent 离完全自主执行还有很长的距离现阶段它的价值是帮你把事情想清楚、把参数填对、把重复动作完成但最终按键的人必须还是用户自己。不建议直接让 Agent 自动做的事包括但不限于发送短信或邮件给联系人、删除任何不可恢复的数据、修改系统级设置、执行支付。这类动作一旦出错用户损失远超 Agent 带来的便利。哪怕将来模型能力提升也建议保留高风险操作人工确认这个最终防线。6.3 后台任务断流、上下文膨胀、设备碎片化除了功能边界还有三个工程问题需要提醒。第一个是后台断流。我实测关机屏一段时间后Agent 在后台的任务经常被系统机制中断尤其是应用被切到后台后网络请求和推理进程都很可能被冻结。部署为前台服务只能缓解不能根除。设计产品时要把 Agent 任务尽量控制在秒级不要把手机 Agent 当成可以跑十分钟的云端批处理。第二个是上下文膨胀。多轮工具调用后历史记录会越积越多。我遇到的情况是聊到第 20 轮时请求延迟明显上升内存占用也不断上涨。OpenMinis 需要你在上层配置好历史裁剪策略比如只保留最近六轮消息更早的用摘要文本压缩。不要以为小模型就无所谓所有模型都会因上下文变长而变慢、变贵、变不稳定。第三个是设备碎片化。不同手机对后台限制策略、GPU 支持程度、传感器能力差别很大。同一台手机上跑得很流畅换到另一台中端机可能直接 OOM 或者发热严重。所以如果你想基于 OpenMinis 做产品一定要准备一台低配测试机在 Android 原生限制最严格的环境下去验证别只拿顶配旗舰机自测完就宣称支持所有机型。6.4 我最后留下的一套推荐组合所有测试收尾之后我自己最终留下的是一个偏保守的组合云端模型负责复杂规划和条件判断本地模型负责快速和隐私敏感的小任务高风险工具全部人工确认中风险工具执行前在通知栏展示结果日常对话保留最近几轮上下文每周任务做一个摘要。这套组合不一定适合所有人但方向我认为是对的。OpenMinis 这类开源项目真正提供给开发者的不是一行行写好的代码而是一个可以自由改造成自己需要形态的起点。你可以给它换模型、加工具、调整安全策略把它变成贴着自己生活习惯的智能助手。这个过程本身比直接下载一个成品有意思得多。如果你也准备在自己的手机上编译这个项目我最后只有一条忠告第一次跑通以后别急着加各种花哨功能先把内存曲线、工具调用闭环和权限模型这三样弄扎实。移动端 Agent 拼的不是模型多聪明而是整个系统有多稳。稳住了才谈得上好用。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进