18 KiB
description, icon, lang
| description | icon | lang |
|---|---|---|
| OpenHuman 代码库的深度架构参考 —— 仓库布局、运行时范围、双 socket 同步、RPC 流程。 | code-branch | zh-CN |
OpenHuman 架构
基于 Rust 构建的加密社区 AI 超级助手。
OpenHuman 是一款为加密货币生态系统量身打造的跨平台通信与自动化平台。单一的 React + Rust(Tauri)代码库可以面向多个平台;我们目前为用户文档和发布的仅是桌面端 —— Windows、macOS 和 Linux。Android、iOS 和 Web 尚未在当前文档或发布中支持。技术栈包括一个托管的 Node.js 运行时,用于支持工具能力的技能;持久化的 Rust 原生 WebSocket 基础设施;以及一个 AI 工具协议,让语言模型实时调用任何已连接的服务。
仓库布局(monorepo)
| 路径 | 内容 |
|---|---|
app/ |
Yarn workspace openhuman-app:Vite/React UI(app/src/)、Tauri 壳层(app/src-tauri/)、Vitest 测试 |
仓库根目录 src/ |
Rust openhuman_core 库 + openhuman-core CLI 二进制文件 —— 核心服务器、JSON-RPC、一等 JavaScript 运行时(src/openhuman/javascript/),由托管的 Node.js 实现驱动、频道、内存等 |
Cargo.toml(根目录) |
构建 openhuman-core 二进制文件(cargo build --bin openhuman-core),staging 到 app/src-tauri/binaries/ 以供桌面打包 |
skills/ |
运行时消耗的技能包 |
docs/ |
本书 + 每棵树指南(docs/src/、docs/src-tauri/) |
桌面应用 WebView 从 app/ 加载 UI;繁重的 RPC 和技能在 openhuman-core 进程中运行,可通过 HTTP 从 Tauri 主机访问(core_rpc_relay)。
平台覆盖范围
今天支持的(终端用户): 桌面端。Windows、macOS、Linux(原生安装包)。
尚未支持: Android、iOS、独立 Web 客户端(仓库中可能以实验性目标存在;不要视为产品就绪)。
OpenHuman(已发布)
|
Desktop
/ | \
Windows macOS Linux
x64 x64 x64
ARM64 ARM64 ARM64
Tauri v2 将 Rust 核心编译为每个平台的原生二进制文件,将 React 前端作为轻量级 WebView 嵌入。桌面构建产出 .dmg、.msi、.AppImage 和 .deb 安装包。额外目标(移动端、Web)在明确文档化支持之前均超出范围。
高层架构
+------------------------------------------------------------------+
| React 前端 |
| Redux Toolkit | Socket.io 客户端 | MCP 传输层 | UI |
+------------------------------------------------------------------+
| Tauri IPC 桥接 |
+------------------------------------------------------------------+
| Rust 核心引擎 |
| |
| +------------------+ +------------------+ +-----------------+ |
| | QuickJS 技能 | | Socket 管理器 | | AI 加密 | |
| | 运行时引擎 | | (持久化 WS) | | & 内存存储 | |
| +------------------+ +------------------+ +-----------------+ |
| |
| +------------------+ +------------------+ +-----------------+ |
| | 技能注册表 | | Cron 调度器 | | 会话 & 认证 | |
| | & 桥接 API | | (5s tick 循环) | | 管理 | |
| +------------------+ +------------------+ +-----------------+ |
| |
| +------------------+ +------------------+ +-----------------+ |
| | Telegram | | SQLite 存储 | | OS 钥匙串 | |
| | 集成 | | (rusqlite) | | 集成 | |
| +------------------+ +------------------+ +-----------------+ |
+------------------------------------------------------------------+
|
+-----------+-----------+
| |
后端服务 外部 API
(Socket.io 服务器) (Telegram 等)
前端通过两种方式与 openhuman Rust 核心通信:用于一小部分壳层命令的 Tauri IPC(窗口、AI 文件辅助函数、core_rpc_relay),以及用于业务逻辑和技能的 HTTP JSON-RPC。核心拥有持久连接(如适用)、内存/功能的加密工作,以及 QuickJS 沙盒化技能执行。
Rust 驱动的性能
OpenHuman 选择 Tauri + Rust 而非 Electron,基于根本的性能和安全原因:
| 指标 | OpenHuman(Tauri + Rust) | 典型 Electron 应用 |
|---|---|---|
| 二进制体积 | 取决于功能(CEF 运行时 + 技能包占主导) | ~150 MB+ |
| 每技能上下文内存 | ~1-2 MB(QuickJS) | ~150 MB+(Chromium 渲染器) |
| 冷启动 | 亚 500ms | 2-5 秒 |
| 垃圾回收暂停 | 无(Rust 所有权模型) | V8 GC 暂停 |
| 内存安全 | 编译期保证 | 运行时异常 |
| TLS 实现 | rustls(无 OpenSSL 依赖) | Chromium 的 BoringSSL |
这对加密平台为何重要:交易员和分析师在运行 OpenHuman 的同时,还会运行资源密集型工具、图表软件、多个浏览器标签、交易终端。原生二进制文件加上亚 500ms 启动意味着应用感觉像原生应用,不会碍事。零 GC 暂停意味着实时价格推送和警报永远不会因内存管理而延迟。
Tokio 异步运行时驱动所有 I/O。WebSocket 连接、HTTP 请求、文件操作和技能间通信,都是线程池上的非阻塞任务。数千个并发操作(技能执行、cron job、socket 事件)共享一小套固定的 OS 线程。
实时 Socket 基础设施
OpenHuman 实现了双 socket 架构:桌面端使用 Rust 原生 WebSocket 客户端,Web 端使用 JavaScript Socket.io 客户端。Rust 实现能在应用后台存活,独立于 WebView 运行,并通过 rustls 处理 TLS。
桌面模式: Web 模式:
+-------------+ +-------------+
| React UI | | React UI |
+------+------+ +------+------+
| Tauri IPC | Direct
+------+------+ +------+------+
| Rust Socket | | JS Socket |
| Manager | | .io Client |
+------+------+ +------+------+
| tokio-tungstenite | Socket.io
| + rustls TLS | (websocket/polling)
+------+------+ +------+------+
| Backend | | Backend |
+-------------+ +-------------+
Rust Socket 管理器通过原始 WebSocket 实现 Engine.IO v4 + Socket.IO v4 帧:
- 握手:WebSocket 连接、Engine.IO OPEN(提取
sid、pingInterval、pingTimeout)、带 JWT 认证的 Socket.IO CONNECT、CONNECT ACK - 保活:响应 Engine.IO PING 以 PONG;超时阈值 =
pingInterval + pingTimeout + 5s(默认:50 秒) - 重连:指数退避,从 1 秒到最大 30 秒。成功连接丢失后重置为 1s;如果连接从未建立则持续增长
- CORS 绕过:Rust
reqwestHTTP 客户端直接发起外部 API 调用,不受浏览器 CORS 限制
socket 连接在所有技能间共享。当事件到达时,socket 管理器通过异步消息通道将它们路由到相应的技能。这完全消除了每个技能的连接开销。
tool:sync 协议:每次 socket 连接和技能生命周期变化时,客户端都会发出一个 tool:sync 事件,包含可用工具的完整列表及其连接状态。这使后端 AI 系统能实时感知所有能力。
技能运行时引擎
OpenHuman 的决定性能力是其运行在 Rust 进程内部的沙盒化 JavaScript 执行引擎。技能是轻量级自动化脚本,通过自定义工具、集成和定时任务扩展平台。
+---------------------------------------------------------------+
| RuntimeEngine |
| |
| +-------------------+ +-------------------+ |
| | SkillRegistry | | CronScheduler | |
| | (HashMap + MPSC) | | (5s tick loop) | |
| +--------+----------+ +--------+----------+ |
| | | |
| +--------v----------+ +--------v----------+ +----------+ |
| | JavaScript Layer | | runtime_node | | Bridge | |
| | skill metadata | | managed Node.js | | APIs | |
| | + prompt context | | system/bundled | +----+-----+ |
| | + tool discovery | | tool execution | | |
| +-------------------+ +-------------------+ | |
| | |
| +---------------------------------------------------v-----+ |
| | net | db | store | cron | log | tauri | | |
| | HTTP SQLite KV Schedule Log Platform| | |
| +------------------------------------------------------+ | |
+---------------------------------------------------------------+
Node.js 运行时:核心尽可能解析兼容的系统 node,否则将托管发行版安装到 OpenHuman 缓存中。技能主要暴露工具元数据,并使用运行时桥接来列出和执行工具,而非在核心内运行隔离的 QuickJS VM。
| 参数 | 值 |
|---|---|
| 公共语言槽位 | javascript |
| 当前 JS 后端 | runtime_node |
| 托管 Node 版本 | 默认 v22.11.0 |
| 运行时来源 | 系统 node 或托管安装 |
| 完整性验证 | 针对 SHASUMS256.txt 的 SHA-256 |
工具桥架构:SKILL.md 包提供元数据、指令和可选的捆绑 JS 辅助函数。Rust 核心拥有权威的工具注册表,JavaScript 运行时桥接列出工具并将具名工具调用分派到核心或 Node-backed 辅助函数中。
桥接 API 向运行时桥接和 Node-backed 辅助函数暴露平台能力:
| 桥接 | 能力 |
|---|---|
| net | 通过 reqwest 的 HTTP fetch(默认 30s 超时,所有方法) |
| db | 通过 rusqlite 的每个技能 SQLite 数据库 |
| store | 键值持久化 |
| cron | 定时注册(6 字段 cron 表达式) |
| log | 通过 Rust log crate 的结构化日志 |
| tauri | 平台检测、通知、白名单环境变量 |
技能发现 使用 SKILL.md 加上可选的捆绑资源:
| 字段 | 用途 |
|---|---|
name |
人类可读的显示名称 |
description |
触发/选择摘要 |
metadata.id |
存在时的稳定技能 slug |
allowed-tools |
工具允许列表指引 |
| 捆绑资源 | 脚本、参考、资源 |
技能从 GitHub 仓库同步并在运行时发现。执行不再建模为每个技能一个嵌入式 QuickJS VM;JavaScript 行为通过共享运行时桥接流动。
Cron 调度器:一个 5 秒 tick 循环对照 UTC 时间检查所有已注册的调度,使用 cron crate 进行表达式解析。当调度触发时,调度器向技能的通道发送 CronTrigger 消息,调用技能的 onCronTrigger() 处理程序。
AI & 工具协议(MCP)
OpenHuman 实现了模型上下文协议,一个基于 Socket.io 的 JSON-RPC 2.0 层,让 AI 模型发现并由技能暴露的工具。
用户提示
|
v
AI 模型(后端)
|
| 1. mcp:listTools --> 前端/Rust 聚合所有技能工具
| <-- 工具目录
|
| 2. 决定调用哪个工具
|
| 3. mcp:toolCall { skillId__toolName, arguments }
| |
| v
| Socket 管理器路由到技能注册表
| |
| v
| QuickJS 技能实例执行工具
| |
| v
| 桥接 API 调用(HTTP、DB 等)
| |
| <-- mcp:toolCallResponse { result }
|
v
AI 对用户的响应
传输:每次请求 30 秒超时,mcp: 事件前缀,请求 ID 在待处理响应映射中跟踪。工具名称以 skillId__toolName 命名空间化,以实现明确路由。
工具同步:tool:sync 事件在每次 socket 连接和技能状态变化时广播完整的工具清单、技能 ID、名称、连接状态和工具列表。后端 AI 系统始终拥有可用能力的最新视图。
AI 记忆系统:
| 功能 | 实现 |
|---|---|
| 静态加密 | 带 Argon2id 密钥派生的 AES-256-GCM |
| 分块 | 每块 512 token,64 token 重叠 |
| 搜索 | 混合:70% 向量相似度 + 30% FTS5 全文 |
| 嵌入 | OpenAI text-embedding-3-small |
| 知识图谱 | 通过 REST API 的 Neo4j,用于实体关系 |
| 会话 | 带压缩和工具压缩的 JSONL 转录 |
记忆加密密钥通过 Argon2id 从用户凭证派生,确保记忆文件在未经认证的情况下不可读。混合搜索结合语义理解(向量相似度)和关键词精确度(SQLite FTS5)以实现可靠的召回。
安全架构
+-------------------------------------------------------------------+
| 安全层 |
| |
| +------------------+ +------------------+ +------------------+ |
| | OS 钥匙串 | | AES-256-GCM | | 沙盒化 | |
| | (macOS/Win/Lin) | | 内存加密 | | QuickJS 每 | |
| | 用于凭证 | | + Argon2id KDF | | 技能 (64 MB) | |
| +------------------+ +------------------+ +------------------+ |
| |
| +------------------+ +------------------+ +------------------+ |
| | 一次性 | | rustls TLS | | 无 localStorage | |
| | 登录 token | | 用于所有网络 | | 存储敏感数据 | |
| | (5-min TTL) | | 连接 | | | |
| +------------------+ +------------------+ +------------------+ |
+-------------------------------------------------------------------+
- 凭证存储:通过
keyringcrate 的 OS 钥匙串集成(macOS Keychain、Windows Credential Manager、Linux Secret Service),仅限桌面端 - 内存加密:带 Argon2id 密钥派生的 AES-256-GCM。所有 AI 内存静态加密
- 技能沙盒化:每个 QuickJS 实例都有强制内存限制(默认 64 MB)和栈限制(512 KB)。禁止跨技能内存访问
- 认证交接:Web 到桌面认证使用 5 分钟 TTL 的一次性登录 token,通过 Rust HTTP 客户端交换(绕过 CORS)
- 网络 TLS:所有 WebSocket 和 HTTP 连接使用 rustls,不依赖平台 OpenSSL
- 状态管理:敏感数据保存在 Redux(内存)和 OS 钥匙串(持久化)中。凭证或 token 不使用 localStorage
- 提示注入防护:用户提示在模型/工具执行前经过规范化/评分,并在服务器端强制执行(
allow | review | block)。详见docs/PROMPT_INJECTION_GUARD.md
端到端数据流
从用户操作到外部服务再返回的完整流程:
用户在聊天 UI 中输入命令
|
v
React 前端分派到 AI 提供商
|
v
AI 模型接收提示 + 工具目录(通过 tool:sync)
|
v
AI 决定调用技能工具(例如,发送 Telegram 消息)
|
v
通过 Socket.io 发送 mcp:toolCall 事件
|
v
Socket 管理器(Rust)接收事件,解析 skillId__toolName
|
v
技能注册表通过 MPSC 通道将消息路由到正确的 QuickJS 实例
|
v
QuickJS 技能执行工具处理程序
|
v
桥接 API:net.rs 通过 reqwest 发起 HTTP 请求(无 CORS,rustls TLS)
|
v
外部服务响应(例如,Telegram API)
|
v
结果回流:桥接 -> QuickJS -> 注册表 -> Socket -> MCP -> AI -> UI
|
v
用户在聊天界面中看到结果
每一层都是异步且非阻塞的。Rust 核心在固定的 Tokio 线程池上处理数千个并发的技能执行、cron 触发和 socket 事件。
技术栈
| 层 | 技术 | 原因 |
|---|---|---|
| 前端 | React 19, TypeScript 5.8 | 现代组件模型,类型安全 |
| 状态 | Redux Toolkit + Persist | 可预测状态,支持离线持久化 |
| 构建 | Vite 7 | 亚秒级 HMR,优化的生产构建 |
| 样式 | Tailwind CSS | 工具优先,一致的设计系统 |
| 框架 | Tauri v2 | 原生跨平台,开销最小 |
| 语言 | Rust (2021 edition) | 内存安全,零成本抽象 |
| 异步 | Tokio | 高性能异步 I/O 运行时 |
| JS 运行时 | Node.js | 用于工具辅助函数和技能相关 JS 的托管 V8 运行时 |
| 数据库 | SQLite (rusqlite) | 嵌入式,零配置,每技能隔离 |
| WebSocket | tokio-tungstenite + rustls | 持久连接,原生 TLS |
| HTTP | reqwest | 异步 HTTP,支持 rustls + native-tLS 双栈 |
| 加密 | aes-gcm + argon2 | AES-256-GCM 加密,Argon2id 密钥派生 |
| 调度 | cron crate + 自定义调度器 | 标准 cron 表达式,5 秒精度 |
| Telegram | 已移除 | Telegram 集成已移除 |
| 实时 | Socket.io(客户端) | 双向基于事件的通信 |
| AI | MCP(JSON-RPC 2.0) | LLM 集成的标准化工具协议 |
| 搜索 | OpenAI 嵌入 + SQLite FTS5 | 混合语义 + 关键词搜索 |
| 图谱 | Neo4j | 实体关系知识图谱 |