开源第一周,我收到了一份 57GB 的"用户反馈"

4 阅读5分钟

我把 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 开源,本项目为独立社区作品,与其无隶属关系。