From 6895545a0eaaff322d919942fb5b031ee82c4e55 Mon Sep 17 00:00:00 2001 From: xiaowei Date: Fri, 29 May 2026 23:50:30 +0800 Subject: [PATCH] =?UTF-8?q?design:=20add=20section=202.8=20=E6=99=BA?= =?UTF-8?q?=E8=83=BD=E8=AE=B0=E5=BF=86=E8=B7=AF=E7=94=B1=EF=BC=88Middlewar?= =?UTF-8?q?e=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New section covers: - Problem: recall as passive API vs memory as本能 - Query Classifier: automatic channel selection (FTS/vector/graph/session) - Multi-Channel Router: 4 parallel search paths - Result Merger: weighted merge with dedup - Context Weaver: structured injection into Agent context - Proactive Push: context-aware delivery before query - Integration: Sidecar pattern (stdin/stdout hooks) - Implementation phases prioritized by value --- DESIGN.md | 244 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 2 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index 6d66728..c9d9ff0 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -22,7 +22,8 @@ - 2.4 Rerank 重排层(bge-reranker-v2-m3,API 细节) - 2.5 知识图谱(节点/边 Schema、建图来源、多跳导航、修剪、Namespace 隔离) - 2.6 Recall 完整链路(编码→ANN→重排→MMR→预取推送) - - 2.7 核心 API(全部端点 + WebSocket 事件类型) + - 2.8 智能记忆路由(Middleware:自动判断·自动织入·无需 Agent 调用) + - 2.9 核心 API(全部端点 + WebSocket 事件类型) 3. [Part 3:记忆生命周期](#part-3记忆生命周期) - 3.1 蒸馏引擎(硬规则 + LLM 评估 + 批量 + 成本控制) - 3.2 自优化引擎 @@ -504,7 +505,246 @@ query 进入 - `diversity=0.5`(推荐):平衡 - `diversity=1.0`:最大多样性 -### 2.7 核心 API +### 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 #### REST 端点