Files
zclaw_openfang/wiki/memory.md
iven 3e78dacef3
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
docs(wiki): 追加身份信号提取与持久化修复日志
2026-04-23 10:31:46 +08:00

7.1 KiB
Raw Blame History

title, updated, status, tags
title updated status tags
记忆管道 2026-04-22 active
module
memory
fts5
growth

记忆管道 (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 数据库,跨库查询需使用正确连接
  • 记忆注入在中间件@150AFTER ButlerRouter@80BEFORE SkillIndex@200
  • Embedding 当前为 NoOpEmbeddingClient用户配置 provider 后替换为真实实现
  • 30 秒去重窗口:同一 agent 30 秒内跳过重复提取
  • URI scheme: agent://{agent_id}/{type}/{category}

非显然逻辑

  • TF-IDF 语义路由70% embedding 权重 + 30% TF-IDFembedding 未激活时退化为纯 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 身份信号提取: 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