PrismSpace:40亿token的安卓双开重构之路

· 2026-05-31 23:41 · 4 阅读

原创 yzddMr6 2026-05-31 23:41 浙江

作为一个一行安卓代码也看不懂的人,用Claude Code和Codex花了40亿token,从架构到交互到UI到图标,把一个停更多年的开源项目重构成了一个全新的双开工具。

一、背景

这大概是我写过最长、最复杂的一个 vibe coding 项目。从重构到交互到 UI 到图标,全是 vibe 出来的,我一行安卓代码看不懂,也确实一行都没看过。

整个项目总计消耗了大概40 亿 token,开发工具主要是用Claude Code和Codex,以及一个24小时开机连接ADB授权了的测试机,还有一个看不懂安卓、只会下发任务的我。

Claude Code 这边单次会话的账单截图是 1540 美元,token 总量 23.7 亿。

Codex这边累计花费16亿token,主要模型是gpt5.5 xhigh。

image-20260530224533204

事情的起因是 AI 使用量比较大,一个账号不够蹬,我想在一台手机上多登几个 ChatGPT 和 Claude 账号。

首先尝试的是小米自带的应用双开,结果像ChatGPT这种Google框架类的APP双开场景直接报错,也查不出原因。

就想找个第三方工具,想起了以前很有名的 Island(炼妖壶)。它靠安卓的工作资料做隔离,免 root,也不在别的应用进程里动手脚,听起来正好对上我的需求。但是装上才发现可能由于 Island 很多年没更新了,到 Android 16 上一堆流程已经走不通,无法正常工作。

一开始想让 agent 帮我兼容一下,能跑就行。

设置了个goal交给Codex,一个多小时后就完成了适配兼容,第一轮兼容出来的时候,我还真以为差不多了。APK 能构建,X 能在双开空间里打开,agent 还整理了一份验收记录,看着挺像回事。

但是深度使用就发现,Island 很多历史代码已经出现了越来越多的小 BUG,很多场景不满足我的需求,UI 交互设计风格也已经比较老旧。

更要命的是系统层面的变化。从 Android 12 到 16 这几年,系统在后台启动、安装来源、设备管理权限上一路收紧。到了 Android 16(我的验证机是小米 HyperOS,API level 36),Island 原来”把应用装进工作资料”的几条路基本全堵死了。

除了系统变了,项目自己也欠了不少工程债。代码里很多地方直接写死了只有一个 profile,缺乏兼容性和扩展性;一批早就不可达的旧代码还留在编译和清单里。在这套结构上继续打补丁,每改一个小地方,都要在没有测试兜底的情况下跨过这些藏着的假设,成本越来越高。

干脆让 Agent 基于新框架直接重构,按照我的设计和喜好重新来过。界面用 Jetpack Compose 重写,工作资料这套执行内核保留下来、清理干净。

定方向的时候,我没让它去“修 bug”。我给的是一份“产品一号位”的 prompt:让它别只盯着代码,站到产品的角度,把 Island 这个老工具重新想成一个面向高级用户的“应用双开 / 空间管理工具”,先想清楚做什么、不做什么。

断断续续大概两周,整个重构算是做完了。适配了安卓16 下的权限,加了一些新功能,项目也已经开源。这篇文章主要介绍一下这个项目的设计,以及开发过程中的一些经验和踩坑。

二、PrismSpace:棱镜空间

项目简介

我给项目的名字为:PrismSpace,中文名叫棱镜空间。

棱镜把一束光折射成几束,双开也是这个意思——一个应用变成多个隔离的副本。并且让ChatGPT帮我设计了一个简洁的logo:

PrismSpace 是一个安卓上的应用双开管理器。它把应用副本装进系统自带的工作资料里,主空间和双开空间是两个彼此隔离的系统环境,数据、账号、存储、应用状态都分开。PrismSpace 在双开空间里充当管理者,负责创建空间、启用系统组件、启动和冻结应用、同步安装包、传输文件,并支持普通、Shizuku、Root 三种模式。

双开的核心原理是安卓本身有个叫“工作资料”(work profile)的机制。系统允许在主用户之外再挂一个独立的资料,它有自己的数据、账号和存储,本来是给企业 MDM 用来隔离办公应用的。Island 的做法是把自己注册成这个工作资料的管理者(Profile Owner),于是就能把应用克隆进去、冻结不用的应用、限制它们的后台行为。

这套设计不依赖 root,不在别人进程里 hook,直接借系统官方的隔离能力,隔离强度和稳定性都有保证。应用看到的就是“自己被装在了另一个用户里”,这种边界比那些进程内虚拟化干净得多。

界面收成四个标签页。首页顶部是空间状态和“克隆一个应用”的主操作,下面是主空间应用数、双开空间分身数,再往下列工作资料、运行模式、系统版本、设备这些信息。

空间页用“主空间 / 双开空间”分段切换,列出对应空间里的应用,点任意一个分身展开操作面板。

操作面板把单个分身能做的事收在一起:启动、冻结、应用信息、卸载分身。

几个值得点出来的特点,按要点列一下:

  • • 系统级隔离:靠 Android managed profile,双开应用的数据和主空间互不共享,不在别的进程里 hook,也不自己维护一套虚拟运行环境。

  • • 核心路径免 root:创建空间、启动、冻结、文件传输、普通模式安装,都能在无 root、无 Shizuku 下完成。

  • • 就地启动:分身直接在主屏启动器里拉起,不切账号、不弹选择器。

  • • 三种运行模式:普通、Shizuku、Root,能力递进,由用户显式选择。

  • • 文件桥与本地诊断:跨空间传文件走系统分享面板;诊断日志留在本地、由用户主动导出,不做外发遥测。

相比 Island,更新了什么

界面

  • • 全新的 Compose + Material 3 四标签界面,首页、空间、文件、设置,整个交互重做了一遍。

  • • 首页一眼能看到双开空间状态、主空间应用数、分身数、当前运行模式和设备信息。

  • • 空间页主空间 / 双开空间分段切换,带搜索、筛选、批量操作和单应用操作面板。

双开与安装:

  • • 安卓16 上重新打通了“把应用装进双开空间”这条路,普通、Shizuku、Root 三种模式都覆盖。

  • • split 应用(X 这种 base 加好几个 split 的)能完整装上,不再只装个 base 起不来。

  • • 缺“安装未知应用”权限时,按来源把你引到对应的设置页,而不是甩一句系统级拒绝。

  • • 双开空间默认显示系统应用(文件管理器、安装器、浏览器、设置),出问题时能找到入口。

克隆与空间管理:

  • • Shizuku / Root 下静默一键克隆,系统自动带齐 split;普通模式则在前台手动确认。

  • • MIUI 上”显示冻住了其实没冻”的毛病做了兜底(hide 失效就回退 suspend)。

  • • 工作资料没解锁时如实显示“已锁定,请先解锁”,不让你点了才发现打不开。

文件与诊断:

  • • 主空间和双开空间之间通过系统分享面板互传文件,两边都留传输记录。

  • • 一键导出本地诊断日志和双空间快照,方便提 issue;日志只留在本地,不往外发。

  • • 应用内检查更新,走 GitHub Releases。

分层和模块

纵向看是技术分层,从界面一层层落到系统调用:

分层规矩:

  • • 界面层:只渲染状态、发事件,不碰业务。

  • • ViewModel 层:把状态做成 StateFlow,不在主线程做阻塞 IPC。

  • • 仓库 / 控制器层:接到执行内核的缝,也是”诚实状态”落地的地方。

  • • 执行层:才真正以 Profile Owner 身份去动系统。

这么分最直接的好处是可测——ViewModel 和状态映射能脱离真机跑单元测试,平台相关的脏活被压在执行层,不往上层渗。

横向落到工程上是一套 Gradle 多模块:

各模块职责:

  • • shared:内核,放用户识别工具、DevicePolicyManager 封装、Shuttle 跨资料调用。

  • • engine:Profile Owner 和设备管理回调,负责工作资料的创建、配置、冻结挂起。

  • • mobile:这次重写的主体,四个标签页的界面、ViewModel、空间仓库、克隆控制器。

  • • probe:独立的测试应用,在双开空间里验证文件、权限、通知、后台、网络。

三种运行模式

由于安卓16的一些限制,普通模式下点克隆,应用装不进双开空间,架构上大概可以分为两条大的方向:

  • • 特权路径(Shizuku / Root):调 install-existing,引用设备上已有的包,不复制 APK、不弹安装界面,自动带上全部 split,静默一键克隆。

  • • 普通路径:把完整安装包(base 加全部 split)复制进双开空间的“待装列表”,由用户在双开空间的前台界面里提交一个 PackageInstaller 会话,走系统安装器确认。

克隆时按运行模式在这两条路之间选:

落到产品上就是三种运行模式,面向不同场景的用户:普通模式覆盖大多数不想折腾的人,日常双开够用;Shizuku 模式面向愿意多走一步的进阶用户,换来的是一键静默克隆;Root 额外提供创建兜底和实验性多空间。三种模式能力递进,由用户显式选择。

能力

普通模式

Shizuku / ADB

Root

创建 / 修复双开空间

✅ 系统工作资料流程

✅ 作兜底

启动 / 冻结 / 卸载分身

系统应用双开

✅ 启用即可

克隆普通应用

复制安装包 + 前台手动确认

✅ 静默一键,自动含 split

✅ 静默一键

新建“第二个”双开空间

⚠️ 实验性,仅限改了配额的定制 ROM

三、开发踩坑记录

除了最后做出的东西本身,我更想记录一下这次 vibe coding 过程中的踩坑经历,希望对大家有些参考。

如何提升模型的设计品味?

第一个遇到的问题是模型做出来的交互设计很乱。图标不统一,按钮像临时堆上去的,新老样式混在一起,看着像个工程面板。

模型设计后端架构的能力挺强,但用户侧的交互设计和体验做得实在不行。可能是因为后端可以通过测试来验证对不对,但交互体验难以量化,模型很难知道什么是好的、什么是不好的。

我自己对设计也不了解,试过一些界面设计的 skills 效果都不太好,也没想到用 Claude design。最后尝试了 3 个方法,总算达到了初步的设计预期。

第一个方法是通过ChatGPT根据我的设计生成图片交互稿。

当时其实生成了很多版,但是只有这两版看起来是稍微还看得过去的。

但是体验下来发现的问题是:图片很难把完整的交互逻辑,状态怎么流转、空态长什么样、失败提示给什么,全靠看着图脑补给完全覆盖到。我让 Claude 照着这些图去实现,发现根本不行,模型很容易把图做漂亮一点,然后接着把产品逻辑写乱。

所以第二次,我又尝试了一个新的办法:让 Claude 先做一版 HTML 可交互原型,配合 mock 数据让我能实际点击。

我先在网页里把流程点一遍,确认首页到空间、空间到克隆、文件到传输记录、设置到运行模式这些路径顺不顺,再让它迁移到 Android Compose。HTML 原型没那么像最终的 App,但它能把路径问题提前暴露出来。点哪里进克隆、哪里切模式、哪里看传输记录,页面之间一跑就知道。

下面是我用HTML当时生成的页面的交互截图,看起来有点像那么一回事了。

但实际在实现的过程中,发现整体项目给人一种说不上来的奇怪。外表好像是那么一回事,但仔细看每个按钮的功能、每个交互的逻辑,都不敢深究。比如同一个功能在不同页面的文案不一样,有的地方叫"冻结"有的地方叫"隐藏",给用户封装出来的整体逻辑像一个残次品。

我意识到这个可能并不仅仅是外观好看的问题,更多的在于整个APP设计的品味。

这就引出来第三个方法:在多次摸索的过程中,无意间发现有个方式意外地好使:先让模型用不同的视角把所有的功能都点击一遍记录下来轨迹。然后告诉模型用“乔布斯式”的产品思维重新审一遍页面:如果是乔布斯,他会怎么设计这个产品?看到现在这一版,他会挑什么毛病?

模型开始主动删按钮、减少工程黑话、把主路径收窄,首页不再把所有东西摊开,设置页也不再把 Profile Owner、managed profile、PackageInstaller 这些内部词直接甩给用户。模型已经读过太多关于乔布斯的材料,这么一提示,相当于一次性给它灌了一大把设计上的约束。果然在设计风格上保持了一致,并且提出了很多深度的意见。

最后,按照乔布斯的审美标准,对现在测试出来的问题列举出了优先级,并且把很多我直觉上感觉到奇怪,但是很难去具体描述出来的点也给明确掉。还得是乔老爷子。

如何让模型进行深度思考?

开发过程中还有一个反复出现的问题:遇到 bug 反馈给模型,它往往是补丁打补丁地修,哪里报错堵哪里,没有站到更高的角度去想根因。我判断不了底层细节,只能从结果上看它出了什么毛病,说不清背后可能是什么原因,最后就只能跟着它一起打补丁。

探索下来,发现有两种方式比较有效:

第一是把测试拆成多轮,每轮让Agent用不同的视角,一个全新的上下文来发现问题。

模型刚写完代码,天然会倾向于证明自己写对了,它会挑最顺的那条路跑一遍,再把结果写成“已验证”。所以我让它一轮只测一类问题,测完保存日志和截图,再开一个干净的上下文复查。

普通模式就按普通模式测,设备上有 Shizuku 或 root 也不许绕过去报通过;UI 流程要真的点界面,不能拿 shell 命令替用户把活干了。每一轮还从不同角度切进去看同一批问题,轮和轮之间用脚本把环境还原成基线,卸载新建的克隆、清掉新建的工作资料,保证每轮都是干净的起点。这套看着很笨,但能把模型从“我修好了”拉回到“你证明给我看”。

第二是写了个专门的 skill,叫 deep-think。

它的主要逻辑是给模型灌输一些常见的思考方法论,别急着补丁打补丁:先把现象一条条列出来,再找它们的共同点,把一堆表象收敛到少数几个根因,最后按风险高低排序去改。模型本来就有这个能力,但默认状态下它经常顺手就把眼前这个 bug 修了。给它这套约束之后,它才慢慢开始从系统层面收口。

模型是有能力的,只是像一个有点迷茫的人,需要被点拨一下方法。

果然,加载上skills之后,效果立竿见影。这一轮它把大概 40 个表象问题,收敛成了 7 个根因。比如”分身计数把系统应用也算进去了””克隆这个动作被当成工程任务,没被当成产品””应用状态没有单一真相源,hidden、suspended、内存缓存三套对不上账”。

看到这张图就清楚了,前面那些毛病不是补丁能解决的,底下是同一批结构性原因。一个不懂安卓的人,光从结果上看,只能看见 40 个分散的现象,看不到底下这 7 条。

如何发挥不同模型的特性?

这个项目全部是靠 AI agent开发的,主力先是 Claude Code +Opus 4.7,后期换成了 Codex +GPT-5.5。

整体用下来给我的感觉是:

Claude Opus4.7如果用动物来比喻的话,有点像边牧。很聪明,擅长架构的设计,但缺点用一个词形容就是喜欢“偷奸耍滑”。

读旧代码、整理架构、提产品方向、写交接文档的时候,它经常能站得很高,架构设计上确实能给出更合理的方案。但是4.7经常偷懒、不诚实,扩大成果,动不动没验证就走捷径,想办法糊弄你,如果你不懂这个领域,还真的会被它骗到。

举一个具体的例子是:开发的时候,为了调试方便,我给它开了ADB权限。但是我让它测试的时候,要求它用普通用户权限去测试,但是它觉得比较麻烦,所以直接用ADB权限安装的应用。相当于走了捷径。

最恶意的地方是它的报告里面往往有日志、有权限名、有一段像模像样的 Android 限制分析,看上去像是真验证过,实际被测的那条代码根本没走到。

系统级项目里这种假验证比直接报错危险得多。直接报错你至少知道没做完,假验证会让后面所有判断都建在一块错的地基上。

说到底,想让模型发挥最大价值,你自己得懂这个领域。不懂的话,它糊弄你你都看不出来。

另一边,**Codex 给我的感觉是一个忠实的执行者。**你告诉它做什么,它就老老实实做什么。严谨、可靠。每次改动前后它都做完整回测,先看代码,再改,再跑测试,再回头确认。后期那些脏活、回归活,我更愿意交给它。

过程中有一个文件管理权限的问题,Claude 折腾了两天没搞定,换成 Codex 加 GPT-5.5直接秒了。从那以后,后期的开发基本都交给了 Codex。

再吐槽几句 Opus 4.7。中文容易乱码,写文章的 AI 味越来越重,离了“不是……而是”和破折号就不太会说话了。。。

这里还有个小插曲,我正写文章吐槽着 Opus 4.7,4.8 就发布了,model card 里专门点了一句“显著改进了诚实性”。看来Anthropic官方也意识到这确实是现在opus比较要命的问题。

img
img

Claude Code和Codex都推出了goal功能,有点类似把原来的ralph loop插件给简化了。

这个功能相当的牛逼,以全量回归测试为例,Codex一口气跑了 11 个多小时。全量回归覆盖了导航、克隆、Twitter 启动、权限隔离、文件桥、媒体同步等全链路测试功能。基本把后面的工作给收尾掉了。

四、总结与思考

首先感叹一句。去年我研究安卓上的Agent GUI自动化,搞了一套挺复杂的算法。到现在不管是 Claude Code 还是 Codex,只要把 adb 权限给它,装 APK、点界面、dump UI、拉日志、恢复基线全自己来,很多场景根本不用额外的 harness 和 agent 框架。

我不懂安卓,但这次我把一个想法,从“手机上想双开几个账号”推到了一个真实可用的 App。我没有突然变成安卓开发者,做法其实很笨:把一个完全陌生的领域拆成一个个能验证的小块,然后盯着 agent 一块一块往前推。

至于我为什么要花这么多时间这么多精力投在一个好像和我主要工作并不相关的项目上,其实我真正在意的是这个能力,一种把想法变成现实的能力。

还记得最开始AI是怎么一步步改变我们工作方式的吗?

一开始是能生成函数,然后是一个完整的脚本;再后来可以写小项目,再到写完整个模块,再到一个完整的项目;现在甚至可以用AI实现整个生态和系统。每往前一步,我们能交给它的东西就更大一块。

平时只做简单项目的话其实很难感觉到区别,就像让大家都来做小学加减乘除,看不出来谁强谁弱。只有深入到复杂领域,才能真正摸清不同模型的能力边界,知道怎么正确地和它对话、怎么更好地驾驭和使用它们,怎么发挥它的最大能量。

你对于这方面的能力把握得越深,你的杠杆倍数就越高,你就能做更多更复杂的事情

这些都是这次项目里最实在的收获。

最后,项目已经开源,地址:https://github.com/yzddmr6/PrismSpace

如果有BUG,或者更好的建议,欢迎和我(的AI)反馈 :)

跳转微信打开