我把 DeepSeek 开源的 AI Agent 框架塞进了 Android 手机(免 Root 免 Termux,70MB APK)。开源第一周,star 从 2 涨到 9,收获了一个粉丝、两个 issue、六个真机 bug、以及一份 57.6GB 的"用户反馈"。
这是那 48 小时的救火实录。全部问题都在 Android 8.0 到 16 的真机/模拟器矩阵上复现并修复,GitHub 已推齐七个版本。
背景:这个项目是什么
DeepSeek 8 月开源了 Agent 框架 DeepSeek Harness(MIT,一切皆插件)。我的项目 DSH Mobile 把它完整搬进 Android 沙箱:
- 自建 bionic 运行时闭包:node/bash/rg/pnpm/curl 从 Termux 包生态收集、ELF 依赖校验、CI 出包——不依赖 Termux App,不依赖 root
- 扩展中心:19 项工具链(Python/Go/Rust/Clang/OpenJDK…)国内镜像一键装,AI 自己也能自助安装
- 系统能力桥:通知推送、无障碍读屏+点击、进程管理——Agent 从"聊天"变成"动手"
开源第一周,用户开始报障。以下是修掉的六个,按荒诞程度排序。
一、"应用占了 60GB 存储空间"
用户原话。第一反应是不可能——APK 才 70MB。
du 逐层钻取:files/root-backup/ = 57.6GB,204 份 dsh-home 的全量 tar。
代码注释写着"一次轻量备份"(进入 Root 模式时保护用户资产)。实现却是:每次切 Root 模式都全量重拍一份,一份都不删。那几天反复切权限模式修 bug,每次拍一张 295MB 的"全家福"。
修复:滚动保留最近 2 份。62.8GB → 5.8GB。
教训:任何"自动备份/自动归档",清理策略必须和创建逻辑同一次提交。只写创建不写清理 = 定时炸弹。
二、新用户首启必崩,而我的设备永远复现不了
Android 11 用户报告:装上就闪退。我的旗舰机(Android 16)怎么都复现不了。
模拟器复现(API 30 镜像 + pm clear 模拟新用户):FATAL EXCEPTION: UninitializedPropertyAccessException: lateinit property webView has not been initialized。
根因一行代码:首启时主界面跳转引导页后立即 finish(),onDestroy() 里访问还没初始化的 lateinit var webView。所有已过首启的设备永不复现,新用户/新设备必崩——开源项目的新用户第一印象,就死在这一行上。
修复:if (::webView.isInitialized) 守卫。Android 11 模拟器实测 FATAL 归零。
三、WebUI 永远转圈:WebView 版本跨度 69 → 133
另一台 Android 11 设备:引擎就绪、页面渲染、界面内部永远转圈。
取证(本机 serve 前端 + adb reverse + API 30 模拟器):前端 bundle 用了 Object.hasOwn(Chrome 93+)、.at()(92+)、replaceChildren(86+)——而 Android 11 出厂 WebView 是 Chrome 83,国产设备还常常没有 WebView 更新渠道。四版本兼容矩阵跑完:WebView 版本跨度 69 → 133。
修复:构建时注入 polyfill(幂等脚本,进 CI 和本地双链路)。老 WebView 瞬间获得新 API。
四、资源站盗版了,还自称"官方无广告"
开源第一周就被国内资源站爬了:APK 原封搬走(大小一致),版本落后一个,签名完全不同(重打包),宣称"官方无广告"。
MIT 许可证允许任何人再分发——法律上拦不住。但签名不同意味着:用户装了假包就永远无法覆盖升级官方真包(签名冲突必须卸载丢数据),内容也无法确认未被篡改。
应对:不追求下架(成本高、收益低),做品牌防御——README 公示官方签名指纹(SHA-256)、声明唯一官方渠道,App 内"关于"页展示签名信息供用户比对。被爬本身是传播力的证明,把用户引导回官方源就好。
五、Root 切普通模式后的"幽灵引擎"
症状:Root 切普通后 App 卡死;重启后反复弹"进程异常退出,正在重启中",但页面和 AI 一切正常。
取证:Root 模式引擎经 su -c 'exec node' 启动,进程树是 su(外壳)→ sh(exec 后变 node)。停止引擎的 SIGTERM/SIGKILL 只杀到 su 外壳——root 的 node 成孤儿继续霸占端口,普通模式引擎反复启动撞端口失败。页面正常,是因为服务的其实是孤儿。
修复:进程组击杀(kill -9 -- -$pid)+ 端口冲突时自动清理孤儿。
六、自愈层在数学上永远不可能触发
配置自愈层的设计:连续 5 次同签名崩溃回滚,再 5 次进安全模式。用户反馈:从来没见过它工作。
数数:自动重启上限 8 次 < 需要的 10 次。第 8 次失败监督器就停机了——安全模式在数学上不可能触发。另外崩溃签名用日志原文哈希,堆栈行号/内存地址每次都变——连第一次的 5 连都凑不齐。
修复:上限提到 14,签名数字归一化(保留结构)。这是"两段代码各自正确、拼起来必死"的经典案例。
今天的账本
- 48 小时,24 个版本,Android 8.0/11/14/16 四版本兼容矩阵全绿(WebView 跨度 69 → 133)
- GitHub 仓库清掉 32GB 的 CI 历史垃圾(287 个构建产物)
- 收获:2 → 9 star,1 个粉丝,2 个 issue,1 份社区深度审计报告(质量高到直接入库)
开源第一周最大的收获不是 star,是这些真实环境喂回来的 bug——每一个都是坐在电脑前永远想不到的。
项目地址:Soodok/Deepseek-Harness-Local-Android(MIT) Releases 下载:v1.2.25(70MB,arm64-v8a,可覆盖升级)
DeepSeek Harness 由 DeepSeek AI 开源,本项目为独立社区作品,与其无隶属关系。