- Create docs/README.md as documentation index - Add WORK_SUMMARY_2026-03-16.md for today's work - Move test reports to docs/test-reports/ - Move completed plans to docs/archive/completed-plans/ - Move research reports to docs/archive/research-reports/ - Move technical reference to docs/knowledge-base/ - Move all plans from root plans/ to docs/plans/ New structure: docs/ ├── README.md # Documentation index ├── DEVELOPMENT.md # Development guide ├── OPENVIKING_INTEGRATION.md # OpenViking integration ├── USER_MANUAL.md # User manual ├── ZCLAW_AGENT_INTELLIGENCE_EVOLUTION.md ├── archive/ # Archived documents ├── knowledge-base/ # Technical knowledge ├── plans/ # Execution plans └── test-reports/ # Test reports Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
16 KiB
16 KiB
ZCLAW OpenViking 深度集成方案
Context
背景:ZCLAW 项目基于 OpenFang 定制开发,目标是结合 OpenClaw、NanoClaw、ZeroClaw 等系统的优点。当前 Agent 智能层已超前完成(Phase 1-3 完成, Phase 4 部分完成),但 OpenViking 集成依赖外部 Python 服务,用户安装繁琐。
问题:如何深度集成 OpenViking,避免 Python 依赖,实现无感安装体验?
目标:以 OpenViking Rust CLI (ov) 为核心,通过 Tauri sidecar 集成,让记忆系统成为原生组件。CLI 缺失的功能再自行开发补充。
关键决策总结
基于头脑风暴讨论,确定以下技术决策:
| 决策点 | 选择 | 理由 |
|---|---|---|
| 集成方式 | OpenViking Rust CLI + 自建补充 | 利用成熟工具,减少开发量,缺失功能自行补充 |
| 记忆存储 | CLI 内置 SQLite + sqlite-vec | CLI 已实现,无需重复开发 |
| Embedding 模型 | doubao-embedding-vision | 中文效果优秀,火山引擎生态 |
| 记忆提取 | LLM 提取 | 对话结束后调用 LLM 分析并提取 |
| 部署方式 | Tauri Sidecar | CLI 作为可执行文件随应用分发 |
Architecture Design
┌─────────────────────────────────────────────────────────────────┐
│ ZCLAW Desktop (Tauri + React) │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ React UI Layer │ │
│ │ ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌──────────────┐ │ │
│ │ │ ChatArea │ │MemoryPanel│ │SwarmPanel│ │ SkillMarket │ │ │
│ │ └────┬─────┘ └────┬─────┘ └─────┬─────┘└──────┬───────┘ │ │
│ └───────────┼────────────┼─────────────┼───────────────┼─────┘ │
│ ▼ ▼ ▼ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ TypeScript Integration Layer │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ VikingAdapter (已存在,保持兼容) │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────┬─────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────▼─────────────────────────────────┐ │
│ │ Tauri Command Layer (Rust) │ │
│ │ ┌────────────────────────────────────────────────────────┐│ │
│ │ │ SidecarWrapper: 调用 `ov` CLI ││ │
│ │ │ - invoke('viking_add', ...) → ov add ││ │
│ │ │ - invoke('viking_find', ...) → ov find ││ │
│ │ │ - invoke('viking_grep', ...) → ov grep ││ │
│ │ └────────────────────────────────────────────────────────┘│ │
│ │ ┌────────────────────────────────────────────────────────┐│ │
│ │ │ SupplementalModule: CLI 缺失功能补充 ││ │
│ │ │ - SessionExtractor (LLM 记忆提取) ││ │
│ │ │ - EmbeddingService (doubao API 封装) ││ │
│ │ │ - ContextBuilder (L0/L1/L2 分层加载) ││ │
│ │ └────────────────────────────────────────────────────────┘│ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────▼─────────────────────────────────┐ │
│ │ Storage Layer │ │
│ │ ┌──────────────────┐ ┌──────────────────────────────────┐ │ │
│ │ │ OpenViking CLI │ │ AppData (配置) │ │ │
│ │ │ ~/.viking/ │ │ ~/.zclaw/config.toml │ │ │
│ │ │ - SQLite + vec │ │ │ │ │
│ │ │ - 向量索引 │ │ │ │ │
│ │ └──────────────────┘ └──────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
OpenViking Rust CLI 能力分析
CLI 已实现功能 (直接使用)
| 命令 | 功能 | 状态 |
|---|---|---|
ov add <uri> |
添加资源到索引 | ✅ 可用 |
ov find <query> |
语义搜索 | ✅ 可用 |
ov grep <pattern> |
正则搜索 | ✅ 可用 |
ov ls <path> |
列出资源 | ✅ 可用 |
ov tree <path> |
目录树 | ✅ 可用 |
ov chat |
交互式对话 | ✅ 可用 |
CLI 缺失功能 (需要自建)
| 功能 | 说明 | 优先级 |
|---|---|---|
| Session Extraction | 对话后 LLM 提取记忆 | 高 |
| L0/L1/L2 分层加载 | Token 优化上下文构建 | 高 |
| Embedding 批量生成 | doubao API 封装 | 中 |
| 记忆老化/清理 | 低重要性记忆自动清理 | 低 |
| 多 Agent 隔离 | agent_id 维度隔离 | 中 |
Implementation Phases
Phase 1: Sidecar 集成 (Week 1)
Goal: 将 OpenViking CLI 集成为 Tauri sidecar
Steps
-
下载并嵌入 CLI
# 将 ov 二进制放入 src-tauri/binaries/ # Windows: ov-x86_64-pc-windows-msvc.exe # macOS: ov-x86_64-apple-darwin # Linux: ov-x86_64-unknown-linux-gnu -
配置 tauri.conf.json
{ "tauri": { "bundle": { "externalBin": ["binaries/ov"] } } } -
创建 Tauri Commands
// src-tauri/src/viking_commands.rs #[tauri::command] pub async fn viking_add(uri: String, content: String) -> Result<String, String> { let sidecar = Command::new_sidecar("ov") .map_err(|e| e.to_string())?; let output = sidecar .args(["add", &uri]) .output() .await .map_err(|e| e.to_string())?; Ok(String::from_utf8_lossy(&output.stdout).to_string()) } #[tauri::command] pub async fn viking_find(query: String, limit: usize) -> Result<Vec<FindResult>, String> { let sidecar = Command::new_sidecar("ov") .map_err(|e| e.to_string())?; let output = sidecar .args(["find", "--json", &query, "--limit", &limit.to_string()]) .output() .await .map_err(|e| e.to_string())?; serde_json::from_slice(&output.stdout) .map_err(|e| e.to_string()) }
Files to Create
| File | Purpose |
|---|---|
src-tauri/src/viking_commands.rs |
Tauri 命令封装 |
src-tauri/binaries/ov-* |
Sidecar 二进制 |
Files to Modify
| File | Changes |
|---|---|
src-tauri/src/lib.rs |
注册 viking 模块 |
src-tauri/tauri.conf.json |
添加 externalBin 配置 |
desktop/src/lib/viking-adapter.ts |
添加 invoke() 调用 |
Phase 2: TypeScript 适配层 (Week 1-2)
Goal: 更新 VikingAdapter 使用 Tauri 命令
Key Changes
// desktop/src/lib/viking-adapter.ts
import { invoke } from '@tauri-apps/api/tauri';
export class VikingAdapter {
private mode: 'sidecar' | 'remote' = 'sidecar';
async addResource(uri: string, content: string): Promise<void> {
if (this.mode === 'sidecar') {
await invoke('viking_add', { uri, content });
} else {
// Remote fallback
await this.httpClient.addResource(uri, content);
}
}
async find(query: string, options?: FindOptions): Promise<FindResult[]> {
if (this.mode === 'sidecar') {
return await invoke('viking_find', {
query,
limit: options?.limit || 10
});
} else {
return this.httpClient.find(query, options);
}
}
}
Phase 3: 补充模块开发 (Week 2-3)
Goal: 实现 CLI 缺失的功能
3.1 Session Extractor
// src-tauri/src/memory/extractor.rs
pub struct SessionExtractor {
llm_client: LlmClient,
}
impl SessionExtractor {
/// Extract memories from conversation
pub async fn extract(
&self,
messages: Vec<ChatMessage>,
agent_id: &str,
) -> Result<Vec<ExtractedMemory>, Error> {
let prompt = self.build_extraction_prompt(&messages);
let response = self.llm_client.complete(&prompt).await?;
self.parse_extraction(&response, agent_id)
}
}
3.2 Context Builder (L0/L1/L2)
// src-tauri/src/memory/context_builder.rs
pub struct ContextBuilder {
viking: VikingSidecar,
}
impl ContextBuilder {
/// Build layered context for token efficiency
pub async fn build_context(
&self,
query: &str,
agent_id: &str,
max_tokens: usize,
) -> Result<EnhancedContext, Error> {
// L0: Quick scan - top 50 by similarity
let l0_results = self.viking.find(query, 50).await?;
// L1: Load overview for top 10
let l1_items = self.load_overviews(&l0_results[..10]).await?;
// L2: Full content for top 3
let l2_items = self.load_full_content(&l0_results[..3]).await?;
Ok(EnhancedContext { l1_items, l2_items })
}
}
Files to Create
| File | Purpose |
|---|---|
src-tauri/src/memory/mod.rs |
模块入口 |
src-tauri/src/memory/extractor.rs |
LLM 记忆提取 |
src-tauri/src/memory/context_builder.rs |
L0/L1/L2 分层加载 |
src-tauri/src/llm/client.rs |
doubao API 客户端 |
Phase 4: UI 集成 (Week 3-4)
Goal: 完善记忆面板 UI
Files to Modify
| File | Changes |
|---|---|
desktop/src/components/MemoryPanel.tsx |
集成 sidecar 模式 |
desktop/src/components/RetrievalTrace.tsx |
显示 L0/L1/L2 检索轨迹 |
desktop/src/store/chatStore.ts |
使用新的 VikingAdapter |
Critical Files
Existing Files (Reuse)
| File | Path | Purpose |
|---|---|---|
| VikingAdapter | desktop/src/lib/viking-adapter.ts |
保持兼容,添加 sidecar 模式 |
| VikingHttpClient | desktop/src/lib/viking-client.ts |
远程模式时使用 |
| AgentMemory | desktop/src/lib/agent-memory.ts |
现有记忆接口 |
| MemoryPanel | desktop/src/components/MemoryPanel.tsx |
现有 UI |
New Files (Create)
| File | Path | Purpose |
|---|---|---|
| VikingCommands | src-tauri/src/viking_commands.rs |
Sidecar 命令封装 |
| SessionExtractor | src-tauri/src/memory/extractor.rs |
LLM 提取 (CLI 缺失) |
| ContextBuilder | src-tauri/src/memory/context_builder.rs |
分层加载 (CLI 缺失) |
| LlmClient | src-tauri/src/llm/client.rs |
doubao API 封装 |
Dependencies to Add
# src-tauri/Cargo.toml
[dependencies]
tauri = { version = "2", features = ["process-command-api"] }
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.11" } # For LLM API calls
serde = { version = "1", features = ["derive"] }
serde_json = "1"
Verification Plan
Unit Tests
# Run Rust tests
cargo test --manifest-path=src-tauri/Cargo.toml
# Run TypeScript tests
pnpm vitest run tests/desktop/memory*.test.ts
Integration Tests
- Sidecar 启动: CLI 能正确作为 sidecar 运行
- Memory Save/Load: 通过 Tauri 命令保存和检索记忆
- Vector Search: 语义搜索返回相关结果
- Session Extraction: 对话结束后正确提取记忆
- Context Building: L0/L1/L2 分层加载正常工作
- UI Integration: MemoryPanel 正确显示数据
Manual Testing
- 启动应用,验证 CLI sidecar 自动启动
- 发送消息,检查记忆是否保存
- 发送新消息,验证 Agent 能回忆之前的信息
- 测试记忆搜索功能
- 验证无 Python 依赖
Migration Path
From Current State
Current: Target:
viking-client.ts ─────────────► Tauri Command
(HTTP to Python server) (Sidecar wrapper)
│
▼
viking-adapter.ts ──────────────► Dual mode: sidecar + remote fallback
Data Compatibility
- OpenViking CLI 使用
~/.viking/目录存储数据 - 与 Python Server 版本数据格式兼容
- 可无缝迁移现有数据
Success Criteria
- OpenViking CLI 作为 sidecar 正确运行
- Tauri 命令可调用 CLI 功能
- 记忆保存和检索功能正常
- 语义搜索返回相关结果
- LLM 记忆提取正常工作 (自建模块)
- L0/L1/L2 分层加载正常工作 (自建模块)
- MemoryPanel UI 正确显示
- 所有测试通过
- 无需 Python 依赖
Risks and Mitigations
| Risk | Mitigation |
|---|---|
| CLI 二进制兼容性 | 提供多平台预编译版本 |
| CLI 功能不足 | 自建补充模块填补空白 |
| Embedding API 限流 | 实现本地缓存 |
| LLM 提取失败 | 保留规则提取作为 fallback |
| Sidecar 启动失败 | 优雅降级到远程模式 |
Timeline
| Week | Phase | Deliverables |
|---|---|---|
| 1 | Sidecar 集成 | CLI 嵌入 + Tauri 命令 + TypeScript 适配 |
| 2 | 补充模块 | SessionExtractor + ContextBuilder |
| 3 | LLM 集成 | doubao API 客户端 + 提取逻辑 |
| 4 | UI 集成 | MemoryPanel + RetrievalTrace |
| 5 | 测试完善 | 集成测试 + 文档 |
开发策略总结
- Phase 1: 直接集成 OpenViking Rust CLI 作为 sidecar
- Phase 2: 检测 CLI 功能覆盖度
- Phase 3: 自行开发 CLI 缺失的功能 (Session Extraction, Context Builder)
- Phase 4: UI 完善和测试
核心原则: 最大化利用现有成熟工具,最小化自建代码量,只在必要时补充缺失功能。