LAMBDA_RAG_PLAN.md 25 KB

LambdaRAG: 统一知识检索方案

Context

综合 RAG v1 (BM25)、RAG v2 (Hybrid)、RAG Fusion (Multi-query)、Wiki (知识图谱) 四种方案的优势,结合 lambdagentpaas 平台的三层抽象 (Skill → Pattern → Orchestration) 和 Lambda DSL,设计一个统一的自适应知识检索系统。

核心理念:不同问题用不同策略,由 Orchestrator 智能路由,利用 entity 关系图谱增强跨文档推理。


一、架构总览:三层抽象

┌─────────────────────────────────────────────────────────┐
│  Layer 3: Orchestration (编排层)                         │
│                                                         │
│  QueryClassifier >> Route({                             │
│    fact     → Pipeline(keyword_search),                 │
│    compare  → Pipeline(graph_expand >> fusion_search),  │
│    relation → Pipeline(graph_walk >> wiki_query),       │
│    synthesis→ fan_out_merge(wiki, fusion, graph),       │
│    temporal → Pipeline(time_filter >> keyword_search),  │
│  }) >> KnowledgeFeedback                                │
│                                                         │
├─────────────────────────────────────────────────────────┤
│  Layer 2: Pattern (组合模式层)                           │
│                                                         │
│  Pipeline:       skill1 >> skill2 >> skill3             │
│  fan_out_merge:  Par(s1, s2, s3) >> merge               │
│  map_reduce:     split >> Par(process...) >> reduce     │
│  review:         generate >> check >> (retry or pass)   │
│  graph_expand:   entity_extract >> bfs_walk >> expand   │
│                                                         │
├─────────────────────────────────────────────────────────┤
│  Layer 1: Skill (原子能力层)                             │
│                                                         │
│  bm25_search      向量检索 embedding_search             │
│  query_expand      rerank        graph_walk             │
│  wiki_page_read    entity_extract  relation_lookup      │
│  time_filter       citation_check  fact_extract         │
│  answer_generate   merge_results   cost_track           │
│                                                         │
└─────────────────────────────────────────────────────────┘

二、Layer 1: Skill 原子能力

每个 Skill 是一个独立的 Lambda Term (Lam 或 Tool),单一职责。

检索类 Skill

Skill 类型 Lambda 输入→输出 成本
bm25_search Tool λq. BM25(q, top_k) str → [chunk] 0, <10ms
embedding_search Tool λq. cosine(embed(q), vectors) str → [chunk] $0.0001, ~100ms
wiki_page_read Tool λq. read_wiki_pages(q) str → [page_content] 0, <50ms
relation_lookup Tool λe. graph.neighbors(e) entity → [relation] 0, <10ms

处理类 Skill

Skill 类型 Lambda 说明
query_expand Lam λq. LLM(q) → [q1..qN] 用本地 vLLM 扩展查询
entity_extract Lam λq. LLM(q) → [entities] 从查询中提取实体
rerank Tool λ(q, docs). API(q, docs) → [ranked_docs] SiliconFlow rerank API
time_filter Tool λ(q, docs). filter(docs, date) 按时效性过滤
rrf_merge Tool λ([list1, list2..]) → [merged] RRF 倒数排名融合
merge_results Tool λ(wiki_r, rag_r) → combined 合并多源结果

生成类 Skill

Skill 类型 Lambda 说明
answer_generate Lam λ(q, context). LLM → answer 基于上下文生成回答
citation_check Lam λ(answer, sources). LLM → verdict 核查引用准确性
fact_extract Lam λanswer. LLM → [facts, relations] 从回答中提取新知识

图谱类 Skill

Skill 类型 Lambda 说明
graph_walk Tool λ(entities, n_hops). BFS → [entities, relations, paths] N跳图遍历
graph_expand Tool λ(query, entities). query + related_terms 用图谱扩展查询范围

三、Layer 2: Pattern 组合模式

Pattern 1: keyword_search (快速精确)

λq. bm25_search(q) >> answer_generate(q, _)

适用: fact 类问题 ("2019年船员注册人数")

Pattern 2: hybrid_search (语义增强)

λq. Par(bm25_search(q), embedding_search(q)) >> rrf_merge >> rerank(q, _)

适用: 需要语义理解但单一查询够用的问题

Pattern 3: fusion_search (多视角)

λq. query_expand(q) → [q1..qN]
     >> map(qi → hybrid_search(qi))
     >> rrf_merge
     >> rerank(q, _)

适用: 复杂对比类问题,表达方式影响检索结果

Pattern 4: graph_retrieval (关系增强)

λq. entity_extract(q) → [entities]
     >> graph_walk(entities, 2) → [expanded_entities, relations]
     >> graph_expand(q, expanded_entities) → expanded_query
     >> hybrid_search(expanded_query)

适用: 关系类问题 ("海事局的上级部门是谁")

Pattern 5: wiki_deep (编译知识)

λq. wiki_page_read(q) → [wiki_pages]
     >> If(sufficient(wiki_pages),
           then_= answer_generate(q, wiki_pages),
           else_= gap_fill(q, wiki_pages))

其中 gap_fill:

λ(q, wiki). missing_topics(q, wiki)
     >> fusion_search(missing)
     >> merge_results(wiki, fusion)

适用: 综合性问题,wiki 已有部分知识但不完整

Pattern 6: synthesis (全量综合)

λq. fan_out_merge(
       wiki_deep(q),
       graph_retrieval(q),
       fusion_search(q)
     ) >> merge_deduplicate >> review(citation_check)

适用: 跨文档综合分析 ("总结海事局近年政策方向")

Pattern 7: temporal_search (时效性)

λq. extract_time_range(q)
     >> bm25_search(q)
     >> time_filter(results, time_range)
     >> answer_generate

适用: "琼州海峡定线制最新版本何时施行"


四、Layer 3: Orchestration 编排

4.1 查询分类器 (智能路由)

# 规则快速分类 (零成本)
def fast_classify(query):
    if re.search(r'\d{4}年.*多少|数量|人数|统计', query): return "fact"
    if re.search(r'异同|比较|区别|对比|不同', query): return "compare"
    if re.search(r'关系|隶属|上级|下级|依据|谁.*管', query): return "relation"
    if re.search(r'最新|修订|变化|趋势|演变', query): return "temporal"
    if re.search(r'总结|综合|梳理|分析.*体系|框架', query): return "synthesis"
    return None  # 无法快速判断

# LLM 精确分类 (有成本但准确)
classifier_lam = Lam("classify", """
分类用户问题为以下之一:
- fact: 事实查找 (具体数字/日期/名称/条款)
- compare: 对比分析 (两个以上事物的异同)
- relation: 关系查询 (实体间的关系、层级、依据)
- synthesis: 综合分析 (跨文档总结、体系梳理)
- temporal: 时效相关 (最新版本、变化趋势、修订历史)

同时提取问题中的关键实体。

输出JSON: {"type":"...", "entities":["..."], "confidence": 0.9}
""")

# 自适应分类: 先试规则,不确定时用 LLM
adaptive_classifier = If(
    cond=Tool("try_fast", fast_classify),  # 返回非 None 表示成功
    then_=Tool("identity", lambda x: x),   # 用快速结果
    else_=classifier_lam                    # 回退 LLM
)

4.2 问题类型 → 策略映射

问题类型 策略 (Pattern) 为什么 示例
fact keyword_search 精确匹配,快速,零成本 "2019年船员注册总数"
compare graph_expand >> fusion_search 图谱找到两个实体的关联文档,多视角检索覆盖两侧 "海上交通安全法与水污染防治法异同"
relation graph_walk >> wiki_query 图谱直接回答关系,wiki 补充细节 "海事局的职责和上级部门"
synthesis fan_out_merge(wiki, fusion, graph) 三路并行获取最大信息量 "总结船员管理法规体系"
temporal time_filter >> keyword_search 时间过滤确保获取最新版本 "琼州海峡定线制最新规定"

4.3 完整编排 Lambda 表达式

unified_retrieval = Compose(
    # Step 0: 分类
    adaptive_classifier,
    
    # Step 1: 路由到对应策略
    Route(
        classifier=identity,
        routes={
            "fact":      Compose(bm25_search, answer_generate),
            
            "compare":   Compose(
                            entity_extract,
                            graph_walk,
                            graph_expand,
                            fusion_search,
                            Guard(answer_generate, citation_check, retry=1)
                         ),
            
            "relation":  Compose(
                            entity_extract,
                            graph_walk,
                            Par(wiki_page_read, relation_lookup),
                            merge_results,
                            answer_generate
                         ),
            
            "synthesis": Compose(
                            Par(
                                Compose(wiki_page_read, answer_generate),
                                Compose(entity_extract, graph_walk, fusion_search),
                            ),
                            merge_results,
                            Guard(answer_generate, citation_check, retry=1)
                         ),
            
            "temporal":  Compose(
                            time_filter,
                            bm25_search,
                            answer_generate
                         ),
        },
        default=Compose(fusion_search, answer_generate),  # 兜底
    ),
    
    # Step 2: 知识反馈 (仅多源回答触发)
    If(
        cond=Tool("has_multi_source", lambda r: r.count("[来源:") >= 2),
        then_=Compose(fact_extract, update_wiki, update_relations),
        else_=identity
    ),
)

4.4 效果类型注解

fact:      io                              (纯 BM25)
compare:   llm · io · (io ∥ io) · llm     (classify + graph + par_search + generate)
relation:  llm · io · (io ∥ io) · llm     (classify + graph + par(wiki,relation) + generate)
synthesis: llm · ((io · llm) ∥ (llm · io · io)) · llm  (最复杂)
temporal:  io · io · llm                   (filter + search + generate)

五、Entity 关系图谱核心设计

5.1 数据结构

class EntityGraph:
    # 邻接表: entity → [(relation_type, target, source_doc, description)]
    adjacency: Dict[str, List[Tuple]]
    # 反向邻接: entity → [(relation_type, source_entity, source_doc)]
    reverse: Dict[str, List[Tuple]]
    # 实体元数据: entity → {type, refs_count, wiki_page_path}
    entities: Dict[str, Dict]
    
    def walk(self, seeds, max_hops=2, max_nodes=20):
        """BFS N-hop 遍历,返回子图"""
    
    def find_entities(self, text):
        """从文本中模糊匹配已知实体"""
    
    def shortest_path(self, entity_a, entity_b):
        """两实体间最短关系路径"""
    
    def subgraph(self, entities):
        """提取包含指定实体的子图"""

5.2 关系增强检索流程

Q: "海上交通安全法与水污染防治法在船舶管理方面有何异同?"

Step 1: entity_extract → ["海上交通安全法", "水污染防治法", "船舶管理"]

Step 2: graph_walk(entities, hops=2)
  海上交通安全法 --规定--> 船舶航行安全
  海上交通安全法 --发布机构--> 全国人大常委会
  海上交通安全法 --涉及--> 船员管理
  水污染防治法 --规定--> 船舶排放标准
  水污染防治法 --发布机构--> 全国人大常委会
  水污染防治法 --涉及--> 海洋环境保护
  船舶管理 --相关法规--> 防治船舶污染海洋环境管理条例
  
Step 3: graph_expand → 扩展查询增加:
  "船舶航行安全", "船舶排放标准", "船员管理", "海洋环境保护"

Step 4: fusion_search (原始query + 扩展terms)
  → 现在能检索到法律原文,而不仅是行政检查清单

Step 5: answer_generate with relations context
  → 回答中自然包含关系链信息

5.3 关系在回答中的作用

Prompt 增强:

## 实体关系 (来自知识图谱)
- 海上交通安全法 --发布机构--> 全国人大常委会
- 海上交通安全法 --规定--> 船舶航行安全
- 水污染防治法 --发布机构--> 全国人大常委会  
- 水污染防治法 --规定--> 船舶排放标准
- 两法 --共同涉及--> 船舶管理

## 检索到的文档片段
[doc1: 海上交通安全法原文] ...
[doc2: 水污染防治法原文] ...

## 问题
海上交通安全法与水污染防治法在船舶管理方面有何异同?

六、新增/修改文件清单

新增文件

文件 位置 说明
graph_engine.py qaagent67/scripts/ EntityGraph 类 + graph_walk/expand
search_engine_v2.py qaagent67/scripts/ 混合检索 (BM25+Embedding+Rerank)
search_engine_fusion.py qaagent67/scripts/ RAG Fusion (Multi-query)
search_unified.py qaagent67/scripts/ 统一入口: 分类→路由→策略→反馈
build_vector_index.py qaagent67/scripts/ 向量索引构建

修改文件

文件 改动
agent-config.yml 新增 retrieval 配置段
qademo/app.py import 改为 from search_unified import search

不动的文件

文件 说明
search_engine.py BM25 v1,被 v2 内部调用
wiki_compile.py Wiki 编译,已有关系提取
rebuild_index.py 旧索引构建,保留参考

七、agent-config.yml 配置

# 统一检索配置
retrieval:
  mode: unified

  # Layer 1: Skills
  skills:
    bm25:
      enabled: true
      topK: 10
    embedding:
      enabled: true
      model: bge-m3
      backend: npu                        # 本地 NPU 推理 (免费)
      baseUrl: http://127.0.0.1:11435/api/embed
      batchSize: 32
      dimensions: 1024
    rerank:
      enabled: true
      backend: vllm                       # 用本地 vLLM qwen2.5-32b 做 rerank
      baseUrl: http://127.0.0.1:8000/v1
    graph:
      enabled: true
      relationsFile: wiki/relations.json
      maxHops: 2
      maxExpand: 20
    wiki:
      enabled: true
      dir: wiki/

  # Layer 2: Patterns
  patterns:
    keyword_search:
      skills: [bm25]
    hybrid_search:
      skills: [bm25, embedding]
      merge: rrf
      rrfK: 60
    fusion_search:
      skills: [bm25, embedding]
      merge: rrf
      queryExpansion: true
      expansionCount: 4
    graph_retrieval:
      skills: [graph, hybrid_search]
    wiki_deep:
      skills: [wiki, hybrid_search]
      gapFill: true

  # Layer 3: Orchestration
  orchestration:
    classifier:
      fastClassify: true          # 规则优先
      llmFallback: true           # 规则不确定时用 LLM
    routing:
      fact: keyword_search
      compare: [graph_retrieval, fusion_search]
      relation: [graph_retrieval, wiki_deep]
      synthesis: [wiki_deep, fusion_search, graph_retrieval]
      temporal: [keyword_search]
      default: hybrid_search
    feedback:
      enabled: true
      minSources: 2
    cost:
      budgetPerQuery: 0.05
      fallback: keyword_search

八、实施顺序

阶段 内容 依赖
1 graph_engine.py — 实体关系图谱 relations.json (Wiki 编译产出)
2 search_engine_v2.py — 混合检索 SiliconFlow API + numpy
3 build_vector_index.py — 构建向量索引 search_engine_v2
4 search_engine_fusion.py — RAG Fusion search_engine_v2 + vLLM
5 search_unified.py — 统一编排 以上全部
6 app.py 改 1 行 import search_unified

每阶段独立可用,逐层叠加。


九、预期效果

问题类型 当前 (BM25) 统一方案 提升原因
"2019年船员注册人数" ✅ 准确 ✅ 准确 (fact→BM25快速路径) 不退化
"海上交通安全法与水污染防治法异同" ❌ 检索到行政清单 ✅ 检索到法律原文 graph_expand + fusion
"海事局的职责" ⚠️ 部分 ✅ 完整 (含上下级关系) relation_lookup + wiki
"船员管理法规体系梳理" ❌ 碎片化 ✅ 体系化 synthesis 三路并行
"琼州海峡定线制最新版本" ⚠️ 新旧混淆 ✅ 最新版 temporal_filter

十、自增强学习机制 (越用越好)

核心理念:每次用户查询都是一次学习机会,系统从使用中积累知识、优化检索、改进路由。

10.1 四维自增强闭环

用户查询 → 检索 → LLM 回答 → 反馈信号
                                 │
         ┌───────────────────────┼───────────────────────┐
         ↓                       ↓                       ↓
    知识积累                  检索优化                 路由优化
         │                       │                       │
  ① Wiki 更新              ③ Query-Doc 对           ⑤ 路由权重
  ② 关系图谱扩展           ④ 同义词表               ⑥ 策略成功率
    新实体发现                 BM25 Boost               分类校准

10.2 维度一:知识积累 (Wiki Feedback Loop)

每次多源回答自动提取新知识写回 Wiki:

# Lambda: If(has_multi_source, Compose(fact_extract, update_wiki, update_graph), identity)

def knowledge_feedback(query, answer, sources):
    # 触发条件: 回答引用了 2+ 来源
    if answer.count("[来源:") < 2:
        return  # 跳过单源简单回答
    
    # ① 新实体发现: 回答中出现但图谱中不存在的实体
    new_entities = extract_entities(answer) - graph.known_entities
    # → 写入 wiki/entities/
    
    # ② 新关系发现: 从回答中提取实体间关系
    # "海上交通安全法由全国人大常委会制定" 
    #   → (海上交通安全法, 制定机构, 全国人大常委会)
    new_relations = extract_relations(answer)
    # → 追加 relations.json + 更新 entity 页面
    
    # ③ 跨文档综合: 多源综合的新知识
    synthesis = summarize_cross_doc(query, answer, sources)
    # → 写入 wiki/analyses/{query_hash}.md

效果: 图谱越丰富 → graph_walk 覆盖越广 → 检索越准 → 回答越好 → 产生更多新知识

10.3 维度二:检索优化 (Relevance Learning)

# 每次查询记录 query-doc 关联
query_log = {
    "query": "海上交通安全法与水污染防治法",
    "type": "compare",
    "strategy": "graph_retrieval",
    "top_docs": ["海上交通安全法.txt", "水污染防治法.txt"],
    "scores": [0.85, 0.82],
    "response_quality": "good",  # 可选: 用户反馈/LLM 自评
    "timestamp": "2026-04-06T13:00:00"
}

用途:

机制 说明 Lambda 表达
热门缓存 相同问题直接返回 If(in_cache, cache_hit, full_search)
同义词表 "异同"↔"区别"↔"对比" 从 query_expand 积累 扩展 BM25 tokenizer
BM25 Boost 高频 query-doc 对加权 修改 IDF 分数
失败记录 检索失败的 query 触发 Wiki 补充 异步 wiki_compile

10.4 维度三:路由优化 (Strategy Learning)

# 记录每种分类+策略的效果
routing_stats = {
    "fact → keyword_search":      {"total": 50, "success": 48, "avg_time": 0.5},
    "compare → graph_retrieval":  {"total": 20, "success": 18, "avg_time": 3.2},
    "compare → fusion_search":    {"total": 10, "success": 6,  "avg_time": 5.1},
}

# 动态调整路由权重
def adaptive_route(query_type):
    candidates = routing_stats.get_strategies(query_type)
    # 选成功率最高 + 耗时最短的策略
    return max(candidates, key=lambda s: s.success_rate * 0.7 + (1/s.avg_time) * 0.3)

效果: 系统自动发现哪种策略对哪类问题最有效,逐渐优化路由决策。

10.5 维度四:分类校准

# 当用户纠正或回答不满意时,记录分类错误
# 例: "琼州海峡定线制" 被分为 fact 但实际需要 temporal
correction_log = {
    "query": "琼州海峡定线制",
    "predicted_type": "fact",
    "correct_type": "temporal",  # 从回答质量推断
}

# 积累后: 更新规则分类器的模式
# re.search(r'定线制', q) → 'temporal' (新增规则)

10.6 存储结构

knowledge/maritime/
  feedback/
    query_log.jsonl           # 查询日志 (append-only, 每次追加)
    synonym_map.json          # 同义词映射 (从 query_expand 积累)
    query_cache.json          # 热门查询缓存 (LRU, max 1000)
    routing_stats.json        # 路由策略统计 (per type × strategy)
    classification_rules.json # 学习到的分类规则

10.7 增强触发时机

触发条件 动作 Lambda 表达
回答引用 2+ 来源 提取新知识→Wiki If(multi_source, feedback, identity)
每次查询完成 记录 query log Compose(search, log_query)
相同查询出现 3+ 次 加入热门缓存 Tool("cache_check")
检索结果为空 触发补充索引 If(empty_results, trigger_reindex, pass)
每 100 次查询 更新路由统计 Tool("update_routing_stats")
Wiki 编译完成 刷新图谱缓存 Tool("reload_graph")

10.8 实现优先级

机制 难度 影响 优先级
查询日志 (JSONL) 数据基础 P0
Wiki 新关系写回 图谱持续增长 P0
热门查询缓存 重复查询加速 P1
路由成功率统计 自动调优路由 P1
同义词表积累 扩展检索覆盖 P2
分类规则学习 减少 LLM 分类 P2
BM25 Boost 检索精度提升 P3

10.9 飞轮效应

更多查询 → 更多 query log → 更好的路由
         → 更多知识反馈 → 更丰富的 Wiki + 图谱
         → 更准的检索 → 更好的回答
         → 用户更多使用 → 更多查询 ...

十一、Wiki 编译优化项

11.1 时间规范化 (Temporal Normalization)

问题: 文档中大量相对时间表达("近年来"、"本规定自发布之日起施行"、"去年"),导致 temporal 类查询无法精确匹配。

方案: 在 wiki_compile.py 的 LLM prompt 中增加时间规范化指令:

## 时间规范化要求
文档中所有相对时间表述,必须根据文件的发布日期转换为绝对时间:
- "自发布之日起施行" → "自{文件发布年份}起施行"
- "近年来" → "{发布年份前2-3年}至{发布年份}"  
- "去年" → "{发布年份-1}年"
- "现行有效" → "截至{文件日期}现行有效"
- "经最新修订" → "经{具体修订年份}年修订"

文件名中通常包含施行日期,如:
  "2017年8月31日起施行--交通运输部关于..."
  → 发布日期=2017年,所有相对时间以此为基准

实现:

  1. 从文件名中提取日期(正则 \d{4}年\d+月\d+日
  2. 将日期注入 prompt:文件发布日期: {date}
  3. LLM 在摘要中将所有相对时间转为绝对时间

影响: temporal 类查询准确率预计从 82% → 92%+

11.2 Wiki 质量提升路径

优化 效果 依赖
时间规范化 temporal 准确率 +10% 修改 prompt
换更强模型重编译 摘要质量、关系准确率全面提升 72B 模型或 API
关系质量过滤 去除泛化关系(如"实行社会主义制度") 规则过滤
实体去重/合并 "XX海事局"合并为具体名称 后处理脚本

十二、验证方式

  1. 用之前的 5 个标准问题做 A/B 对比
  2. search_unified.py 独立测试模式: 输出分类结果 + 选中策略 + 检索结果
  3. Web 页面显示: 问题分类标签 + 使用的策略 + 耗时分解
  4. 降级测试: 关闭各组件验证 fallback 链
  5. 自增强验证: 连续问 20 个问题,观察图谱增长和缓存命中率