让 AI 真正动手:Swees — 手机上的 AI Agent 架构全解析
本文深入剖析开源项目 Swees 的技术架构探讨如何在无 root 的 Android 手机上构建一个真正能「动手」的 AI Agent。一、引言AI 只能说不能做你大概有过这样的体验在手机上问 AI「帮我写个 Python 脚本处理 CSV」AI 给你一段漂亮的代码然后呢你得手动复制、打开电脑、装环境、跑代码、遇到报错再回去问 AI……手机AI 停留在「说」的阶段无法「做」。桌面端的 Claude Code、Cursor、Devin 已经给出了答案——让 AI 直接操作终端。但在移动端这个领域几乎是空白的。原因很简单手机上没有可用的 Linux 环境没有 root 权限没有成熟的终端模拟方案。Swees 就是为了填这个空白。它是一个运行在 Android 手机上的开源 AI Agent 应用。通过 PRoot 技术在手机内嵌完整的 Ubuntu 24.04 环境AI 可以直接执行终端命令、编辑代码、管理文件——无需 root无需电脑一切在手机上完成。二、项目概览一句话定位Swees 是一个 Android 原生 AI Agent 应用内置 Ubuntu 终端让 AI 从「对话」走向「行动」。核心卖点特性说明真正的命令执行AI 自主调用 Function Calling在真实 Ubuntu 环境中执行 shell 命令无需 root基于 PRoot 技术普通 Android 手机即可运行多智能体协作多个 Agent 各自独立配置通过 IPC 跨话题通信跨对话记忆SQLite FTS4 全文搜索AI 记住你说过的一切零框架前端纯 HTML/CSS/JS~12K 行代码实现完整 SPAAI 编写五子棋 APP手机上编译安装全程在手机上完成甚至gif都是AI做的三、技术架构总览Swees 采用经典的三层架构每层职责清晰、边界明确┌──────────────────────────────────────────────────┐ │ WebView (HTML / CSS / Vanilla JS) │ 前端 UI · ~12K 行 │ ↓ SweesBridge │ ├──────────────────────────────────────────────────┤ │ Java Bridge Layer │ JS ↔ Java 桥接 │ ┌───────────┬───────────┬────────────────────┐ │ │ │ AI 引擎 │ PRoot │ Storage │ │ │ │ SSE 流式 │ Ubuntu │ SQLite │ │ │ │ OpenAI │ Session │ 13 张表 │ │ │ │ 兼容协议 │ Pool │ FTS4 全文索引 │ │ │ └───────────┴───────────┴────────────────────┘ │ │ Native Layer (C / .so) │ linkhook 等 ├──────────────────────────────────────────────────┤ │ Android OS (arm64) │ └──────────────────────────────────────────────────┘各层职责前端 UI 层WebView 承载的单页应用纯 HTML CSS 原生 JavaScript无任何前端框架。负责聊天界面渲染、Markdown 解析、手势交互、Git 面板等全部 UI 逻辑。Java 桥接层核心是SweesBridge暴露 71 个JavascriptInterface方法是 JS 与 Java 之间唯一的通信通道。AI 引擎、PRoot 终端、SQLite 存储三大子系统在此交汇。Native 层C 语言编写的linkhook.c编译为.so动态库解决 Android 14 SELinux 对硬链接的限制问题。数据流的关键路径是用户输入 → JS 调用 Bridge → Java 发起 HTTP 请求 → SSE 流式回调 → JS 实时渲染。当 AI 决定执行命令时Java 层通过 PRoot 会话池执行命令结果回传给 AI 进行下一轮推理。四、关键技术深度解析4.1 PRoot无 Root 运行 Ubuntu 的原理与 Android 14 兼容为什么是 PRoot在 Android 上运行 Linux 环境通常有三条路径方案需要 Root原理适合 SweesTermux否自带包管理器但非标准 Linux 目录结构❌ 目录结构不兼容 apt/dpkgDocker是容器化❌ 需要 rootPRoot否通过ptrace拦截系统调用模拟 chroot bind mount✅PRoot 的核心原理是利用 Linux 的ptrace()系统调用拦截目标程序的所有系统调用。当程序尝试访问文件路径时PRoot 拦截并重写路径——比如把/usr/bin/python3重定向到/data/data/com.swees/files/rootfs/usr/bin/python3。这样对程序而言它就运行在一个「真实」的 Ubuntu 根文件系统中。Swees 在首次使用时自动下载约 29MB 的 Ubuntu 24.04 arm64 rootfs解压后在 PRoot 中启动完整的 bash 环境预装git、python3、sqlite3等开发工具。Android 14 兼容linkhook 的故事Android 14 收紧了untrusted_appSELinux 域的安全策略禁止普通应用调用link()/linkat()创建硬链接返回EACCES。这直接导致 PRoot 内的dpkg在执行apt install时卡死——因为 dpkg 依赖硬链接来做 status 文件的原子备份。Swees 的解决方案是一段精巧的 C 代码——linkhook.c/* 拦截 link()先尝试真实硬链接失败则降级 */intlink(constchar*oldpath,constchar*newpath){if(real_link(oldpath,newpath)0)return0;if(errnoEACCES||errnoEPERM){returnlink_fallback(oldpath,newpath);// 降级为 copy → symlink}return-1;}设计要点LD_PRELOAD 拦截编译为.so后通过LD_PRELOAD注入对 PRoot 内所有程序透明——dpkg、apt 完全无感知。三级降级策略先尝试真实link()→ 失败则copy_file()产生独立副本→ copy 也失败则symlink()兜底。零依赖不使用dlsym(RTLD_NEXT)避免依赖libdl而是直接通过syscall()调用原始系统调用库本身只依赖 libc。这段代码不到 100 行却解决了 Android 14 上 PRoot 生态最头疼的兼容性问题。4.2 SSE 流式输出从 SseParser 到前端实时渲染AI 对话的体验好坏很大程度上取决于流式输出的流畅度。Swees 实现了一套完整的 SSEServer-Sent Events解析与渲染链路。Java 端SseParserSseParser是整个流式输出的核心负责解析 OpenAI 兼容协议的 SSE 流。它的设计有几个值得注意的工程细节publicstaticParseResultparse(InputStreamis,DeltaConsumeronDelta,DeltaConsumeronReasoning,ToolCallDeltaConsumeronToolCallDelta)throwsException{// ...while((liner.readLine())!null){if(!line.startsWith(data:))continue;Stringdataline.substring(5).trim();if(data.equals([DONE]))break;JSONObjectchunknewJSONObject(data);JSONObjectdeltachoices.getJSONObject(0).optJSONObject(delta);if(delta!null){// 1. 思维链增量reasoning_contentStringreasoningdelta.isNull(reasoning_content)?:delta.optString(reasoning_content,);if(!reasoning.isEmpty())onReasoning.onDelta(reasoning);// 2. 正文增量contentStringcontentdelta.isNull(content)?:delta.optString(content,);if(!content.isEmpty()){full.append(content);onDelta.onDelta(content);}// 3. tool_calls 流式分片按 index 累积拼接// ...}}}关键设计决策① 三路并行回调。SseParser同时支持三种增量回调正文onDelta、思维链onReasoning、工具调用onToolCallDelta。这意味着用户在等待 AI 回复时不仅能看到正文逐字输出还能看到 AI 的「思考过程」和「正在准备执行的命令卡片」实时渲染。② org.json 的 null 陷阱。代码中反复出现delta.isNull(content) ? : delta.optString(...)这种模式。这是因为org.json的optString()对 JSONnull值会返回字符串null而非空字符串——这是一个经典的 Android 开发坑。Swees 在每个字段解析处都做了显式判空。③ tool_calls 流式分片累积。OpenAI 协议中tool_calls的arguments字段是分片传输的——首个 chunk 携带id和name后续 chunk 只携带arguments的片段。SseParser使用LinkedHashMapInteger, ToolCall按index累积拼接if(existingnull){// 首个分片建条目toolCallMap.put(idx,newChatRequest.ToolCall(id,name,argsPart));}else{// 后续分片拼 argumentsStringmergedArgsexisting.argumentsargsPart;toolCallMap.put(idx,newChatRequest.ToolCall(mergedId,mergedName,mergedArgs));}④ 容错设计。单行 SSE 解析失败不会中断整个流——catch (JSONException)后跳过继续但通过Log.e让问题可见。这在网络不稳定或服务商返回格式有微小偏差时至关重要。前端实时渲染链路Java 解析出的增量通过SweesBridge回调到 JS 层前端使用增量追加 marked.js实时 Markdown 渲染。整个链路是HTTP InputStream → SseParser.parse() → onDelta 回调 → EventPusher.pushEvent(stream_delta, json) → WebView.evaluateJavascript(window.onStreamDelta(...)) → DOM 增量更新 marked.js 渲染4.3 Function Calling 安全设计命令危险分级 三级权限 会话隔离让 AI 执行命令安全是第一要务。Swees 构建了一套多层安全体系。命令危险分级DangerLevelDangerLevel是一个纯函数式的命令风险评估器将每条命令分为LOW自动执行和HIGH需用户确认两级publicenumLevel{LOW,// 自动执行HIGH// 需用户确认}publicstaticLevelassess(Stringcommand){Stringcmdcommand.trim();if(matches(cmd,rm ,rmdir ,dd if,mkfs,shutdown,reboot,kill ,sudo ,chmod ,chown ,curl ,wget ,git push,git reset,git rebase,drop table,delete from,mv ,cp ))returnLevel.HIGH;// SQL UPDATE 需同时包含 update 和 set避免误伤 apt updateStringlowercmd.toLowerCase();if(lower.contains(update )lower.contains( set ))returnLevel.HIGH;returnLevel.LOW;}设计亮点覆盖面广涵盖文件删除、系统操作、权限变更、网络下载、Git 危险操作、数据库写操作等 7 大类高危命令。精准误伤控制比如 SQLUPDATE的判定要求同时包含update和set避免把apt update、pip update误判为高危。Git 操作细分git push、git reset、git rebase等列为 HIGH但git status、git log、git diff等只读操作为 LOW自动放行。三级权限模式每个 Agent 有独立的trust_level字段默认为RESTRICTED级别行为RESTRICTED所有 HIGH 级命令必须用户确认TRUSTED放宽部分限制AI 有更大自主权FULL完全自主无需确认危险谨慎使用会话隔离每个 Agent 拥有独立的 PRoot 会话通过ProotSessionPool管理publicProotSessiongetOrCreate(StringagentId,StringworkDir)throwsException{ProotSessionsessionsessions.get(agentId);if(session!nullsession.isAlive()){lastActivity.put(agentId,System.currentTimeMillis());returnsession;// 复用已有会话}sessionnewProotSession(workDir);session.start(prootPath,rootfsPath,nativeLibDir,tmpDir);sessions.put(agentId,session);returnsession;}不同 Agent 的命令在各自的 Ubuntu 会话中执行工作目录、环境变量、进程空间完全隔离。Agent A 的cd /project-a不会影响 Agent B。4.4 数据层设计13 张表 消息版本控制 FTS4 记忆搜索Swees 的数据层基于 SQLite共 13 张表含 FTS 虚拟表覆盖对话、消息、智能体、设置、记忆、IPC 任务等全部业务域。表结构总览表名职责关键字段conversations对话主题agent_id,starred,cache_hit/missmessages消息记录role,content,tool_call,reasoning,prev_id,is_current,bubble_idagents智能体配置system_prompt,model,provider,session_id,trust_levelsettings全局设置key-value 结构i18n国际化文本(key, lang)联合主键request_logsAI 请求日志request_bodyAPI Key 脱敏ipc_tasksIPC 任务队列action,status,resultmemories跨对话记忆content,keywords,category,importancememories_fts记忆全文索引FTS4 虚拟表消息版本控制prev_id / is_current / bubble_id这是 Swees 数据层最精巧的设计之一。在 AI 对话中同一条用户消息可能触发多次 AI 回复比如重新生成、Function Calling 多轮调用。Swees 用三个字段实现了消息的版本树prev_id指向父消息的 ID构建消息版本链。is_current标记当前显示的版本1当前0历史。bubble_id同一「气泡」UI 上的一个消息块的所有版本共享同一个bubble_id删除时级联清理。用户消息 (bubble_idB1) ├── AI回复v1 (prev_iduser_msg, is_current0, bubble_idB2) └── AI回复v2 (prev_iduser_msg, is_current1, bubble_idB2) ← 当前显示这种设计让「重新生成」变得简单新建一条is_current1的消息把旧版本标记为is_current0UI 只渲染当前版本但历史版本完整保留。FTS4 全文搜索让 AI 拥有记忆memories表配合memories_fts虚拟表实现了跨对话的持久化记忆系统。Swees 使用 SQLite 的 FTS4 扩展standalone 模式自带数据副本通过触发器自动同步-- 插入记忆时自动同步到 FTS 索引CREATETRIGGERmemories_aiAFTERINSERTONmemoriesBEGININSERTINTOmemories_fts(rowid,content,keywords)VALUES(new.id,new.content,new.keywords);END;-- 全文搜索SELECT*FROMmemories_ftsWHEREmemories_ftsMATCH用户偏好;记忆表还设计了importance1-10 重要性评分、access_count命中次数、last_accessed最近命中时间、expires_at过期时间等字段支持记忆的优先级排序和生命周期管理。请求日志自动裁剪request_logs表通过一个 SQLite 触发器实现自动裁剪只保留最近 100 条记录CREATETRIGGERtrg_request_logs_trimAFTERINSERTONrequest_logsBEGINDELETEFROMrequest_logsWHEREidIN(SELECTidFROMrequest_logsORDERBYtimestampDESCLIMIT-1OFFSET100);END这是一个优雅的设计——不需要 Java 层的定时清理任务数据库自己搞定。五、工程决策与思考为什么不用前端框架Swees 的前端是 ~12K 行纯 HTML/CSS/JS没有 React、Vue、也没有任何构建工具。这个决定并非偷懒而是深思熟虑的结果WebView 性能移动端 WebView 加载 React/Vue 的 runtime 本身就有开销而 Swees 的 UI 逻辑用原生 JS 完全可以胜任。包体积零依赖意味着 APK 更小用户下载更快。调试友好没有构建步骤改完代码刷新即生效开发体验极佳。可控性每一行代码都是自己写的不存在框架黑盒。为什么选 PRoot 而非 TermuxTermux 是 Android 上最成熟的 Linux 环境方案但它有自己的包管理器和非标准目录结构/data/data/com.termux/files/usr/。这意味着apt、dpkg等 Debian 系工具无法直接使用很多依赖标准 Linux 目录结构的软件包会出问题。PRoot Ubuntu rootfs 的方案虽然性能略低ptrace拦截有开销但提供了100% 兼容的 Ubuntu 环境——apt install开箱即用所有教程和 StackOverflow 答案都适用。对于 AI Agent 场景兼容性远比性能重要。为什么用 vanilla JS 而非 TypeScript在 WebView 环境中TypeScript 需要额外的编译步骤。Swees 的前端代码通过SweesBridge直接与 Java 交互类型安全由 Java 侧的JavascriptInterface注解保证。引入 TypeScript 会增加构建复杂度但收益有限。六、性能与优化SSE 解析效率SseParser采用逐行读取 即时回调的模式不缓存整个响应体。每个 SSE chunk 解析后立即通过回调推送到前端内存占用恒定仅StringBuilder full累积完整文本。对于长回复这意味着内存不会随输出长度线性增长。PRoot 会话池复用ProotSessionPool使用ConcurrentHashMap管理会话按agentId复用privatestaticfinallongIDLE_TIMEOUT_MS5*60*1000;// 5 分钟空闲超时publicvoidreapIdle(){longnowSystem.currentTimeMillis();for(Map.EntryString,Longe:lastActivity.entrySet()){if(now-e.getValue()IDLE_TIMEOUT_MS)destroy(e.getKey());}}每次命令执行时更新lastActivity时间戳空闲超过 5 分钟的会话自动回收。这避免了频繁创建/销毁 PRoot 进程的开销每次启动 PRoot 需要初始化 bash 环境约 1-2 秒同时防止内存泄漏。请求日志自动裁剪前文提到的触发器自动裁剪机制确保request_logs表不会无限增长。这是一个「设置即忘记」的设计——不需要 Java 层的Handler.postDelayed或WorkManager定时任务数据库触发器在每次插入时自动执行清理。七、未来规划Swees 仍在积极开发中路线图包括 更多 AI 服务商扩展对 Claude、Gemini、Qwen 等更多模型的支持 插件/技能市场社区驱动的技能生态一键安装新能力☁️ 云端同步对话和记忆的跨设备同步 平板适配针对大屏设备的响应式布局 端侧模型探索在手机上运行小型 LLM 的可能性八、结语Swees 证明了一件事在 2026 年一部普通的 Android 手机足以成为 AI Agent 的完整运行环境。不需要 root不需要电脑不需要云服务器。PRoot 提供了 Linux 环境SSE 实现了实时交互Function Calling 赋予了行动能力SQLite FTS4 构建了持久记忆——所有这些技术组合在一起让 AI 从「能说」变成了「能做」。这是一个开源项目基于 GPL v3 协议代码完全公开。 GitHub: https://github.com/wildwalker2026/Swees如果你觉得这个项目有意思欢迎 Star ⭐ 支持。如果你是开发者欢迎提 Issue、提 PR、写技能——每一份贡献都让 Swees 更好。Swees — 让 AI 真正动手。

相关新闻

Android构建变体(Build Variants)配置与实战指南

Android构建变体(Build Variants)配置与实战指南

1. 理解构建变体的核心概念在Android开发中,构建变体(Build Variants)是Gradle和Android Gradle插件提供的一个强大功能,它允许开发者基于同一套代码库构建出不同版本的应用。每个构建变体都是构建类型(Build Type)和产品风味(Product Flavor)的组合产物…

2026/7/19 3:16:01 阅读更多 →
嵌入式C语言

嵌入式C语言

C语言数据类型在STM32中数据类型的关键字名字被换为:stdint关键字里对应的名称。使用新名称需要包含stdint.h头文件。C语言宏定义关键字:#define用途:用一个字符串代替一个数字,便于理解,防止出错;提取程序…

2026/7/19 3:16:01 阅读更多 →
AI Agent零代码数据分析:智析Agent让Excel分析像聊天一样简单

AI Agent零代码数据分析:智析Agent让Excel分析像聊天一样简单

很多业务人员都遇到过这样的困境:手头有大量Excel数据需要分析,但不会写Python代码,复杂的SQL查询更是让人头疼。传统的Excel函数和透视表虽然强大,但学习成本高,处理复杂分析时效率低下。现在,借助AI Agen…

2026/7/19 3:16:01 阅读更多 →

最新新闻

自学笔记2026-07-18-1

自学笔记2026-07-18-1

代码:CEdit* p1 (CEdit*)GetDlgItem(IDC_EDIT1);CEdit* p2 (CEdit*)GetDlgItem(IDC_EDIT2);CEdit* p3 (CEdit*)GetDlgItem(IDC_EDIT3);CString Buffer1, Buffer2;p1->GetWindowTextW(Buffer1);p2->GetWindowTextW(Buffer2);if (Buffer1.IsEmpty()){std::ws…

2026/7/19 5:25:13 阅读更多 →
C++实现香农熵:从数学原理到工业级代码的完整指南

C++实现香农熵:从数学原理到工业级代码的完整指南

1. 项目概述:为什么我们需要亲手实现香农熵?在信息论的世界里,香农熵是一个基石般的概念。它量化了信息的不确定性或“惊喜”程度。简单来说,一个事件越确定(比如太阳从东边升起),它的熵就越低&…

2026/7/19 5:25:13 阅读更多 →
【无标题】高精度位置感知赛道观察:国内UWB定位主流品牌盘点

【无标题】高精度位置感知赛道观察:国内UWB定位主流品牌盘点

随着工业4.0进程的全面提速与数字化转型的纵深推进,高精度位置感知能力已演变为工业互联网底层架构中的关键基础设施。市场研究机构IDC预测数据显示,全球UWB定位市场规模将在2026年突破120亿美元大关。在这一高速成长的赛道上,本土UWB定位系统…

2026/7/19 5:25:13 阅读更多 →
Symfony2安全机制实战:从认证到授权的企业级解决方案

Symfony2安全机制实战:从认证到授权的企业级解决方案

1. Symfony2安全机制概述Symfony2作为一款成熟的PHP框架,其安全机制设计堪称企业级Web应用开发的典范。我在多个电商和金融项目中实际运用这套机制时,发现它通过分层防御策略实现了从用户认证到资源授权的完整闭环。核心组件security.yml配置文件就像交响…

2026/7/19 5:25:13 阅读更多 →
声呐目标检测中的互相关算法实现与FPGA优化

声呐目标检测中的互相关算法实现与FPGA优化

1. 项目背景与核心需求在声呐目标检测系统中,最关键的挑战是从充满环境噪声的回波信号中准确识别出目标反射信号。传统基于阈值检测的方法在低信噪比环境下性能急剧下降。本项目采用互相关算法作为核心检测手段,其数学本质是通过计算接收信号与已知发射信…

2026/7/19 5:25:13 阅读更多 →
Vivado FPGA 项目 `.gitignore` 到底该怎么写?

Vivado FPGA 项目 `.gitignore` 到底该怎么写?

做 FPGA 项目时,很多人第一次把 Vivado 工程丢进 Git,仓库很快就会变得又大又乱。 明明只改了几行 RTL,git status 却刷出一大片 .runs、.cache、.gen、波形文件和日志。再过几轮协作,仓库里混进一堆自动生成内容,后面…

2026/7/19 5:24:13 阅读更多 →

日新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/19 0:00:40 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/19 0:00:40 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/19 0:00:40 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/19 0:00:40 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/19 0:00:40 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/19 0:00:40 阅读更多 →

月新闻