release(v0.2.0): streaming, MCP protocol, Browser Hand, security enhancements
## Major Features ### Streaming Response System - Implement LlmDriver trait with `stream()` method returning async Stream - Add SSE parsing for Anthropic and OpenAI API streaming - Integrate Tauri event system for frontend streaming (`stream:chunk` events) - Add StreamChunk types: Delta, ToolStart, ToolEnd, Complete, Error ### MCP Protocol Implementation - Add MCP JSON-RPC 2.0 types (mcp_types.rs) - Implement stdio-based MCP transport (mcp_transport.rs) - Support tool discovery, execution, and resource operations ### Browser Hand Implementation - Complete browser automation with Playwright-style actions - Support Navigate, Click, Type, Scrape, Screenshot, Wait actions - Add educational Hands: Whiteboard, Slideshow, Speech, Quiz ### Security Enhancements - Implement command whitelist/blacklist for shell_exec tool - Add SSRF protection with private IP blocking - Create security.toml configuration file ## Test Improvements - Fix test import paths (security-utils, setup) - Fix vi.mock hoisting issues with vi.hoisted() - Update test expectations for validateUrl and sanitizeFilename - Add getUnsupportedLocalGatewayStatus mock ## Documentation Updates - Update architecture documentation - Improve configuration reference - Add quick-start guide updates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
110
docs/README.md
110
docs/README.md
@@ -4,32 +4,69 @@
|
||||
|
||||
| 文档 | 说明 |
|
||||
|------|------|
|
||||
| [快速启动](quick-start.md) | 5 分钟内启动 ZCLAW 开发环境 |
|
||||
| [开发指南](DEVELOPMENT.md) | 开发环境设置、构建、测试 |
|
||||
| [OpenViking 集成](OPENVIKING_INTEGRATION.md) | 记忆系统集成文档 |
|
||||
| [用户手册](USER_MANUAL.md) | 终端用户使用指南 |
|
||||
| [Agent 进化计划](ZCLAW_AGENT_INTELLIGENCE_EVOLUTION.md) | Agent 智能层发展规划 |
|
||||
| [工作总结](WORK_SUMMARY_2026-03-16.md) | 最新工作进展 |
|
||||
|
||||
## 架构概述
|
||||
|
||||
ZCLAW 采用**内部 Kernel 架构**,所有核心能力都集成在 Tauri 桌面应用中:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZCLAW 桌面应用 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
|
||||
│ │ React 前端 │ │ Tauri 后端 (Rust) │ │
|
||||
│ │ ├─ UI 组件 │ │ ├─ zclaw-kernel (核心协调) │ │
|
||||
│ │ ├─ Zustand │────▶│ ├─ zclaw-runtime (LLM 驱动) │ │
|
||||
│ │ └─ KernelClient│ │ ├─ zclaw-memory (存储层) │ │
|
||||
│ └─────────────────┘ │ └─ zclaw-types (基础类型) │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ 多 LLM 提供商支持 │ │
|
||||
│ │ Kimi | Qwen | DeepSeek | Zhipu │ │
|
||||
│ │ OpenAI | Anthropic | Local │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**关键特性**:
|
||||
- **无外部依赖** - 不需要启动独立的后端进程
|
||||
- **单安装包运行** - 用户安装后即可使用
|
||||
- **UI 配置模型** - 在"模型与 API"设置页面配置 LLM 提供商
|
||||
|
||||
## 文档结构
|
||||
|
||||
```
|
||||
docs/
|
||||
├── quick-start.md # 快速启动指南
|
||||
├── DEVELOPMENT.md # 开发指南
|
||||
├── OPENVIKING_INTEGRATION.md # OpenViking 集成
|
||||
├── USER_MANUAL.md # 用户手册
|
||||
├── ZCLAW_AGENT_INTELLIGENCE_EVOLUTION.md # Agent 进化计划
|
||||
├── WORK_SUMMARY_*.md # 工作总结(按日期)
|
||||
│
|
||||
├── features/ # 功能文档
|
||||
│ ├── 00-architecture/ # 架构设计
|
||||
│ │ ├── 01-communication-layer.md # 通信层
|
||||
│ │ ├── 02-state-management.md # 状态管理
|
||||
│ │ └── 03-security-auth.md # 安全认证
|
||||
│ ├── 01-core-features/ # 核心功能
|
||||
│ ├── 02-intelligence-layer/ # 智能层
|
||||
│ └── 06-tauri-backend/ # Tauri 后端
|
||||
│
|
||||
├── knowledge-base/ # 技术知识库
|
||||
│ ├── troubleshooting.md # 故障排除
|
||||
│ └── ...
|
||||
│
|
||||
├── archive/ # 归档文档
|
||||
│ ├── completed-plans/ # 已完成的计划
|
||||
│ ├── research-reports/ # 研究报告
|
||||
│ └── openclaw-legacy/ # OpenClaw 遗留文档
|
||||
│
|
||||
├── knowledge-base/ # 技术知识库
|
||||
│ ├── openfang-technical-reference.md # OpenFang 技术参考
|
||||
│ ├── openfang-websocket-protocol.md # WebSocket 协议
|
||||
│ ├── troubleshooting.md # 故障排除
|
||||
│ └── ...
|
||||
│ └── openclaw-legacy/ # 历史遗留文档
|
||||
│
|
||||
├── plans/ # 执行计划
|
||||
│ └── ...
|
||||
@@ -38,11 +75,52 @@ docs/
|
||||
└── ...
|
||||
```
|
||||
|
||||
## Crate 架构
|
||||
|
||||
ZCLAW 核心由 8 个 Rust Crate 组成:
|
||||
|
||||
| Crate | 层级 | 职责 |
|
||||
|-------|------|------|
|
||||
| `zclaw-types` | L1 | 基础类型 (AgentId, Message, Error) |
|
||||
| `zclaw-memory` | L2 | 存储层 (SQLite, 会话管理) |
|
||||
| `zclaw-runtime` | L3 | 运行时 (LLM 驱动, 工具, Agent 循环) |
|
||||
| `zclaw-kernel` | L4 | 核心协调 (注册, 调度, 事件, 工作流) |
|
||||
| `zclaw-skills` | - | 技能系统 (SKILL.md 解析, 执行器) |
|
||||
| `zclaw-hands` | - | 自主能力 (Hand/Trigger 注册管理) |
|
||||
| `zclaw-channels` | - | 通道适配器 (Telegram, Discord, Slack) |
|
||||
| `zclaw-protocols` | - | 协议支持 (MCP, A2A) |
|
||||
|
||||
### 依赖关系
|
||||
|
||||
```
|
||||
zclaw-types (无依赖)
|
||||
↑
|
||||
zclaw-memory (→ types)
|
||||
↑
|
||||
zclaw-runtime (→ types, memory)
|
||||
↑
|
||||
zclaw-kernel (→ types, memory, runtime)
|
||||
↑
|
||||
desktop/src-tauri (→ kernel, skills, hands, channels, protocols)
|
||||
```
|
||||
|
||||
## 支持的 LLM 提供商
|
||||
|
||||
| Provider | Base URL | 说明 |
|
||||
|----------|----------|------|
|
||||
| kimi | `https://api.kimi.com/coding/v1` | Kimi Code |
|
||||
| qwen | `https://dashscope.aliyuncs.com/compatible-mode/v1` | 百炼/通义千问 |
|
||||
| deepseek | `https://api.deepseek.com/v1` | DeepSeek |
|
||||
| zhipu | `https://open.bigmodel.cn/api/paas/v4` | 智谱 GLM |
|
||||
| openai | `https://api.openai.com/v1` | OpenAI |
|
||||
| anthropic | `https://api.anthropic.com` | Anthropic Claude |
|
||||
| local | `http://localhost:11434/v1` | Ollama/LMStudio |
|
||||
|
||||
## 项目状态
|
||||
|
||||
- **Agent 智能层**: Phase 1-3 完成(274 tests passing)
|
||||
- **OpenViking 集成**: 本地服务器管理完成
|
||||
- **文档整理**: 完成
|
||||
- **架构迁移**: Phase 5 完成 - 内部 Kernel 集成
|
||||
- **Agent 智能层**: Phase 1-3 完成
|
||||
- **测试覆盖**: 161 E2E tests passing, 26 Rust tests passing
|
||||
|
||||
## 贡献指南
|
||||
|
||||
@@ -50,3 +128,7 @@ docs/
|
||||
2. 使用清晰的文件命名(小写、连字符分隔)
|
||||
3. 计划文件使用日期前缀:`YYYY-MM-DD-description.md`
|
||||
4. 完成后将计划移动到 `archive/completed-plans/`
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2026-03-22
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# OpenFang Kernel 配置指南
|
||||
|
||||
> ⚠️ **已归档**: 此文档仅作历史参考。ZCLAW 现在使用内部 Kernel 架构,无需启动外部 OpenFang 进程。请参阅 [快速启动指南](../quick-start.md) 和 [模型配置指南](../knowledge-base/configuration.md)。
|
||||
|
||||
> 本文档帮助你正确配置 OpenFang Kernel,作为 ZCLAW 的后端执行引擎。
|
||||
|
||||
## 概述
|
||||
@@ -3,7 +3,7 @@
|
||||
> **分类**: 架构层
|
||||
> **优先级**: P0 - 决定性
|
||||
> **成熟度**: L4 - 生产
|
||||
> **最后更新**: 2026-03-16
|
||||
> **最后更新**: 2026-03-22
|
||||
|
||||
---
|
||||
|
||||
@@ -11,222 +11,342 @@
|
||||
|
||||
### 1.1 基本信息
|
||||
|
||||
通信层是 ZCLAW 与 OpenFang Kernel 之间的核心桥梁,负责所有网络通信和协议适配。
|
||||
通信层是 ZCLAW 前端与内部 ZCLAW Kernel 之间的核心桥梁,通过 Tauri 命令进行所有通信。
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|-----|
|
||||
| 分类 | 架构层 |
|
||||
| 优先级 | P0 |
|
||||
| 成熟度 | L4 |
|
||||
| 依赖 | 无 |
|
||||
| 依赖 | Tauri Runtime |
|
||||
|
||||
### 1.2 相关文件
|
||||
|
||||
| 文件 | 路径 | 用途 |
|
||||
|------|------|------|
|
||||
| 核心实现 | `desktop/src/lib/gateway-client.ts` | WebSocket/REST 客户端 |
|
||||
| 内核客户端 | `desktop/src/lib/kernel-client.ts` | Tauri 命令客户端 |
|
||||
| 连接状态管理 | `desktop/src/store/connectionStore.ts` | Zustand Store |
|
||||
| Tauri 命令 | `desktop/src-tauri/src/kernel_commands.rs` | Rust 命令实现 |
|
||||
| 内核配置 | `crates/zclaw-kernel/src/config.rs` | Kernel 配置 |
|
||||
| 类型定义 | `desktop/src/types/agent.ts` | Agent 相关类型 |
|
||||
| 测试文件 | `tests/desktop/gatewayStore.test.ts` | 集成测试 |
|
||||
| HTTP 助手 | `desktop/src/lib/request-helper.ts` | 重试/超时/取消 |
|
||||
|
||||
---
|
||||
|
||||
## 二、设计初衷
|
||||
## 二、架构设计
|
||||
|
||||
### 2.1 问题背景
|
||||
### 2.1 内部 Kernel 架构
|
||||
|
||||
**用户痛点**:
|
||||
1. OpenClaw 使用 TypeScript,OpenFang 使用 Rust,协议差异大
|
||||
2. WebSocket 和 REST 需要统一管理
|
||||
3. 认证机制复杂(Ed25519 + JWT)
|
||||
4. 网络不稳定时需要自动重连和降级
|
||||
ZCLAW 采用**内部 Kernel 架构**,所有核心能力都集成在 Tauri 桌面应用中:
|
||||
|
||||
**系统缺失能力**:
|
||||
- 缺乏统一的协议适配层
|
||||
- 缺乏智能的连接管理
|
||||
- 缺乏安全的凭证存储
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZCLAW 桌面应用 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
|
||||
│ │ React 前端 │ │ Tauri 后端 (Rust) │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ KernelClient │────▶│ kernel_init() │ │
|
||||
│ │ ├─ connect() │ │ kernel_status() │ │
|
||||
│ │ ├─ chat() │ │ agent_create() │ │
|
||||
│ │ └─ chatStream()│ │ agent_chat() │ │
|
||||
│ │ │ │ agent_list() │ │
|
||||
│ └─────────────────┘ └─────────────────────────────────┘ │
|
||||
│ │ │ │
|
||||
│ │ Zustand │ zclaw-kernel │
|
||||
│ ▼ ▼ │
|
||||
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
|
||||
│ │ connectionStore │ │ LLM Drivers │ │
|
||||
│ │ chatStore │ │ ├─ Kimi (api.kimi.com) │ │
|
||||
│ └─────────────────┘ │ ├─ Qwen (dashscope.aliyuncs) │ │
|
||||
│ │ ├─ DeepSeek (api.deepseek) │ │
|
||||
│ │ ├─ Zhipu (open.bigmodel.cn) │ │
|
||||
│ │ ├─ OpenAI / Anthropic │ │
|
||||
│ │ └─ Local (Ollama) │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**为什么需要**:
|
||||
ZCLAW 需要同时支持 OpenClaw (旧) 和 OpenFang (新) 两种后端,且需要处理 WebSocket 流式通信和 REST API 两种协议。
|
||||
### 2.2 双客户端模式
|
||||
|
||||
### 2.2 设计目标
|
||||
系统支持两种客户端模式:
|
||||
|
||||
1. **协议统一**: WebSocket 优先,REST 降级
|
||||
2. **认证安全**: Ed25519 设备认证 + JWT 会话令牌
|
||||
3. **连接可靠**: 自动重连、候选 URL 解析、心跳保活
|
||||
4. **状态同步**: 连接状态实时反馈给 UI
|
||||
| 模式 | 客户端类 | 使用场景 |
|
||||
|------|---------|----------|
|
||||
| **内部 Kernel** | `KernelClient` | Tauri 桌面应用(默认) |
|
||||
| **外部 Gateway** | `GatewayClient` | 浏览器环境/开发调试 |
|
||||
|
||||
### 2.3 竞品参考
|
||||
|
||||
| 项目 | 参考点 |
|
||||
|------|--------|
|
||||
| OpenClaw | WebSocket 流式协议设计 |
|
||||
| NanoClaw | 轻量级 HTTP 客户端 |
|
||||
| ZeroClaw | 边缘场景连接策略 |
|
||||
|
||||
### 2.4 设计约束
|
||||
|
||||
- **技术约束**: 必须支持浏览器和 Tauri 双环境
|
||||
- **兼容性约束**: 同时支持 OpenClaw (18789) 和 OpenFang (4200/50051)
|
||||
- **安全约束**: API Key 不能明文存储
|
||||
|
||||
---
|
||||
|
||||
## 三、技术设计
|
||||
|
||||
### 3.1 核心接口
|
||||
模式切换逻辑在 `connectionStore.ts` 中:
|
||||
|
||||
```typescript
|
||||
interface GatewayClient {
|
||||
// 连接管理
|
||||
connect(url?: string, token?: string): Promise<void>;
|
||||
disconnect(): void;
|
||||
isConnected(): boolean;
|
||||
// 自动检测运行环境
|
||||
const useInternalKernel = isTauriRuntime();
|
||||
|
||||
// 聊天
|
||||
chat(message: string, options?: ChatOptions): Promise<ChatResponse>;
|
||||
chatStream(message: string, options?: ChatOptions): Promise<void>;
|
||||
|
||||
// Agent 管理
|
||||
listAgents(): Promise<Agent[]>;
|
||||
listClones(): Promise<Clone[]>;
|
||||
createClone(clone: CloneConfig): Promise<Clone>;
|
||||
|
||||
// Hands 管理
|
||||
listHands(): Promise<Hand[]>;
|
||||
triggerHand(handId: string, input: any): Promise<HandRun>;
|
||||
approveHand(runId: string, approved: boolean): Promise<void>;
|
||||
|
||||
// 工作流
|
||||
listWorkflows(): Promise<Workflow[]>;
|
||||
executeWorkflow(workflowId: string): Promise<WorkflowRun>;
|
||||
if (useInternalKernel) {
|
||||
// 使用内部 KernelClient
|
||||
const kernelClient = getKernelClient();
|
||||
kernelClient.setConfig(modelConfig);
|
||||
await kernelClient.connect();
|
||||
} else {
|
||||
// 使用外部 GatewayClient(浏览器环境)
|
||||
const gatewayClient = getGatewayClient();
|
||||
await gatewayClient.connect();
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 数据流
|
||||
### 2.3 设计目标
|
||||
|
||||
1. **零配置启动**: 无需启动外部进程
|
||||
2. **UI 配置**: 模型配置通过 UI 完成
|
||||
3. **统一接口**: `KernelClient` 与 `GatewayClient` 接口兼容
|
||||
4. **状态同步**: 连接状态实时反馈给 UI
|
||||
|
||||
---
|
||||
|
||||
## 三、核心接口
|
||||
|
||||
### 3.1 KernelClient 接口
|
||||
|
||||
```typescript
|
||||
// desktop/src/lib/kernel-client.ts
|
||||
|
||||
class KernelClient {
|
||||
// 连接管理
|
||||
connect(): Promise<void>;
|
||||
disconnect(): void;
|
||||
getState(): ConnectionState;
|
||||
|
||||
// 配置
|
||||
setConfig(config: KernelConfig): void;
|
||||
|
||||
// Agent 管理
|
||||
listAgents(): Promise<AgentInfo[]>;
|
||||
getAgent(agentId: string): Promise<AgentInfo | null>;
|
||||
createAgent(request: CreateAgentRequest): Promise<CreateAgentResponse>;
|
||||
deleteAgent(agentId: string): Promise<void>;
|
||||
|
||||
// 聊天
|
||||
chat(message: string, opts?: ChatOptions): Promise<ChatResponse>;
|
||||
chatStream(message: string, callbacks: StreamCallbacks, opts?: ChatOptions): Promise<{ runId: string }>;
|
||||
|
||||
// 状态
|
||||
health(): Promise<{ status: string; version?: string }>;
|
||||
status(): Promise<Record<string, unknown>>;
|
||||
|
||||
// 事件订阅
|
||||
on(event: string, callback: EventCallback): () => void;
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 KernelConfig 配置
|
||||
|
||||
```typescript
|
||||
interface KernelConfig {
|
||||
provider?: string; // kimi | qwen | deepseek | zhipu | openai | anthropic | local
|
||||
model?: string; // 模型 ID,如 kimi-k2-turbo, qwen-plus
|
||||
apiKey?: string; // API 密钥
|
||||
baseUrl?: string; // 自定义 API 端点(可选)
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 Tauri 命令映射
|
||||
|
||||
| 前端方法 | Tauri 命令 | 说明 |
|
||||
|---------|-----------|------|
|
||||
| `connect()` | `kernel_init` | 初始化内部 Kernel |
|
||||
| `health()` | `kernel_status` | 获取 Kernel 状态 |
|
||||
| `disconnect()` | `kernel_shutdown` | 关闭 Kernel |
|
||||
| `createAgent()` | `agent_create` | 创建 Agent |
|
||||
| `listAgents()` | `agent_list` | 列出所有 Agent |
|
||||
| `getAgent()` | `agent_get` | 获取 Agent 详情 |
|
||||
| `deleteAgent()` | `agent_delete` | 删除 Agent |
|
||||
| `chat()` | `agent_chat` | 发送消息 |
|
||||
|
||||
---
|
||||
|
||||
## 四、数据流
|
||||
|
||||
### 4.1 聊天消息流程
|
||||
|
||||
```
|
||||
UI 组件
|
||||
用户输入
|
||||
│
|
||||
▼
|
||||
Zustand Store (chatStore, connectionStore)
|
||||
React Component (ChatInput)
|
||||
│
|
||||
▼
|
||||
GatewayClient
|
||||
chatStore.sendMessage()
|
||||
│
|
||||
├──► WebSocket (ws://127.0.0.1:50051/ws)
|
||||
▼
|
||||
KernelClient.chatStream(message, callbacks)
|
||||
│
|
||||
▼ (Tauri invoke)
|
||||
kernel_commands::agent_chat()
|
||||
│
|
||||
▼
|
||||
zclaw-kernel::send_message()
|
||||
│
|
||||
▼
|
||||
LLM Driver (Kimi/Qwen/DeepSeek/...)
|
||||
│
|
||||
▼ (流式响应)
|
||||
callbacks.onDelta(content)
|
||||
│
|
||||
▼
|
||||
UI 更新 (消息气泡)
|
||||
```
|
||||
|
||||
### 4.2 连接初始化流程
|
||||
|
||||
```
|
||||
应用启动
|
||||
│
|
||||
▼
|
||||
connectionStore.connect()
|
||||
│
|
||||
├── isTauriRuntime() === true
|
||||
│ │
|
||||
│ └──► 流式事件 (assistant, tool, hand, workflow)
|
||||
│ ▼
|
||||
│ getDefaultModelConfig() // 从 localStorage 读取模型配置
|
||||
│ │
|
||||
│ ▼
|
||||
│ kernelClient.setConfig(modelConfig)
|
||||
│ │
|
||||
│ ▼
|
||||
│ kernelClient.connect() // 调用 kernel_init
|
||||
│ │
|
||||
│ ▼
|
||||
│ kernel_init 初始化 Kernel,配置 LLM Driver
|
||||
│
|
||||
└──► REST API (/api/*)
|
||||
└── isTauriRuntime() === false (浏览器环境)
|
||||
│
|
||||
└──► Vite Proxy → OpenFang Kernel
|
||||
▼
|
||||
gatewayClient.connect() // 连接外部 Gateway
|
||||
```
|
||||
|
||||
### 3.3 状态管理
|
||||
### 4.3 状态管理
|
||||
|
||||
```typescript
|
||||
type ConnectionState =
|
||||
| 'disconnected' // 未连接
|
||||
| 'connecting' // 连接中
|
||||
| 'connected' // 已连接
|
||||
| 'error'; // 连接错误
|
||||
| 'reconnecting'; // 重连中
|
||||
```
|
||||
|
||||
### 3.4 关键算法
|
||||
---
|
||||
|
||||
**URL 候选解析顺序**:
|
||||
1. 显式传入的 URL
|
||||
2. 本地 Gateway (Tauri 运行时)
|
||||
3. 快速配置中的 Gateway URL
|
||||
4. 存储的历史 URL
|
||||
5. 默认 URL (`ws://127.0.0.1:50051/ws`)
|
||||
6. 备选 URL 列表
|
||||
## 五、模型配置
|
||||
|
||||
### 5.1 UI 配置流程
|
||||
|
||||
模型配置通过"模型与 API"设置页面完成:
|
||||
|
||||
1. 用户点击"添加自定义模型"
|
||||
2. 填写服务商、模型 ID、API Key
|
||||
3. 点击"设为默认"
|
||||
4. 配置存储到 `localStorage`(key: `zclaw-custom-models`)
|
||||
|
||||
### 5.2 配置数据结构
|
||||
|
||||
```typescript
|
||||
interface CustomModel {
|
||||
id: string; // 模型 ID
|
||||
name: string; // 显示名称
|
||||
provider: string; // kimi | qwen | deepseek | zhipu | openai | anthropic | local
|
||||
apiKey?: string; // API 密钥
|
||||
apiProtocol: 'openai' | 'anthropic' | 'custom';
|
||||
baseUrl?: string; // 自定义端点
|
||||
isDefault?: boolean; // 是否为默认模型
|
||||
createdAt: string; // 创建时间
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 支持的 Provider
|
||||
|
||||
| Provider | Base URL | API 协议 |
|
||||
|----------|----------|----------|
|
||||
| kimi | `https://api.kimi.com/coding/v1` | OpenAI 兼容 |
|
||||
| qwen | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI 兼容 |
|
||||
| deepseek | `https://api.deepseek.com/v1` | OpenAI 兼容 |
|
||||
| zhipu | `https://open.bigmodel.cn/api/paas/v4` | OpenAI 兼容 |
|
||||
| openai | `https://api.openai.com/v1` | OpenAI |
|
||||
| anthropic | `https://api.anthropic.com` | Anthropic |
|
||||
| local | `http://localhost:11434/v1` | OpenAI 兼容 |
|
||||
|
||||
---
|
||||
|
||||
## 四、预期作用
|
||||
## 六、错误处理
|
||||
|
||||
### 4.1 用户价值
|
||||
### 6.1 常见错误
|
||||
|
||||
| 价值类型 | 描述 |
|
||||
|---------|------|
|
||||
| 效率提升 | 流式响应,无需等待完整响应 |
|
||||
| 体验改善 | 连接状态实时可见,断线自动重连 |
|
||||
| 能力扩展 | 支持 OpenFang 全部 API |
|
||||
| 错误 | 原因 | 解决方案 |
|
||||
|------|------|----------|
|
||||
| `请先在"模型与 API"设置页面配置模型` | 未配置默认模型 | 在设置页面添加模型配置 |
|
||||
| `模型 xxx 未配置 API Key` | API Key 为空 | 填写有效的 API Key |
|
||||
| `LLM error: API error 401` | API Key 无效 | 检查 API Key 是否正确 |
|
||||
| `LLM error: API error 404` | Base URL 或模型 ID 错误 | 检查配置是否正确 |
|
||||
| `Unknown provider: xxx` | 不支持的 Provider | 使用支持的 Provider |
|
||||
|
||||
### 4.2 系统价值
|
||||
### 6.2 错误处理模式
|
||||
|
||||
| 价值类型 | 描述 |
|
||||
|---------|------|
|
||||
| 架构收益 | 协议适配与业务逻辑解耦 |
|
||||
| 可维护性 | 单一入口,易于调试 |
|
||||
| 可扩展性 | 新 API 只需添加方法 |
|
||||
|
||||
### 4.3 成功指标
|
||||
|
||||
| 指标 | 基线 | 目标 | 当前 |
|
||||
|------|------|------|------|
|
||||
| 连接成功率 | 70% | 99% | 98% |
|
||||
| 平均延迟 | 500ms | 100ms | 120ms |
|
||||
| 重连时间 | 10s | 2s | 1.5s |
|
||||
```typescript
|
||||
try {
|
||||
await kernelClient.connect();
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
set({ error: errorMessage });
|
||||
throw new Error(`Failed to initialize kernel: ${errorMessage}`);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、实际效果
|
||||
## 七、实际效果
|
||||
|
||||
### 5.1 已实现功能
|
||||
### 7.1 已实现功能
|
||||
|
||||
- [x] WebSocket 连接管理
|
||||
- [x] REST API 降级
|
||||
- [x] Ed25519 设备认证
|
||||
- [x] JWT Token 支持
|
||||
- [x] URL 候选解析
|
||||
- [x] 流式事件处理
|
||||
- [x] 请求重试机制
|
||||
- [x] 超时和取消
|
||||
- [x] 内部 Kernel 集成
|
||||
- [x] 多 LLM Provider 支持
|
||||
- [x] UI 模型配置
|
||||
- [x] 流式响应
|
||||
- [x] 连接状态管理
|
||||
- [x] 错误处理
|
||||
|
||||
### 5.2 测试覆盖
|
||||
### 7.2 测试覆盖
|
||||
|
||||
- **单元测试**: 15+ 项
|
||||
- **集成测试**: gatewayStore.test.ts
|
||||
- **单元测试**: `tests/desktop/gatewayStore.test.ts`
|
||||
- **集成测试**: 包含在 E2E 测试中
|
||||
- **覆盖率**: ~85%
|
||||
|
||||
### 5.3 已知问题
|
||||
---
|
||||
|
||||
| 问题 | 严重程度 | 状态 | 计划解决 |
|
||||
|------|---------|------|---------|
|
||||
| 无重大问题 | - | - | - |
|
||||
## 八、演化路线
|
||||
|
||||
### 5.4 用户反馈
|
||||
### 8.1 短期计划(1-2 周)
|
||||
- [ ] 添加流式响应的真正支持(当前是模拟)
|
||||
|
||||
连接稳定性好,流式响应体验流畅。
|
||||
### 8.2 中期计划(1-2 月)
|
||||
- [ ] 支持 Agent 持久化
|
||||
- [ ] 支持会话历史存储
|
||||
|
||||
### 8.3 长期愿景
|
||||
- [ ] 支持多 Agent 并发
|
||||
- [ ] 支持 Agent 间通信
|
||||
|
||||
---
|
||||
|
||||
## 六、演化路线
|
||||
## 九、与旧架构对比
|
||||
|
||||
### 6.1 短期计划(1-2 周)
|
||||
- [ ] 优化重连策略,添加指数退避
|
||||
|
||||
### 6.2 中期计划(1-2 月)
|
||||
- [ ] 支持多 Gateway 负载均衡
|
||||
|
||||
### 6.3 长期愿景
|
||||
- [ ] 支持分布式 Gateway 集群
|
||||
| 特性 | 旧架构 (外部 OpenFang) | 新架构 (内部 Kernel) |
|
||||
|------|----------------------|---------------------|
|
||||
| 后端进程 | 需要独立启动 | 内置在 Tauri 中 |
|
||||
| 通信方式 | WebSocket/HTTP | Tauri 命令 |
|
||||
| 模型配置 | TOML 文件 | UI 设置页面 |
|
||||
| 启动时间 | 依赖外部进程 | 即时启动 |
|
||||
| 安装包 | 需要额外运行时 | 单一安装包 |
|
||||
|
||||
---
|
||||
|
||||
## 七、头脑风暴笔记
|
||||
|
||||
### 7.1 待讨论问题
|
||||
1. 是否需要支持 gRPC 协议?
|
||||
2. 离线模式如何处理?
|
||||
|
||||
### 7.2 创意想法
|
||||
- 智能协议选择:根据网络条件自动选择 WebSocket/REST
|
||||
- 连接池管理:复用连接,减少握手开销
|
||||
|
||||
### 7.3 风险与挑战
|
||||
- **技术风险**: WebSocket 兼容性问题
|
||||
- **缓解措施**: REST 降级兜底
|
||||
**最后更新**: 2026-03-22
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# OpenFang 集成 (OpenFang Integration)
|
||||
# ZCLAW Kernel 集成
|
||||
|
||||
> **分类**: Tauri 后端
|
||||
> **优先级**: P0 - 决定性
|
||||
> **成熟度**: L4 - 生产
|
||||
> **最后更新**: 2026-03-16
|
||||
> **最后更新**: 2026-03-22
|
||||
|
||||
---
|
||||
|
||||
@@ -11,263 +11,532 @@
|
||||
|
||||
### 1.1 基本信息
|
||||
|
||||
OpenFang 集成模块是 Tauri 后端的核心,负责与 OpenFang Rust 运行时的本地集成,包括进程管理、配置读写、设备配对等。
|
||||
ZCLAW Kernel 集成模块是 Tauri 后端的核心,负责与内部 ZCLAW Kernel 的集成,包括 Agent 生命周期管理、消息处理、模型配置等。
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|-----|
|
||||
| 分类 | Tauri 后端 |
|
||||
| 优先级 | P0 |
|
||||
| 成熟度 | L4 |
|
||||
| 依赖 | Tauri Runtime |
|
||||
| 依赖 | Tauri Runtime, zclaw-kernel crate |
|
||||
|
||||
### 1.2 相关文件
|
||||
|
||||
| 文件 | 路径 | 用途 |
|
||||
|------|------|------|
|
||||
| 核心实现 | `desktop/src-tauri/src/lib.rs` | OpenFang 命令 (1043行) |
|
||||
| Viking 命令 | `desktop/src-tauri/src/viking_commands.rs` | OpenViking sidecar |
|
||||
| 服务器管理 | `desktop/src-tauri/src/viking_server.rs` | 本地服务器 |
|
||||
| 安全存储 | `desktop/src-tauri/src/secure_storage.rs` | Keyring 集成 |
|
||||
| Kernel 命令 | `desktop/src-tauri/src/kernel_commands.rs` | Tauri 命令封装 |
|
||||
| Kernel 状态 | `desktop/src-tauri/src/lib.rs` | Kernel 初始化 |
|
||||
| Kernel 配置 | `crates/zclaw-kernel/src/config.rs` | 配置结构定义 |
|
||||
| Kernel 实现 | `crates/zclaw-kernel/src/lib.rs` | Kernel 核心实现 |
|
||||
|
||||
---
|
||||
|
||||
## 二、设计初衷
|
||||
## 二、架构设计
|
||||
|
||||
### 2.1 问题背景
|
||||
### 2.1 设计背景
|
||||
|
||||
**用户痛点**:
|
||||
1. 需要手动启动 OpenFang 运行时
|
||||
1. 外部进程启动失败、版本兼容问题频发
|
||||
2. 配置文件分散难以管理
|
||||
3. 跨平台兼容性问题
|
||||
3. 分发复杂,需要额外配置运行时
|
||||
|
||||
**系统缺失能力**:
|
||||
- 缺乏本地运行时管理
|
||||
- 缺乏统一的配置接口
|
||||
- 缺乏进程监控能力
|
||||
**解决方案**:
|
||||
- 将 ZCLAW Kernel 直接集成到 Tauri 应用中
|
||||
- 通过 UI 配置模型,无需编辑配置文件
|
||||
- 单一安装包,开箱即用
|
||||
|
||||
**为什么需要**:
|
||||
Tauri 后端提供了原生系统集成能力,让用户无需关心运行时的启动和管理。
|
||||
|
||||
### 2.2 设计目标
|
||||
|
||||
1. **自动发现**: 自动找到 OpenFang 运行时
|
||||
2. **生命周期管理**: 启动、停止、重启
|
||||
3. **配置管理**: TOML 配置读写
|
||||
4. **进程监控**: 状态和日志查看
|
||||
|
||||
### 2.3 运行时发现优先级
|
||||
### 2.2 架构概览
|
||||
|
||||
```
|
||||
1. 环境变量 ZCLAW_OPENFANG_BIN
|
||||
2. Tauri 资源目录中的捆绑运行时
|
||||
3. 系统 PATH 中的 openfang 命令
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Tauri 桌面应用 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ 前端 (React + TypeScript) │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
|
||||
│ │ │ ModelsAPI │ │ ChatStore │ │ Connection │ │ │
|
||||
│ │ │ (UI 配置) │ │ (消息管理) │ │ Store │ │ │
|
||||
│ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ └────────────────┼────────────────┘ │ │
|
||||
│ │ │ │ │
|
||||
│ │ ▼ │ │
|
||||
│ │ ┌─────────────────────┐ │ │
|
||||
│ │ │ KernelClient │ │ │
|
||||
│ │ │ (Tauri invoke) │ │ │
|
||||
│ │ └──────────┬──────────┘ │ │
|
||||
│ └─────────────────────────┼──────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ Tauri Commands │
|
||||
│ │ │
|
||||
│ ┌─────────────────────────┼──────────────────────────────┐ │
|
||||
│ │ 后端 (Rust) │ │ │
|
||||
│ │ ▼ │ │
|
||||
│ │ ┌────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ kernel_commands.rs │ │ │
|
||||
│ │ │ ├─ kernel_init │ │ │
|
||||
│ │ │ ├─ kernel_status │ │ │
|
||||
│ │ │ ├─ kernel_shutdown │ │ │
|
||||
│ │ │ ├─ agent_create │ │ │
|
||||
│ │ │ ├─ agent_list │ │ │
|
||||
│ │ │ ├─ agent_get │ │ │
|
||||
│ │ │ ├─ agent_delete │ │ │
|
||||
│ │ │ └─ agent_chat │ │ │
|
||||
│ │ └────────────────────┬───────────────────────────┘ │ │
|
||||
│ │ │ │ │
|
||||
│ │ ▼ │ │
|
||||
│ │ ┌────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ zclaw-kernel crate │ │ │
|
||||
│ │ │ ├─ Kernel::boot() │ │ │
|
||||
│ │ │ ├─ spawn_agent() │ │ │
|
||||
│ │ │ ├─ kill_agent() │ │ │
|
||||
│ │ │ ├─ list_agents() │ │ │
|
||||
│ │ │ └─ send_message() │ │ │
|
||||
│ │ └────────────────────┬───────────────────────────┘ │ │
|
||||
│ │ │ │ │
|
||||
│ │ ▼ │ │
|
||||
│ │ ┌────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ zclaw-runtime crate │ │ │
|
||||
│ │ │ ├─ AnthropicDriver │ │ │
|
||||
│ │ │ ├─ OpenAiDriver │ │ │
|
||||
│ │ │ ├─ GeminiDriver │ │ │
|
||||
│ │ │ └─ LocalDriver │ │ │
|
||||
│ │ └────────────────────────────────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2.4 设计约束
|
||||
### 2.3 Crate 依赖
|
||||
|
||||
- **安全约束**: 配置文件需要验证
|
||||
- **性能约束**: 进程操作不能阻塞 UI
|
||||
- **兼容性约束**: Windows/macOS/Linux 统一接口
|
||||
```
|
||||
zclaw-types
|
||||
↑
|
||||
zclaw-memory
|
||||
↑
|
||||
zclaw-runtime
|
||||
↑
|
||||
zclaw-kernel
|
||||
↑
|
||||
desktop/src-tauri
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、技术设计
|
||||
## 三、Tauri 命令
|
||||
|
||||
### 3.1 核心命令
|
||||
### 3.1 Kernel 命令
|
||||
|
||||
```rust
|
||||
/// 初始化内部 ZCLAW Kernel
|
||||
#[tauri::command]
|
||||
fn openfang_status(app: AppHandle) -> Result<LocalGatewayStatus, String>
|
||||
pub async fn kernel_init(
|
||||
state: State<'_, KernelState>,
|
||||
config_request: Option<KernelConfigRequest>,
|
||||
) -> Result<KernelStatusResponse, String>
|
||||
|
||||
/// 获取 Kernel 状态
|
||||
#[tauri::command]
|
||||
fn openfang_start(app: AppHandle) -> Result<LocalGatewayStatus, String>
|
||||
pub async fn kernel_status(
|
||||
state: State<'_, KernelState>,
|
||||
) -> Result<KernelStatusResponse, String>
|
||||
|
||||
/// 关闭 Kernel
|
||||
#[tauri::command]
|
||||
fn openfang_stop(app: AppHandle) -> Result<LocalGatewayStatus, String>
|
||||
|
||||
#[tauri::command]
|
||||
fn openfang_restart(app: AppHandle) -> Result<LocalGatewayStatus, String>
|
||||
|
||||
#[tauri::command]
|
||||
fn openfang_local_auth(app: AppHandle) -> Result<GatewayAuth, String>
|
||||
|
||||
#[tauri::command]
|
||||
fn openfang_prepare_for_tauri(app: AppHandle) -> Result<(), String>
|
||||
|
||||
#[tauri::command]
|
||||
fn openfang_approve_device_pairing(app: AppHandle, device_id: String) -> Result<(), String>
|
||||
|
||||
#[tauri::command]
|
||||
fn openfang_process_list(app: AppHandle) -> Result<ProcessListResponse, String>
|
||||
|
||||
#[tauri::command]
|
||||
fn openfang_process_logs(app: AppHandle, pid: Option<u32>, lines: Option<usize>) -> Result<ProcessLogsResponse, String>
|
||||
|
||||
#[tauri::command]
|
||||
fn openfang_version(app: AppHandle) -> Result<VersionInfo, String>
|
||||
pub async fn kernel_shutdown(
|
||||
state: State<'_, KernelState>,
|
||||
) -> Result<(), String>
|
||||
```
|
||||
|
||||
### 3.2 状态结构
|
||||
### 3.2 Agent 命令
|
||||
|
||||
```rust
|
||||
#[derive(Serialize)]
|
||||
struct LocalGatewayStatus {
|
||||
running: bool,
|
||||
port: Option<u16>,
|
||||
pid: Option<u32>,
|
||||
config_path: Option<String>,
|
||||
binary_path: Option<String>,
|
||||
service_name: Option<String>,
|
||||
error: Option<String>,
|
||||
/// 创建 Agent
|
||||
#[tauri::command]
|
||||
pub async fn agent_create(
|
||||
state: State<'_, KernelState>,
|
||||
request: CreateAgentRequest,
|
||||
) -> Result<CreateAgentResponse, String>
|
||||
|
||||
/// 列出所有 Agent
|
||||
#[tauri::command]
|
||||
pub async fn agent_list(
|
||||
state: State<'_, KernelState>,
|
||||
) -> Result<Vec<AgentInfo>, String>
|
||||
|
||||
/// 获取 Agent 详情
|
||||
#[tauri::command]
|
||||
pub async fn agent_get(
|
||||
state: State<'_, KernelState>,
|
||||
agent_id: String,
|
||||
) -> Result<Option<AgentInfo>, String>
|
||||
|
||||
/// 删除 Agent
|
||||
#[tauri::command]
|
||||
pub async fn agent_delete(
|
||||
state: State<'_, KernelState>,
|
||||
agent_id: String,
|
||||
) -> Result<(), String>
|
||||
|
||||
/// 发送消息
|
||||
#[tauri::command]
|
||||
pub async fn agent_chat(
|
||||
state: State<'_, KernelState>,
|
||||
request: ChatRequest,
|
||||
) -> Result<ChatResponse, String>
|
||||
```
|
||||
|
||||
### 3.3 数据结构
|
||||
|
||||
```rust
|
||||
/// Kernel 配置请求
|
||||
pub struct KernelConfigRequest {
|
||||
pub provider: String, // kimi | qwen | deepseek | zhipu | openai | anthropic | local
|
||||
pub model: String, // 模型 ID
|
||||
pub api_key: Option<String>,
|
||||
pub base_url: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct GatewayAuth {
|
||||
gateway_token: Option<String>,
|
||||
device_public_key: Option<String>,
|
||||
/// Kernel 状态响应
|
||||
pub struct KernelStatusResponse {
|
||||
pub initialized: bool,
|
||||
pub agent_count: usize,
|
||||
pub database_url: Option<String>,
|
||||
pub default_provider: Option<String>,
|
||||
pub default_model: Option<String>,
|
||||
}
|
||||
|
||||
/// Agent 创建请求
|
||||
pub struct CreateAgentRequest {
|
||||
pub name: String,
|
||||
pub description: Option<String>,
|
||||
pub system_prompt: Option<String>,
|
||||
pub provider: String,
|
||||
pub model: String,
|
||||
pub max_tokens: u32,
|
||||
pub temperature: f32,
|
||||
}
|
||||
|
||||
/// Agent 创建响应
|
||||
pub struct CreateAgentResponse {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub state: String,
|
||||
}
|
||||
|
||||
/// 聊天请求
|
||||
pub struct ChatRequest {
|
||||
pub agent_id: String,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
/// 聊天响应
|
||||
pub struct ChatResponse {
|
||||
pub content: String,
|
||||
pub input_tokens: u32,
|
||||
pub output_tokens: u32,
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 运行时发现
|
||||
---
|
||||
|
||||
## 四、Kernel 初始化
|
||||
|
||||
### 4.1 初始化流程
|
||||
|
||||
```rust
|
||||
fn find_openfang_binary(app: &AppHandle) -> Option<PathBuf> {
|
||||
// 1. 环境变量
|
||||
if let Ok(path) = std::env::var("ZCLAW_OPENFANG_BIN") {
|
||||
let path = PathBuf::from(path);
|
||||
if path.exists() {
|
||||
return Some(path);
|
||||
// desktop/src-tauri/src/kernel_commands.rs
|
||||
|
||||
pub async fn kernel_init(
|
||||
state: State<'_, KernelState>,
|
||||
config_request: Option<KernelConfigRequest>,
|
||||
) -> Result<KernelStatusResponse, String> {
|
||||
let mut kernel_lock = state.lock().await;
|
||||
|
||||
// 如果已初始化,返回当前状态
|
||||
if kernel_lock.is_some() {
|
||||
let kernel = kernel_lock.as_ref().unwrap();
|
||||
return Ok(KernelStatusResponse { ... });
|
||||
}
|
||||
|
||||
// 构建配置
|
||||
let mut config = zclaw_kernel::config::KernelConfig::default();
|
||||
|
||||
if let Some(req) = &config_request {
|
||||
config.default_provider = req.provider.clone();
|
||||
config.default_model = req.model.clone();
|
||||
|
||||
// 根据 Provider 设置 API Key
|
||||
match req.provider.as_str() {
|
||||
"kimi" => {
|
||||
if let Some(key) = &req.api_key {
|
||||
config.kimi_api_key = Some(key.clone());
|
||||
}
|
||||
if let Some(url) = &req.base_url {
|
||||
config.kimi_base_url = url.clone();
|
||||
}
|
||||
}
|
||||
"qwen" => {
|
||||
if let Some(key) = &req.api_key {
|
||||
config.qwen_api_key = Some(key.clone());
|
||||
}
|
||||
if let Some(url) = &req.base_url {
|
||||
config.qwen_base_url = url.clone();
|
||||
}
|
||||
}
|
||||
// ... 其他 Provider
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 捆绑运行时
|
||||
if let Some(resource_dir) = app.path().resource_dir().ok() {
|
||||
let bundled = resource_dir.join("bin").join("openfang");
|
||||
if bundled.exists() {
|
||||
return Some(bundled);
|
||||
}
|
||||
}
|
||||
// 启动 Kernel
|
||||
let kernel = Kernel::boot(config.clone())
|
||||
.await
|
||||
.map_err(|e| format!("Failed to initialize kernel: {}", e))?;
|
||||
|
||||
// 3. 系统 PATH
|
||||
if let Ok(path) = which::which("openfang") {
|
||||
return Some(path);
|
||||
}
|
||||
*kernel_lock = Some(kernel);
|
||||
|
||||
None
|
||||
Ok(KernelStatusResponse {
|
||||
initialized: true,
|
||||
agent_count: 0,
|
||||
database_url: Some(config.database_url),
|
||||
default_provider: Some(config.default_provider),
|
||||
default_model: Some(config.default_model),
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 配置管理
|
||||
### 4.2 Kernel 状态管理
|
||||
|
||||
```rust
|
||||
fn read_config(config_path: &Path) -> Result<OpenFangConfig, String> {
|
||||
let content = std::fs::read_to_string(config_path)
|
||||
.map_err(|e| format!("Failed to read config: {}", e))?;
|
||||
// Kernel 状态包装器
|
||||
pub type KernelState = Arc<Mutex<Option<Kernel>>>;
|
||||
|
||||
let config: OpenFangConfig = toml::from_str(&content)
|
||||
.map_err(|e| format!("Failed to parse config: {}", e))?;
|
||||
|
||||
Ok(config)
|
||||
// 创建 Kernel 状态
|
||||
pub fn create_kernel_state() -> KernelState {
|
||||
Arc::new(Mutex::new(None))
|
||||
}
|
||||
```
|
||||
|
||||
fn write_config(config_path: &Path, config: &OpenFangConfig) -> Result<(), String> {
|
||||
let content = toml::to_string_pretty(config)
|
||||
.map_err(|e| format!("Failed to serialize config: {}", e))?;
|
||||
### 4.3 lib.rs 注册
|
||||
|
||||
std::fs::write(config_path, content)
|
||||
.map_err(|e| format!("Failed to write config: {}", e))
|
||||
```rust
|
||||
// desktop/src-tauri/src/lib.rs
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.setup(|app| {
|
||||
// 注册 Kernel 状态
|
||||
app.manage(kernel_commands::create_kernel_state());
|
||||
Ok(())
|
||||
})
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
// Kernel 命令
|
||||
kernel_commands::kernel_init,
|
||||
kernel_commands::kernel_status,
|
||||
kernel_commands::kernel_shutdown,
|
||||
// Agent 命令
|
||||
kernel_commands::agent_create,
|
||||
kernel_commands::agent_list,
|
||||
kernel_commands::agent_get,
|
||||
kernel_commands::agent_delete,
|
||||
kernel_commands::agent_chat,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、预期作用
|
||||
## 五、LLM Provider 支持
|
||||
|
||||
### 4.1 用户价值
|
||||
### 5.1 支持的 Provider
|
||||
|
||||
| 价值类型 | 描述 |
|
||||
|---------|------|
|
||||
| 便捷体验 | 一键启动/停止 |
|
||||
| 统一管理 | 配置集中管理 |
|
||||
| 透明度 | 进程状态可见 |
|
||||
| Provider | 实现方式 | Base URL |
|
||||
|----------|---------|----------|
|
||||
| kimi | OpenAiDriver | `https://api.kimi.com/coding/v1` |
|
||||
| qwen | OpenAiDriver | `https://dashscope.aliyuncs.com/compatible-mode/v1` |
|
||||
| deepseek | OpenAiDriver | `https://api.deepseek.com/v1` |
|
||||
| zhipu | OpenAiDriver | `https://open.bigmodel.cn/api/paas/v4` |
|
||||
| openai | OpenAiDriver | `https://api.openai.com/v1` |
|
||||
| anthropic | AnthropicDriver | `https://api.anthropic.com` |
|
||||
| gemini | GeminiDriver | `https://generativelanguage.googleapis.com` |
|
||||
| local | LocalDriver | `http://localhost:11434/v1` |
|
||||
|
||||
### 4.2 系统价值
|
||||
### 5.2 Driver 创建
|
||||
|
||||
| 价值类型 | 描述 |
|
||||
|---------|------|
|
||||
| 架构收益 | 原生系统集成 |
|
||||
| 可维护性 | Rust 代码稳定 |
|
||||
| 可扩展性 | 易于添加新命令 |
|
||||
```rust
|
||||
// crates/zclaw-kernel/src/config.rs
|
||||
|
||||
### 4.3 成功指标
|
||||
|
||||
| 指标 | 基线 | 目标 | 当前 |
|
||||
|------|------|------|------|
|
||||
| 启动成功率 | 80% | 99% | 98% |
|
||||
| 配置解析成功率 | 90% | 99% | 99% |
|
||||
| 响应时间 | - | <1s | 500ms |
|
||||
impl KernelConfig {
|
||||
pub fn create_driver(&self) -> Result<Arc<dyn LlmDriver>> {
|
||||
let driver: Arc<dyn LlmDriver> = match self.default_provider.as_str() {
|
||||
"kimi" => {
|
||||
let key = self.kimi_api_key.clone()
|
||||
.ok_or_else(|| ZclawError::ConfigError("KIMI_API_KEY not set".into()))?;
|
||||
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()))?;
|
||||
Arc::new(OpenAiDriver::with_base_url(
|
||||
SecretString::new(key),
|
||||
self.qwen_base_url.clone(),
|
||||
))
|
||||
}
|
||||
// ... 其他 Provider
|
||||
_ => return Err(ZclawError::ConfigError(
|
||||
format!("Unknown provider: {}", self.default_provider)
|
||||
)),
|
||||
};
|
||||
Ok(driver)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、实际效果
|
||||
## 六、前端集成
|
||||
|
||||
### 5.1 已实现功能
|
||||
### 6.1 KernelClient
|
||||
|
||||
- [x] 运行时自动发现
|
||||
- [x] 启动/停止/重启
|
||||
- [x] TOML 配置读写
|
||||
- [x] 设备配对审批
|
||||
- [x] 进程列表查看
|
||||
- [x] 进程日志查看
|
||||
- [x] 版本信息获取
|
||||
```typescript
|
||||
// desktop/src/lib/kernel-client.ts
|
||||
|
||||
export class KernelClient {
|
||||
private config: KernelConfig = {};
|
||||
|
||||
setConfig(config: KernelConfig): void {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
async connect(): Promise<void> {
|
||||
// 验证配置
|
||||
if (!this.config.provider || !this.config.model || !this.config.apiKey) {
|
||||
throw new Error('请先在"模型与 API"设置页面配置模型');
|
||||
}
|
||||
|
||||
// 初始化 Kernel
|
||||
const status = await invoke<KernelStatus>('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<ChatResponse> {
|
||||
return invoke<ChatResponse>('agent_chat', {
|
||||
request: {
|
||||
agentId: opts?.agentId || this.defaultAgentId,
|
||||
message,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.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 环境,使用外部 Gateway
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、与旧架构对比
|
||||
|
||||
| 特性 | 旧架构 (外部 OpenFang) | 新架构 (内部 Kernel) |
|
||||
|------|----------------------|---------------------|
|
||||
| 后端进程 | 独立 OpenFang 进程 | 内置 zclaw-kernel |
|
||||
| 通信方式 | WebSocket/HTTP | Tauri 命令 |
|
||||
| 模型配置 | TOML 文件 | UI 设置页面 |
|
||||
| 启动时间 | 依赖外部进程 | 即时启动 |
|
||||
| 安装包 | 需要额外运行时 | 单一安装包 |
|
||||
| 进程管理 | 需要 openfang 命令 | 自动管理 |
|
||||
|
||||
---
|
||||
|
||||
## 八、实际效果
|
||||
|
||||
### 8.1 已实现功能
|
||||
|
||||
- [x] 内部 Kernel 集成
|
||||
- [x] 多 LLM Provider 支持
|
||||
- [x] UI 模型配置
|
||||
- [x] Agent 生命周期管理
|
||||
- [x] 消息发送和响应
|
||||
- [x] 连接状态管理
|
||||
- [x] 错误处理
|
||||
|
||||
### 5.2 测试覆盖
|
||||
### 8.2 测试覆盖
|
||||
|
||||
- **单元测试**: Rust 内置测试
|
||||
- **集成测试**: 包含在前端测试中
|
||||
- **集成测试**: E2E 测试覆盖
|
||||
- **覆盖率**: ~85%
|
||||
|
||||
### 5.3 已知问题
|
||||
---
|
||||
|
||||
| 问题 | 严重程度 | 状态 | 计划解决 |
|
||||
|------|---------|------|---------|
|
||||
| 某些 Linux 发行版路径问题 | 中 | 已处理 | - |
|
||||
## 九、演化路线
|
||||
|
||||
### 5.4 用户反馈
|
||||
### 9.1 短期计划(1-2 周)
|
||||
- [ ] 添加真正的流式响应支持
|
||||
|
||||
本地集成体验流畅,无需关心运行时管理。
|
||||
### 9.2 中期计划(1-2 月)
|
||||
- [ ] Agent 持久化存储
|
||||
- [ ] 会话历史管理
|
||||
|
||||
### 9.3 长期愿景
|
||||
- [ ] 多 Agent 并发支持
|
||||
- [ ] Agent 间通信
|
||||
- [ ] 工作流引擎集成
|
||||
|
||||
---
|
||||
|
||||
## 六、演化路线
|
||||
|
||||
### 6.1 短期计划(1-2 周)
|
||||
- [ ] 添加自动更新检查
|
||||
- [ ] 优化错误信息
|
||||
|
||||
### 6.2 中期计划(1-2 月)
|
||||
- [ ] 多实例管理
|
||||
- [ ] 配置备份/恢复
|
||||
|
||||
### 6.3 长期愿景
|
||||
- [ ] 远程 OpenFang 管理
|
||||
- [ ] 集群部署支持
|
||||
|
||||
---
|
||||
|
||||
## 七、头脑风暴笔记
|
||||
|
||||
### 7.1 待讨论问题
|
||||
1. 是否需要支持自定义运行时路径?
|
||||
2. 如何处理运行时升级?
|
||||
|
||||
### 7.2 创意想法
|
||||
- 运行时健康检查:定期检测运行时状态
|
||||
- 自动重启:运行时崩溃后自动恢复
|
||||
- 资源监控:CPU/内存使用追踪
|
||||
|
||||
### 7.3 风险与挑战
|
||||
- **技术风险**: 跨平台兼容性
|
||||
- **安全风险**: 配置文件权限
|
||||
- **缓解措施**: 路径验证,权限检查
|
||||
**最后更新**: 2026-03-22
|
||||
|
||||
@@ -1,302 +1,230 @@
|
||||
# OpenFang 配置指南
|
||||
# ZCLAW 模型配置指南
|
||||
|
||||
> 记录 OpenFang 配置文件位置、格式和最佳实践。
|
||||
> 讌**重要变更**: ZCLAW 现在使用 UI 配置模型,不再需要编辑配置文件。
|
||||
|
||||
---
|
||||
|
||||
## 1. 配置文件位置
|
||||
## 1. 配置方式
|
||||
|
||||
### 1.1 UI 配置(推荐)
|
||||
|
||||
在 ZCLAW 桌面应用中直接配置模型:
|
||||
|
||||
1. 打开应用,点击设置图标 ⚙️
|
||||
2. 进入"模型与 API"页面
|
||||
3. 点击"添加自定义模型"
|
||||
4. 填写配置信息
|
||||
5. 点击"设为默认"
|
||||
|
||||
### 1.2 配置存储位置
|
||||
|
||||
配置保存在浏览器的 localStorage 中:
|
||||
|
||||
```
|
||||
~/.openfang/
|
||||
├── config.toml # 主配置文件(启动时读取)
|
||||
├── .env # API Key 环境变量
|
||||
├── secrets.env # 敏感信息(可选)
|
||||
├── daemon.json # 守护进程状态
|
||||
└── data/
|
||||
└── openfang.db # SQLite 数据库(持久化配置)
|
||||
localStorage Key: zclaw-custom-models
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 主配置文件 (config.toml)
|
||||
## 2. 支持的 Provider
|
||||
|
||||
### 智谱 (Zhipu) 配置
|
||||
### 2.1 国内 Provider
|
||||
|
||||
```toml
|
||||
[default_model]
|
||||
provider = "zhipu"
|
||||
model = "glm-4-flash"
|
||||
api_key_env = "ZHIPU_API_KEY"
|
||||
| Provider | 名称 | Base URL | 说明 |
|
||||
|----------|------|----------|------|
|
||||
| kimi | Kimi Code | `https://api.kimi.com/coding/v1` | Kimi 编程助手 |
|
||||
| qwen | 百炼/通义千问 | `https://dashscope.aliyuncs.com/compatible-mode/v1` | 阿里云百炼 |
|
||||
| deepseek | DeepSeek | `https://api.deepseek.com/v1` | DeepSeek |
|
||||
| zhipu | 智谱 GLM | `https://open.bigmodel.cn/api/paas/v4` | 智谱 AI |
|
||||
| minimax | MiniMax | `https://api.minimax.chat/v1` | MiniMax |
|
||||
|
||||
[kernel]
|
||||
data_dir = "C:\\Users\\szend\\.openfang\\data"
|
||||
### 2.2 国际 Provider
|
||||
|
||||
[memory]
|
||||
decay_rate = 0.05
|
||||
```
|
||||
| Provider | 名称 | Base URL | 说明 |
|
||||
|----------|------|----------|------|
|
||||
| openai | OpenAI | `https://api.openai.com/v1` | OpenAI GPT |
|
||||
| anthropic | Anthropic | `https://api.anthropic.com` | Anthropic Claude |
|
||||
| gemini | Google Gemini | `https://generativelanguage.googleapis.com` | Google Gemini |
|
||||
|
||||
### 百炼 (Bailian) 配置
|
||||
### 2.3 本地 Provider
|
||||
|
||||
```toml
|
||||
[default_model]
|
||||
provider = "bailian"
|
||||
model = "qwen3.5-plus"
|
||||
api_key_env = "BAILIAN_API_KEY"
|
||||
|
||||
[kernel]
|
||||
data_dir = "C:\\Users\\szend\\.openfang\\data"
|
||||
|
||||
[memory]
|
||||
decay_rate = 0.05
|
||||
```
|
||||
|
||||
### 配置项说明
|
||||
|
||||
| 配置项 | 说明 | 示例值 |
|
||||
|--------|------|--------|
|
||||
| `default_model.provider` | 默认 LLM 提供商 | `zhipu`, `bailian`, `gemini` |
|
||||
| `default_model.model` | 默认模型名称 | `glm-4-flash`, `qwen3.5-plus` |
|
||||
| `default_model.api_key_env` | API Key 环境变量名 | `ZHIPU_API_KEY` |
|
||||
| `kernel.data_dir` | 数据目录 | `~/.openfang/data` |
|
||||
| `memory.decay_rate` | 记忆衰减率 | `0.05` |
|
||||
| Provider | 名称 | Base URL | 说明 |
|
||||
|----------|------|----------|------|
|
||||
| local | Ollama | `http://localhost:11434/v1` | Ollama 本地 |
|
||||
| local | LM Studio | `http://localhost:1234/v1` | LM Studio 本地 |
|
||||
|
||||
---
|
||||
|
||||
## 3. API Key 配置
|
||||
## 3. UI 配置步骤
|
||||
|
||||
### 方式 1: .env 文件(推荐)
|
||||
### 3.1 添加模型
|
||||
|
||||
```bash
|
||||
# ~/.openfang/.env
|
||||
ZHIPU_API_KEY=sk-sp-xxxxx
|
||||
BAILIAN_API_KEY=sk-sp-xxxxx
|
||||
GEMINI_API_KEY=your_gemini_key
|
||||
DEEPSEEK_API_KEY=your_deepseek_key
|
||||
OPENAI_API_KEY=your_openai_key
|
||||
GROQ_API_KEY=your_groq_key
|
||||
```
|
||||
在"模型与 API"页面:
|
||||
|
||||
### 方式 2: secrets.env 文件
|
||||
1. **服务商**: 从下拉列表选择 Provider
|
||||
2. **模型 ID**: 填写模型标识符(如 `kimi-k2-turbo`、`qwen-plus`)
|
||||
3. **显示名称**: 可选,用于界面显示
|
||||
4. **API Key**: 填写你的 API 密钥
|
||||
5. **API 协议**: 选择 OpenAI(大多数 Provider)或 Anthropic
|
||||
6. **Base URL**: 可选,使用自定义 API 端点
|
||||
|
||||
```bash
|
||||
# ~/.openfang/secrets.env
|
||||
ZHIPU_API_KEY=sk-sp-xxxxx
|
||||
BAILIAN_API_KEY=sk-sp-xxxxx
|
||||
```
|
||||
### 3.2 设为默认
|
||||
|
||||
### 方式 3: 通过 API 设置
|
||||
点击模型列表中的"设为默认"按钮。
|
||||
|
||||
```bash
|
||||
# 设置智谱密钥
|
||||
curl -X POST http://127.0.0.1:50051/api/providers/zhipu/key \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"key":"your-zhipu-api-key"}'
|
||||
### 3.3 修改配置
|
||||
|
||||
# 设置百炼密钥
|
||||
curl -X POST http://127.0.0.1:50051/api/providers/bailian/key \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"key":"your-bailian-api-key"}'
|
||||
```
|
||||
|
||||
### 方式 4: 启动时指定环境变量
|
||||
|
||||
```bash
|
||||
# Windows PowerShell
|
||||
$env:ZHIPU_API_KEY = "your_key"
|
||||
./openfang.exe start
|
||||
|
||||
# Linux/macOS
|
||||
ZHIPU_API_KEY=sk-sp-xxx ./openfang start
|
||||
```
|
||||
点击"编辑"按钮修改已有配置。
|
||||
|
||||
---
|
||||
|
||||
## 4. 支持的 Provider
|
||||
## 4. 可用模型
|
||||
|
||||
### 4.1 国内 Provider
|
||||
### 4.1 Kimi Code
|
||||
|
||||
| Provider | 环境变量 | Base URL | 说明 |
|
||||
|----------|----------|----------|------|
|
||||
| zhipu | `ZHIPU_API_KEY` | `https://open.bigmodel.cn/api/paas/v4` | 智谱 GLM |
|
||||
| zhipu_coding | `ZHIPU_API_KEY` | `https://open.bigmodel.cn/api/coding/paas/v4` | 智谱 CodeGeeX |
|
||||
| bailian | `BAILIAN_API_KEY` | `https://coding.dashscope.aliyuncs.com/v1` | 百炼 Coding Plan |
|
||||
| qwen | `DASHSCOPE_API_KEY` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | 通义千问 |
|
||||
| volcengine | `VOLCENGINE_API_KEY` | `https://ark.cn-beijing.volces.com/api/v3` | 火山引擎 Doubao |
|
||||
| moonshot | `MOONSHOT_API_KEY` | `https://api.moonshot.ai/v1` | Moonshot Kimi |
|
||||
| deepseek | `DEEPSEEK_API_KEY` | `https://api.deepseek.com/v1` | DeepSeek |
|
||||
| 模型 ID | 说明 | 适用场景 |
|
||||
|---------|------|----------|
|
||||
| kimi-k2-turbo | 快速模型 | 日常对话、快速响应 |
|
||||
| kimi-k2-pro | 高级模型 | 复杂推理、深度分析 |
|
||||
|
||||
### 4.2 国际 Provider
|
||||
### 4.2 百炼/通义千问 (Qwen)
|
||||
|
||||
| Provider | 环境变量 | Base URL | 说明 |
|
||||
|----------|----------|----------|------|
|
||||
| openai | `OPENAI_API_KEY` | `https://api.openai.com/v1` | OpenAI GPT |
|
||||
| anthropic | `ANTHROPIC_API_KEY` | `https://api.anthropic.com` | Anthropic Claude |
|
||||
| gemini | `GEMINI_API_KEY` | `https://generativelanguage.googleapis.com` | Google Gemini |
|
||||
| groq | `GROQ_API_KEY` | `https://api.groq.com/openai/v1` | Groq |
|
||||
| mistral | `MISTRAL_API_KEY` | `https://api.mistral.ai/v1` | Mistral AI |
|
||||
| xai | `XAI_API_KEY` | `https://api.x.ai/v1` | xAI Grok |
|
||||
| 模型 ID | 说明 | 适用场景 |
|
||||
|---------|------|----------|
|
||||
| qwen-turbo | 快速模型 | 日常对话 |
|
||||
| qwen-plus | 通用模型 | 复杂任务 |
|
||||
| qwen-max | 高级模型 | 深度分析 |
|
||||
| qwen-coder-plus | 编码专家 | 代码生成 |
|
||||
|
||||
### 4.3 本地 Provider
|
||||
### 4.3 DeepSeek
|
||||
|
||||
| Provider | 环境变量 | Base URL | 说明 |
|
||||
|----------|----------|----------|------|
|
||||
| ollama | - | `http://localhost:11434/v1` | Ollama 本地 |
|
||||
| vllm | - | `http://localhost:8000/v1` | vLLM 本地 |
|
||||
| lmstudio | - | `http://localhost:1234/v1` | LM Studio 本地 |
|
||||
| 模型 ID | 说明 | 适用场景 |
|
||||
|---------|------|----------|
|
||||
| deepseek-chat | 通用对话 | 日常对话 |
|
||||
| deepseek-coder | 编码专家 | 代码生成 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 可用模型
|
||||
|
||||
### 智谱 (Zhipu)
|
||||
### 4.4 智谱 GLM (Zhipu)
|
||||
|
||||
| 模型 ID | 说明 | 适用场景 |
|
||||
|---------|------|----------|
|
||||
| glm-4-flash | 快速模型 | 日常对话、快速响应 |
|
||||
| glm-4-plus | 高级模型 | 复杂推理、深度分析 |
|
||||
| glm-4 | 标准模型 | 通用场景 |
|
||||
| glm-4-air | 轻量模型 | 简单任务 |
|
||||
|
||||
### 百炼 (Bailian)
|
||||
|
||||
| 模型 ID | 说明 | 适用场景 |
|
||||
|---------|------|----------|
|
||||
| qwen3.5-plus | 通用对话 | 日常对话 |
|
||||
| qwen3-coder-next | 编码专家 | 代码生成 |
|
||||
| glm-5-bailian | GLM-5 | 通用场景 |
|
||||
| minimax-m2.5-bailian | 支持视觉 | 多模态任务 |
|
||||
| kimi-k2.5-bailian | Kimi K2.5 | 长文本处理 |
|
||||
|
||||
### 其他推荐模型
|
||||
|
||||
| Provider | 模型 ID | 适用场景 |
|
||||
|----------|---------|----------|
|
||||
| gemini | gemini-2.5-flash | 开发任务 |
|
||||
| deepseek | deepseek-chat | 快速响应 |
|
||||
| groq | llama-3.1-70b | 开源模型 |
|
||||
| glm-4-plus | 高级模型 | 复杂推理 |
|
||||
| glm-4-airx | 轻量模型 | 简单任务 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 快速切换 Provider
|
||||
## 5. 配置示例
|
||||
|
||||
### 方法 A: 修改 config.toml
|
||||
### 5.1 Kimi Code 配置
|
||||
|
||||
```toml
|
||||
# 切换到智谱
|
||||
[default_model]
|
||||
provider = "zhipu"
|
||||
model = "glm-4-flash"
|
||||
api_key_env = "ZHIPU_API_KEY"
|
||||
|
||||
# 切换到百炼
|
||||
[default_model]
|
||||
provider = "bailian"
|
||||
model = "qwen3.5-plus"
|
||||
api_key_env = "BAILIAN_API_KEY"
|
||||
```
|
||||
服务商: kimi
|
||||
模型 ID: kimi-k2-turbo
|
||||
显示名称: Kimi K2 Turbo
|
||||
API Key: 你的 Kimi API Key
|
||||
API 协议: OpenAI
|
||||
Base URL: https://api.kimi.com/coding/v1
|
||||
```
|
||||
|
||||
**重要**: 修改后必须完全重启 OpenFang!
|
||||
### 5.2 百炼 Qwen 配置
|
||||
|
||||
### 方法 B: 创建不同配置的 Agent
|
||||
```
|
||||
服务商: qwen
|
||||
模型 ID: qwen-plus
|
||||
显示名称: 通义千问 Plus
|
||||
API Key: 你的百炼 API Key
|
||||
API 协议: OpenAI
|
||||
Base URL: https://dashscope.aliyuncs.com/compatible-mode/v1
|
||||
```
|
||||
|
||||
```bash
|
||||
# 创建使用智谱的 Agent
|
||||
curl -X POST http://127.0.0.1:50051/api/agents \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"manifest_toml": "name = \"Zhipu Agent\"\nmodel_provider = \"zhipu\"\nmodel_name = \"glm-4-flash\""}'
|
||||
### 5.3 DeepSeek 配置
|
||||
|
||||
# 创建使用百炼的 Agent
|
||||
curl -X POST http://127.0.0.1:50051/api/agents \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"manifest_toml": "name = \"Bailian Agent\"\nmodel_provider = \"bailian\"\nmodel_name = \"qwen3.5-plus\""}'
|
||||
```
|
||||
服务商: deepseek
|
||||
模型 ID: deepseek-chat
|
||||
显示名称: DeepSeek Chat
|
||||
API Key: 你的 DeepSeek API Key
|
||||
API 协议: OpenAI
|
||||
Base URL: https://api.deepseek.com/v1
|
||||
```
|
||||
|
||||
### 5.4 本地 Ollama 配置
|
||||
|
||||
```
|
||||
服务商: local
|
||||
模型 ID: llama3.2
|
||||
显示名称: Llama 3.2 Local
|
||||
API Key: (留空)
|
||||
API 协议: OpenAI
|
||||
Base URL: http://localhost:11434/v1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 配置验证
|
||||
## 6. 常见问题
|
||||
|
||||
### 检查当前配置
|
||||
### Q: 如何获取 API Key?
|
||||
|
||||
```bash
|
||||
# 检查 API 返回的配置
|
||||
curl -s http://127.0.0.1:50051/api/config
|
||||
| Provider | 获取方式 |
|
||||
|----------|----------|
|
||||
| Kimi | 访问 [kimi.com/code](https://kimi.com/code) 注册 |
|
||||
| Qwen | 访问 [百炼平台](https://bailian.console.aliyun.com/) |
|
||||
| DeepSeek | 访问 [platform.deepseek.com](https://platform.deepseek.com/) |
|
||||
| Zhipu | 访问 [open.bigmodel.cn](https://open.bigmodel.cn/) |
|
||||
| OpenAI | 访问 [platform.openai.com](https://platform.openai.com/) |
|
||||
|
||||
# 检查状态
|
||||
curl -s http://127.0.0.1:50051/api/status | grep -E "default_provider|default_model"
|
||||
### Q: API Key 存储在哪里?
|
||||
|
||||
# 检查所有 Provider 状态
|
||||
curl -s http://127.0.0.1:50051/api/providers | grep -E "id|auth_status"
|
||||
```
|
||||
API Key 存储在浏览器的 localStorage 中,不会上传到服务器。
|
||||
|
||||
### 检查 Agent 配置
|
||||
### Q: 如何切换模型?
|
||||
|
||||
```bash
|
||||
# 列出所有 Agent 及其 Provider
|
||||
curl -s http://127.0.0.1:50051/api/agents | grep -E "name|model_provider|ready"
|
||||
```
|
||||
在"模型与 API"页面,点击模型旁边的"设为默认"按钮。
|
||||
|
||||
### 测试聊天
|
||||
### Q: 配置后没有生效?
|
||||
|
||||
```bash
|
||||
# 测试 Agent 是否能正常响应
|
||||
curl -X POST "http://127.0.0.1:50051/api/agents/{agentId}/message" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"message":"Hello"}'
|
||||
```
|
||||
1. 确保点击了"设为默认"
|
||||
2. 检查 API Key 是否正确
|
||||
3. 重新连接(点击"重新连接"按钮)
|
||||
|
||||
### Q: 显示"请先在模型与 API 设置页面配置模型"?
|
||||
|
||||
你需要先添加至少一个自定义模型并设为默认,才能开始对话。
|
||||
|
||||
---
|
||||
|
||||
## 8. 重要注意事项
|
||||
## 7. 架构说明
|
||||
|
||||
### 8.1 配置热重载限制
|
||||
### 7.1 数据流
|
||||
|
||||
**关键**: OpenFang 将配置持久化在 SQLite 数据库中,`config.toml` 只在启动时读取。
|
||||
|
||||
- `/api/config/reload` **不会**更新已持久化的默认模型配置
|
||||
- 修改 `config.toml` 后必须**完全重启 OpenFang**
|
||||
|
||||
```bash
|
||||
# 正确的重启方式
|
||||
curl -X POST http://127.0.0.1:50051/api/shutdown
|
||||
# 然后手动启动
|
||||
./openfang.exe start
|
||||
```
|
||||
UI 配置 (localStorage)
|
||||
│
|
||||
▼
|
||||
connectionStore.getDefaultModelConfig()
|
||||
│
|
||||
▼
|
||||
KernelClient.setConfig()
|
||||
│
|
||||
▼
|
||||
Tauri 命令: kernel_init()
|
||||
│
|
||||
▼
|
||||
zclaw-kernel::Kernel::boot()
|
||||
│
|
||||
▼
|
||||
LLM Driver (Kimi/Qwen/DeepSeek/...)
|
||||
```
|
||||
|
||||
### 8.2 Agent 创建时的 Provider
|
||||
### 7.2 关键文件
|
||||
|
||||
如果创建 Agent 时没有指定 Provider,OpenFang 会使用数据库中存储的默认配置,而不是 `config.toml` 中的配置。
|
||||
|
||||
### 8.3 API Key 验证
|
||||
|
||||
确保 API Key 格式正确:
|
||||
- 智谱: `sk-sp-xxxxx` 或 `xxxxx.xxxxx.xxxxx`
|
||||
- 百炼: `sk-xxxxx`
|
||||
|
||||
---
|
||||
|
||||
## 9. 常见问题
|
||||
|
||||
### Q: 修改 config.toml 后配置没有生效?
|
||||
|
||||
**A**: 必须完全重启 OpenFang,热重载不会更新持久化配置。
|
||||
|
||||
### Q: Agent 显示 ready: false?
|
||||
|
||||
**A**: 检查 Agent 使用的 Provider 是否配置了 API Key:
|
||||
```bash
|
||||
curl -s http://127.0.0.1:50051/api/agents | grep -E "auth_status|ready"
|
||||
```
|
||||
|
||||
### Q: 如何查看所有可用的 Provider?
|
||||
|
||||
**A**:
|
||||
```bash
|
||||
curl -s http://127.0.0.1:50051/api/providers
|
||||
```
|
||||
|
||||
### Q: 如何在不重启的情况下切换 Agent?
|
||||
|
||||
**A**: 前端可以通过选择不同 Provider 的 Agent 来切换,无需重启。
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `desktop/src/components/Settings/ModelsAPI.tsx` | UI 配置组件 |
|
||||
| `desktop/src/store/connectionStore.ts` | 读取配置并传递给 Kernel |
|
||||
| `desktop/src/lib/kernel-client.ts` | Tauri 命令客户端 |
|
||||
| `desktop/src-tauri/src/kernel_commands.rs` | Rust 命令实现 |
|
||||
| `crates/zclaw-kernel/src/config.rs` | Kernel 配置结构 |
|
||||
|
||||
---
|
||||
|
||||
@@ -304,4 +232,5 @@ curl -s http://127.0.0.1:50051/api/providers
|
||||
|
||||
| 日期 | 变更 |
|
||||
|------|------|
|
||||
| 2026-03-17 | 初始版本,记录配置热重载限制 |
|
||||
| 2026-03-22 | 更新为 UI 配置方式,移除 TOML 文件配置 |
|
||||
| 2026-03-17 | 初始版本 |
|
||||
|
||||
558
docs/knowledge-base/openmaic-analysis.md
Normal file
558
docs/knowledge-base/openmaic-analysis.md
Normal file
@@ -0,0 +1,558 @@
|
||||
# OpenMAIC 深度分析报告
|
||||
|
||||
> **来源**: https://github.com/THU-MAIC/OpenMAIC
|
||||
> **分析日期**: 2026-03-22
|
||||
> **许可证**: AGPL-3.0
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
### 1.1 项目定位
|
||||
|
||||
**OpenMAIC** (Open Multi-Agent Interactive Classroom) 是由清华大学 MAIC 团队开发的开源 AI 互动课堂平台。它能够将任何主题或文档转化为丰富的互动学习体验,核心特点是**多智能体协作**驱动的教育场景生成。
|
||||
|
||||
- **在线演示**: https://open.maic.chat/
|
||||
- **学术论文**: 发表于 JCST'26 (Journal of Computer Science and Technology)
|
||||
|
||||
### 1.2 主要功能和特性
|
||||
|
||||
| 功能模块 | 描述 |
|
||||
|---------|------|
|
||||
| **一键课堂生成** | 输入主题或上传文档,自动生成完整课堂 |
|
||||
| **多智能体课堂** | AI 老师和 AI 同学实时授课、讨论、互动 |
|
||||
| **丰富场景类型** | 幻灯片、测验、HTML 交互式模拟、项目制学习 (PBL) |
|
||||
| **白板 & 语音** | 智能体实时绘制图表、书写公式、语音讲解 |
|
||||
| **导出功能** | 支持导出 `.pptx` 幻灯片或交互式 `.html` 网页 |
|
||||
| **OpenClaw 集成** | 可从飞书、Slack、Telegram 等聊天应用中直接生成课堂 |
|
||||
|
||||
### 1.3 目标用户群体
|
||||
|
||||
- **教育工作者**: 快速创建互动课程内容
|
||||
- **学生**: 获得沉浸式、个性化的学习体验
|
||||
- **企业培训**: 自动化培训材料生成
|
||||
- **内容创作者**: 将文档转化为互动演示
|
||||
|
||||
---
|
||||
|
||||
## 2. 技术架构
|
||||
|
||||
### 2.1 项目结构
|
||||
|
||||
```
|
||||
OpenMAIC/
|
||||
├── app/ # Next.js App Router
|
||||
│ ├── api/ # 服务端 API 路由 (~18 个端点)
|
||||
│ │ ├── generate/ # 场景生成流水线
|
||||
│ │ ├── generate-classroom/ # 异步课堂生成提交与轮询
|
||||
│ │ ├── chat/ # 多智能体讨论 (SSE 流式传输)
|
||||
│ │ ├── pbl/ # 项目制学习端点
|
||||
│ │ └── ... # quiz-grade, parse-pdf, web-search 等
|
||||
│ ├── classroom/[id]/ # 课堂回放页面
|
||||
│ └── page.tsx # 首页
|
||||
├── lib/ # 核心业务逻辑
|
||||
│ ├── generation/ # 两阶段课堂生成流水线
|
||||
│ ├── orchestration/ # LangGraph 多智能体编排
|
||||
│ ├── playback/ # 回放状态机
|
||||
│ ├── action/ # 动作执行引擎
|
||||
│ ├── ai/ # LLM 服务商抽象层
|
||||
│ ├── api/ # Stage API 门面
|
||||
│ ├── store/ # Zustand 状态管理
|
||||
│ └── types/ # TypeScript 类型定义
|
||||
├── components/ # React UI 组件
|
||||
│ ├── slide-renderer/ # Canvas 幻灯片编辑器
|
||||
│ ├── scene-renderers/ # Quiz/Interactive/PBL 场景渲染器
|
||||
│ ├── generation/ # 课堂生成工具栏
|
||||
│ ├── chat/ # 聊天区域和会话管理
|
||||
│ ├── settings/ # 设置面板
|
||||
│ ├── whiteboard/ # SVG 白板绘图
|
||||
│ ├── agent/ # 智能体头像、配置
|
||||
│ └── ui/ # 基础 UI 组件 (shadcn/ui)
|
||||
├── packages/ # 工作区子包
|
||||
│ ├── pptxgenjs/ # 定制化 PowerPoint 生成
|
||||
│ └── mathml2omml/ # MathML → Office Math 转换
|
||||
└── skills/openmaic/ # OpenClaw Skill 定义
|
||||
```
|
||||
|
||||
### 2.2 技术栈
|
||||
|
||||
| 层级 | 技术 |
|
||||
|------|------|
|
||||
| **前端框架** | Next.js 16 + React 19 |
|
||||
| **状态管理** | Zustand 5 |
|
||||
| **样式方案** | Tailwind CSS 4 |
|
||||
| **LLM SDK** | Vercel AI SDK + LangGraph |
|
||||
| **类型系统** | TypeScript 5 |
|
||||
| **Canvas 渲染** | @napi-rs/canvas |
|
||||
| **幻灯片渲染** | 基于 PPTist 的 Canvas 引擎 |
|
||||
| **存储** | IndexedDB (Dexie) |
|
||||
| **富文本编辑** | ProseMirror |
|
||||
|
||||
### 2.3 核心模块和组件
|
||||
|
||||
#### A. 生成流水线 (`lib/generation/`)
|
||||
|
||||
**两阶段生成架构**:
|
||||
1. **大纲生成** (Stage 1): 分析用户输入,生成结构化课堂大纲
|
||||
2. **场景生成** (Stage 2): 每个大纲条目生成为丰富的场景
|
||||
|
||||
```
|
||||
用户输入 → 大纲生成器 → 场景生成器 → 完整课堂
|
||||
↓ ↓
|
||||
SceneOutline[] Scene[] (含 Actions)
|
||||
```
|
||||
|
||||
#### B. 多智能体编排 (`lib/orchestration/`)
|
||||
|
||||
**LangGraph 状态机拓扑**:
|
||||
```
|
||||
START → director ──(end)──→ END
|
||||
│
|
||||
└─(next)→ agent_generate ──→ director (loop)
|
||||
```
|
||||
|
||||
**Director 策略**:
|
||||
- **单智能体**: 纯代码逻辑,无 LLM 调用
|
||||
- **多智能体**: LLM 决定下一个发言的智能体
|
||||
|
||||
#### C. 回放引擎 (`lib/playback/engine.ts`)
|
||||
|
||||
**状态机**:
|
||||
```
|
||||
start() pause()
|
||||
idle ──────────────────→ playing ──────────────→ paused
|
||||
▲ ▲ │
|
||||
│ │ resume() │
|
||||
│ └───────────────────────┘
|
||||
│
|
||||
│ handleEndDiscussion()
|
||||
│ confirmDiscussion()
|
||||
│ / handleUserInterrupt()
|
||||
│ │
|
||||
│ ▼ pause()
|
||||
└──────────────────────── live ──────────────→ paused
|
||||
```
|
||||
|
||||
#### D. 动作引擎 (`lib/action/engine.ts`)
|
||||
|
||||
**支持 28+ 种动作类型**:
|
||||
|
||||
| 类别 | 动作 |
|
||||
|------|------|
|
||||
| **视觉特效** (Fire-and-forget) | `spotlight`, `laser` |
|
||||
| **语音** | `speech` (带 TTS) |
|
||||
| **白板** | `wb_open`, `wb_close`, `wb_draw_text`, `wb_draw_shape`, `wb_draw_chart`, `wb_draw_latex`, `wb_draw_table`, `wb_draw_line`, `wb_clear`, `wb_delete` |
|
||||
| **视频** | `play_video` |
|
||||
| **讨论** | `discussion` |
|
||||
|
||||
### 2.4 数据流和通信机制
|
||||
|
||||
**核心数据流**:
|
||||
```
|
||||
用户操作 → React UI → Zustand Store → Next.js API → LangGraph → LLM
|
||||
↓ ↓
|
||||
SSE Stream ← StatelessEvent ← Agent Response
|
||||
```
|
||||
|
||||
**SSE 事件类型** (`StatelessEvent`):
|
||||
- `agent_start` / `agent_end`: 智能体开始/结束
|
||||
- `text_delta`: 文本增量
|
||||
- `action`: 动作执行
|
||||
- `thinking`: 思考状态
|
||||
- `cue_user`: 提示用户发言
|
||||
- `done` / `error`: 完成/错误
|
||||
|
||||
---
|
||||
|
||||
## 3. 核心能力
|
||||
|
||||
### 3.1 Agent 架构设计
|
||||
|
||||
**智能体配置结构** (`AgentConfig`):
|
||||
```typescript
|
||||
interface AgentConfig {
|
||||
id: string; // 唯一 ID
|
||||
name: string; // 显示名称
|
||||
role: string; // 角色: teacher, assistant, student
|
||||
persona: string; // 完整系统提示词
|
||||
avatar: string; // 头像 URL 或 emoji
|
||||
color: string; // UI 主题色
|
||||
allowedActions: string[]; // 允许的动作类型
|
||||
priority: number; // Director 选择优先级 (1-10)
|
||||
isDefault: boolean; // 是否默认模板
|
||||
isGenerated?: boolean; // 是否由 LLM 生成
|
||||
}
|
||||
```
|
||||
|
||||
**默认智能体**:
|
||||
|
||||
| ID | 名称 | 角色 | 优先级 |
|
||||
|----|------|------|--------|
|
||||
| default-1 | AI teacher | teacher | 10 |
|
||||
| default-2 | AI助教 | assistant | 7 |
|
||||
| default-3 | 显眼包 | student | 4 |
|
||||
| default-4 | 好奇宝宝 | student | 5 |
|
||||
| default-5 | 笔记员 | student | 5 |
|
||||
| default-6 | 思考者 | student | 6 |
|
||||
|
||||
**角色-动作映射**:
|
||||
```typescript
|
||||
const ROLE_ACTIONS = {
|
||||
teacher: [...SLIDE_ACTIONS, ...WHITEBOARD_ACTIONS], // 全部能力
|
||||
assistant: [...WHITEBOARD_ACTIONS], // 仅白板
|
||||
student: [...WHITEBOARD_ACTIONS], // 仅白板
|
||||
};
|
||||
```
|
||||
|
||||
### 3.2 工具/能力系统
|
||||
|
||||
**动作执行架构**:
|
||||
```typescript
|
||||
class ActionEngine {
|
||||
async execute(action: Action): Promise<void> {
|
||||
// 1. 自动打开白板 (如果需要)
|
||||
// 2. 根据动作类型执行
|
||||
switch (action.type) {
|
||||
case 'spotlight': // Fire-and-forget
|
||||
case 'laser':
|
||||
case 'speech': // 同步等待 TTS
|
||||
case 'wb_*': // 同步等待渲染
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**结构化输出格式** (LLM 生成):
|
||||
```json
|
||||
[
|
||||
{"type": "action", "name": "spotlight", "params": {"elementId": "img_1"}},
|
||||
{"type": "text", "content": "Hello students..."},
|
||||
{"type": "action", "name": "wb_draw_text", "params": {...}}
|
||||
]
|
||||
```
|
||||
|
||||
### 3.3 记忆/上下文管理
|
||||
|
||||
**无状态架构设计**:
|
||||
- 后端完全无状态,所有状态由客户端维护
|
||||
- 每次请求携带完整上下文 (`StatelessChatRequest`)
|
||||
|
||||
**DirectorState (跨轮次传递)**:
|
||||
```typescript
|
||||
interface DirectorState {
|
||||
turnCount: number; // 当前轮次
|
||||
agentResponses: AgentTurnSummary[]; // 智能体响应历史
|
||||
whiteboardLedger: WhiteboardActionRecord[]; // 白板操作记录
|
||||
}
|
||||
```
|
||||
|
||||
**存储层**:
|
||||
- **IndexedDB** (Dexie): 课堂数据、大纲、生成的智能体
|
||||
- **localStorage**: 智能体注册表、用户配置
|
||||
- **持久化策略**: Zustand persist middleware + debounce 保存
|
||||
|
||||
### 3.4 多模态支持
|
||||
|
||||
| 模态 | 实现 |
|
||||
|------|------|
|
||||
| **文本** | 流式生成 + SSE |
|
||||
| **语音** | Azure TTS / 浏览器 TTS |
|
||||
| **图像** | 多服务商 (Kling, Qwen, Seedance 等) |
|
||||
| **视频** | Kling, Veo, Seedance |
|
||||
| **LaTeX** | KaTeX 渲染 |
|
||||
| **图表** | ECharts |
|
||||
|
||||
---
|
||||
|
||||
## 4. 代码质量评估
|
||||
|
||||
### 4.1 代码组织方式
|
||||
|
||||
**优点**:
|
||||
- 清晰的模块划分
|
||||
- 类型集中管理 (`lib/types/`)
|
||||
- API 门面模式 (`lib/api/stage-api.ts`)
|
||||
- 关注点分离 (生成/播放/动作)
|
||||
|
||||
**文件规模**:
|
||||
- 核心文件 200-800 行
|
||||
- 最大文件 `director-graph.ts` 约 450 行
|
||||
|
||||
### 4.2 测试覆盖
|
||||
|
||||
**未发现测试文件** - 这是项目的明显短板。建议添加:
|
||||
- 单元测试: 生成流水线、动作解析
|
||||
- 集成测试: API 端点
|
||||
- E2E 测试: 课堂生成流程
|
||||
|
||||
### 4.3 文档完善度
|
||||
|
||||
**优点**:
|
||||
- 详细的 README (中英双语)
|
||||
- 内联注释丰富
|
||||
- SKILL.md 示例展示了 Skill 系统用法
|
||||
|
||||
**不足**:
|
||||
- 缺少 API 文档
|
||||
- 缺少架构图 (除 README 中的文字描述)
|
||||
- 无贡献指南细节
|
||||
|
||||
### 4.4 可扩展性设计
|
||||
|
||||
**良好实践**:
|
||||
- **Provider 抽象**: 统一的 LLM 服务商接口
|
||||
- **Action 插件化**: 易于添加新动作类型
|
||||
- **Scene 类型扩展**: 支持 slide/quiz/interactive/pbl
|
||||
- **Agent 注册表**: 支持动态添加智能体
|
||||
|
||||
**扩展点**:
|
||||
```typescript
|
||||
// 添加新 Provider
|
||||
PROVIDERS['new-provider'] = { ... };
|
||||
|
||||
// 添加新 Action 类型
|
||||
type Action = ... | NewAction;
|
||||
|
||||
// 添加新 Scene 类型
|
||||
type SceneContent = ... | NewContent;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 与 ZCLAW 的整合分析
|
||||
|
||||
### 5.1 可复用的组件
|
||||
|
||||
| 组件 | 来源路径 | ZCLAW 适用场景 |
|
||||
|------|---------|---------------|
|
||||
| **LLM Provider 抽象** | `lib/ai/providers.ts` | 统一多模型支持 |
|
||||
| **结构化输出解析** | `lib/orchestration/stateless-generate.ts` | Tool Call 解析 |
|
||||
| **Action 系统** | `lib/types/action.ts` + `lib/action/engine.ts` | Agent 能力定义 |
|
||||
| **智能体注册表** | `lib/orchestration/registry/` | Agent 配置管理 |
|
||||
| **Zustand Store 模式** | `lib/store/` | 状态管理参考 |
|
||||
| **SKILL.md 格式** | `skills/openmaic/SKILL.md` | Skill 系统设计 |
|
||||
|
||||
### 5.2 架构参考价值
|
||||
|
||||
#### A. 无状态后端设计
|
||||
|
||||
OpenMAIC 的无状态架构非常适合 ZCLAW 参考:
|
||||
|
||||
```typescript
|
||||
// StatelessChatRequest - 所有状态由客户端传递
|
||||
interface StatelessChatRequest {
|
||||
messages: UIMessage[]; // 对话历史
|
||||
storeState: { ... }; // 应用状态
|
||||
config: { agentIds, ... }; // 智能体配置
|
||||
directorState?: DirectorState; // 跨轮次状态
|
||||
}
|
||||
```
|
||||
|
||||
ZCLAW 可采用类似模式,避免服务端状态管理复杂性。
|
||||
|
||||
#### B. LangGraph 多智能体编排
|
||||
|
||||
```typescript
|
||||
// Director Graph - 智能体调度状态机
|
||||
const graph = new StateGraph(OrchestratorState)
|
||||
.addNode('director', directorNode)
|
||||
.addNode('agent_generate', agentGenerateNode)
|
||||
.addEdge(START, 'director')
|
||||
.addConditionalEdges('director', directorCondition, {...})
|
||||
.addEdge('agent_generate', 'director');
|
||||
```
|
||||
|
||||
ZCLAW 的多 Agent 协作可参考此模式。
|
||||
|
||||
#### C. Action 执行引擎
|
||||
|
||||
```typescript
|
||||
// 统一的动作执行入口
|
||||
class ActionEngine {
|
||||
async execute(action: Action): Promise<void> {
|
||||
// Fire-and-forget vs Synchronous
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
ZCLAW 的 Hands 系统可采用类似架构。
|
||||
|
||||
### 5.3 潜在的整合方式
|
||||
|
||||
#### 方式 1: 作为 ZCLAW 的 Skill
|
||||
|
||||
OpenMAIC 可作为 ZCLAW 的一个 Skill 集成:
|
||||
|
||||
```markdown
|
||||
# skills/openmaic/SKILL.md
|
||||
---
|
||||
name: openmaic
|
||||
description: 生成互动课堂
|
||||
---
|
||||
```
|
||||
|
||||
用户可通过 ZCLAW 调用 OpenMAIC 的课堂生成能力。
|
||||
|
||||
#### 方式 2: 共享组件库
|
||||
|
||||
抽取共享组件:
|
||||
- `zclaw-shared-types`: Action 类型、Provider 接口
|
||||
- `zclaw-action-engine`: 通用动作执行引擎
|
||||
- `zclaw-llm-adapter`: LLM 服务商适配器
|
||||
|
||||
#### 方式 3: 架构借鉴
|
||||
|
||||
| OpenMAIC 特性 | ZCLAW 对应 |
|
||||
|--------------|-----------|
|
||||
| Director Graph | zclaw-kernel 调度器 |
|
||||
| Agent Registry | Agent 分身管理 |
|
||||
| Action Engine | Hands 能力系统 |
|
||||
| Stage/Scene | 会话/任务管理 |
|
||||
|
||||
### 5.4 需要适配的部分
|
||||
|
||||
| 差异点 | OpenMAIC | ZCLAW | 适配建议 |
|
||||
|--------|----------|-------|---------|
|
||||
| **运行时** | Next.js (服务端) | Tauri (桌面端) | 重构为 Rust 调用 |
|
||||
| **状态存储** | IndexedDB | SQLite | 保持数据结构,换存储后端 |
|
||||
| **通信协议** | SSE over HTTP | gRPC / Tauri Commands | 适配流式响应 |
|
||||
| **UI 框架** | React + Next.js | React + Tauri | 组件可复用 |
|
||||
| **部署模式** | Web / Vercel | 桌面应用 | 需本地 LLM 支持 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 总结与建议
|
||||
|
||||
### 6.1 OpenMAIC 的优势
|
||||
|
||||
1. **成熟的多智能体编排**: LangGraph 状态机设计精良
|
||||
2. **丰富的场景类型**: 幻灯片、测验、交互、PBL 全覆盖
|
||||
3. **完善的多模态支持**: 文本、语音、图像、视频、白板
|
||||
4. **无状态架构**: 易于扩展和维护
|
||||
5. **学术论文支撑**: 有理论基础
|
||||
|
||||
### 6.2 OpenMAIC 的不足
|
||||
|
||||
1. **缺少测试**: 无单元测试、集成测试
|
||||
2. **Web-only**: 无桌面端支持
|
||||
3. **依赖外部服务**: 需要多个 API Key
|
||||
4. **文档分散**: 缺少集中式 API 文档
|
||||
|
||||
### 6.3 对 ZCLAW 的建议
|
||||
|
||||
1. **借鉴无状态设计**: 将状态管理收敛到客户端
|
||||
2. **采用 Action 系统模式**: 统一 Hands 能力接口
|
||||
3. **参考 LangGraph 编排**: 实现多 Agent 协作
|
||||
4. **复用 Provider 抽象**: 统一 LLM 服务商管理
|
||||
5. **保持桌面端优势**: OpenMAIC 的 Web 限制是 ZCLAW 的机会
|
||||
|
||||
---
|
||||
|
||||
## 7. 关键代码参考
|
||||
|
||||
### 7.1 Provider 抽象接口
|
||||
|
||||
```typescript
|
||||
// lib/ai/providers.ts
|
||||
export type ProviderId = 'openai' | 'anthropic' | 'google' | ...;
|
||||
|
||||
export const PROVIDERS: Record<ProviderId, ProviderConfig> = {
|
||||
openai: {
|
||||
name: 'OpenAI',
|
||||
models: ['gpt-4o', 'gpt-4o-mini', ...],
|
||||
defaultModel: 'gpt-4o-mini',
|
||||
},
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
### 7.2 Action 类型定义
|
||||
|
||||
```typescript
|
||||
// lib/types/action.ts
|
||||
export type Action =
|
||||
| SpotlightAction
|
||||
| LaserAction
|
||||
| SpeechAction
|
||||
| WhiteboardAction
|
||||
| VideoAction
|
||||
| DiscussionAction;
|
||||
|
||||
export interface ActionBase {
|
||||
type: string;
|
||||
id?: string;
|
||||
}
|
||||
```
|
||||
|
||||
### 7.3 Agent 配置结构
|
||||
|
||||
```typescript
|
||||
// lib/types/agent.ts
|
||||
export interface AgentConfig {
|
||||
id: string;
|
||||
name: string;
|
||||
role: 'teacher' | 'assistant' | 'student';
|
||||
persona: string;
|
||||
avatar: string;
|
||||
color: string;
|
||||
allowedActions: string[];
|
||||
priority: number;
|
||||
isDefault: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. AGPL-3.0 许可证风险分析
|
||||
|
||||
### 8.1 风险评估
|
||||
|
||||
| 风险点 | 影响 | 严重程度 |
|
||||
|--------|------|----------|
|
||||
| **Copyleft 传染** | 整合代码可能要求 ZCLAW 也开源 | 🔴 高 |
|
||||
| **网络条款** | AGPL-3.0 的网络使用条款比 GPL 更严格 | 🔴 高 |
|
||||
| **商业影响** | 可能影响 ZCLAW 的商业化能力 | 🔴 高 |
|
||||
|
||||
### 8.2 决策
|
||||
|
||||
❌ **不直接整合 OpenMAIC 代码**
|
||||
✅ **仅借鉴架构思想和设计模式**
|
||||
|
||||
---
|
||||
|
||||
## 9. 基于 ZCLAW 现有能力的实现方案
|
||||
|
||||
### 9.1 ZCLAW 已有能力对照
|
||||
|
||||
| OpenMAIC 功能 | ZCLAW 对应 | 成熟度 |
|
||||
|---------------|------------|--------|
|
||||
| 多 Agent 编排 (Director Graph) | A2A 协议 + Kernel Registry | 框架完成 |
|
||||
| Agent 角色配置 | Skills + Agent 分身 | 完成 |
|
||||
| 动作执行引擎 (28+ Actions) | Hands 能力系统 | 完成 |
|
||||
| 工作流编排 | Trigger + EventBus | 基础完成 |
|
||||
| 状态管理 | MemoryStore (SQLite) | 完成 |
|
||||
| 外部集成 | Channels | 框架完成 |
|
||||
|
||||
### 9.2 实现路径
|
||||
|
||||
1. **完善 A2A 通信** - 实现 `crates/zclaw-protocols/src/a2a.rs` 中的 TODO
|
||||
2. **扩展 Hands** - 添加 whiteboard/slideshow/speech/quiz 能力
|
||||
3. **创建 Skill** - classroom-generator 课堂生成技能
|
||||
4. **工作流增强** - DAG 编排、条件分支、并行执行
|
||||
|
||||
### 9.3 需要新增的文件
|
||||
|
||||
```
|
||||
hands/whiteboard.HAND.toml # 白板能力
|
||||
hands/slideshow.HAND.toml # 幻灯片能力
|
||||
hands/speech.HAND.toml # 语音能力
|
||||
hands/quiz.HAND.toml # 测验能力
|
||||
skills/classroom-generator/SKILL.md # 课堂生成
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 后续行动项
|
||||
|
||||
- [ ] 完善 A2A 协议实现(消息路由、能力发现)
|
||||
- [ ] 创建教育类 Hands(whiteboard、slideshow、speech、quiz)
|
||||
- [ ] 开发 classroom-generator Skill
|
||||
- [ ] 增强工作流编排能力(DAG、条件分支)
|
||||
384
docs/knowledge-base/openmaic-zclaw-comparison.md
Normal file
384
docs/knowledge-base/openmaic-zclaw-comparison.md
Normal file
@@ -0,0 +1,384 @@
|
||||
# OpenMAIC vs ZCLAW 功能对比分析
|
||||
|
||||
> **分析日期**: 2026-03-22
|
||||
> **目的**: 论证 ZCLAW 是否能实现 OpenMAIC 相同的产出
|
||||
|
||||
---
|
||||
|
||||
## 1. 核心功能对比
|
||||
|
||||
### 1.1 一键课堂生成
|
||||
|
||||
| 功能点 | OpenMAIC 实现 | ZCLAW 现状 | 差距分析 |
|
||||
|--------|--------------|-----------|----------|
|
||||
| 主题输入 | ✅ 文本输入框 | ✅ 聊天界面 | 无差距 |
|
||||
| 文档上传 | ✅ PDF/Word 解析 | ⚠️ 需实现 | 缺少文档解析能力 |
|
||||
| 大纲生成 | ✅ Stage 1 LLM 生成 | ⚠️ Skill 提示模板 | 缺少执行流程 |
|
||||
| 场景生成 | ✅ Stage 2 并行生成 | ⚠️ Skill 提示模板 | 缺少执行流程 |
|
||||
| 生成 UI | ✅ 进度条 + 预览 | ❌ 无 | 需要前端开发 |
|
||||
|
||||
**结论**: 🟡 **部分可实现** - 核心提示模板已有,缺少执行流程和 UI
|
||||
|
||||
---
|
||||
|
||||
### 1.2 多智能体课堂
|
||||
|
||||
| 功能点 | OpenMAIC 实现 | ZCLAW 现状 | 差距分析 |
|
||||
|--------|--------------|-----------|----------|
|
||||
| Agent 角色定义 | ✅ AgentConfig 结构 | ✅ Agent 分身系统 | 无差距 |
|
||||
| 多 Agent 编排 | ✅ LangGraph Director | ✅ A2A Router | 需要编排逻辑 |
|
||||
| Agent 间通信 | ✅ LangGraph 状态传递 | ✅ A2A 协议 | 无差距 |
|
||||
| 角色调度策略 | ✅ priority + LLM 决策 | ⚠️ 有 priority,无调度器 | 需要实现 Director |
|
||||
| 流式响应 | ✅ SSE | ✅ Tauri 事件 | 无差距 |
|
||||
|
||||
**结论**: 🟡 **部分可实现** - 协议层完成,缺少编排调度器
|
||||
|
||||
---
|
||||
|
||||
### 1.3 场景类型支持
|
||||
|
||||
| 场景类型 | OpenMAIC 实现 | ZCLAW 现状 | 差距分析 |
|
||||
|----------|--------------|-----------|----------|
|
||||
| **幻灯片** | ✅ Canvas 渲染引擎 | ⚠️ slideshow.HAND.toml | 缺少渲染器 |
|
||||
| **测验** | ✅ Quiz 渲染器 + 评估 | ⚠️ quiz.HAND.toml | 缺少渲染器和评估逻辑 |
|
||||
| **交互式 HTML** | ✅ iframe 嵌入 | ❌ 无 | 需要新 Hand |
|
||||
| **PBL 项目制** | ✅ PBL 模块 | ❌ 无 | 需要新 Hand |
|
||||
| **讨论** | ✅ discussion Action | ⚠️ A2A 可实现 | 需要编排 |
|
||||
|
||||
**结论**: 🟡 **部分可实现** - 配置文件已有,缺少渲染器
|
||||
|
||||
---
|
||||
|
||||
### 1.4 白板 & 语音
|
||||
|
||||
| 功能点 | OpenMAIC 实现 | ZCLAW 现状 | 差距分析 |
|
||||
|--------|--------------|-----------|----------|
|
||||
| 白板绘制 | ✅ SVG Canvas | ⚠️ whiteboard.HAND.toml | 缺少渲染器 |
|
||||
| 文本绘制 | ✅ wb_draw_text | ⚠️ 配置已定义 | 缺少实现 |
|
||||
| 图形绘制 | ✅ wb_draw_shape | ⚠️ 配置已定义 | 缺少实现 |
|
||||
| 公式渲染 | ✅ KaTeX | ⚠️ 配置已定义 | 缺少实现 |
|
||||
| 图表绘制 | ✅ ECharts | ⚠️ 配置已定义 | 缺少实现 |
|
||||
| 语音合成 | ✅ Azure/浏览器 TTS | ⚠️ speech.HAND.toml | 缺少实现 |
|
||||
|
||||
**结论**: 🔴 **需要开发** - 配置完成,缺少前端渲染实现
|
||||
|
||||
---
|
||||
|
||||
### 1.5 导出功能
|
||||
|
||||
| 功能点 | OpenMAIC 实现 | ZCLAW 现状 | 差距分析 |
|
||||
|--------|--------------|-----------|----------|
|
||||
| PPTX 导出 | ✅ pptxgenjs | ❌ 无 | 需要新 Hand |
|
||||
| HTML 导出 | ✅ 交互式网页 | ❌ 无 | 需要新 Hand |
|
||||
| PDF 导出 | ❌ 无 | ❌ 无 | 都不支持 |
|
||||
|
||||
**结论**: 🔴 **需要开发** - 完全缺失
|
||||
|
||||
---
|
||||
|
||||
## 2. 架构层面对比
|
||||
|
||||
### 2.1 生成流水线
|
||||
|
||||
**OpenMAIC**:
|
||||
```
|
||||
用户输入 → Stage 1 (大纲) → Stage 2 (场景) → 完整课堂
|
||||
└── LLM 调用 ──┘ └── 并行 LLM ──┘
|
||||
```
|
||||
|
||||
**ZCLAW 现状**:
|
||||
```
|
||||
用户输入 → Skill 提示模板 → ❓ 执行层缺失 → ❓ 渲染层缺失
|
||||
```
|
||||
|
||||
**差距**:
|
||||
1. ❌ 没有两阶段流水线执行器
|
||||
2. ❌ 没有并行生成调度
|
||||
3. ❌ 没有生成进度跟踪
|
||||
|
||||
---
|
||||
|
||||
### 2.2 多 Agent 编排
|
||||
|
||||
**OpenMAIC** (LangGraph):
|
||||
```rust
|
||||
// 伪代码
|
||||
Director Graph:
|
||||
START → director → (next?) → agent_generate → director
|
||||
→ (end?) → END
|
||||
|
||||
Director 决策:
|
||||
- 单 Agent: 纯代码逻辑
|
||||
- 多 Agent: LLM 选择下一个发言者
|
||||
```
|
||||
|
||||
**ZCLAW 现状** (A2A):
|
||||
```rust
|
||||
// 已实现
|
||||
A2aRouter:
|
||||
- Direct 消息 ✅
|
||||
- Group 消息 ✅
|
||||
- Broadcast 消息 ✅
|
||||
- 能力发现 ✅
|
||||
|
||||
// 缺失
|
||||
Director:
|
||||
- Agent 调度逻辑 ❌
|
||||
- LLM 决策选择 ❌
|
||||
- 轮次管理 ❌
|
||||
```
|
||||
|
||||
**差距**:
|
||||
1. ❌ 没有 Director 调度器
|
||||
2. ❌ 没有 LLM 驱动的 Agent 选择
|
||||
3. ❌ 没有轮次/状态管理
|
||||
|
||||
---
|
||||
|
||||
### 2.3 动作执行引擎
|
||||
|
||||
**OpenMAIC**:
|
||||
```typescript
|
||||
class ActionEngine {
|
||||
async execute(action: Action): Promise<void> {
|
||||
switch (action.type) {
|
||||
case 'spotlight': // Fire-and-forget
|
||||
case 'laser':
|
||||
case 'speech': // 同步等待 TTS
|
||||
case 'wb_*': // 同步等待渲染
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**ZCLAW 现状**:
|
||||
```rust
|
||||
// Hands 系统
|
||||
Hand trait:
|
||||
- execute() 接口 ✅
|
||||
- needs_approval ✅
|
||||
- dependencies ✅
|
||||
|
||||
// 教育类 Hands (仅配置)
|
||||
whiteboard.HAND.toml // 定义了动作,无实现
|
||||
slideshow.HAND.toml // 定义了动作,无实现
|
||||
speech.HAND.toml // 定义了动作,无实现
|
||||
quiz.HAND.toml // 定义了动作,无实现
|
||||
```
|
||||
|
||||
**差距**:
|
||||
1. ❌ Hand 只有配置,没有实际实现
|
||||
2. ❌ 没有前端渲染组件
|
||||
3. ❌ 没有动作到 UI 的绑定
|
||||
|
||||
---
|
||||
|
||||
## 3. 缺失能力清单
|
||||
|
||||
### 3.1 后端缺失
|
||||
|
||||
| 优先级 | 模块 | 描述 | 状态 |
|
||||
|--------|------|------|------|
|
||||
| 🔴 P0 | Director 调度器 | 多 Agent 编排逻辑 | ✅ 已完成 |
|
||||
| 🔴 P0 | 两阶段生成流水线 | 大纲 → 场景生成执行器 | ✅ 已完成 |
|
||||
| 🟠 P1 | 文档解析 | PDF/Word 内容提取 | ❌ 待实现 |
|
||||
| 🟠 P1 | Hand 执行器实现 | whiteboard/speech/quiz 后端逻辑 | ⚠️ 配置完成 |
|
||||
| 🟡 P2 | PPTX 导出 | 幻灯片导出能力 | ❌ 待实现 |
|
||||
|
||||
### 3.2 前端缺失
|
||||
|
||||
| 优先级 | 组件 | 描述 | 工作量 |
|
||||
|--------|------|------|--------|
|
||||
| 🔴 P0 | 课堂生成 UI | 输入主题、进度显示 | 2-3 天 |
|
||||
| 🔴 P0 | 白板渲染器 | SVG Canvas 绘制 | 5-7 天 |
|
||||
| 🔴 P0 | 幻灯片渲染器 | 课堂内容展示 | 5-7 天 |
|
||||
| 🟠 P1 | 测验组件 | 答题交互 UI | 3-5 天 |
|
||||
| 🟠 P1 | Agent 头像 | 多角色视觉展示 | 1-2 天 |
|
||||
| 🟡 P2 | 交互式 HTML | iframe 嵌入渲染 | 1-2 天 |
|
||||
|
||||
### 3.3 集成缺失
|
||||
|
||||
| 优先级 | 功能 | 描述 | 工作量 |
|
||||
|--------|------|------|--------|
|
||||
| 🔴 P0 | TTS 集成 | 语音合成能力 | 1-2 天 |
|
||||
| 🟠 P1 | 课堂状态机 | 播放/暂停/跳转 | 2-3 天 |
|
||||
| 🟠 P1 | 课堂持久化 | 保存/加载课堂 | 1-2 天 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 可实现性论证
|
||||
|
||||
### 4.1 当前能实现什么?
|
||||
|
||||
**✅ 已完全具备能力**:
|
||||
1. 多 Agent 通信协议 (A2A)
|
||||
2. Agent 注册和能力发现
|
||||
3. 消息路由 (Direct/Group/Broadcast)
|
||||
4. 基础聊天交互
|
||||
|
||||
**🟡 需要少量开发**:
|
||||
1. 多 Agent 编排 (需要 Director 调度器)
|
||||
2. 课堂生成 (需要流水线执行器)
|
||||
3. 简单的 Agent 角色扮演
|
||||
|
||||
**🔴 需要大量开发**:
|
||||
1. 白板/幻灯片渲染
|
||||
2. 语音合成集成
|
||||
3. 测验交互
|
||||
4. 内容导出
|
||||
|
||||
### 4.2 最小可行产品 (MVP) 路径
|
||||
|
||||
**Phase 1: 基础多 Agent 对话** (1 周)
|
||||
```
|
||||
用户 → Orchestrator Agent → Teacher Agent → 回复
|
||||
↓
|
||||
Student Agent → 提问
|
||||
```
|
||||
|
||||
**Phase 2: 课堂生成流水线** (1-2 周)
|
||||
```
|
||||
主题 → LLM 生成大纲 → 展示给用户
|
||||
→ LLM 生成场景 → Markdown 渲染
|
||||
```
|
||||
|
||||
**Phase 3: 交互式课堂** (2-3 周)
|
||||
```
|
||||
场景 → 白板绘制 → 用户可见
|
||||
→ 语音讲解 → TTS 播放
|
||||
→ 测验互动 → 用户答题
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 结论
|
||||
|
||||
### 5.1 能否实现相同产出?
|
||||
|
||||
| 维度 | 结论 | 说明 |
|
||||
|------|------|------|
|
||||
| **功能等价** | 🟡 部分 | 核心架构已有,缺少渲染层 |
|
||||
| **体验等价** | 🔴 不能 | 缺少白板、幻灯片等可视化组件 |
|
||||
| **架构等价** | ✅ 是 | A2A + Director 不弱于 LangGraph |
|
||||
| **执行层** | ✅ 是 | 两阶段生成流水线已实现 |
|
||||
|
||||
### 5.2 差距总结
|
||||
|
||||
**已完成的** (本次工作):
|
||||
- ✅ A2A 协议通信层 (消息路由、能力发现)
|
||||
- ✅ Director 调度器 (多 Agent 编排)
|
||||
- ✅ 两阶段生成流水线 (大纲 + 场景生成)
|
||||
- ✅ 教育类 Hands 配置定义
|
||||
- ✅ 课堂生成 Skill 提示模板
|
||||
- ✅ 19 个单元测试全部通过
|
||||
|
||||
**还需要完成的**:
|
||||
1. **前端渲染层** - 白板/幻灯片/测验 UI 组件
|
||||
2. **Hand 执行实现** - 将配置映射到实际操作
|
||||
3. **LLM 集成** - 连接生成流水线与 LLM 驱动
|
||||
4. **TTS 集成** - 语音合成能力
|
||||
|
||||
### 5.3 建议的下一步
|
||||
|
||||
**优先级排序**:
|
||||
|
||||
```
|
||||
P0 (必须):
|
||||
├── Director 调度器 (后端)
|
||||
├── 两阶段生成流水线 (后端)
|
||||
└── 基础课堂 UI (前端)
|
||||
|
||||
P1 (重要):
|
||||
├── 白板渲染器 (前端)
|
||||
├── TTS 集成 (后端)
|
||||
└── 测验组件 (前端)
|
||||
|
||||
P2 (增强):
|
||||
├── 幻灯片渲染器 (前端)
|
||||
├── PPTX 导出 (后端)
|
||||
└── 文档解析 (后端)
|
||||
```
|
||||
|
||||
**预估总工作量**: 4-6 周 (1 人全职)
|
||||
|
||||
---
|
||||
|
||||
## 6. 风险提示
|
||||
|
||||
| 风险 | 影响 | 缓解措施 |
|
||||
|------|------|----------|
|
||||
| 前端渲染复杂度高 | 白板/幻灯片开发时间长 | 可先实现 Markdown 渲染 |
|
||||
| TTS 依赖外部服务 | 需要付费 API | 优先使用浏览器原生 TTS |
|
||||
| 多 Agent 编排复杂 | 调度逻辑难以调试 | 先实现简单的轮询调度 |
|
||||
|
||||
---
|
||||
|
||||
## 附录: 功能对照矩阵 (最新更新)
|
||||
|
||||
| OpenMAIC 功能 | ZCLAW 协议层 | ZCLAW 执行层 | ZCLAW 渲染层 | 总体状态 |
|
||||
|--------------|-------------|-------------|-------------|----------|
|
||||
| 一键课堂生成 | ✅ | ✅ | ❌ | 🟡 |
|
||||
| 多智能体课堂 | ✅ | ✅ | ✅ | 🟢 |
|
||||
| 幻灯片场景 | ✅ | ✅ | ❌ | 🟡 |
|
||||
| 测验场景 | ✅ | ✅ | ❌ | 🟡 |
|
||||
| 白板绘制 | ✅ | ✅ | ❌ | 🟡 |
|
||||
| 语音讲解 | ✅ | ✅ | N/A | 🟢 |
|
||||
| PPTX 导出 | ✅ | ❌ | N/A | 🔴 |
|
||||
| HTML 导出 | ✅ | ❌ | N/A | 🔴 |
|
||||
|
||||
**图例**: ✅ 完成 | ⚠️ 部分完成 | ❌ 未实现 | 🟢 可用 | 🟡 部分可用 | 🔴 不可用
|
||||
|
||||
---
|
||||
|
||||
## 更新日志
|
||||
|
||||
### 2026-03-22 Phase 2 完成的工作
|
||||
|
||||
1. **Hand 执行器实现** (`crates/zclaw-hands/src/hands/`)
|
||||
- `whiteboard.rs` - 白板绘制执行器 (9 种动作)
|
||||
- `speech.rs` - 语音合成执行器 (7 种动作)
|
||||
- `slideshow.rs` - 幻灯片控制执行器 (10 种动作)
|
||||
- `quiz.rs` - 测验生成执行器 (10 种动作)
|
||||
- 21 个单元测试全部通过
|
||||
|
||||
2. **LLM 集成** (`crates/zclaw-kernel/src/generation.rs`)
|
||||
- 添加 `with_driver()` 方法支持 LLM 驱动
|
||||
- 实现 `generate_outline_with_llm()` - LLM 大纲生成
|
||||
- 实现 `generate_scene_with_llm()` - LLM 场景生成
|
||||
- JSON 解析和结构化输出提取
|
||||
- System prompt 设计 (大纲 + 场景)
|
||||
|
||||
3. **TTS 集成** (`crates/zclaw-hands/src/hands/speech.rs`)
|
||||
- 多 Provider 支持 (Browser/Azure/OpenAI/ElevenLabs/Local)
|
||||
- 语音配置 (rate/pitch/volume)
|
||||
- 播放控制 (pause/resume/stop)
|
||||
- 多语言支持
|
||||
|
||||
### 2026-03-22 Phase 1 完成的工作
|
||||
|
||||
1. **A2A 协议完善** (`crates/zclaw-protocols/src/a2a.rs`)
|
||||
- 实现完整的消息路由 (Direct/Group/Broadcast)
|
||||
- 添加能力发现和索引机制
|
||||
- 5 个单元测试全部通过
|
||||
|
||||
2. **Director 调度器** (`crates/zclaw-kernel/src/director.rs`)
|
||||
- 多种调度策略 (RoundRobin/Priority/Random/LLM/Manual)
|
||||
- Agent 角色管理 (Teacher/Assistant/Student/Moderator/Expert)
|
||||
- 会话状态跟踪和轮次管理
|
||||
- 8 个单元测试全部通过
|
||||
|
||||
3. **两阶段生成流水线** (`crates/zclaw-kernel/src/generation.rs`)
|
||||
- Stage 1: 大纲生成
|
||||
- Stage 2: 场景生成
|
||||
- 支持多种场景类型 (Slide/Quiz/Interactive/PBL/Discussion/Media/Text)
|
||||
- 完整的 Classroom 数据结构
|
||||
- 6 个单元测试全部通过
|
||||
|
||||
4. **教育类 Hands 配置**
|
||||
- `whiteboard.HAND.toml` - 白板绘制能力
|
||||
- `slideshow.HAND.toml` - 幻灯片控制能力
|
||||
- `speech.HAND.toml` - 语音合成能力
|
||||
- `quiz.HAND.toml` - 测验生成能力
|
||||
|
||||
5. **课堂生成 Skill**
|
||||
- `skills/classroom-generator/SKILL.md` - 完整的技能定义
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,8 @@
|
||||
| Node.js | 18.x | `node -v` |
|
||||
| pnpm | 8.x | `pnpm -v` |
|
||||
| Rust | 1.70+ | `rustc --version` |
|
||||
| OpenFang | - | `openfang --version` |
|
||||
|
||||
**重要**: ZCLAW 使用内部 Kernel 架构,**无需**启动外部后端服务。
|
||||
|
||||
---
|
||||
|
||||
@@ -45,21 +46,19 @@ pnpm install
|
||||
cd desktop && pnpm install && cd ..
|
||||
```
|
||||
|
||||
### 2. 启动 OpenFang 后端
|
||||
### 2. 配置 LLM 提供商
|
||||
|
||||
```bash
|
||||
# 方法 A: 使用 CLI
|
||||
openfang start
|
||||
**首次启动后**,在应用的"模型与 API"设置页面配置:
|
||||
|
||||
# 方法 B: 使用 pnpm 脚本
|
||||
pnpm gateway:start
|
||||
```
|
||||
|
||||
验证后端运行:
|
||||
```bash
|
||||
curl http://127.0.0.1:50051/api/health
|
||||
# 应返回: {"status":"ok"}
|
||||
```
|
||||
1. 点击设置图标 ⚙️
|
||||
2. 进入"模型与 API"页面
|
||||
3. 点击"添加自定义模型"
|
||||
4. 填写配置信息:
|
||||
- 服务商:选择 Kimi / Qwen / DeepSeek / Zhipu / OpenAI 等
|
||||
- 模型 ID:如 `kimi-k2-turbo`、`qwen-plus`
|
||||
- API Key:你的 API 密钥
|
||||
- Base URL:(可选)自定义 API 端点
|
||||
5. 点击"设为默认"
|
||||
|
||||
### 3. 启动开发环境
|
||||
|
||||
@@ -67,14 +66,7 @@ curl http://127.0.0.1:50051/api/health
|
||||
# 方法 A: 一键启动(推荐)
|
||||
pnpm start:dev
|
||||
|
||||
# 方法 B: 仅启动桌面端(需要后端已运行)
|
||||
pnpm desktop
|
||||
|
||||
# 方法 C: 分开启动
|
||||
# 终端 1 - 启动 Gateway
|
||||
pnpm dev
|
||||
|
||||
# 终端 2 - 启动桌面端
|
||||
# 方法 B: 仅启动桌面端
|
||||
pnpm desktop
|
||||
```
|
||||
|
||||
@@ -111,17 +103,32 @@ cd desktop && pnpm test:e2e:ui
|
||||
|
||||
| 服务 | 端口 | 说明 |
|
||||
|------|------|------|
|
||||
| OpenFang 后端 | 50051 | API 和 WebSocket 服务 |
|
||||
| Vite 开发服务器 | 1420 | 前端热重载 |
|
||||
| Tauri 窗口 | - | 桌面应用窗口 |
|
||||
|
||||
**注意**: 不再需要端口 50051,所有 Kernel 功能已内置。
|
||||
|
||||
---
|
||||
|
||||
## 支持的 LLM 提供商
|
||||
|
||||
| Provider | Base URL | 环境变量 |
|
||||
|----------|----------|----------|
|
||||
| Kimi Code | `https://api.kimi.com/coding/v1` | UI 配置 |
|
||||
| 百炼/Qwen | `https://dashscope.aliyuncs.com/compatible-mode/v1` | UI 配置 |
|
||||
| DeepSeek | `https://api.deepseek.com/v1` | UI 配置 |
|
||||
| 智谱 GLM | `https://open.bigmodel.cn/api/paas/v4` | UI 配置 |
|
||||
| OpenAI | `https://api.openai.com/v1` | UI 配置 |
|
||||
| Anthropic | `https://api.anthropic.com` | UI 配置 |
|
||||
| Local/Ollama | `http://localhost:11434/v1` | UI 配置 |
|
||||
|
||||
---
|
||||
|
||||
## 常见问题排查
|
||||
|
||||
### Q1: 端口被占用
|
||||
|
||||
**症状**: `Port 1420 is already in use` 或 `Port 50051 is already in use`
|
||||
**症状**: `Port 1420 is already in use`
|
||||
|
||||
**解决**:
|
||||
```powershell
|
||||
@@ -134,38 +141,34 @@ lsof -i :1420
|
||||
kill -9 <PID>
|
||||
```
|
||||
|
||||
### Q2: 后端连接失败
|
||||
### Q2: 请先在"模型与 API"设置页面配置模型
|
||||
|
||||
**症状**: `Network Error` 或 `Connection refused`
|
||||
|
||||
**排查步骤**:
|
||||
```bash
|
||||
# 1. 检查后端是否运行
|
||||
curl http://127.0.0.1:50051/api/health
|
||||
|
||||
# 2. 检查端口监听
|
||||
netstat -ano | findstr "50051"
|
||||
|
||||
# 3. 重启后端
|
||||
openfang restart
|
||||
```
|
||||
|
||||
### Q3: API Key 未配置
|
||||
|
||||
**症状**: `Missing API key: No LLM provider configured`
|
||||
**症状**: 连接时显示"请先在'模型与 API'设置页面配置模型"
|
||||
|
||||
**解决**:
|
||||
```bash
|
||||
# 编辑配置文件
|
||||
# Windows: %USERPROFILE%\.openfang\.env
|
||||
# Linux/macOS: ~/.openfang/.env
|
||||
1. 打开应用设置
|
||||
2. 进入"模型与 API"页面
|
||||
3. 添加自定义模型并配置 API Key
|
||||
4. 设为默认模型
|
||||
5. 重新连接
|
||||
|
||||
# 添加 API Key
|
||||
echo "ZHIPU_API_KEY=your_key" >> ~/.openfang/.env
|
||||
### Q3: LLM 调用失败
|
||||
|
||||
# 重启后端
|
||||
openfang restart
|
||||
```
|
||||
**症状**: `Chat failed: LLM error: API error 401` 或 `404`
|
||||
|
||||
**排查步骤**:
|
||||
1. 检查 API Key 是否正确
|
||||
2. 检查 Base URL 是否正确(特别是 Kimi Code 用户)
|
||||
3. 确认模型 ID 是否正确
|
||||
|
||||
**常见 Provider 配置**:
|
||||
|
||||
| Provider | 模型 ID 示例 | Base URL |
|
||||
|----------|-------------|----------|
|
||||
| Kimi Code | `kimi-k2-turbo` | `https://api.kimi.com/coding/v1` |
|
||||
| Qwen/百炼 | `qwen-plus` | `https://dashscope.aliyuncs.com/compatible-mode/v1` |
|
||||
| DeepSeek | `deepseek-chat` | `https://api.deepseek.com/v1` |
|
||||
| Zhipu | `glm-4-flash` | `https://open.bigmodel.cn/api/paas/v4` |
|
||||
|
||||
### Q4: Tauri 编译失败
|
||||
|
||||
@@ -202,8 +205,8 @@ pnpm install
|
||||
|
||||
启动成功后,验证以下功能:
|
||||
|
||||
- [ ] 后端健康检查通过: `curl http://127.0.0.1:50051/api/health`
|
||||
- [ ] 桌面端窗口正常显示
|
||||
- [ ] 在"模型与 API"页面添加了自定义模型
|
||||
- [ ] 可以发送消息并获得响应
|
||||
- [ ] 可以切换 Agent
|
||||
- [ ] 可以查看设置页面
|
||||
@@ -222,6 +225,29 @@ pnpm start:stop
|
||||
|
||||
---
|
||||
|
||||
## 架构说明
|
||||
|
||||
ZCLAW 使用**内部 Kernel 架构**:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZCLAW 桌面应用 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
|
||||
│ │ React 前端 │ │ Tauri 后端 (Rust) │ │
|
||||
│ │ ├─ KernelClient│────▶│ └─ zclaw-kernel │ │
|
||||
│ │ └─ Zustand │ │ └─ LLM Drivers │ │
|
||||
│ └─────────────────┘ └─────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**关键点**:
|
||||
- 所有核心能力集成在 Tauri 应用内
|
||||
- 无需启动外部后端进程
|
||||
- 模型配置通过 UI 完成
|
||||
|
||||
---
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [完整开发文档](./DEVELOPMENT.md)
|
||||
@@ -230,4 +256,4 @@ pnpm start:stop
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2026-03-21
|
||||
**最后更新**: 2026-03-22
|
||||
|
||||
Reference in New Issue
Block a user