15 KiB
15 KiB
ZCLAW 独立化架构重构计划
Context
问题背景
- 外部进程不稳定 - OpenFang 作为独立进程运行,启动失败、版本兼容问题频发
- 代码分散 - ZCLAW 和 OpenFang 逻辑分离,维护困难
- 分发复杂 - 用户安装需要额外配置 OpenFang 运行时
- 技术债务 - 架构需要清理,希望借此机会彻底解决
目标
将 ZCLAW 从"基于 OpenFang 定制"转变为完全独立的 AI Agent 桌面系统:
- 代码所有权:所有代码在 ZCLAW 仓库
- 架构自主:完全自由设计
- 品牌独立:无 OpenFang/OpenClaw 痕迹
- 技术栈独立:选择最适合的技术
策略
混合策略:核心能力自研,通用能力借鉴设计,代码层面完全原创
Architecture
Crate 结构
ZCLAW/
├── crates/ # Rust Workspace
│ │
│ ├── zclaw-types/ # L1: 基础类型(无依赖)
│ │ ├── AgentId, SessionId, Message
│ │ ├── Capability, Tool, Event
│ │ ├── Config, Error
│ │ └── 共享 trait 定义
│ │
│ ├── zclaw-memory/ # L2: 存储层(依赖 types)
│ │ ├── KV Store(Agent 配置、状态)
│ │ ├── Session Manager(对话历史)
│ │ ├── Semantic Search(向量搜索)
│ │ └── SQLite 持久化
│ │
│ ├── zclaw-runtime/ # L3: 运行时(依赖 types, memory)
│ │ ├── LLM Drivers(Anthropic, OpenAI, Gemini, Local)
│ │ ├── Tool Runner(23 个内置工具)
│ │ ├── Agent Loop(消息循环、流式处理)
│ │ ├── Loop Guard(防循环)
│ │ └── Session Compactor(上下文压缩)
│ │
│ ├── zclaw-kernel/ # L4: 核心协调(依赖所有下层)
│ │ ├── Agent Registry(注册、生命周期)
│ │ ├── Scheduler(配额、调度)
│ │ ├── Capability Manager(权限)
│ │ ├── Event Bus(事件发布)
│ │ ├── Workflow Engine(工作流)
│ │ ├── Trigger Engine(触发器)
│ │ └── Supervisor(健康监控)
│ │
│ ├── zclaw-skills/ # 技能系统
│ │ ├── Skill Loader(TOML/SKILL.md 解析)
│ │ ├── Skill Runner(Python/WASM/PromptOnly)
│ │ └── Bundled Skills(内置技能)
│ │
│ ├── zclaw-hands/ # Hands 自主能力
│ │ ├── Browser Hand(整合现有 browser/)
│ │ ├── Collector Hand
│ │ ├── Researcher Hand
│ │ └── 其他 Hands
│ │
│ ├── zclaw-channels/ # 通道适配器
│ │ ├── Channel Trait
│ │ ├── Telegram/Discord/Slack 等
│ │ └── Bridge Manager
│ │
│ └── zclaw-protocols/ # 协议支持
│ ├── MCP Client/Server
│ └── A2A Protocol
│
├── desktop/
│ ├── src-tauri/ # Tauri 应用
│ │ ├── src/
│ │ │ ├── lib.rs # 主入口,Kernel 初始化
│ │ │ ├── commands/ # Tauri 命令封装
│ │ │ ├── intelligence/ # 已有智能层(保留)
│ │ │ ├── browser/ # 已有浏览器(保留,后续整合到 zclaw-hands)
│ │ │ └── state.rs # 应用状态
│ │ └── Cargo.toml # 依赖内部 crates
│ └── src/ # React 前端(保持不变)
│
└── Cargo.toml # Workspace 定义
依赖关系
zclaw-types (无依赖)
↑
zclaw-memory (→ types)
↑
zclaw-runtime (→ types, memory)
↑
zclaw-kernel (→ types, memory, runtime)
↑
desktop/src-tauri (→ kernel, skills, hands, channels, protocols)
Core Modules
zclaw-types
// 核心 ID 类型
pub struct AgentId(Uuid);
pub struct SessionId(Uuid);
pub struct ToolId(String);
// 消息类型
pub enum Message {
User { content: String },
Assistant { content: String, thinking: Option<String> },
ToolUse { tool: ToolId, input: Value },
ToolResult { tool: ToolId, output: Value, error: bool },
}
// Agent 配置
pub struct AgentConfig {
pub id: AgentId,
pub name: String,
pub model: ModelConfig,
pub system_prompt: String,
pub capabilities: Vec<Capability>,
pub tools: Vec<ToolId>,
}
// 能力定义
pub enum Capability {
ToolInvoke(String),
MemoryRead(String),
MemoryWrite(String),
NetConnect(String),
ShellExec(String),
AgentSpawn,
AgentMessage(String),
}
// 统一错误类型
pub enum ZclawError {
NotFound(String),
PermissionDenied(String),
LlmError(String),
ToolError(String),
StorageError(String),
}
zclaw-memory
pub struct MemoryStore {
db: Arc<Mutex<Connection>>,
}
impl MemoryStore {
// Agent 配置持久化
pub async fn save_agent(&self, agent: &AgentConfig) -> Result<()>;
pub async fn load_agent(&self, id: &AgentId) -> Result<Option<AgentConfig>>;
pub async fn list_agents(&self) -> Result<Vec<AgentConfig>>;
// 会话管理
pub async fn create_session(&self, agent_id: &AgentId) -> Result<SessionId>;
pub async fn get_session(&self, id: &SessionId) -> Result<Option<Session>>;
pub async fn append_message(&self, session: &SessionId, msg: Message) -> Result<()>;
// KV 存储
pub async fn store(&self, agent: &AgentId, key: &str, value: &Value) -> Result<()>;
pub async fn recall(&self, agent: &AgentId, key: &str) -> Result<Option<Value>>;
// 语义搜索
pub async fn embed(&self, text: &str) -> Result<Vec<f32>>;
pub async fn search_similar(&self, query: &str, limit: usize) -> Result<Vec<MemoryEntry>>;
}
zclaw-runtime
// LLM 驱动 trait
#[async_trait]
pub trait LlmDriver: Send + Sync {
async fn complete(&self, req: CompletionRequest) -> Result<CompletionResponse>;
async fn stream(&self, req: CompletionRequest) -> Result<mpsc::Receiver<StreamEvent>>;
}
// 内置驱动实现
pub struct AnthropicDriver { api_key: SecretString }
pub struct OpenAiDriver { api_key: SecretString, base_url: String }
pub struct GeminiDriver { api_key: SecretString }
pub struct LocalDriver { base_url: String } // Ollama/LMStudio
// Agent 循环
pub struct AgentLoop {
driver: Arc<dyn LlmDriver>,
tools: Vec<Tool>,
memory: Arc<MemoryStore>,
loop_guard: LoopGuard,
}
impl AgentLoop {
pub async fn run(&self, session: SessionId, input: String) -> Result<AgentLoopResult>;
pub async fn run_streaming(&self, session: SessionId, input: String)
-> Result<mpsc::Receiver<LoopEvent>>;
}
zclaw-kernel
pub struct Kernel {
registry: AgentRegistry,
scheduler: Scheduler,
capabilities: CapabilityManager,
events: EventBus,
workflows: WorkflowEngine,
triggers: TriggerEngine,
supervisor: Supervisor,
memory: Arc<MemoryStore>,
}
impl Kernel {
pub async fn boot(config: KernelConfig) -> Result<Self>;
// Agent 生命周期
pub async fn spawn_agent(&self, config: AgentConfig) -> Result<AgentId>;
pub async fn kill_agent(&self, id: &AgentId) -> Result<()>;
pub async fn list_agents(&self) -> Result<Vec<AgentInfo>>;
// 消息处理
pub async fn send_message(&self, agent: &AgentId, msg: String)
-> Result<MessageResponse>;
pub async fn send_message_stream(&self, agent: &AgentId, msg: String)
-> Result<mpsc::Receiver<StreamEvent>>;
// 工作流
pub async fn run_workflow(&self, workflow_id: &str, input: Value) -> Result<Value>;
// 事件
pub fn subscribe(&self) -> broadcast::Receiver<Event>;
}
Tauri Integration
启动流程
// desktop/src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.setup(|app| {
// 1. 初始化内核
let runtime = tokio::runtime::Runtime::new().unwrap();
let kernel = runtime.block_on(async {
Kernel::boot(KernelConfig::load().await?).await
}).expect("Kernel boot failed");
// 2. 存储到应用状态
app.manage(Arc::new(kernel));
app.manage(runtime);
Ok(())
})
.invoke_handler(tauri::generate_handler![
// Agent 命令
agent_spawn, agent_kill, agent_list, agent_chat, agent_chat_stream,
// 配置命令
config_get, config_update,
// 工作流命令
workflow_list, workflow_run,
// 技能命令
skill_list, skill_install,
// Hands 命令
hand_trigger, hand_status,
// 记忆命令
memory_store, memory_recall, memory_search,
// 智能层命令(保留)
heartbeat_start, heartbeat_stop, reflection_reflect, identity_get,
])
.run(tauri::generate_context!())
}
关键变化
| 之前 | 之后 |
|---|---|
| 外部 OpenFang 进程 | 内部 Kernel 单例 |
| WebSocket 连接 localhost:4200 | 直接 Tauri 命令调用 |
| 启动脚本管理进程 | Tauri 应用内自动初始化 |
| 两个代码仓库 | 单一 ZCLAW 仓库 |
Migration Phases
阶段 0:准备(1 周)✅ 已完成
目标:workspace 编译通过
任务:
- 创建
crates/目录 - 创建根
Cargo.tomlworkspace 配置 - 创建各 crate 骨架(
zclaw-types,zclaw-memory,zclaw-runtime,zclaw-kernel) - 更新
desktop/src-tauri/Cargo.toml加入 workspace - 验证
cargo build成功
阶段 1:基础设施(2-3 周)✅ 已完成
目标:可以存储和加载 Agent 配置
任务:
- zclaw-types
- 定义 AgentId, SessionId, ToolId
- 定义 Message 枚举
- 定义 AgentConfig 结构
- 定义 Capability 枚举
- 定义 ZclawError
- zclaw-memory
- SQLite schema 设计(agents, sessions, kv, embeddings)
- 实现 MemoryStore
- Agent 配置 CRUD
- Session 管理
- KV 存储
- 基础语义搜索(可选:延后到阶段 4)
阶段 2:核心运行时(3-4 周)✅ 已完成
目标:可以与 LLM 对话并调用工具
任务:
- zclaw-runtime
- LlmDriver trait 定义
- AnthropicDriver 实现
- OpenAiDriver 实现(含 OpenAI-compatible providers)
- GeminiDriver 实现
- LocalDriver 实现(Ollama/LMStudio)
- Tool trait 和基础工具实现(file_read, file_write, shell_exec, web_fetch)
- AgentLoop 实现
- LoopGuard 实现(防循环)
- 流式响应支持
阶段 3:内核集成(2-3 周)✅ 已完成
目标:Tauri 应用可以创建 Agent 并对话
任务:
- zclaw-kernel
- AgentRegistry 实现
- Scheduler 实现(基础版)
- CapabilityManager 实现
- EventBus 实现
- Kernel 主结构
- boot() 初始化流程
- desktop/src-tauri
- lib.rs 集成 Kernel (kernel_commands 模块)
- Tauri 命令封装(kernel_init, agent_create, agent_chat 等)
- 保留外部 OpenFang 命令作为备选方案
- 前端适配(待实现)
阶段 4:扩展能力(4-6 周)✅ 已完成
目标:技能、Hands、通道功能正常
任务:
- zclaw-skills
- Skill manifest 定义
- SKILL.md 解析器
- SkillRunner trait
- PromptOnly 技能执行
- Python 技能执行(subprocess 隔离)
- 内置技能移植
- zclaw-hands
- Hand/Trigger trait 定义
- HandRegistry/TriggerRegistry 实现
- 整合现有 browser/ 模块(待完整移植)
- Collector Hand
- Researcher Hand
- 其他 Hands
- zclaw-channels
- Channel trait 定义
- ChannelBridge 管理器
- Telegram 适配器(骨架)
- Discord 适配器(骨架)
- Slack 适配器(骨架)
- Console 适配器(测试用)
- zclaw-protocols
- MCP Client 实现
- MCP Server 实现(待完善)
- A2A 协议支持(可选)
阶段 5:清理与优化(2-3 周)
目标:无外部依赖,单安装包可运行
任务:
- 移除
resources/openfang-runtime/ - 移除
start-all.ps1中的 OpenFang 启动逻辑 - 更新所有文档
- 更新 CLAUDE.md
- 性能优化
- 测试覆盖
- 发布准备
Verification
阶段验收标准
| 阶段 | 验收命令/方法 |
|---|---|
| 0 | cargo build 成功 |
| 1 | 运行单元测试验证 MemoryStore CRUD |
| 2 | CLI 测试:与 LLM 对话,工具调用正常 |
| 3 | pnpm tauri dev 启动应用,UI 可创建 Agent 并对话 |
| 4 | 技能加载、Hand 触发、通道消息正常 |
| 5 | 全新机器安装单一安装包可运行 |
最终验证清单
pnpm start:dev启动 Tauri 应用,无需外部进程- 可创建、配置、删除 Agent
- 可与 Agent 对话,流式响应正常
- 工具调用正常(文件读写、网络请求)
- 技能加载和执行正常
- Hands 触发正常(浏览器自动化等)
- 智能层功能正常(心跳、反思、身份)
- 打包后的安装程序可独立运行
Critical Files
需要修改的文件
Cargo.toml- 添加 workspace 配置desktop/src-tauri/Cargo.toml- 加入 workspace,更新依赖desktop/src-tauri/src/lib.rs- Kernel 初始化,命令注册start-all.ps1- 移除 OpenFang 启动逻辑CLAUDE.md- 更新架构说明
需要创建的文件
crates/zclaw-types/Cargo.tomlcrates/zclaw-types/src/lib.rscrates/zclaw-memory/Cargo.tomlcrates/zclaw-memory/src/lib.rscrates/zclaw-runtime/Cargo.tomlcrates/zclaw-runtime/src/lib.rscrates/zclaw-kernel/Cargo.tomlcrates/zclaw-kernel/src/lib.rscrates/zclaw-skills/Cargo.tomlcrates/zclaw-skills/src/lib.rscrates/zclaw-hands/Cargo.tomlcrates/zclaw-hands/src/lib.rscrates/zclaw-channels/Cargo.tomlcrates/zclaw-channels/src/lib.rscrates/zclaw-protocols/Cargo.tomlcrates/zclaw-protocols/src/lib.rs
需要删除的文件(阶段 5)
desktop/src-tauri/resources/openfang-runtime/- 整个目录
Reference
OpenFang 架构参考
OpenFang 是成熟的 Rust workspace,包含 14 个 crate:
openfang-types- 共享类型openfang-memory- SQLite 存储openfang-runtime- LLM 驱动、工具、Agent 循环openfang-kernel- 核心协调器openfang-api- HTTP API(ZCLAW 不需要,用 Tauri 命令替代)openfang-channels- 40 个通道适配器openfang-skills- 60 个技能openfang-desktop- Tauri 桌面应用
设计借鉴点
- 分层架构 - types → memory → runtime → kernel
- LLM Driver 抽象 - 统一 trait,多 provider 实现
- 能力系统 - Capability 枚举,权限检查
- Agent Loop - 消息循环、工具调用、流式处理
- Loop Guard - 防止 Agent 陷入循环
- WASM 沙箱 - 技能安全执行(可选)
ZCLAW 独特价值
- 智能层 - heartbeat, compactor, reflection, identity(已实现)
- 中文优先 - 面向中文用户优化
- 简化的架构 - 去除不需要的 HTTP API 层
- Tauri 原生集成 - 无进程间通信开销