Files
zclaw_openfang/plans/nifty-wondering-kahn.md
iven b7f3d94950
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
fix(presentation): 修复 presentation 模块类型错误和语法问题
- 创建 types.ts 定义完整的类型系统
- 重写 DocumentRenderer.tsx 修复语法错误
- 重写 QuizRenderer.tsx 修复语法错误
- 重写 PresentationContainer.tsx 添加类型守卫
- 重写 TypeSwitcher.tsx 修复类型引用
- 更新 index.ts 移除不存在的 ChartRenderer 导出

审计结果:
- 类型检查: 通过
- 单元测试: 222 passed
- 构建: 成功
2026-03-26 17:19:28 +08:00

12 KiB
Raw Blame History

开箱即用的上下文记忆库方案 (简化版)

一、背景与目标

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() - 写入 SQLite
    • get() - 从 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.rsrun() 函数中初始化 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: true
  • viking_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 结论

推荐采用简化方案

  1. 工作量小3-4 天 vs 7+ 天)
  2. 风险低(复用现有代码)
  3. 满足"开箱即用"核心需求
  4. 后续可渐进增强(添加 embedding