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
Agent tab 展示的信息对用户无实际作用,身份记忆已通过 soul.md → pre_conversation_hook 实现跨会话。移除 Agent tab (简洁+专业模式),清理 ~280 行 dead code。
7.2 KiB
7.2 KiB
title, updated, status, tags
| title | updated | status | tags | ||||
|---|---|---|---|---|---|---|---|
| 记忆管道 | 2026-04-22 | active |
|
记忆管道 (Memory Pipeline)
从 index 导航。关联: chat middleware butler 详细提取逻辑归档: archive/memory-extraction-details
1. 设计决策
核心问题: LLM 无状态,每次对话从零开始。需要从历史对话中积累知识。
| 决策 | WHY |
|---|---|
| 闭环架构 | 对话→提取→索引→检索→注入,形成正向循环。每次聊天都积累,每次提问都利用 |
| 双数据库 | memories.db (FTS5 全文索引) + data.db (结构化画像)。前者处理模糊语义检索,后者处理精确字段查询 |
| FTS5+TF-IDF+Embedding 三层 | FTS5 粗筛 + TF-IDF 加权 + Embedding 精排(当前 NoOp,配置后激活)。不依赖外部服务即可工作 |
| 进化引擎 | 从对话中检测行为模式变化,生成进化候选项(技能建议/工作流优化),通过 EvolutionMiddleware@78 注入 system prompt |
| Token 预算控制 | 注入 system prompt 时有 token 上限,防止记忆注入挤占用户实际对话空间 |
Hermes 核心借鉴 (详见 archive/hermes-analysis): 经验库 FTS5 全文检索 + 用户画像结构化建模 + 自然语言 cron 调度 + 轨迹记录压缩。4 Chunk 已交付: ExperienceStore(10 tests) + UserProfileStore(14 tests) + NlScheduleParser(16 tests) + TrajectoryRecorder(18 tests)。
2. 关键文件 + 数据流
核心文件
| 文件 | 职责 |
|---|---|
crates/zclaw-growth/src/extractor.rs |
LLM 记忆提取 (偏好/知识/经验) |
crates/zclaw-growth/src/retriever.rs |
语义检索 (FTS5 + TF-IDF + 意图分类) |
crates/zclaw-growth/src/injector.rs |
Prompt 注入 (token 预算) |
crates/zclaw-growth/src/storage/sqlite.rs |
FTS5 + TF-IDF 核心 (memories.db) |
crates/zclaw-runtime/src/middleware/memory.rs |
记忆中间件 (提取+注入编排) |
crates/zclaw-runtime/src/growth.rs |
GrowthIntegration 闭环编排 |
crates/zclaw-memory/src/user_profile_store.rs |
UserProfileStore (data.db) |
闭环数据流
[提取] 对话完成 → MemoryMiddleware.after_completion
→ MemoryExtractor.extract_combined() → LLM 单次调用
→ CombinedExtraction { memories, experiences, profile_signals (含 agent_name/user_name) }
→ VikingAdapter → SqliteStorage → memories.db (FTS5 索引)
→ UserProfileStore → data.db (结构化画像)
→ [身份信号] identity/* → VikingStorage → post_conversation_hook → soul.md + Tauri event
[检索] 新请求 → MemoryMiddleware.before_completion
→ MemoryRetriever.retrieve(agent_id, user_input)
→ QueryAnalyzer 意图分类 (5类: Preference/Knowledge/Experience/Code/General)
→ FTS5 全文搜索 + TF-IDF 评分 + IdentityRecall 43+ 模式
→ 弱身份 fallback: <3 结果 → 补充 broad retrieval
→ PromptInjector.inject_with_format(system_prompt, memories)
集成契约
| 方向 | 模块 | 触发点 |
|---|---|---|
| Called by | middleware: Memory@150 | Every chat completion (after) + new request (before) |
| Calls | zclaw-memory: FTS5 store, TF-IDF scorer | Memory extraction + retrieval |
| Calls | zclaw-growth: GrowthIntegration, EvolutionEngine | Pattern detection + skill generation |
| Provides | loop_runner: Context injection into system prompt | Before LLM call |
Tauri 命令
| 分类 | 命令数 | 关键命令 |
|---|---|---|
Memory CRUD (memory_commands.rs) |
11 | memory_store, memory_search, memory_build_context |
VikingStorage (viking_commands.rs) |
14 | viking_add, viking_find, viking_inject_prompt |
Intelligence (intelligence/) |
~40 | identity(13), heartbeat(11), pain(5), reflection(6) |
| 提取+Embedding | 5 | extract_session_memories, embedding_create |
3. 代码逻辑
跨会话记忆完整链路
[初始化] kernel_init → init_storage(memories.db) → MemoryStore(data.db)
→ set_viking(SqliteStorage) → set_extraction_driver(LLM)
→ [首次聊天] create_middleware_chain() 重建 GrowthIntegration:
VikingAdapter + ExtractionDriver + UserProfileStore(data.db)
→ MemoryMiddleware@150 注册到中间件链
[写入] after_completion → 30秒去重 → extract_combined(LLM)
→ memories → memories.db | profile_signals → data.db
[读取] before_completion → retrieve(agent_id, query)
→ FTS5 + TF-IDF + IdentityRecall → inject_with_format()
[展示] 管家Tab → viking_ls/viking_read(memories.db) + agent_get(data.db)
不变量
- memories.db 和 data.db 是独立的 SQLite 数据库,跨库查询需使用正确连接
- 记忆注入在中间件@150,AFTER ButlerRouter@80,BEFORE SkillIndex@200
- Embedding 当前为 NoOpEmbeddingClient,用户配置 provider 后替换为真实实现
- 30 秒去重窗口:同一 agent 30 秒内跳过重复提取
- URI scheme:
agent://{agent_id}/{type}/{category}
非显然逻辑
- TF-IDF 语义路由:70% embedding 权重 + 30% TF-IDF(embedding 未激活时退化为纯 TF-IDF)
- IdentityRecall: 43+ 模式匹配("你记得我"/"上次说的"/"我的偏好"等)触发记忆检索
- 弱身份 fallback: 检索结果 <3 且含弱身份关键词时,补充 broad retrieval 扩大搜索范围
4. 活跃问题 + 陷阱
活跃
| 问题 | 状态 | 说明 |
|---|---|---|
| Embedding 未激活 | 🚧 长期观察 | NoOpEmbeddingClient 是默认值,用户配置 provider 后替换 |
| SaaS pgvector | 🚧 deferred | HNSW 索引就绪 (knowledge_chunks, vector(1536)),生成逻辑未实现 |
历史陷阱 (已修复)
- 跨会话记忆断裂 (profile_store 未连接 + 双数据库不一致 + 缺日志) → 04-22 已修复 (
adf0251) - 记忆去重失败 (同 URI+content 重复添加) → 04-17 已修复 (
a504a40) - 记忆非 Agent 隔离 (viking_find 返回所有 Agent 记忆) → 04-17 已修复 (
a504a40) - 跨会话注入断裂 (新会话报 "no conversation history found") → 04-17 已修复 (
a504a40)
警告
memories.db / data.db 连接池隔离。修改存储层代码务必确认目标数据库。 GrowthIntegration 缓存在
set_viking()/set_extraction_driver()时会被清除,首次聊天时重建。
5. 变更日志
| 日期 | 变更 | 关联 |
|---|---|---|
| 2026-04-23 | agent_update 同步写 soul.md + 命名检测解耦 memory extraction + Agent tab 移除 | commit 394cb66+0bb5265+1c00290 |
| 2026-04-23 | 身份信号提取: ProfileSignals+agent_name/user_name + VikingStorage identity 存储 + soul.md 写回 | commit 08812e5+e64a3ea |
| 2026-04-22 | 跨会话记忆断裂修复: profile_store 连接 + 双数据库统一 + 诊断日志 | commit adf0251 |
| 2026-04-22 | Wiki 5-section 重构: 363→~190 行,详细逻辑归档 | wiki/ |
| 2026-04-21 | Embedding 接通 + 自学习自动化 A线+B线 (SemanticScorer + EvolutionMiddleware) | 934 tests PASS |
| 2026-04-17 | E2E 全系统验证 129 链路: 记忆去重+注入+跨会话 修复 | 79.1% 通过率 |
| 2026-04-15 | Heartbeat 统一健康系统 (health_snapshot + 健康快照集成) | 183 commands |
测试概览
| Crate | 测试数 | 覆盖 |
|---|---|---|
| zclaw-growth | 181 (29 文件) | 全覆盖 |
| zclaw-memory | 54 (4 文件) | 全覆盖 |
| 合计 | 235 |