design: add section 2.8 智能记忆路由(Middleware)
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
This commit is contained in:
parent
da9694a264
commit
6895545a0e
244
DESIGN.md
244
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 端点
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue