Files
MemoryBear/docs/rag/evolution/future-extensions-roadmap.md
Multica PM Agent 343a5eebe3
Some checks failed
Sync to Gitee / sync (push) Has been cancelled
docs(rag): add MemoryBear RAG implementation docs v1.0
Submit the formed RAG documentation set produced across Sprint-1/2/3
(WS-12 through WS-26) under docs/rag/. Includes:

- README.md / INDEX.md: landing + total index (responsibility matrix,
  review verdicts, dual-link to source issues)
- overview/: full-pipeline architecture (4 .mmd diagrams),
  11-stage boundary contracts, doc map, source-code inventory
- pipeline/: 5 deep-dives (Loader/Parser/Chunking, Embedding,
  VDB & retrieval, GraphRAG, Rerank/Prompt/LLM)
- graphrag/, end-to-end/: v1.0 formal versions with full source
  retained as reference
- evolution/: 11 architecture-refactor proposals,
  6-direction roadmap, capability map
- review/: S3-T1 / S3-T2 final reviews, S2-T7 final summary
- _indexes/: glossary (81 terms), source->doc reverse index, chart index
- _release/: v1.0-RC1 release manifest, versioning convention,
  ops & freshness plan
- _meta/README.md: placeholder noting WS-12 governance assets gap

Aggregate review score 92.6/100 (8/8 PASS, 31/31 source-code spot
checks hit). The legacy docs/ ignore in .gitignore is narrowed to
docs/* with an explicit allowlist for docs/rag/.

Refs: WS-26
Co-authored-by: multica-agent <github@multica.ai>
2026-05-09 10:51:48 +08:00

31 KiB
Raw Blame History

MemoryBear RAG · 后续迭代功能新增方式建议S3-T2

上游:[WS-11] 总规划、[S1-T2 全链路架构]、[S1-T3 源码盘点]、Sprint-2 各环节深度文档、[S3-T1 架构改造建议] 输出形态:能力地图 + 6 个重点扩展方向 + 2 条 Quick PoC + 优先级矩阵 + 落地路线图 设计原则:所有方向 必须 复用 [S3-T1] 提议的统一抽象(Retriever / Reranker / Generator / Embedder / Loader / Chunker),避免出现新功能 = 新一团耦合。


0. 现状速览与设计基线

0.1 一图看清"已有 / 可上 / 愿景"

详见附件 capability-map.mmdMermaid 格式)。三色对应:

  • 🟢 已有Sprint-2 文档已覆盖、源码可证、生产可用。
  • 🟡 近期可上12 个 Sprint 内可落地,依赖最少。
  • 🟣 中长期愿景36 个月,存在跨团队/外部依赖。

0.2 关键源码事实(用于支撑后续方案)

事实 源码定位 对扩展的影响
多模态目前 走文本通道 rag/app/picture.py:54vision_model.describerag/app/audio.py:29seq2txt_mdl.transcriptionnaive.py 走 video → VLM → 文本 跨模态语义损失大;扩展为"原生跨模态向量"是方向 D1
MatchSparseExpr 已声明但未接入 rag/utils/doc_store_conn.py:75vdb/field.py:11(SPARSE_VECTOR) 都已存在;grep -r SparseVector 仅 1 处定义、0 处调用 SPLADE 接入是脚手架级改造不是从零开始D2
混合检索权重写死 0.05,0.95 rag/nlp/search.py:439FusionExpr("weighted_sum", topk, {"weights": "0.05,0.95"}) 语义路由 / 自适应权重的注入点天然存在D2
GraphRAG 是"一次构建"模型 tasks.pybuild_graphrag_for_document Celery 链;图存于 ES knowledge_graph_kwd 字段 增量演化、时间维度、Neo4j 双引擎需要在 Celery 链上加 hookD3
对话记忆与 RAG 不互通 core/memory/ 自成一套Ebbinghaus、ACT-R、Neo4j、langgraph 读图);workflow/nodes/knowledge/node.py 完全不引用 core/memory 对话记忆 ↔ 检索的协同是最大产品差异化机会D4
评估只在 README 体现 仓内无 eval/ragasF1 类计算代码 反馈闭环要从 0 搭,但与 [S3-T1] 提议的"可观测性"天然合并D5
Reranker 只能推理不能学 core/models/rerank.py:11 包装 langchain BaseDocumentCompressor,仅做远程调用 自训练 Cross-Encoder 是一条独立、可量化收益的小路径D5
检索模式硬编码在 enum RetrieveType.{PARTICIPLE, SEMANTIC, HYBRID, Graph}schemas/chunk_schema.py 引入"语义路由"需要把 enum 改成 strategy 模式D6

0.3 与 [S3-T1] 接口抽象的联动约定

[S3-T1] 提议把当前散落的检索/排序/生成代码抽象为协议(参考 LangChain Runnable。本路线图的所有"接口改造点"都引用以下统一协议(命名以 [S3-T1] 终稿为准,本稿先行登记):

# rag/protocols.py[S3-T1] 提议)
class Retriever(Protocol):
    async def retrieve(self, query: Query, ctx: RetrievalContext) -> list[ScoredChunk]: ...

class Reranker(Protocol):
    async def rerank(self, query: Query, chunks: list[ScoredChunk], ctx: RerankContext) -> list[ScoredChunk]: ...

class Embedder(Protocol):
    def encode(self, items: list[Embeddable]) -> EmbeddingResult: ...   # Embeddable = str | Image | Audio | ...

class Generator(Protocol):
    async def generate(self, system: str, history: list[Msg], ctx: GenContext) -> GenResult: ...

原则:本文档每条扩展方向都以"新增/扩展某 Protocol 实现 + 注册到工厂"为接入方式,改动调用方代码。这样可以保持 N 个扩展方向 并行落地 而不互相阻塞。


1. 重点扩展方向

共 6 个方向。第 5、6 个为前述 5 个外的延伸(自适应路由),但和"评估闭环 / 混合搜索 / 对话记忆"高度互补,建议合并审阅。

D1. 多模态检索(原生跨模态向量空间)

1.1 触发场景

  • 客户问:"去年那张含 'Q3 GMV' 的 PPT 切片在哪?" — 当前只能命中 OCR 抽出的文字,布局/图表整体语义 丢失。
  • 视频会议纪要库:用户描述"那段讲到老王说'下季度先稳住毛利'的会议",纯 ASR 文本无法绑定 说话人 + 时间 + 屏幕共享上下文
  • 设备图谱:硬件型号识图("这块板子是哪一版"),目前只能让 VLM 描述后再走文本检索VLM 描述不稳定。

1.2 技术方案

分三层逐步推进:

层级 方案 依赖组件
L1基线增强 关键帧抽样 + VLM 多次 describe:视频每 N 秒抽帧,每帧 VLM 描述独立 chunkframe_ts 元数据;图片在 OCR + describe 之外再加 结构化 VQA"图中有什么图表/品牌/人脸?" 现有 cv_model.pysequence2txt_model.py 即可;新增 rag/app/video.py
L2跨模态检索 引入 CLIP / BGE-VL / Jina-Clip-v2 作为 MultimodalEmbedder Protocol 实现:图片直接编码为向量,文本 query 编码到 同一向量空间ES 索引增加 vec_image_q_<dim>_vec 新依赖 transformers / sentence-transformers 或托管 APIGPU 资源
L3视听统一 Whisper + speaker diarizationpyannote替换当前一段式 ASR视频 chunk 同时持有 text_vecASR 文本)+ image_vec(关键帧) + audio_vec(可选,用 CLAP pyannote.audioopen_clip;额外存储约 +30%

1.3 接口改造点(基于 S3-T1

  • 扩展 Embedder.encode(items: list[Embeddable])Embeddable = str | PILImage | AudioBytes | VideoFrame,返回 EmbeddingResult(vector, modality, dim)
  • 新增 MultimodalRetriever(Retriever) 实现:内部根据 query 的 modality_hint(文本默认)选择走 text_vec 还是 image_vec 列。
  • VDB 层 schema 演进(rag/vdb/elasticsearch/elasticsearch_vector.py:653+ 的 mapping 创建):把"硬编码单 vector 列"改造为"按 modality 多列动态注册";落地依赖 [S3-T1] 提到的 mapping 模板化改造。
  • app/picture.py / app/audio.pychunk() 函数输出 dict 中新增 image_b64 / audio_b64 字段,供 Embedder 后续无损取用(避免 PIL 对象在 Celery pickle 边界丢失)。

1.4 工作量估计

  • L1 基线:1.5 人周2 个 PR视频抽帧结构化 VQA prompt
  • L2 跨模态:3 人周(含 Embedder 抽象、ES schema 迁移、回归测试)
  • L3 视听统一:4 人周(含 GPU 容器、speaker diarization 集成)
  • 合计:~1.5 + 3 + 4 ≈ 8.5 人周(可分阶段产出)

1.5 风险与依赖

  • ⚠️ 存储膨胀image_vec768d float32单图 3KB1M 图 ≈ 3GBES dense_vector 启用 int8_hnsw 量化可减 75%。
  • ⚠️ VLM 描述漂移:同一图不同时间不同模型版本,描述差异大;需要 caption 缓存key = sha256(image)+model_version)。
  • ⛓️ 强依赖[S3-T1] mapping 模板化改造完成后再做 L2否则 schema 演进会成阻塞点。
  • ⛓️ GPU 依赖L2/L3 在自建 GPU 节点或托管 API 二选一建议先走托管Jina-Clip API跑通端到端再评估自托管。

D2. 混合搜索增强Sparse + Dense + Late-Interaction + 自适应路由)

2.1 触发场景

  • "工号 E12345 的 OKR" — 长尾标识符BM25 强、稠密向量弱,当前 0.05/0.95 权重几乎让 BM25 失语
  • "怎么做用户分层运营?" — 概念性问题dense 强、BM25 弱。
  • "GraphRAG 和 LightRAG 的区别" — 需要 ColBERT 这类 token 级精排,单向量混淆术语。

2.2 技术方案

子方向 方案 价值
SPLADE 学习稀疏 naver/splade-cocondenser-ensembledistil 或国产 BGE-M3 sparse 输出,每个文档生成稀疏向量(含 token expansion接入 MatchSparseExpr已存在但未启用 把 BM25 的"词形匹配"升级为"学习权重 + 自动同义扩展"
ColBERT 后期交互 文档级向量改为 token 级(一篇文档 N 个 token vectorN≈chunk_token_num/3retrieval 时用 MaxSim可仅在 reranker 阶段使用 在精确匹配上比 cross-encoder 快 510×质量接近
语义路由 / 自适应权重 先用一个轻 LLM或 query classifier判定 query 类型lookup / concept / list / multi-hop / temporal路由到 {BM25权重, vector权重, 是否使用 Graph, 是否使用 Rerank} 替代当前写死的 0.05/0.95可灰度query 哈希 % 100 < 5 上新策略)
多向量召回融合 同 chunk 同时索引 BM25、dense、sparse 三类retrieval 后用 RRF (Reciprocal Rank Fusion) 融合 工程上 RRF 不需训练,落地最快

2.3 接口改造点

  • 新增 SparseEmbedder(Embedder) 实现:返回 SparseVector(indices, values)ES mapping 增加 q_sparse_<vocab>_vec 字段,使用 rank_features/sparse_vector 类型ES ≥ 8.11)。
  • rag/nlp/search.py:Dealer.search()(第 387 行起)把 FusionExpr 的硬编码权重改为 ctx.fusion_weights,由 Retriever 实现的 ctx 参数注入。
  • 新增 RouterRetriever(Retriever):组合多个底层 retrieverDenseRetriever / SparseRetriever / GraphRetriever按 router 决策选择 / 融合。
  • ColBERT 仅在 Reranker 层接入:新增 ColBERTReranker(Reranker) 实现;接 Reranker 协议,完全不影响调用方。

2.4 工作量估计

  • RRF 多路融合(Quick PoC见 §20.5 人周
  • SPLADE 接入:2 人周(含 ES mapping、批量重建索引
  • 语义路由:2.5 人周(含 router 训练数据采集、灰度框架)
  • ColBERT Reranker3 人周GPU 部署 + 蒸馏小型化)
  • 合计:~8 人周

2.5 风险与依赖

  • ⚠️ 重建索引成本:现网 KB 数量 × chunk 数 × 维度,估算总耗时;需要提供"灰度索引切换"工具(详见 §6 路线图 P0
  • ⚠️ 路由器误判:错路由比无路由更糟;必须配 fallback路由失败回退到当前默认 0.05/0.95)。
  • ⛓️ 依赖 [S3-T1]Retriever Protocol 落地后才能优雅接入路由器;否则会污染 Dealer 类。

D3. 知识图谱增强(基于 [S2-T4] GraphRAG 的延伸)

3.1 触发场景

  • 法务/合规库每月新增 200+ 条法规:当前必须 重建整个图CI 跑 1 小时;用户要求"增量入库 + 增量图更新"。
  • 报错排查:"TS_001 错误码可能由哪些组件触发?" — 需要从 错误码 节点 N-hop 走到 组件 节点;当前 KGSearch 走的是文本相似度匹配实体,不是路径推理
  • 团队要求"为什么是这个答案" — 需要把推理路径A→关系1→B→关系2→C作为 citation 一同返回,提供 可解释性

3.2 技术方案

子方向 方案 现状 → 目标
增量图演化 tasks.py:build_graphrag_for_document 链上插入 GraphMerge 阶段:新文档抽出的子图与全图做 节点对齐 + 关系合并 + 冲突标记;保留 version_int 字段记录每条边的"加入/失效"版本号 一次构建 → 增量更新 + 时间溯源
路径解释性 KGSearch.retrieval() 输出新增 evidence_path: list[Edge];在 prompt 组装时把路径作为引用源;前端渲染"由 X→Y→Z 推断" 黑盒答案 → 带溯源链路
Neo4j 双引擎 当前图存在 ES 的 chunk 表里(knowledge_graph_kwd 字段),不能利用图算法;引入 Neo4j 作为 算法引擎PageRank 已在 ES 里跑过,但 Cypher 跑社区检测、最短路径远更便利ES 仍负责文本召回Neo4j 负责图算法。README 已声明 Neo4j 是组件,只是 RAG 层没用 单引擎 → 检索 ES + 图算法 Neo4j 混合
温度敏感的图衰减 复用 core/memory/forgetting_engine 的 Ebbinghaus 实现到图边权重:长期未被命中的实体/关系权重衰减;与 D4 共享一套衰减逻辑 静态图 → 动态、有"记忆"的图
自动本体演化 借鉴 core/memory/ontology_services/General_purpose_entity.ttl,定期用 LLM 检查"这批新加的实体类型是否应该归并到已有类型?" 类型膨胀 → 受控演化

3.3 接口改造点

  • 新增 GraphRetriever(Retriever) 实现,包装现有 KGSearch;输出 ScoredChunk.metadata 增加 evidence_pathlist[(from_entity, relation, to_entity, confidence)])。
  • 新增 GraphStore 抽象层:add_subgraph / merge / query_path / pagerank / community_detect;实现两个:ESGraphStore(保留现状)、Neo4jGraphStore(新增)。graphrag/general/index.py 现在直接操作 nx.Graph,全部替换为 GraphStore 调用。
  • tasks.py 的 Celery 链增加 graph_merge_task:依赖 build_graphrag_for_document,处理增量合并;需要分布式锁(已有 redis_lock.py 可用)。
  • Prompt 层(prompts/generator.py)新增 evidence_aware_citation_prompt:把 evidence_path 作为额外上下文注入。

3.4 工作量估计

  • 增量图演化(最小可用):3 人周(最复杂的是合并冲突的实体消歧)
  • 路径解释性:2 人周
  • Neo4j 双引擎:3 人周(含 Cypher 工具集、Neo4j 数据迁移脚本)
  • 图衰减 + 本体演化:2 人周(与 D4 共享代码)
  • 合计:~10 人周

3.5 风险与依赖

  • ⚠️ 实体消歧难度:跨文档同名异义("苹果"=公司 / 水果);建议用现有 entity_resolution.py 改造,但需要补全单元测试。
  • ⚠️ Neo4j 运维成本:用户已在 README 声明依赖 Neo4j但当前 RAG 层零调用;引入意味着同时管理两个图的一致性。建议把 Neo4j 定位为"算法只读 / 异步同步",避免双写一致性。
  • ⛓️ 依赖 [S3-T1]GraphStoreRetriever 协议落实,否则会跨层塌方。

D4. 对话记忆 ↔ RAG 协同(短期 / 长期 / 检索召回三段桥接)

MemoryBear 的核心特色。当前最大产品差异化机会就在这里——core/memory/core/rag/两条独立链路,没有联动。

4.1 触发场景

  • 用户在第 3 轮说"我对海鲜过敏",第 7 轮问"今晚吃什么?" — 当前 RAG 层无任何记忆能力,每次只看当轮 query。
  • 多 Agent 协作:售前 Agent 收集到客户预算,售后 Agent 重新询问 — 跨 Agent 记忆需要从 core/memory 读出 + 注入 RAG 检索 query 重写。
  • 长对话上下文压缩:第 50 轮时,前 40 轮对话需要 被遗忘但保留要点,要点变成"用户档案 chunk"加入 KB。

4.2 短期 / 长期 / 检索召回的边界(产品决策)

维度 短期记忆Working Memory 长期记忆Episodic / Semantic 检索召回KB
存储位置 Redis单 session 8KB cap Neo4j + EScore/memory EScore/rag
生命周期 session< 24h 永久(按 forgetting curve 衰减) 永久(人工治理)
写入触发 每轮 user/assistant message reflection_engine 周期性提炼 文档入库流水线
召回时机 始终注入 prompt LLM 重写 query 时 + 主动检索 RetrievalNode 命中
数据契约 list[Msg] MemoryItem(content, strength, type, ts) DocumentChunk
可信度 高(用户原话) LLM 提炼) 高(人工审核)

决策原则"用户原话进短期,提炼事实进长期,世界知识进 KB。" 三者不能互相替代。

4.3 技术方案

  • MemoryAugmentedRetriever:在 RouterRetriever 之外再包一层retrieve 前用 core/memory.read_services 拿到当前 user 的 top-K 长期记忆条目,改写 query"今晚吃什么?" + 长期记忆"对海鲜过敏" → "今晚吃什么?避免海鲜")。
  • Memory Citation:检索结果与长期记忆条目并入同一 chunks 列表prompt 模板区分两者来源("用户提及" vs "知识库"),避免幻觉混淆。
  • 反向写入:每轮对话产出后,让 core/memory.write_router 决定 是否需要把"新事实"写入长期记忆;这一步 复用 core/memory.agent.langgraph_graph.write_graph(已存在)。
  • 遗忘对齐:把 core/memory/forgetting_engine 的 ACT-R 计算复用到 KB chunk 上D3 已提);让"很少被命中的过期 KB chunk"自动沉睡,反向触发治理团队复审。

4.4 接口改造点

  • workflow/nodes/knowledge/node.pyKnowledgeRetrievalNode.execute() 中注入 MemoryService:当节点配置里 enable_memory=true 时,先调 memory_service.recall(user_id, query) 拿记忆,再传给 Retriever.retrieve(query, ctx={memory: ...})
  • 新增 MemoryAwareRetriever(Retriever) 实现,包装任一底层 Retriever。
  • Workflow Node 配置 KnowledgeRetrievalNodeConfig 增加 memory_strategy: Literal["off", "context_only", "rewrite_query", "merge_chunks"]
  • Prompt 模板新增 <MEMORY> 段落。

4.5 工作量估计

  • 单向memory → retrieval3 人周
  • 双向retrieval 结果反写 memory2 人周(大部分代码已在 core/memory 存在)
  • 遗忘对齐 + 治理触发:2 人周(与 D3 共享)
  • 合计:~7 人周

4.6 风险与依赖

  • ⚠️ 隐私边界:长期记忆是 per-userKB 是 per-tenant;混淆会导致跨用户泄露。设计时必须 user_id 级强隔离code review 重点。
  • ⚠️ Prompt 长度膨胀:记忆 + KB 双源;如果未做摘要,长对话场景 token 成本翻倍;必须配合记忆摘要(已有 summary4memory.md)。
  • ⛓️ 依赖 [S3-T1]Retriever / Reranker 协议;强依赖 [S2-T6] 的 E2E 时序图明确两条链路的衔接点。

D5. 评估与反馈闭环(用户反馈 → Reranker 微调)

5.1 触发场景

  • 答案错了 / 引用不对,用户点👎 — 当前数据 进了日志,没人消费
  • 同一 query 在不同时段表现波动 → 需要离线 A/B 评估。
  • 业务方问"再加一个 KB 之后效果到底变好还是变差?" — 没有可量化的回归指标。
  • README 给的 F1/BLEU/J 在论文中实现过,但仓内没有这套代码,每次评估靠手工。

5.2 技术方案(双轨:评估在线化 + 反馈学习)

5.2.1 评估轨:离线 / 在线 / CI 三层
层级 内容 工具
离线评估集 每 KB 维护一个 eval_cases.jsonl{query, ideal_chunks, ideal_answer, hard_negatives};增量构建(每周从用户问句 + 答疑团队补充) DSL + Excel 导入工具
在线指标 Hit@K / MRR / nDCG / Citation Coverage / Hallucination Rate / Latency P50/P95;通过 OpenTelemetry 埋点写入 Prometheus OTel + Prometheus + Grafana
CI 评估 每个 PR 跑核心 KB 的回归集;指标低于 baseline n% 时阻塞合并 RAGAS开源+ 自研判分 prompt
5.2.2 反馈学习轨:从👍/👎到 Reranker 微调
用户反馈(👍/👎/edit
   ↓ event log
事件清洗(同一 query 多个 chunk 评分)
   ↓
形成 (query, positive_chunk, negative_chunk) 三元组
   ↓
  ├─ 短链:在线 PairWise 调整 BM25/dense 权重D2 路由器配置)
  └─ 长链:周/月一次离线训练 Cross-Encoder reranker基础模型用 bge-reranker-base 蒸馏)
       ↓
   新 reranker 走 D6 灰度框架上线
       ↓
   评估轨自动验证收益

5.3 接口改造点

  • 新增 EvaluationProtocol{evaluate(query, retrieved, generated, ground_truth) -> Metrics};在 OpenTelemetry trace 末尾自动落 Prometheus。
  • RedBearRerank 改造:接入 LocalCrossEncoderRerank(Reranker) 子类,加载本地 ONNX/TorchScript 模型;可与 Jina/DashScope 并存于工厂。
  • 反馈采集:复用 core/memory 的事件总线(如有)或新建 feedback_event 表;前端组件加 thumbscitation 点击行为也作为隐式反馈。
  • 训练 pipeline 独立仓 / 独立服务产物ONNX通过模型注册表用现有 ModelConfig 表扩展即可)滚动上线。

5.4 工作量估计

  • 评估指标埋点 + Grafana 看板:1.5 人周
  • 离线评估集 + RAGAS CI 集成:2 人周
  • 反馈采集 + 三元组清洗:1 人周
  • Cross-Encoder 蒸馏训练 pipeline3 人周(含数据扩充、训练脚本、产出 ONNX
  • 合计:~7.5 人周

5.5 风险与依赖

  • ⚠️ 冷启动:刚上线时反馈数据 < 1k 不足以训练;必须先用大模型 LLM-as-Judge 合成训练数据(现成 prompt 在 prompts/generator.py 可借鉴)。
  • ⚠️ 反馈污染:恶意 / 误点;需要置信度过滤(同一 user 短时多次相反反馈丢弃)。
  • ⛓️ 依赖 [S3-T1] 的可观测性方案,否则数据采不到。
  • ⛓️ 依赖 D2 的语义路由,否则没有"权重可调"的注入点。

D6. 自适应检索路由Adaptive Retrieval Routing

这是 D2 中"语义路由"的工程化升级版,独立列出是因为它会统一所有检索能力dense / sparse / graph / memory / web是 RAG 系统的中央调度器。

6.1 触发场景

  • 同一用户在同一 session 内:第 1 个问题需要走 KB第 2 个问题需要走 Web 搜索("今天的新闻"),第 3 个问题需要 Graph 推理 — 当前必须用户手动切模式。
  • "你刚才推荐的方案做不了"(指代消解)→ 需要先走对话记忆,再决定是否检索;当前都是无脑全检索。

6.2 技术方案

决策类型 输入 输出
是否需要检索 query + 短期记忆 bool need_retrieval
检索来源 query 类型 [KB_id, Graph_flag, Web_flag, Memory_flag]
检索策略 query 类型 + 用户场景 (retriever_name, top_k, fusion_weights, rerank_id)
兜底 第一次检索结果差 触发 query rewriting + 二次检索

实现:

  • 路由器 = 小型 LLM如 1.5B3B+ rule-based fallback输出结构化 JSON。
  • 训练数据来源D5 的反馈数据 + 标注团队人工标 1k 条。
  • 推理用 vllm 或 SGLang 自托管P95 延迟控制在 50ms。

6.3 接口改造点

  • RetrieveType enum 改造成 strategy与 D2 共享的 RouterRetrieverworkflow 层调用方不再选模式,而是传入 query。
  • 新增 RoutingPolicy 配置实体:可被工作空间管理员通过 UI 编辑(默认策略 + 灰度策略)。
  • 与 D5 形成闭环:评估指标决定路由器升级时机。

6.4 工作量估计

  • 规则+LLM 路由器最小可用:2 人周
  • 完整训练 / 灰度 / 配置 UI5 人周
  • 合计:~7 人周

6.5 风险与依赖

  • ⚠️ 路由器变成单点:必须有 fallback 到当前默认策略。
  • ⛓️ 强依赖 D2 + D5;不建议独立做。

2. Quick PoC 路径(≤ 1 周可见效果)

PoC-ARRF 多路融合检索(属 D2

目标:现网 KB 在不重建索引、不改 schema 的前提下,加入 BM25 + dense 各自独立 top-50 → RRF 融合 → 同一接口返回。1 周内拿到 A/B 数据。

改动范围(最小集):

  • rag/nlp/search.py:Dealer.search() 拆为两步:先单独跑 BM25emb_mdl=None),再单独跑 dense无 BM25合并时用 RRF。
  • 增加 feature flag RETRIEVAL_FUSION_MODE = {"weighted", "rrf"},默认 weighted不影响现网

预期收益:在长尾 lookup query 上 Hit@10 +510pp参考社区数据。无负向风险因为 weighted 路径保留。

PoC 代码草案(伪代码,约 30 行;正式实现需走完整 PR + 评估):

# rag/retrieval/rrf.py新增
def rrf_merge(rankings: list[list[ScoredChunk]], k: int = 60, top_k: int = 20) -> list[ScoredChunk]:
    """Reciprocal Rank Fusion: score = Σ 1/(k + rank_i)。
    rankings: 多个独立排序结果,每个内部按相关度降序。
    """
    score_map: dict[str, float] = {}
    chunk_map: dict[str, ScoredChunk] = {}
    for ranking in rankings:
        for rank, chunk in enumerate(ranking, start=1):
            cid = chunk.metadata["doc_id"]
            score_map[cid] = score_map.get(cid, 0.0) + 1.0 / (k + rank)
            chunk_map[cid] = chunk  # 保留首次见到的对象
    merged = sorted(chunk_map.values(),
                    key=lambda c: score_map[c.metadata["doc_id"]],
                    reverse=True)
    for c in merged:
        c.metadata["score_rrf"] = score_map[c.metadata["doc_id"]]
    return merged[:top_k]


# 调用侧rag/nlp/search.py:Dealer.search 增量改造)
if os.getenv("RETRIEVAL_FUSION_MODE", "weighted") == "rrf":
    bm25_hits = self._search_bm25_only(req, ...)
    dense_hits = self._search_dense_only(req, ...)
    return rrf_merge([bm25_hits, dense_hits], k=60, top_k=req.get("topk", 20))
# else: 走现有 weighted 路径

PoC-BMemory-Augmented Query Rewrite属 D4

目标:把 core/memory.read_services 已有的"长期记忆召回"接到 KnowledgeRetrievalNode 之前,做 query 改写。1 周内对 1 个内部 demo 应用上线。

改动范围

  • KnowledgeRetrievalNode.execute() 第一行加 5 行:拿 user_id已有 user_ids),调 memory_service.get_user_summary(user_id),把 summary 拼到 query 前。
  • 新增 feature flag MEMORY_AUGMENT_RETRIEVAL = false(默认关闭)。
  • 不改 prompt不改 schema不改 ES。

预期收益:在多轮对话场景下,第 N 轮 query 的指代消解正确率提升无回归风险flag 默认关)。

# workflow/nodes/knowledge/node.py:KnowledgeRetrievalNode.execute() 头部增量
if os.getenv("MEMORY_AUGMENT_RETRIEVAL") == "true" and user_ids:
    from app.services.user_memory_service import get_user_summary
    summary = get_user_summary(user_ids[0], ttl_sec=3600)  # 已存在 / 类似函数
    if summary:
        query = f"[用户背景: {summary}]\n{query}"

注意:上述两段代码均为 PoC 草案真实落地需要1完整单测2评估对比3feature flag 走配置中心4权限审查D4 涉及隐私)。


3. 优先级矩阵(用户价值 × 实现成本 × 风险)

评分 155 最高 / 5 最低)。建议落地顺序按"用户价值高 + 成本低 + 风险低"加权。

方向 用户价值 实现成本 (越低越好) 风险 (越低越好) 综合分V × 1/√(C×R) 建议落地阶段
D2-PoC RRF 融合 4 5 (0.5 人周) 5 (无回归) 8.0 立即Sprint-3 内)
D4-PoC Memory Rewrite 4 5 (0.5 人周) 4 (隐私) 7.2 立即Sprint-3 内)
D5 评估埋点 + Grafana 5 4 (1.5 人周) 5 5.6 短期1 月)
D5 RAGAS CI 4 4 5 4.5 短期1 月)
D2 SPLADE 接入 4 3 (2 人周) 4 (索引重建) 3.7 短期1 月)
D4 完整双向集成 5 3 (5 人周) 3 (隐私 / token) 3.5 中期2 月)
D5 Reranker 微调 4 3 (3 人周) 3 (冷启动) 2.7 中期2 月)
D6 自适应路由 4 2 (5 人周) 3 2.3 中期3 月)
D1 多模态 L1基线 3 4 (1.5 人周) 4 3.0 短期1 月)
D1 多模态 L2 跨模态 5 2 (3 人周) 3 (GPU) 2.5 中期3 月)
D3 增量图演化 4 2 (3 人周) 2 (实体消歧) 2.0 中长期34 月)
D3 Neo4j 双引擎 3 2 (3 人周) 2 (运维) 1.5 长期46 月)
D1 多模态 L3 视听统一 3 1 (4 人周) 2 (GPU + diarization) 1.1 长期6 月+
D3 自动本体演化 2 2 2 1.0 长期 (按需)

维度说明

  • 用户价值高优先级业务场景toB 客户)调研访谈得分。
  • 实现成本人周折算1 人周=1 分6 人周=2 分10 人周=1 分)。
  • 风险:含技术风险 + 数据迁移 + 上线回滚 + 安全 / 隐私。
  • 综合分用 V / sqrt(C×R) 倒数化,仅作排序参考,不取代产品/架构会判断。

4. 落地路线图Roadmap

gantt
    title MemoryBear RAG 后续迭代 路线图
    dateFormat  YYYY-MM-DD
    axisFormat  %m/%d
    section Sprint-3 (现 Sprint)
    PoC-A RRF 融合 (D2)            :a1, 2026-06-02, 5d
    PoC-B Memory Rewrite (D4)      :a2, 2026-06-02, 5d
    section 短期 (1 个月)
    评估埋点 + Grafana (D5)         :s1, 2026-06-09, 7d
    RAGAS CI (D5)                  :s2, after s1, 7d
    SPLADE 接入 (D2)                :s3, after s1, 10d
    多模态 L1 基线 (D1)            :s4, 2026-06-09, 7d
    section 中期 (2-3 个月)
    Memory ↔ RAG 双向集成 (D4)     :m1, after s2, 25d
    Reranker 微调 pipeline (D5)    :m2, after s3, 15d
    自适应路由 (D6)                 :m3, after m1, 25d
    多模态 L2 跨模态 (D1)          :m4, after s4, 15d
    section 长期 (3-6 个月)
    增量图演化 (D3)                 :l1, after m1, 20d
    Neo4j 双引擎 (D3)              :l2, after l1, 15d
    多模态 L3 视听统一 (D1)        :l3, after m4, 20d
    本体演化 (D3)                   :l4, after l2, 10d

所有阶段分别绑定一组 OKR + 评估指标D5 提供数据),未达指标停止下阶段。


5. 风险与依赖总表

类型 风险 缓解策略
架构 [S3-T1] 接口抽象未落地,本路线图全部方向受阻 Sprint-3 内先把 Retriever / Reranker / Embedder / Generator 4 个 Protocol 落地([S3-T1] 必交付项)
数据 索引重建D1/D2/D3导致服务不可用 灰度索引切换工具:双写期 + 流量按租户灰度 + 一键回滚
隐私 D4 跨用户记忆泄露 user_id 级强隔离 + 单元测试覆盖 + 上线前安全 review
资源 D1/D6 引入 GPU 依赖 优先走托管 API 跑通 PoC自托管列入 long-term需要预算评审
治理 D5 评估集质量低 → CI 阻塞误判 评估集双人复核 + 周复盘 + 例外白名单
运维 D3 Neo4j 双引擎一致性 定位 Neo4j 为算法只读,从 ES 异步同步;不双写
业务 路线图与产品 PRD 脱节 与 [@产品需求分析师] 在 Sprint-3 启动前对齐 1 次

6. 与 [S3-T1] / [S3-T3] 的对齐清单

  • 每个方向都标注了"接口改造点",所有改造均落到 [S3-T1] 提议的 Retriever / Reranker / Embedder / Generator / GraphStore / Loader Protocol不新增其它接口。
  • 所有方向有"工作量、风险、依赖"三件套,可被 [S3-T3] 终审按统一模板核对。
  • Quick PoC 已覆盖 D2 与 D4 各 1 条(≥ 2 条要求达成)。
  • 优先级建议已按"用户价值 × 实现成本 × 风险"三维评分给出,并配有路线图甘特图。
  • 多模态、混合搜索、KG 增强、对话记忆、评估闭环均覆盖5/5额外补充自适应路由作为联动方向。

— END —