阿里钉钉"悟空"App拆解:一个AI Agent桌面应用是怎么造出来的

最近有人用逆向分析的方式,把阿里钉钉团队开发的一款名叫”悟空(Wukong)”的 AI Agent 桌面客户端拆开看了个透。
所谓逆向分析,就是不看源代码,只拿到最终的软件包,通过分析它的目录结构、可执行文件里的符号信息、依赖的动态库、以及打包进去的资源文件,来推断这个应用到底是怎么构建的。这个方法在工程师圈子里很常见,尤其是研究竞品技术架构时经常用到。
这篇文章把逆向分析得到的所有信息整理出来,带你系统看看这个产品在技术层面做了什么。
这是什么产品,从哪里来
先说基本信息。
这款应用的正式名称是 Wukong(悟空),Bundle ID 是 com.dingtalk.real,主可执行文件叫 DingTalkReal,目前版本是 0.9.0,还处于早期阶段。从内部代号来看,开发团队把这个项目叫做”Real”,构建系统使用的是 Jenkins CI,流水线名称是 real-wukong-release,构建用户名是 yuanzhan。
它只支持 macOS 14 及以上系统,并且仅支持 Apple Silicon(也就是 M 系列芯片),不支持老的 Intel Mac。
开发团队是钉钉,背靠阿里巴巴。
应用注册了一个自定义 URL Scheme:wukong://,这意味着其他应用或网页可以直接唤起它。
技术选型:为什么不用 Electron
说到桌面 App 的开发框架,大多数人第一个想到的是 Electron——VS Code、Slack、Discord 都用它。Electron 的原理是把 Node.js 和 Chromium 浏览器一起打包进应用,前端写什么网页就显示什么,开发效率极高,但代价是内存占用大、启动慢、包体积臃肿。
悟空选择了 Tauri 2.x + Rust,这是一个完全不同的路线。
Tauri 的思路是:主程序用 Rust 写(性能好、内存安全),前端界面用系统自带的 WebKit 渲染(不像 Electron 那样自己打包一个 Chromium),两者之间通过 IPC(进程间通信)机制交互。这样的好处是包体积小得多,性能也更好。
从分析结果来看,悟空的主可执行文件 DingTalkReal 只有 122MB,而且包含了大量业务逻辑。相比之下,一个中等规模的 Electron 应用光框架本身就要占 200MB 以上。
前端 UI 跑在 WebView 里,Tauri 生态里通常配合 React、Vue 或 Svelte 这类前端框架使用。IPC 通信走的是 Tauri 自定义协议 tauriipc://,并且启用了 Isolation Pattern 安全隔离模式——这个机制的作用是防止前端代码直接调用敏感的系统接口,所有操作都要经过 Rust 主进程的审查和代理。
除了核心框架之外,悟空还链接了大量 macOS 系统原生框架:
-
WebKit + JavaScriptCore:负责 WebView 渲染和 JavaScript 执行 -
AVFoundation + AVFAudio + CoreMedia:音视频处理 -
ScreenCaptureKit:屏幕截图和录制 -
CoreLocation:地理定位 -
UserNotifications:系统通知 -
OSAKit:AppleScript 自动化(可以控制系统上其他应用) -
Metal + QuartzCore:GPU 渲染加速 -
CloudKit:iCloud 数据同步 -
CoreData:本地数据持久化 -
Security:密钥链和加密 -
IOKit:硬件交互 -
SystemConfiguration:网络配置
这个依赖列表说明悟空对 macOS 系统能力的调用相当全面,已经不是一个普通的聊天 App,而是深度集成了操作系统的工具平台。
包内目录结构:应用里藏了什么
从 App Bundle 的目录结构可以看出这个应用打包了哪些东西:
主程序目录(MacOS/)里除了主执行文件,还有一个独立的命令行工具 real-cli(2.8MB),供脚本或终端调用。
资源目录(Resources/)里有几个值得注意的子目录:
browser-runtime/:一个用 TypeScript 写的浏览器自动化微服务,后面会详细介绍。
bundled-skills/:内置技能包,以 zip 格式打包进去的功能模块。
dws/:DWS 内部服务目录,DWS 是一个版本号为 0.2.19 的服务守护进程。
environment/:运行环境管理相关文件,控制各种运行时组件的安装和版本。
mbb-skills/:针对特定网站的浏览器增强技能,比如 12306 查票、携程订机票、大众点评查信息等。
real_networking/:网络层,包含了一个叫做 GaeaMac.framework 的阿里内部网络框架。这个框架包含 AI、Aladdin、Base、Bridge 等子模块,并且有 Wukong 专用的头文件,说明是针对这个产品定制的。
python/:预留的 Python 目录(目前是空的,但方向已经定了)。
Agent 运行时:程序的大脑是怎么工作的
这是悟空最核心的部分。从 Rust 源码的路径信息中,可以推断出整个 Agent 运行时的设计思路。
两套 Agent 引擎并行运行
悟空内部有两套 Agent 循环引擎:
Real Loop(主 Agent 循环引擎)负责处理整体流程:命令处理、消息格式转换、对话记忆压缩、工具定义、沙箱安全策略加载,以及一个叫做 session_approval_memory 的模块——这个模块记录用户对各种操作的授权决策,是”人在环(HITL,Human-in-the-Loop)”机制的核心,确保 AI 在执行敏感操作前需要获得用户许可。
Spark Loop(自研 Agent 引擎,代号 AllSpark)是钉钉自己造的 Agent 内核,采用了 DDD(领域驱动设计)架构,分为三层:
-
应用层(Application):流式服务实现、会话记忆刷新 -
领域层(Domain):Agent 状态压缩、LLM 交互抽象、会话实体 -
基础设施层(Infrastructure):LLM 适配器、沙箱网关、”Soul”模块(Agent 的人格和记忆)、系统提示词模板
这种分层架构的意义在于,领域逻辑不依赖具体实现,换一个 LLM 或者换一套存储方案,核心逻辑不需要改。
支持的 Agent 类型
悟空是一个多 Agent 宿主平台,可以同时运行不同类型的 Agent 引擎:
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这意味着悟空不绑死在某一个 AI 模型上,用户可以选择用哪个引擎来执行任务。
LLM 多后端:接了哪些大模型
在大模型接入层面,从 AllSpark 的基础设施代码中可以推断出三个适配器:
MaaS(阿里云模型服务):请求结构支持 model、max_tokens、tools、stream、enable_thinking、tool_choice、parallel_tool_calls、temperature、top_p、top_k、min_p、extra_body、cache_control 等参数。其中 enable_thinking 是思考模式开关,prompt_cache_hit_tokens 用来统计提示词缓存命中情况(有助于降低成本)。
Qwen(通义千问):使用 OpenAI 兼容格式,同样支持 enable_thinking。
OpenAI:标准的 Chat Completions 格式。
三个适配器全部支持:流式输出(streaming)、工具选择(tool_choice)、并行工具调用(parallel_tool_calls)、用量统计(usage tracking)。
内嵌运行时:自带了一整套开发环境
这里是悟空比较有意思的地方——它把执行代码所需的运行时环境全部打包进去了,用户不需要自己安装任何东西:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这些运行时通过 resource_manifest.json 统一管理,支持按平台和使用场景差异化分发。
内置本地 Qwen 模型这一点值得关注:这意味着部分推理任务可以完全在本地完成,不需要联网,也不会把数据发到云端。
浏览器自动化:Agent 是怎么操控浏览器的
browser-runtime 是一个独立的 TypeScript 微服务,专门处理浏览器自动化任务。它的技术栈是:
-
Playwright(playwright-core 1.58.2):浏览器自动化引擎,可以控制 Chrome 执行点击、输入、截图等操作 -
Express 5:提供 HTTP API,让主程序可以发指令给浏览器 -
WebSocket(ws 8.19.0):处理实时通信 -
Bun:运行时
从源码路径可以看出,这个模块的功能相当完整:
-
cdp.ts:Chrome DevTools Protocol 客户端(这是控制 Chrome 的底层协议) -
chrome.ts:Chrome 启动和管理 -
client-actions.ts:页面操作,包括点击、输入、内容观察等 -
navigation-guard.ts:导航守卫(防止 Agent 误操作跳转到危险网址) -
profiles.ts:浏览器 Profile 管理(可以保存不同用户的登录状态) -
form-fields.ts:表单字段处理 -
pw-ai-module.ts:Playwright 的 AI 增强模块 -
extension-relay.ts:Chrome 扩展中继(可与浏览器扩展交互)
安全方面,这个微服务实现了多层认证:Bridge 认证注册、CSRF 防护、控制认证(含自动 Token)、HTTP 认证、扩展中继认证。防止外部程序或恶意网页通过这个微服务控制用户的浏览器。
技能系统:功能如何扩展
悟空的功能扩展通过”技能(Skills)”系统来实现,分三类:
内置技能包(Bundled Skills):打包在应用内的基础技能,目前包括:钉钉工作台、Word 文档处理、PPT 演示文稿处理、Excel 电子表格处理、PDF 文档处理、PDF 转 Word,以及一个”技能创建器”——这是一个元技能,让用户可以在 AI 的帮助下创建新技能。
浏览器增强技能(MBB Skills):针对具体网站定制的自动化操作,已知的有:
-
12306-train-query:12306 火车票查询 -
ctrip-flight-search:携程航班查询 -
dianping-info-query:大众点评信息查询
用户自装技能:支持从本地路径或远程 URL 安装技能包。
技能管理的核心 API 包括:
-
search_skills:搜索可用技能 -
use_skill(skill_name, level="preview"|"full"):激活技能,支持预览和完整两种加载级别 -
cli_skills_install_local/cli_skills_install_url:安装技能 -
cli_skills_toggle_enabled:启用或禁用技能 -
cli_skills_delete:删除技能
技能发现机制采用”渐进式披露”设计——先展示常用技能,用户有需要时再搜索更多,避免一次性暴露太多选项让用户不知所措。技能注入策略(skill_injection_policy)支持显式和自动两种模式,可以控制技能在什么时机被加载进 Agent 的上下文。
内置工具集:Agent 能做哪些具体操作
从 real_loop/types.rs 中可以提取出 Agent 默认携带的工具清单:
|
|
|
|---|---|
understand_image_content |
|
parse_file |
|
text2image |
|
image2image |
|
text2video |
|
read_url_v2 |
|
reader_html_content |
|
internet-search |
|
browser_start |
|
browser_stop |
|
browser_screenshot |
|
browser_wait_for_download |
|
browser_status |
|
execute_shell |
|
cron_* |
|
这套工具让 Agent 具备了一套完整的”手脚”:能看(截图、读网页)、能写(文件处理)、能操作(浏览器、Shell)、能生成(图像、视频)、能定时执行任务。
多渠道分发:一个 Agent,多个入口
同一个 Agent 可以通过不同的渠道与用户交互:
-
钉钉:通过 AI Card(流式卡片)和 Stream 长连接,支持 IM 机器人和群聊两种场景 -
Slack:通过 OAuth API,支持线程回复 -
WhatsApp:独立集成模块 -
Agent Device:通过 RPC 接口支持设备注册、更新、列表和删除
消息事件的流转顺序是:任务开始(TaskStart)→ 工具使用前(PreToolUse)→ 工具使用后(PostToolUse)→ 权限请求(PermissionRequest)→ 任务完成或任务出错(TaskComplete/TaskError)。
这个设计意味着同一个 Agent 逻辑可以复用在多个平台,不需要为每个渠道单独实现一套 AI 逻辑。
MCP 协议支持:连接外部工具的标准接口
悟空原生支持 **MCP(Model Context Protocol)**协议。这是一个由 Anthropic 提出的开放协议,让 AI 应用可以通过标准化的方式连接外部工具和数据源。
实现上包括:
-
mcp/runtime.rs:MCP 服务器运行时 -
mcp/config.rs:通过mcpServerConfig.json配置文件管理 MCP 服务器连接
有了 MCP 支持,悟空可以接入社区里已有的大量 MCP 工具,比如数据库查询、文件系统操作、邮件收发等,而不需要为每个工具都自己写适配代码。
安全架构:Agent 权限怎么管
当一个 AI 能控制浏览器、执行命令、读写文件的时候,安全就是必须认真对待的问题。悟空在安全上做了多层设计:
沙箱系统:使用 SandboxV2Config 配置沙箱,支持沙箱级别、Profile 和授权根路径,并且支持沙箱状态的保存和恢复。execute_shell 工具执行的命令都运行在沙箱内,不能随意访问系统文件。
人在环(HITL)权限审批:session_approval_memory 模块记录用户的授权决策,支持”永远允许”和”永远拒绝”两种持久化策略。评估模式下可以设置 EvalAutoAllow 自动通过,方便批量测试。
敏感路径过滤:sensitive_paths.rs 负责屏蔽 ~/.real/.acp 等内部目录,防止 Agent 访问自身的配置和凭证文件。
Prompt 安全护栏:PromptGuardrailsConfig 对输入到 LLM 的提示词进行安全检查,防止提示词注入攻击。
Tauri 安全机制:Isolation Pattern 隔离前端 WebView 的 IPC 调用,加上 CSP(内容安全策略)保护,防止前端代码越权操作。
凭证加密:LLM API Key 和登录凭证通过 PreferenceCrypto 加密存储,支持从历史明文格式自动迁移到加密存储,还有 LLM 凭证的过期和刷新机制。
数据存储:信息保存在哪里
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
对话记忆存在本地 SQLite 里,涉及 memory_summarizer.rs 模块——长对话会被自动压缩成摘要,防止上下文窗口超出限制。
系统权限:申请了哪些敏感权限
应用在安装后会申请以下系统权限:
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
其中 AppleEvents 权限比较特殊——它允许应用通过 AppleScript 控制系统上其他应用(比如发送 Terminal 命令、操作 Safari 等),权限范围相当大。
技术总结
把以上所有信息汇总起来,悟空的技术架构可以归纳为以下几个特点:
架构选型务实:选 Tauri + Rust 而不是 Electron,主二进制 122MB 包含所有逻辑,兼顾了性能和可维护性。
多 Agent 引擎共存:不依赖单一 AI 模型,自研的 Spark 引擎和 Claude Code、Gemini CLI、Codex CLI 并列支持,降低了对单一供应商的依赖。
工具能力全面:代码执行、浏览器自动化、屏幕截图、UI 自动化、文件处理、文生图/视频,覆盖了 Agent 在桌面端完成任务所需的主要能力。
自包含运行时:内嵌 Bun、Node.js、Python、Chromium、本地 Qwen 模型,用户不需要手动配置开发环境。
标准协议优先:原生支持 MCP 协议,LLM 接口兼容 OpenAI 格式,降低了生态接入的成本。
安全设计分层:沙箱、HITL 权限审批、Prompt 护栏、凭证加密,每一层都有对应的实现,而不是依赖单一的安全机制。
DDD 内核架构:AllSpark 内核采用领域驱动设计,应用层/领域层/基础设施层分离,方便长期维护和迭代。
这不是一个普通的 AI 聊天窗口,而是一个能控制电脑、操作浏览器、执行代码、管理定时任务、跨平台分发消息的 AI Agent 操作平台。它目前仍然是 0.9.0 版本,但从技术架构的完整程度来看,核心框架已经基本成型。
本文所有信息均来源于对 Wukong App Bundle 的逆向分析结果,分析方法包括:App Bundle 目录结构分析、二进制符号表提取、动态库依赖分析(otool -L)、资源文件读取。
夜雨聆风