Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- 创建 types.ts 定义完整的类型系统 - 重写 DocumentRenderer.tsx 修复语法错误 - 重写 QuizRenderer.tsx 修复语法错误 - 重写 PresentationContainer.tsx 添加类型守卫 - 重写 TypeSwitcher.tsx 修复类型引用 - 更新 index.ts 移除不存在的 ChartRenderer 导出 审计结果: - 类型检查: 通过 - 单元测试: 222 passed - 构建: 成功
12 KiB
12 KiB
开箱即用的上下文记忆库方案 (简化版)
一、背景与目标
1.1 问题
当前 ZCLAW 的 OpenViking 集成需要用户独立安装 Python 包 (pip install openviking),不是开箱即用的。
1.2 关键发现 ⚠️
经过深入分析,发现 zclaw-growth crate 已经实现了核心功能:
| 组件 | 文件 | 状态 |
|---|---|---|
VikingStorage trait |
viking_adapter.rs |
✅ 已实现 |
SqliteStorage |
storage/sqlite.rs |
⚠️ 只用内存缓存 |
SemanticScorer (TF-IDF) |
retrieval/semantic.rs |
✅ 已实现 |
MemoryExtractor |
extractor.rs |
✅ 已实现 |
MemoryRetriever |
retriever.rs |
✅ 已实现 |
PromptInjector |
injector.rs |
✅ 已实现 |
问题:SqliteStorage 虽然名字是 SQLite,但实际只用内存缓存(见 storage/sqlite.rs:96-99)。
1.3 修订目标
- 完善现有实现:让
SqliteStorage真正持久化到 SQLite - 集成 TF-IDF:使用已有的
SemanticScorer提供语义搜索 - 替换外部依赖:Tauri 命令使用
SqliteStorage而非 Python 进程 - 无需 LanceDB:现有 TF-IDF 方案已足够
二、简化方案
2.1 核心改动
| 改动 | 工作量 | 说明 |
|---|---|---|
完善 SqliteStorage |
中 | 添加真正的 SQLite 持久化 |
集成 SemanticScorer |
小 | 替换简单的相似度计算 |
修改 viking_commands.rs |
中 | 使用 SqliteStorage 替代 Python 调用 |
删除 viking_server.rs |
小 | 不再需要服务器管理 |
2.2 架构对比
当前架构 (需要外部 Python):
前端 → viking-client.ts → Tauri Commands → Python OpenViking 进程
目标架构 (纯 Rust):
前端 → viking-client.ts → Tauri Commands → SqliteStorage (Rust)
→ SemanticScorer (TF-IDF)
→ ~/.zclaw/memories.db
三、架构设计
3.1 整体架构
┌─────────────────────────────────────────────────────────────────┐
│ ZCLAW Desktop (Tauri) │
│ │
│ ┌─────────────────┐ │
│ │ viking-client.ts│ (前端 API 保持不变) │
│ └────────┬────────┘ │
│ │ invoke() │
│ ┌────────▼────────────────────────────────────────────────────┐│
│ │ viking_commands.rs ││
│ │ (Tauri 命令层 - 接口不变,实现改为调用 zclaw-growth) ││
│ └────────┬────────────────────────────────────────────────────┘│
│ │ │
│ ┌────────▼────────────────────────────────────────────────────┐│
│ │ zclaw-growth (已存在) ││
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ ││
│ │ │SqliteStorage│ │SemanticScorer│ │ MemoryExtractor │ ││
│ │ │ (完善持久化)│ │ (TF-IDF) │ │ MemoryRetriever │ ││
│ │ └─────────────┘ └─────────────┘ │ PromptInjector │ ││
│ │ └─────────────────────┘ ││
│ └────────┬────────────────────────────────────────────────────┘│
│ │ │
│ ┌────────▼────────────────────────────────────────────────────┐│
│ │ 本地存储层 ││
│ │ ~/.zclaw/ ││
│ │ ├── memories.db (SQLite 持久化) ││
│ │ └── growth.json (成长指标) ││
│ └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘
3.2 模块变更
| 模块 | 位置 | 变更 |
|---|---|---|
SqliteStorage |
crates/zclaw-growth/src/storage/sqlite.rs |
完善:添加真正的 SQLite 持久化 |
viking_commands.rs |
desktop/src-tauri/src/viking_commands.rs |
修改:使用 SqliteStorage |
viking_server.rs |
desktop/src-tauri/src/viking_server.rs |
删除:不再需要 |
3.3 数据模型 (已存在)
// crates/zclaw-growth/src/types.rs
pub struct MemoryEntry {
pub uri: String, // agent://{agent_id}/{type}/{category}
pub memory_type: MemoryType,
pub content: String,
pub keywords: Vec<String>,
pub importance: u8, // 1-10
pub access_count: u32,
pub created_at: DateTime<Utc>,
pub last_accessed: DateTime<Utc>,
}
pub enum MemoryType {
Preference, // 用户偏好
Knowledge, // 知识积累
Experience, // 技能经验
Session, // 会话历史
}
四、接口设计
4.1 保持兼容的 Tauri 命令
| 命令 | 功能 | 变化 |
|---|---|---|
viking_status |
检查状态 | 返回 available: true (始终可用) |
viking_add |
添加资源 | 内部使用 SqliteStorage |
viking_find |
语义搜索 | 使用 TF-IDF + SQLite FTS |
viking_grep |
模式搜索 | 使用 SQLite FTS |
viking_ls |
列出资源 | 从 SQLite 读取 |
viking_read |
读取内容 | 从 SQLite 读取 |
viking_remove |
删除资源 | 从 SQLite 删除 |
viking_tree |
资源树 | 从 SQLite 构建 |
4.2 移除的命令
| 命令 | 原因 |
|---|---|
viking_server_start |
无需服务器 |
viking_server_stop |
无需服务器 |
viking_server_status |
无需服务器 |
五、实施计划
Phase 1: 完善 SqliteStorage (1-2 天)
任务 1.1: 添加 sqlx 依赖
# crates/zclaw-growth/Cargo.toml
[dependencies]
sqlx = { workspace = true, features = ["runtime-tokio", "sqlite"] }
任务 1.2: 实现真正的 SQLite 持久化
- 文件:
crates/zclaw-growth/src/storage/sqlite.rs - 改动:
pub struct SqliteStorage { pool: SqlitePool, // 替换 RwLock<HashMap> scorer: SemanticScorer, // 添加语义评分器 } - 功能:
initialize_schema()- 创建 memories 表和 FTS5 索引store()- 写入 SQLiteget()- 从 SQLite 读取find()- 使用 SemanticScorer + FTS
任务 1.3: 集成 SemanticScorer
- 替换
compute_similarity()简单实现 - 使用已有的 TF-IDF 算法
Phase 2: 修改 Tauri 命令 (1 天)
任务 2.1: 修改 viking_commands.rs
// 替换
async fn viking_find(...) {
let cli = get_viking_cli_path()?;
let output = Command::new(&cli).arg("find")...
}
// 为
lazy_static! {
static ref STORAGE: SqliteStorage = ...;
}
async fn viking_find(...) {
STORAGE.find(query, options).await
}
任务 2.2: 删除 viking_server.rs
- 移除服务器管理相关命令
- 更新
lib.rs移除模块引用
任务 2.3: 初始化存储
- 在
lib.rs的run()函数中初始化SqliteStorage - 存储路径:
~/.zclaw/memories.db
Phase 3: 测试与验证 (1 天)
任务 3.1: 单元测试
- 完善
SqliteStorage测试 - 测试持久化和恢复
任务 3.2: 集成测试
- 端到端测试: 前端 → Tauri → SqliteStorage
- 验证
viking_find返回语义相关结果
任务 3.3: 验收测试
- 启动 Tauri 后无需配置即可使用
- 打包体积无显著增加
六、文件变更清单
修改文件
| 文件 | 变更 |
|---|---|
crates/zclaw-growth/src/storage/sqlite.rs |
添加真正的 SQLite 持久化 |
crates/zclaw-growth/Cargo.toml |
添加 sqlx 依赖 |
desktop/src-tauri/src/viking_commands.rs |
使用 SqliteStorage |
desktop/src-tauri/src/lib.rs |
移除 viking_server 模块,初始化存储 |
删除文件
| 文件 | 原因 |
|---|---|
desktop/src-tauri/src/viking_server.rs |
不再需要服务器管理 |
保持不变
| 文件 | 原因 |
|---|---|
desktop/src/lib/viking-client.ts |
API 兼容 |
desktop/src/components/VikingPanel.tsx |
UI 不变 |
crates/zclaw-growth/src/viking_adapter.rs |
接口不变 |
crates/zclaw-growth/src/retrieval/semantic.rs |
TF-IDF 已实现 |
七、风险与缓解
| 风险 | 影响 | 缓解措施 |
|---|---|---|
| SQLite FTS5 中文支持 | 搜索质量 | 使用 unicode61 tokenizer |
| TF-IDF 语义理解有限 | 搜索精度 | 可选:后续添加 embedding API |
| 数据迁移 | 用户数据丢失 | localStorage 降级保留 |
八、验收标准
- 启动 Tauri 后无需任何配置即可使用记忆功能
viking_status返回available: trueviking_find返回语义相关结果(基于 TF-IDF)- 数据持久化到
~/.zclaw/memories.db - 打包体积无显著增加(< 1MB)
- 所有现有测试通过
- 前端 API (
viking-client.ts) 无需修改
九、与现有设计文档的关系
本方案是对 docs/superpowers/specs/2026-03-26-agent-growth-design.md 的简化实现:
| 设计文档要求 | 本方案实现 |
|---|---|
| OpenViking 作为完整记忆层 | SqliteStorage (实现 VikingStorage trait) |
| 语义搜索 | TF-IDF (SemanticScorer) |
| L0/L1/L2 分层 | 已有实现,保持不变 |
| 记忆提取 | 已有 MemoryExtractor,保持不变 |
核心差异:设计文档说用 OpenViking Python 包,本方案用纯 Rust 实现替代,保持接口兼容。
十、对系统架构的影响分析
10.1 正面影响
| 影响 | 说明 |
|---|---|
| 消除外部依赖 | 不再需要 Python 环境 |
| 降低复杂度 | 移除进程管理代码 |
| 提高可靠性 | 无进程启动失败风险 |
| 减少打包体积 | 无需打包 Python |
10.2 潜在风险
| 风险 | 影响 | 缓解措施 |
|---|---|---|
| TF-IDF 语义理解不如 embedding | 搜索精度降低 | 后续可选添加 embedding API |
| 大量记忆时性能下降 | 查询变慢 | 添加分页、索引优化 |
10.3 功能完整性
| 功能 | 原方案 (OpenViking) | 新方案 (SqliteStorage) |
|---|---|---|
| 存储记忆 | ✅ | ✅ |
| 语义搜索 | ✅ embedding | ⚠️ TF-IDF (可接受) |
| URI 寻址 | ✅ | ✅ |
| L0/L1/L2 分层 | ✅ | ✅ 已有实现 |
| 记忆提取 | ✅ | ✅ 已有实现 |
| 记忆检索 | ✅ | ✅ 已有实现 |
| Prompt 注入 | ✅ | ✅ 已有实现 |
10.4 结论
推荐采用简化方案:
- 工作量小(3-4 天 vs 7+ 天)
- 风险低(复用现有代码)
- 满足"开箱即用"核心需求
- 后续可渐进增强(添加 embedding)