# ZCLAW Kernel 技术参考文档 > **文档版本**: v2.1 > **更新日期**: 2026-03-24 > **目标**: 为 ZCLAW 内部 Kernel 架构提供技术参考 --- ## 一、项目概述 ### 1.1 基本信息 | 属性 | 值 | |------|-----| | **项目名称** | ZCLAW | | **架构** | 8 个 Rust Crates 模块化设计 | | **定位** | AI Agent 桌面客户端 | | **许可** | MIT | ### 1.2 核心特性 ``` ┌─────────────────────────────────────────────────────────────────┐ │ ZCLAW 核心特性 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 🚀 内部 Kernel 架构 │ │ ├── 无外部进程依赖 │ │ ├── 单一安装包可运行 │ │ └── 即时启动 │ │ │ │ 🤖 多 LLM Provider 支持 │ │ ├── Kimi Code (kimi) │ │ ├── 百炼/通义千问 (qwen) │ │ ├── DeepSeek (deepseek) │ │ ├── 智谱 GLM (zhipu) │ │ ├── OpenAI (openai) │ │ ├── Anthropic (anthropic) │ │ └── 本地模型 (local/ollama) │ │ │ │ 🔒 UI 配置 │ │ ├── 无需编辑配置文件 │ │ ├── "模型与 API"设置页面配置 │ │ └── 配置存储在 localStorage │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## 二、Crate 架构 ### 2.1 模块结构 ``` 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 自主能力 │ │ ├── Hand/Trigger trait 定义 │ │ ├── HandRegistry/TriggerRegistry 实现 │ │ ├── Browser Hand │ │ ├── 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 初始化 │ │ │ ├── kernel_commands.rs # Tauri 命令封装 │ │ │ └── state.rs # 应用状态 │ │ └── Cargo.toml # 依赖内部 crates │ └── src/ # React 前端 │ └── Cargo.toml # Workspace 定义 ``` ### 2.2 依赖关系 ``` zclaw-types (无依赖) ↑ zclaw-memory (→ types) ↑ zclaw-runtime (→ types, memory) ↑ zclaw-kernel (→ types, memory, runtime) ↑ desktop/src-tauri (→ kernel, skills, hands, channels, protocols) ``` --- ## 三、zclaw-types ### 3.1 核心 ID 类型 ```rust pub struct AgentId(Uuid); pub struct SessionId(Uuid); pub struct ToolId(String); ``` ### 3.2 消息类型 ```rust pub enum Message { User { content: String }, Assistant { content: String, thinking: Option }, ToolUse { tool: ToolId, input: Value }, ToolResult { tool: ToolId, output: Value, error: bool }, } ``` ### 3.3 Agent 配置 ```rust pub struct AgentConfig { pub id: AgentId, pub name: String, pub model: ModelConfig, pub system_prompt: String, pub capabilities: Vec, pub tools: Vec, } pub struct ModelConfig { pub provider: String, pub model: String, pub api_key_env: Option, pub base_url: Option, } ``` ### 3.4 统一错误类型 ```rust pub enum ZclawError { NotFound(String), PermissionDenied(String), LlmError(String), ToolError(String), StorageError(String), ConfigError(String), } ``` --- ## 四、zclaw-memory ### 4.1 MemoryStore ```rust pub struct MemoryStore { db: Arc>, } impl MemoryStore { // Agent 配置持久化 pub async fn save_agent(&self, agent: &AgentConfig) -> Result<()>; pub async fn load_agent(&self, id: &AgentId) -> Result>; pub async fn list_agents(&self) -> Result>; // 会话管理 pub async fn create_session(&self, agent_id: &AgentId) -> Result; pub async fn get_session(&self, id: &SessionId) -> Result>; 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>; // 语义搜索 pub async fn embed(&self, text: &str) -> Result>; pub async fn search_similar(&self, query: &str, limit: usize) -> Result>; } ``` ### 4.2 数据库 Schema ```sql -- Agent 配置表 CREATE TABLE agents ( id TEXT PRIMARY KEY, name TEXT NOT NULL, config JSON NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 会话表 CREATE TABLE sessions ( id TEXT PRIMARY KEY, agent_id TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (agent_id) REFERENCES agents(id) ); -- 消息表 CREATE TABLE messages ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id TEXT NOT NULL, role TEXT NOT NULL, content TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (session_id) REFERENCES sessions(id) ); ``` --- ## 五、zclaw-runtime ### 5.1 LLM Driver Trait ```rust #[async_trait] pub trait LlmDriver: Send + Sync { async fn complete(&self, req: CompletionRequest) -> Result; async fn stream(&self, req: CompletionRequest) -> Result>; } ``` ### 5.2 Driver 实现 ```rust // Anthropic Claude pub struct AnthropicDriver { api_key: SecretString, } // OpenAI 兼容(支持 Kimi, Qwen, DeepSeek, Zhipu 等) pub struct OpenAiDriver { api_key: SecretString, base_url: String, } impl OpenAiDriver { pub fn with_base_url(api_key: SecretString, base_url: String) -> Self { Self { api_key, base_url } } } // Google Gemini pub struct GeminiDriver { api_key: SecretString, } // 本地模型(Ollama/LMStudio) pub struct LocalDriver { base_url: String, } ``` ### 5.3 Agent Loop ```rust pub struct AgentLoop { driver: Arc, tools: Vec, memory: Arc, loop_guard: LoopGuard, // 模型配置(2026-03-22 添加) model: String, system_prompt: Option, max_tokens: u32, temperature: f32, } impl AgentLoop { pub fn new(...) -> Self; pub fn with_model(self, model: impl Into) -> Self; pub fn with_system_prompt(self, prompt: impl Into) -> Self; pub fn with_max_tokens(self, max_tokens: u32) -> Self; pub fn with_temperature(self, temperature: f32) -> Self; pub async fn run(&self, session: SessionId, input: String) -> Result; pub async fn run_streaming(&self, session: SessionId, input: String) -> Result>; } ``` **重要**: `AgentLoop` 必须通过 builder 方法配置模型,否则将使用默认值。`run()` 方法会从 `CompletionResponse.content` 中提取 `ContentBlock::Text` 作为响应内容。 --- ## 六、zclaw-kernel ### 6.1 Kernel 主结构 ```rust pub struct Kernel { registry: AgentRegistry, scheduler: Scheduler, capabilities: CapabilityManager, events: EventBus, workflows: WorkflowEngine, triggers: TriggerEngine, supervisor: Supervisor, memory: Arc, config: KernelConfig, } ``` ### 6.2 Kernel 方法 ```rust impl Kernel { /// 启动 Kernel pub async fn boot(config: KernelConfig) -> Result; /// 关闭 Kernel pub async fn shutdown(self) -> Result<()>; // Agent 生命周期 pub async fn spawn_agent(&self, config: AgentConfig) -> Result; pub async fn kill_agent(&self, id: &AgentId) -> Result<()>; pub fn list_agents(&self) -> Vec; pub fn get_agent(&self, id: &AgentId) -> Option; // 消息处理 pub async fn send_message(&self, agent: &AgentId, msg: String) -> Result; pub async fn send_message_stream(&self, agent: &AgentId, msg: String) -> Result>; } // send_message 实现:从 AgentConfig 获取模型配置传递给 AgentLoop // 优先级:agent_config.model > kernel_config.default_model ``` **消息处理流程**: ``` send_message(agent_id, message) │ ├── 获取 AgentConfig: registry.get(agent_id) │ ├── 确定模型: │ if !agent_config.model.model.is_empty(): │ model = agent_config.model.model │ else: │ model = kernel_config.default_model │ ├── 创建 AgentLoop (使用 builder 模式): │ AgentLoop::new(...) │ .with_model(model) │ .with_max_tokens(agent_config.max_tokens || kernel_config.max_tokens) │ .with_temperature(agent_config.temperature || kernel_config.temperature) │ .with_system_prompt(agent_config.system_prompt) // 可选 │ └── 运行: loop_runner.run(session_id, message) │ ├── 调用 LLM: driver.complete(request) │ └── 提取响应: 从 ContentBlock::Text 获取内容 ``` // 工作流 pub async fn run_workflow(&self, workflow_id: &str, input: Value) -> Result; // 事件 pub fn subscribe(&self) -> broadcast::Receiver; } ``` ### 6.3 KernelConfig ```rust pub struct KernelConfig { // 数据库 pub database_url: String, // 默认 Provider 和模型 pub default_provider: String, pub default_model: String, // API Keys(从 UI 传入) pub anthropic_api_key: Option, pub openai_api_key: Option, pub gemini_api_key: Option, pub kimi_api_key: Option, pub qwen_api_key: Option, pub deepseek_api_key: Option, pub zhipu_api_key: Option, // Base URLs pub kimi_base_url: String, pub qwen_base_url: String, pub deepseek_base_url: String, pub zhipu_base_url: String, pub local_base_url: Option, // 生成参数 pub max_tokens: u32, pub temperature: f32, } ``` ### 6.4 create_driver 方法 ```rust impl KernelConfig { pub fn create_driver(&self) -> Result> { match self.default_provider.as_str() { "anthropic" => { let key = self.anthropic_api_key.clone() .ok_or_else(|| ZclawError::ConfigError("ANTHROPIC_API_KEY not set".into()))?; Ok(Arc::new(AnthropicDriver::new(SecretString::new(key)))) } "kimi" => { let key = self.kimi_api_key.clone() .ok_or_else(|| ZclawError::ConfigError("KIMI_API_KEY not set".into()))?; Ok(Arc::new(OpenAiDriver::with_base_url( SecretString::new(key), self.kimi_base_url.clone(), ))) } "qwen" => { let key = self.qwen_api_key.clone() .ok_or_else(|| ZclawError::ConfigError("QWEN_API_KEY not set".into()))?; Ok(Arc::new(OpenAiDriver::with_base_url( SecretString::new(key), self.qwen_base_url.clone(), ))) } "deepseek" => { let key = self.deepseek_api_key.clone() .ok_or_else(|| ZclawError::ConfigError("DEEPSEEK_API_KEY not set".into()))?; Ok(Arc::new(OpenAiDriver::with_base_url( SecretString::new(key), self.deepseek_base_url.clone(), ))) } "zhipu" => { let key = self.zhipu_api_key.clone() .ok_or_else(|| ZclawError::ConfigError("ZHIPU_API_KEY not set".into()))?; Ok(Arc::new(OpenAiDriver::with_base_url( SecretString::new(key), self.zhipu_base_url.clone(), ))) } "openai" => { let key = self.openai_api_key.clone() .ok_or_else(|| ZclawError::ConfigError("OPENAI_API_KEY not set".into()))?; Ok(Arc::new(OpenAiDriver::new(SecretString::new(key)))) } "gemini" => { let key = self.gemini_api_key.clone() .ok_or_else(|| ZclawError::ConfigError("GEMINI_API_KEY not set".into()))?; Ok(Arc::new(GeminiDriver::new(SecretString::new(key)))) } "local" | "ollama" => { let base_url = self.local_base_url.clone() .unwrap_or_else(|| "http://localhost:11434/v1".to_string()); Ok(Arc::new(LocalDriver::new(base_url))) } _ => Err(ZclawError::ConfigError( format!("Unknown provider: {}", self.default_provider) )), } } } ``` ### 6.5 自我进化系统 ZCLAW 内置自我进化能力,通过四个核心组件实现: ``` ┌─────────────────────────────────────────────────────────────────┐ │ 自我进化数据流 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 对话 ──► 记忆存储 ──► 反思引擎 ──► 提案生成 ──► 用户审批 │ │ │ │ │ ▼ │ │ 心跳引擎 (定期检查) │ │ │ │ │ ▼ │ │ 人格改进 / 学习机会 / 任务积压 │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` **核心文件**: | 组件 | 后端文件 | 前端文件 | |------|----------|----------| | 心跳引擎 | `intelligence/heartbeat.rs` | `intelligence-client.ts` | | 反思引擎 | `intelligence/reflection.rs` | `intelligence-client.ts` | | 身份管理 | `intelligence/identity.rs` | `intelligence-client.ts` | | 记忆存储 | `memory/persistent.rs` | `intelligence-client.ts` | **心跳检查函数**: ```rust // heartbeat.rs fn check_pending_tasks(agent_id: &str) -> Option; // 任务积压 fn check_memory_health(agent_id: &str) -> Option; // 存储健康 fn check_correction_patterns(agent_id: &str) -> Vec; // 纠正模式 fn check_learning_opportunities(agent_id: &str) -> Option; // 学习机会 fn check_idle_greeting(agent_id: &str) -> Option; // 空闲问候 ``` **关键注意事项**: 1. **DateTime 类型转换**: `chrono::DateTime::parse_from_rfc3339()` 返回 `DateTime`,需要转换为 `DateTime` 才能与 `chrono::Utc::now()` 计算时间差: ```rust let last_time = chrono::DateTime::parse_from_rfc3339(×tamp) .ok()? .with_timezone(&chrono::Utc); // 必须转换时区 ``` 2. **API 参数命名**: 前端调用 Tauri 命令时使用 snake_case 参数名: ```typescript await invoke('heartbeat_update_memory_stats', { agent_id: agentId, // 不是 agentId task_count: taskCount, // 不是 taskCount // ... }); ``` 3. **MemoryStats 类型**: 后端使用 `total_entries`,前端转换为 `totalEntries` --- ## 七、Tauri 集成 ### 7.1 命令封装 ```rust // desktop/src-tauri/src/kernel_commands.rs /// Kernel 状态包装器 pub type KernelState = Arc>>; /// 初始化 Kernel #[tauri::command] pub async fn kernel_init( state: State<'_, KernelState>, config_request: Option, ) -> Result { // ... } /// 创建 Agent #[tauri::command] pub async fn agent_create( state: State<'_, KernelState>, request: CreateAgentRequest, ) -> Result { // ... } /// 发送消息 #[tauri::command] pub async fn agent_chat( state: State<'_, KernelState>, request: ChatRequest, ) -> Result { // ... } ``` ### 7.2 lib.rs 注册 ```rust // desktop/src-tauri/src/lib.rs #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .setup(|app| { app.manage(kernel_commands::create_kernel_state()); Ok(()) }) .invoke_handler(tauri::generate_handler![ kernel_commands::kernel_init, kernel_commands::kernel_status, kernel_commands::kernel_shutdown, kernel_commands::agent_create, kernel_commands::agent_list, kernel_commands::agent_get, kernel_commands::agent_delete, kernel_commands::agent_chat, ]) .run(tauri::generate_context!()) } ``` --- ## 八、前端集成 ### 8.1 KernelClient ```typescript // desktop/src/lib/kernel-client.ts export class KernelClient { private config: KernelConfig = {}; private defaultAgentId: string = ''; setConfig(config: KernelConfig): void { this.config = config; } async connect(): Promise { if (!this.config.provider || !this.config.model || !this.config.apiKey) { throw new Error('请先在"模型与 API"设置页面配置模型'); } const status = await invoke('kernel_init', { configRequest: { provider: this.config.provider, model: this.config.model, apiKey: this.config.apiKey, baseUrl: this.config.baseUrl || null, }, }); // 创建默认 Agent const agents = await this.listAgents(); if (agents.length === 0) { const agent = await this.createAgent({ name: 'Default Agent', provider: this.config.provider, model: this.config.model, }); this.defaultAgentId = agent.id; } } async chat(message: string, opts?: ChatOptions): Promise { return invoke('agent_chat', { request: { agentId: opts?.agentId || this.defaultAgentId, message, }, }); } } ``` ### 8.2 ConnectionStore ```typescript // desktop/src/store/connectionStore.ts connect: async (url?: string, token?: string) => { const useInternalKernel = isTauriRuntime(); if (useInternalKernel) { const kernelClient = getKernelClient(); const modelConfig = getDefaultModelConfig(); if (!modelConfig) { throw new Error('请先在"模型与 API"设置页面添加自定义模型配置'); } kernelClient.setConfig({ provider: modelConfig.provider, model: modelConfig.model, apiKey: modelConfig.apiKey, baseUrl: modelConfig.baseUrl, }); await kernelClient.connect(); set({ client: kernelClient, gatewayVersion: '0.2.0-internal' }); return; } // 非 Tauri 环境... } ``` --- ## 九、支持的 Provider ### 9.1 Provider 列表 | Provider | Driver | Base URL | API 协议 | |----------|--------|----------|----------| | kimi | OpenAiDriver | `https://api.kimi.com/coding/v1` | OpenAI 兼容 | | qwen | OpenAiDriver | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI 兼容 | | deepseek | OpenAiDriver | `https://api.deepseek.com/v1` | OpenAI 兼容 | | zhipu | OpenAiDriver | `https://open.bigmodel.cn/api/paas/v4` | OpenAI 兼容 | | openai | OpenAiDriver | `https://api.openai.com/v1` | OpenAI | | anthropic | AnthropicDriver | `https://api.anthropic.com` | Anthropic | | gemini | GeminiDriver | `https://generativelanguage.googleapis.com` | Gemini | | local | LocalDriver | `http://localhost:11434/v1` | OpenAI 兼容 | ### 9.2 配置示例 ```typescript // Kimi Code 配置 { provider: 'kimi', model: 'kimi-k2-turbo', apiKey: 'your-kimi-api-key', baseUrl: 'https://api.kimi.com/coding/v1' } // 百炼 Qwen 配置 { provider: 'qwen', model: 'qwen-plus', apiKey: 'your-qwen-api-key', baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1' } ``` --- ## 十、开发命令 ### 10.1 构建命令 ```bash # 构建所有 crates cargo build # 构建生产版本 cargo build --release # 运行测试 cargo test # 启动开发环境 pnpm start:dev ``` ### 10.2 常用命令 ```bash # 安装依赖 pnpm install # 类型检查 pnpm tsc --noEmit # 运行测试 pnpm vitest run # E2E 测试 pnpm test:e2e ``` --- ## 十一、Skill 系统架构 ### 11.1 概述 Skill 系统是 ZCLAW 的可扩展技能框架,允许通过 `SKILL.md` 或 `skill.toml` 文件定义和加载技能。 ### 11.2 核心组件 ``` ┌─────────────────────────────────────────────────────────────────┐ │ Skill 系统架构 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ zclaw-skills/ │ │ ├── SkillManifest # 技能元数据 │ │ ├── SkillContext # 执行上下文 (agent_id, session_id) │ │ ├── SkillResult # 执行结果 │ │ ├── SkillRegistry # 技能注册表 │ │ ├── SkillLoader # SKILL.md/skill.toml 解析 │ │ └── SkillRunner # 执行器 (PromptOnly/Shell) │ │ │ │ zclaw-runtime/ │ │ ├── ExecuteSkillTool # execute_skill 工具 │ │ ├── SkillExecutor # 技能执行 trait │ │ └── ToolContext # 包含 skill_executor │ │ │ │ zclaw-kernel/ │ │ ├── KernelSkillExecutor # SkillExecutor 实现 │ │ └── default_skills_dir # 默认 ./skills 目录 │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 11.3 数据流 ``` LLM 调用 execute_skill 工具 ↓ AgentLoop.execute_tool() ↓ ExecuteSkillTool.execute() ↓ ToolContext.skill_executor.execute_skill() ↓ KernelSkillExecutor.execute_skill() ↓ SkillRegistry.execute() ↓ 返回结果给 LLM ``` ### 11.4 Tauri 命令 | 命令 | 说明 | |------|------| | `skill_list` | 列出所有已加载的技能 | | `skill_execute` | 执行指定技能 | | `skill_refresh` | 刷新技能目录 | ### 11.5 前端集成 ```typescript // 从后端加载技能列表 const skills = await invoke('skill_list'); // 执行技能 const result = await invoke('skill_execute', { id: 'skill-id', context: { agentId: '...', sessionId: '...', workingDir: null }, input: { ... } }); ``` ### 11.6 技能发现 1. Kernel 启动时扫描 `./skills` 目录 2. 查找 `SKILL.md` 或 `skill.toml` 文件 3. 解析 frontmatter 元数据 4. 注册到 SkillRegistry ### 11.7 已知限制 | 限制 | 说明 | |------|------| | Python/WASM 模式 | 未实现,回退到 PromptOnly | | Frontmatter 解析 | 仅支持简单 `key: value` 格式 | | 模式字符串 | `"PromptOnly"` 而非 `"prompt_only"` | --- ## 十二、参考资料 ### 12.1 相关文档 - [快速启动指南](../quick-start.md) - [模型配置指南](./configuration.md) - [通信层文档](../features/00-architecture/01-communication-layer.md) - [后端集成文档](../features/06-tauri-backend/00-backend-integration.md) ### 12.2 架构演进 | 版本 | 架构 | 说明 | |------|------|------| | v1.x | 外部 OpenFang | 需要启动独立后端进程 | | v2.0 | 内部 Kernel | Kernel 集成在 Tauri 中,无需外部进程 | | v2.1 | Skill 工具执行 | 完整的 execute_skill 工具链路 | --- *文档版本: v2.1 | 更新日期: 2026-03-24*