diff --git a/DESIGN.md b/DESIGN.md index c9d9ff0..6d66728 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -22,8 +22,7 @@ - 2.4 Rerank 重排层(bge-reranker-v2-m3,API 细节) - 2.5 知识图谱(节点/边 Schema、建图来源、多跳导航、修剪、Namespace 隔离) - 2.6 Recall 完整链路(编码→ANN→重排→MMR→预取推送) - - 2.8 智能记忆路由(Middleware:自动判断·自动织入·无需 Agent 调用) - - 2.9 核心 API(全部端点 + WebSocket 事件类型) + - 2.7 核心 API(全部端点 + WebSocket 事件类型) 3. [Part 3:记忆生命周期](#part-3记忆生命周期) - 3.1 蒸馏引擎(硬规则 + LLM 评估 + 批量 + 成本控制) - 3.2 自优化引擎 @@ -505,246 +504,7 @@ query 进入 - `diversity=0.5`(推荐):平衡 - `diversity=1.0`:最大多样性 -### 2.8 智能记忆路由(Middleware) - -> **目标**:织忆作为消息入口的 middleware,主动拦截、感知、自动织入——Agent 不需要"想起"去调 API,记忆自动出现在该出现的地方。 -> -> **现状问题**:当前 recall 是被动 API(Agent 调 `memory_search` → 返回结果),本质是"查工具",不是"记忆本能"。Agent 还在用"有没有这条记忆"的意识来判断要不要调用,而不是记忆自然地涌上来。 -> -> **设计原则**: -> - **Middleware 拦截**:织忆作为消息流必经层,每个 incoming query 和 outgoing response 都经过它 -> - **自动判断**:不是 Agent 决定用什么搜索,而是 Middleware 根据 query 特征自动路由 -> - **自动织入**:结果直接注入 Agent context,不经过工具调用 -> - **无需显式调用**:Agent 忘掉"有记忆 API 这件事",记忆按需自然呈现 - -#### 2.8.1 整体架构 - -``` -Agent 消息入口 - ↓ -┌─────────────────────────────────────────────────────┐ -│ Memory Middleware(织忆) │ -│ │ -│ ① Query Classifier(查询分类器) │ -│ ├── 类型:精确查找 / 语义搜索 / 结构查询 / 闲聊 │ -│ └── 路由信号:channel, top_k, recall_strategy │ -│ │ -│ ② Multi-Channel Router(多通道路由) │ -│ │ │ -│ ├── FTS 通道 — 精确匹配 │ -│ │ 用处:文件名、函数名、配置项、技术术语 │ -│ │ 触发:"zhiyi-sidecar 的 systemd 配置" │ -│ │ 工具:SQLite FTS5(session_search 等效) │ -│ │ │ -│ ├── 向量通道 — 语义相似 │ -│ │ 用处:概念相关但表述不同 │ -│ │ 触发:"我想了解之前做的 AI 视频那套流程" │ -│ │ 工具:LanceDB ANN(Recall 管线) │ -│ │ │ -│ ├── 图谱通道 — 结构关系 │ -│ │ 用处:需要 1→2→3 跳关联 │ -│ │ 触发:"织忆的记忆是怎么组织的" │ -│ │ 工具:Graph Navigate(多跳 BFS) │ -│ │ │ -│ └── 会话通道 — 历史上下文 │ -│ 用处:直接引用之前的对话 │ -│ 触发:"我们上次修 pagerank 那个" │ -│ 工具:session_search(FTS5,跨会话) │ -│ │ -│ ③ Result Merger(结果合并) │ -│ └── 多通道结果 → 去重 → 置信度排序 → top-5 │ -│ │ -│ ④ Context Weaver(上下文织入) │ -│ └── 直接注入 Agent 输入 context(无需工具调用) │ -└─────────────────────────────────────────────────────┘ - ↓ -Agent 直接回答(已携带记忆) -``` - -#### 2.8.2 Query Classifier(查询分类器) - -**输入**:原始用户 query -**输出**:路由决策(channel × strategy) - -**分类规则**(可配置,优先级从高到低): - -| 类型 | 检测规则 | 路由 | 策略 | -|------|---------|------|------| -| 精确查找 | query 含:文件名、路径、配置项、正则、手机号 | FTS | exact_match | -| 项目上下文 | query 含:项目名、仓库名、特定技术栈 | FTS + 图谱 | namespace_scope | -| 语义关联 | query 是开放式问题、模糊描述、自然语言提问 | 向量 | semantic | -| 结构查询 | query 含:"怎么连接的""什么关系""哪一层" | 图谱 | graph_expand | -| 历史引用 | query 含:"上次""之前""我们做过" | 会话通道 | session_recall | -| 闲聊 / 寒暄 | query 无技术实质内容 | 不触发记忆 | skip | -| 混合 | 多个信号同时触发 | 多通道并行 | merge | - -**优先级**:精确查找 > 历史引用 > 项目上下文 > 语义关联 > 结构查询 -**说明**:所有通道并行搜索,最终合并。分类器只是调整各通道的权重和 top_k。 - -#### 2.8.3 Multi-Channel Router(多通道设计) - -每个通道是独立的搜索路径,最终在 Merger 层合并: - -**通道 1 — FTS(精确匹配)** -- 触发条件:query 包含技术术语、文件名、配置路径 -- 数据源:commit 时同时写 FTS 表(`memories_fts`) -- 搜索方式:SQLite FTS5 MATCH -- 特点:毫秒级响应,精确召回 - -**通道 2 — 向量(语义相似)** -- 触发条件:query 是自然语言表述、开放式问题 -- 数据源:LanceDB `memories` 表 -- 搜索方式:bge-m3 ANN + bge-reranker 重排 -- 特点:跨表述匹配,发现隐式关联 - -**通道 3 — 图谱(结构关系)** -- 触发条件:query 问结构、关系、层级 -- 数据源:LanceDB `graph_nodes` + `graph_edges` -- 搜索方式:Bidirectional BFS 多跳导航 -- 特点:发现 2-3 跳的间接关系 - -**通道 4 — 会话(历史上下文)** -- 触发条件:query 含"上次""之前""我们讨论过" -- 数据源:Hermes 内部 session_search 索引 -- 搜索方式:FTS5 全文搜索历史会话 -- 特点:直接引用具体对话片段(这是唯一跨记忆库的通道) - -#### 2.8.4 Result Merger(结果合并) - -``` -各通道返回候选结果(带置信度分数 × 通道权重) - ↓ -去重(相同 memory_id 只保留最高分) - ↓ -通道加权: - - FTS 命中 × 1.0(精确信号权重最高) - - 向量命中 × 0.8 - - 图谱命中 × 0.7 - - 会话命中 × 0.9(含直接引用语义) - ↓ -MMR 去重(diversity=0.3,避免结果趋同) - ↓ -输出 top-5,带通道来源标注 -``` - -**去重策略**:相同 `memory_id` 跨通道只保留一个,取最高分。"相同"定义为 memory_id 完全相同,或 content 相似度 > 0.95(重复提交保护)。 - -#### 2.8.5 Context Weaver(自动织入) - -**织入方式**:Merger 输出 → 构造成特定格式 → 写入 Agent context 的 `memory_context` 字段 - -**Agent 看到的形式**: -``` -[记忆上下文](来源:织忆,命中率:0.87) -━━━━━━━━━━━━━━━━━━━━━━━━━━ -1. [向量] "织忆 pagerank 列缺失的修复过程"(相关性 0.92) - 来源:hermes-main | 2026-05-29 -2. [FTS] config: zhiyi-sidecar.service systemd 配置(精确匹配) - 来源:hermes-main | 2026-05-29 -3. [图谱] pagerank 列 → graph_prune.rs → graph_nodes 表(1跳关联) - 来源:shared | 2026-05-29 -━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -**关键设计**: -- 结果以**结构化文本**注入,不是一堆 JSON -- 每个结果带**通道来源标注**(Agent 可见性:知道这条记忆从哪个通道来) -- **不打断 Agent 思维**:异步预取,不在 critical path 上 - -#### 2.8.6 主动感知(Proactive Context Push) - -不是等 query 才触发,是根据上下文主动推送: - -**触发条件**(满足任一即推送): -1. **项目切换**:检测到工作目录变更 → 推送该项目相关的 top-5 记忆 -2. **高频概念**:某个 concept 在短时间多次出现 → 推送该概念的完整上下文 -3. **知识缺口**:Agent 回答时出现犹豫词("不确定""需要确认")→ 推送相关记忆 -4. **时间衰减提醒**:某条重要记忆超过 N 天未被 recall → 在闲聊中自然提起 - -**推送方式**: -- 短时间窗口内的记忆:WebSocket 推送(`push` 事件类型) -- 非紧急记忆:写入 Agent context 的 `proactive_hints` 字段,异步可见 - -#### 2.8.7 与 Agent 的集成方式 - -**方案 A(推荐):Middleware Sidecar** -``` -Hermes Agent ←→ (stdout/stdin) ←→ Memory Middleware ←→ 织忆 API -``` -- Middleware 作为 Agent 的 sidecar 进程 -- 拦截 stdin 的用户消息 + stdout 的 Agent 回复 -- 中间件自己维护 context window,自动注入记忆 -- **优点**:不修改 Agent 本身,独立演进 -- **缺点**:需要 IPC,延迟略有增加 - -**方案 B:嵌入式(Lib)** -- 织忆作为 Hermes Agent 的 library 直接集成 -- 消息流 hooks 直接注入 -- **优点**:无 IPC 延迟 -- **缺点**:耦合,升级影响 Agent - -**方案 C:HTTP/WebSocket 中间层** -- Agent 所有消息经过 Middleware 反向代理 -- Middleware 在转发前注入记忆上下文 -- **优点**:Agent 改造成本最低 -- **缺点**:所有流量绕经 Middleware,有单点 - -**推荐方案 A**(Sidecar),原因: -1. 解耦:织忆升级不影响 Agent -2. 可测试:Middleware 独立测试 -3. 可观测:sidecar 独立日志、metrics - -#### 2.8.8 数据流全览 - -``` -用户消息 - ↓ -Middleware 接收(stdin hook) - ↓ -Query Classifier 分析 query - ↓ -Multi-Channel Router 并行搜索(×4 通道) - ├→ FTS: SQLite FTS5 - ├→ Vector: LanceDB ANN + Rerank - ├→ Graph: Graph Navigate(BFS) - └→ Session: Hermes session_search(跨会话 FTS) - ↓ -Result Merger 合并 + 去重 + 排序 - ↓ -Context Weaver 构造成可读格式 - ↓ -注入 Agent context 的 memory_context 字段 - ↓ -Agent 处理(已带记忆)→ 回复 - ↓ -Middleware 接收(stdout hook) - ↓ -主动感知:判断是否需要 commit / proactive push - ↓ -记忆写入:新的重要信息 → 异步 commit -``` - -#### 2.8.9 命名空间隔离(Middleware 层) - -Middleware 感知 namespace: -- 每条记忆带 namespace 标注(`hermes-main` / `openclaw-main` / `shared`) -- Router 在搜索时默认只搜当前 Agent 的 namespace + shared -- **跨 namespace 查询**需要明确路由信号(如"OpenClaw 的配置"→ 路由到 `openclaw-main`) -- 查询结果自动携带 namespace,Agent 能感知信息来源 - -#### 2.8.10 实现优先级 - -| 阶段 | 内容 | 价值 | -|------|------|------| -| Phase 1 | 实现 Query Classifier + 至少 2 个通道(FTS + 向量) | 核心链路跑通 | -| Phase 2 | Context Weaver + 注入格式 | Agent 可见效果 | -| Phase 3 | 图谱通道 + 会话通道 | 完整多通道 | -| Phase 4 | 主动感知(Proactive Push) | 从"被动查"到"主动推" | -| Phase 5 | 自我优化的路由策略(根据实际使用调整通道权重) | 越用越准 | - ---- - -### 2.9 核心 API +### 2.7 核心 API #### REST 端点