# hxclaw 记忆体系统架构图 ## 一、数据流向总图 ```mermaid flowchart TB subgraph 用户输入 A[用户输入] A1[普通对话] A2[查询历史] A3[/recall 命令] end subgraph 上下文注入 B[GetContextPrompt] B0[读取 picoclaw MEMORY.md] B1[获取当前 Session 摘要] B2[检测查询意图] B3[按需调用 Recall] end subgraph AI 处理 C[ProcessDirect] C1[工具调用] C2[多轮对话] end subgraph 保存流程 D[SaveChat] D1[INSERT chat] D2[UPDATE chat 摘要+向量] D3[UPDATE session 摘要+向量] end subgraph 数据库 E[sessions 表] F[chats 表] end subgraph 向量服务 G[硅基流动 API] end subgraph 外部记忆 H[picoclaw MEMORY.md] end A --> B B0 --> B H --> B0 B --> C C --> D D --> F D --> E F --> G E --> G A1 -->|普通对话| B1 A2 -->|检测关键词| B2 A3 -->|强制触发| B3 ``` --- ## 二、对话流程(默认模式) ```mermaid sequenceDiagram participant U as 用户 participant M as main.go participant CP as GetContextPrompt participant PicoMem as picoclaw MEMORY.md participant AI as ProcessDirect participant SC as SaveChat participant DB as libSQL participant VS as 向量服务 U->>M: 用户输入 M->>CP: GetContextPrompt(userInput) CP->>PicoMem: 读取长期记忆 PicoMem-->>CP: 长期记忆内容 CP->>DB: 获取 currentSession DB->>CP: session.Summary Note over CP: 合并:长期记忆 + 会话摘要 CP->>M: 返回上下文 M->>AI: ProcessDirect(context + input) AI->>U: 返回 AI 回复 U->>SC: SaveChat(userInput, aiReply) SC->>DB: INSERT chat SC->>DB: UPDATE session Note over SC: 更新摘要和向量 SC->>VS: 异步生成向量 VS-->>SC: embedding SC->>DB: 保存到 chats.summary_embedding SC->>DB: 保存到 sessions.summary_embedding ``` --- ## 三、四种查询场景 ```mermaid flowchart LR subgraph 查询场景 Q1[场景1: 历史摘要] Q2[场景2: 话题检索] Q3[场景3: 会话详情] Q4[场景4: 会话内检索] end subgraph 触发条件 T1["之前聊过什么?"] T2["谈论过 xxx?"] T3["那次还说过什么?"] T4["xxx 呢?"] end subgraph 查询逻辑 L1[查 sessions 表] L2[chats 向量检索
Group By session_id] L3[查 sessions 表
WHERE id = ?] L4[chats 向量检索
WHERE session_id = ?] end subgraph 返回 R1[所有会话摘要] R2[按 session 分组
top5 摘要拼接] R3[指定 session 摘要] R4[同 session 内相关摘要] end T1 --> Q1 T2 --> Q2 T3 --> Q3 T4 --> Q4 Q1 --> L1 Q2 --> L2 Q3 --> L3 Q4 --> L4 L1 --> R1 L2 --> R2 L3 --> R3 L4 --> R4 ``` --- ## 四、三重检测机制 ```mermaid flowchart TB I[用户输入] subgraph 检测层 D1[/recall 命令] D2[关键词匹配] D3[向量相似度] end subgraph 配置 C1[keywords] C2[auto_recall] C3[similarity_threshold] end I --> D1 I --> D2 I --> D3 D2 --> C1 D3 --> C3 C1 -->|匹配成功| R[强制 Recall] D3 --> C2 C2 -->|开启| C3 C3 -->|阈值判断| R D1 -->|触发| R ``` --- ## 五、数据库表结构 ```mermaid erDiagram sessions { int id PK string uuid text summary blob summary_embedding string chat_ids int created_at int updated_at } chats { int id PK int session_id FK text user_input text ai_replies text summary blob summary_embedding int created_at int updated_at } sessions ||--o{ chats : "has many" ``` --- ## 六、上下文演变 ```mermaid flowchart LR subgraph 时间线 T1[开始] T2[第1次对话] T3[第2次对话] T4[第N次对话] T5[第1000次对话] end subgraph 上下文状态 S1[空] S2[摘要1] S3[摘要1+摘要2] SN[摘要N] S1000[摘要1000] end subgraph 实际状态 A1["context = 空 + 长期记忆"] A2["context = 摘要1 + 长期记忆"] A3["context = 摘要2 + 长期记忆"] AN["context = 摘要N + 长期记忆"] A1000["context = 摘要1000 + 长期记忆"] end T1 --> S1 --> A1 T2 --> S2 --> A2 T3 --> S3 -->|覆盖| A3 T4 --> SN -->|覆盖| AN T5 --> S1000 -->|覆盖| A1000 Note over A1000: 始终只有1条会话摘要 + 长期记忆 ``` **注意**:长期记忆来自 `~/.picoclaw/workspace/memory/MEMORY.md`,不受会话影响,会持续保留。 --- ## 七、完整流程图 ```mermaid flowchart TB subgraph 输入层 INPUT[用户输入] CMD[/recall] KW[关键词] end subgraph 检测层 CHECK{检测查询意图} RECALL{Recall 触发?} end subgraph 上下文构建 CONTEXT[上下文] SESSION_SUM[当前 Session 摘要] RECALL_RES[Recall 结果] end subgraph AI 层 AI[ProcessDirect] RESP[AI 回复] end subgraph 保存层 SAVE[SaveChat] INSERT_CHAT[INSERT chat] UPDATE_CHAT[UPDATE chat] UPDATE_SESSION[UPDATE session] end subgraph 数据库 DB[(libSQL)] SESSIONS[sessions 表] CHATS[chats 表] end subgraph 向量服务 VS[向量服务] EMB[Generate Embedding] end INPUT --> CHECK CMD --> CHECK KW --> CHECK CHECK -->|普通对话| RECALL CHECK -->|是查询| RECALL_RES RECALL -->|否| SESSION_SUM RECALL_RES --> CONTEXT SESSION_SUM --> CONTEXT CONTEXT --> AI INPUT --> AI AI --> RESP RESP --> SAVE SAVE --> INSERT_CHAT INSERT_CHAT --> DB DB --> CHATS SAVE --> UPDATE_CHAT UPDATE_CHAT --> DB SAVE --> UPDATE_SESSION UPDATE_SESSION --> DB CHATS --> EMB SESSIONS --> EMB EMB --> VS VS --> CHATS VS --> SESSIONS ``` --- ## 八、关键文件对应关系 | 模块 | 文件 | 职责 | |------|------|------| | 主流程 | `main.go` | 调用 GetContextPrompt、SaveChat | | 配置 | `internal/config.go` | RecallConfig、VectorConfig | | 数据库 | `internal/memory/db.go` | CRUD 操作 | | 模型 | `internal/memory/model.go` | Session、Chat 结构体 | | 向量 | `internal/memory/vector.go` | 硅基流动 API 调用 | | 保存 | `internal/memory/save.go` | SaveChat、三重检测、长期记忆读取 | | 查询 | `internal/memory/skill.go` | 4 个 Recall 函数 | | 导出 | `internal/memory/export.go` | JSON 导出 | --- ## 九、双记忆系统合并 ### 记忆来源 | 类型 | 来源 | 持久性 | |------|------|--------| | **长期记忆** | `~/.picoclaw/workspace/memory/MEMORY.md` | 跨会话,AI 自动更新 | | **会话摘要** | `~/.config/hxclaw/hxclaw.db` sessions 表 | 当前会话,动态更新 | | **聊天详情** | `~/.config/hxclaw/hxclaw.db` chats 表 | 所有历史,支持向量检索 | ### 上下文注入格式 ```markdown === 长期记忆 === (picoclaw MEMORY.md 内容) === 当前会话摘要 === (hxclaw sessions 表中的摘要) 用户新问题: xxx ``` ### 实现原理 `GetContextPrompt()` 函数在构建上下文时: 1. 读取 picoclaw 的 `MEMORY.md` 文件 2. 解析并提取有效内容(跳过 Markdown 标题) 3. 合并到上下文顶部 4. 追加会话摘要 5. 如有 recall 结果,继续追加 ### 数据流向 ``` picoclaw MEMORY.md ──┐ ├──→ GetContextPrompt ──→ AI 上下文 hxclaw sessions ────┘ ``` --- ## 十、配置项说明 ```yaml memory: recall: keywords: ["之前", "聊过", "记得", "找找", "曾经", "谈论过", "提过"] auto_recall: true # 自动相似度检测 similarity_threshold: 0.7 # 相似度阈值 max_results: 5 # 最大检索结果 vector: max_search_results: 10 # 向量检索最大结果 ``` --- ## 十一、MongoDB 风格导出 ### 导出文件 - 路径:`~/.config/hxclaw/export-data.json` - 格式:每次退出时自动增量导出 ### JSON 结构 ```json { "version": 1, "exported_at": "2026-04-27T06:12:22+08:00", "sessions": [ { "id": 1, "uuid": "session-uuid", "summary": "会话摘要...", "chat_ids": [1, 2, 3], "created_at": 1740000000, "updated_at": 1740000000, "chats": [ { "id": 1, "session_id": 1, "user_input": "用户输入", "ai_replies": ["AI回复1", "AI回复2"], "summary": "摘要", "created_at": 1740000000, "updated_at": 1740000000 } ] } ] } ``` ### 设计特点 | 特性 | 说明 | |------|------| | 嵌套结构 | chats 嵌套在 sessions 下,类似 MongoDB 文档 | | 增量导出 | 同 session 的 chats 累加,不重复创建 | | UUID 匹配 | 按 UUID 判断是新建还是更新 | | 版本控制 | version 字段支持格式演进 | ```