Ch 41 R/V/G/D 四引擎 RAG 检索¶
面包屑
本书主页 › Part VII Data+AI 转型 › Ch 41
项目第 4 年 · Data+AI转型期——四引擎RAG
本章你将学到¶
- 四引擎 RAG:R(关系精确)/ V(向量语义)/ G(图遍历)/ D(动态 few-shot)——各引擎的访问模式、目标表与并行/串行协作
- Reranker 四阶段重排:术语绑定提升 → QU 信号 → 动态列裁剪 → Join 路径简化
- 术语绑定强路由:业务术语全链路传播(检索→重排→Prompt→护栏→自愈)
- Corrective-RAG 回退与重排(含 Self-RAG / CRAG 理论引用)
- Token 预算分配与上下文压缩
- Naive→Advanced→Modular RAG 演进谱系与当前实现可改进之处
41.1 四引擎 RAG:R/V/G/D¶
Ch 40 把业务知识编码为语义资产发布到了检索引擎,这一章讲 AI 怎么检索这些资产。
我在专利数据领域做过类似的事。专利检索系统得理解同义词——用户搜"锂电池",系统要知道这东西也属于"二次电池""储能器件"。当时我们维护了一套专利术语词典,把同义词、上下位词编码成机器可读的映射,倒排索引负责精确命中。但光精确不够——用户问"和储能相关的专利",需要语义相似度;问"这个分类下有哪些子类",需要层级遍历。最后我们搞了个"精确匹配 + 语义召回 + 层级遍历"三路检索再融合。
Agentic BI 的四引擎 RAG 沿用了这个思路,但检索对象从专利文档变成了结构化语义资产(表/列/指标/join/术语),还多了一种"经验复用"(D 引擎),复杂度也上了一个量级。
为什么需要四引擎而非单一向量检索¶
通用 RAG(如文档问答)检索的是文本 chunk——一段段话,用向量相似度召回完事。但 NL2SQL 检索的是结构化元数据——表定义、列属性、指标公式、join 规则、术语映射、业务规则。这些元数据的访问模式天然不同:
| 检索需求 | 例子 | 适合的引擎 | 为什么单一向量不够 |
|---|---|---|---|
| 精确匹配 | "GMV 是什么" → 查术语定义 | R(关系查询,精确) | V 擅长"语义相似"但不擅长"精确匹配"——问"GMV"可能返回"销售额"而非精确的 GMV 定义 |
| 语义模糊 | "和销售相关的表" → 向量相似度 | V(pgvector,模糊) | R 只能精确匹配,"和销售相关的表"没有精确关键词可查 |
| 关系推理 | "fact_transaction 能 join 到哪些表" | G(图遍历,关系) | V 不擅长"关系推理"——"哪些表能 join"需要图遍历而非相似度 |
| 经验复用 | "上次类似查询怎么写的" | D(动态 few-shot) | 以上三引擎都不提供"历史成功案例"参考 |
四引擎互补:R 管精确性,V 管灵活性,G 管关系推理,D 管经验复用。单一引擎没法同时优化这四种模式。
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TB
QUERY@{ icon: "codicon:comment", form: "rounded", label: "用户问题", pos: "b", h: 40 } --> PARALLEL[并行检索]
PARALLEL --> R@{ icon: "codicon:database", form: "rounded", label: "Engine R 关系精确<br/>结构化查询语义资产<br/>表/列/指标精确匹配", pos: "b", h: 40 }
PARALLEL --> V@{ icon: "codicon:search", form: "rounded", label: "Engine V 向量语义<br/>pgvector 向量相似度<br/>模糊语义匹配", pos: "b", h: 40 }
PARALLEL --> D@{ icon: "codicon:references", form: "rounded", label: "Engine D 动态 few-shot<br/>历史问答→SQL 示例<br/>自学习积累", pos: "b", h: 40 }
R --> MERGE[结果合并+术语绑定]
V --> MERGE
D --> MERGE
MERGE --> G@{ icon: "codicon:graph", form: "rounded", label: "Engine G 图遍历<br/>Apache AGE Cypher<br/>串行:依赖上游 asset_ids", pos: "b", h: 40 }
G --> CONTEXT@{ icon: "codicon:sparkle", form: "rounded", label: "检索上下文<br/>供 Reranker 重排+SQL 生成", pos: "b", h: 40 }
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
class QUERY bpInfo
class PARALLEL bpProcess
class R,V,D bpProcess
class MERGE bpProcess
class G bpProcess
class CONTEXT bpData
linkStyle default stroke:#697077,stroke-width:2px
图 41-1 四引擎 RAG:R/V/G/D 并行+串行协作
| 引擎 | 目标表 | 访问模式 | 解决的问题 | 技术 |
|---|---|---|---|---|
| R(关系精确) | semlayer.business_term |
LLM 提取的 search_terms 逐词 ILIKE | 精确匹配表/列/指标——"GMV"不能靠向量近似 | 关系型查询 |
| V(向量语义) | 7 张 *_embedding 表 |
pgvector cosine, top-k, threshold=0.65 | 模糊语义召回——"和销售相关的表" | pgvector |
| G(图遍历) | AGE ttd_governance 图 |
Cypher 遍历, depth=3 | 关系推理——join 路径、术语网络、治理边界 | Apache AGE + Cypher |
| D(动态 few-shot) | semlayer.dynamic_few_shot_cache |
cosine ≥ 0.95 + approved | 经验复用——从修复成功中自学习的 few-shot | 向量检索 + 自积累 |
表 41-1 四引擎职责深度解析
并行与串行的设计原理¶
Engine R+V+D 并行执行(asyncio.gather),Engine G 串行(依赖上游 asset_ids 做图遍历)。这是依赖关系决定的——图遍历得先知道有哪些 asset,才能沿它们的关系链往下走。无依赖的检索并行化降低延迟,有依赖的检索串行化保证正确性。
落到代码,检索编排是一个 async def 函数,用 asyncio.gather 并行拉起 R/V/D 三路检索,合并后再触发 G 图遍历:
# 示意:四引擎检索编排(R+V+D 并行,G 串行)
import asyncio
async def data_retrieval(state):
embedding = state["question_embedding"]
search_terms = from_query_understanding(state["qu"]) # 复用 QU 的 LLM 输出,零额外调用
# Engine R + V + D 并行(asyncio.gather)
term_hits, vector_results, dynamic_few_shots = await asyncio.gather(
exact_term_match(search_terms), # Engine R:ILIKE 精确匹配 business_term
pgvector_search(embedding, top_k=20, threshold=0.65), # Engine V:向量相似度
dynamic_few_shot_cache.search_similar(embedding), # Engine D:历史成功问答
)
# 合并:Engine D 的 few-shot 追加到 V 结果中(仅 approved + sim ≥ 0.95)
if dynamic_few_shots:
vector_results["few_shots"].extend(dynamic_few_shots)
# 构建术语绑定视图(核心创新,见 41.3)
term_bindings = build_term_bindings(term_hits, vector_results["terms"])
# Engine G 串行:依赖上游 asset_ids 做图遍历
all_asset_ids = collect_asset_ids(vector_results)
graph_context = await graph_traversal(all_asset_ids, depth=3) # Cypher 遍历 join 路径
return {
"retrieval_results": {**vector_results, "_term_bindings": term_bindings},
"graph_context": graph_context, # join 路径供 Ch 43 Steiner 树消费
}
引申:基石回扣——从被动血缘到主动语义资产
四引擎检索的对象是 Ch 40 发布的语义资产,而这些资产是 Ch 20 元数据管理的演进。Ch 20 的被动血缘(审计日志、batch_id 关联)只能"事后追溯数据怎么来的";语义资产则是"主动的、机器可读的业务知识"——它不只描述"表结构是什么",还描述"这个字段在业务上意味着什么、应该怎么用、和别的字段什么关系"。四引擎 RAG 正是消费这些主动语义资产的运行时机制。
41.2 Reranker 四阶段重排¶
四引擎并行检索回来的上下文不能直接塞进 Prompt——可能有几十张表、上百个列,既超 token 预算又稀释了关键信号。Reranker 对检索结果做检索后优化(post-retrieval),这是 Advanced RAG 的核心模块。
| 阶段 | 动作 | 理论依据 |
|---|---|---|
| ① 术语绑定提升 | 绑定列 boost 到 0.95,父表 +0.25,无绑定表 -0.10 | 强信号优先——术语绑定是高置信度信号 |
| ② QU 信号重排 | 匹配 metric/entity 加分,certified 资产加分 | 查询理解信号应影响检索排序 |
| ③ 动态列裁剪 | 保留 metric/dimension/filter 相关、PK/FK/时间列,裁剪无关列 | 上下文压缩——只保留相关列,省 token |
| ④ Join 路径简化 | 按 fanout 风险去重,优先 low risk | 避免高扇出 join 导致重复计数 |
表 41-2 Reranker 四阶段重排
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart LR
RET[四引擎检索结果] --> S1[① 术语绑定提升<br/>绑定列→0.95<br/>父表+0.25<br/>无绑定表-0.10]
S1 --> S2[② QU 信号重排<br/>匹配 metric/entity 加分<br/>certified 资产加分]
S2 --> S3[③ 动态列裁剪<br/>保留 metric/dimension/filter<br/>PK/FK/时间列<br/>裁剪无关列]
S3 --> S4[④ Join 路径简化<br/>按 fanout 风险去重<br/>优先 low risk]
S4 --> OUT[精简检索上下文<br/>供 SQL 生成]
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
class RET,OUT bpData
class S1,S2,S3,S4 bpProcess
linkStyle default stroke:#697077,stroke-width:2px
图 41-2 Reranker 四阶段重排
重排算法:规则 vs Cross-encoder¶
引申:重排算法理论
检索重排(Reranking)是 RAG 提升精度的关键环节,主流方法有三类:
- Cross-encoder 模型:把 query 和 document 拼接输入 BERT 类模型,输出相关性分数。精度最高但慢(每个 query-doc 对都要前向传播)。代表:BGE-reranker、Cohere Rerank。
- Bi-encoder + 近似最近邻:query 和 doc 分别编码,向量相似度召回。快但精度低——这正是 Engine V 做的。
- 规则重排:基于领域信号(如术语绑定、certified 状态)手工规则加分/降权。快、可解释、领域定制性强,但精度不及模型。
NewtonData 当前用规则重排(阶段 ①②),优势是快且可解释,劣势是精度不及 cross-encoder 模型。改进方向是支持 Admin 配置的 Reranker 模型,在精度要求高的场景启用 cross-encoder。
41.3 术语绑定强路由:业务术语全链路传播¶
术语绑定强路由是 NewtonData 区别于"普通 RAG"的核心创新,也是降低 NL2SQL 幻觉的关键手段。普通 RAG 检索完就结束了,LLM 可能忽略检索结果;术语绑定不一样——检索结果强制注入全链路,从检索到生成到护栏,GMV 这个术语始终绑定到 metric_gmv,不会被 LLM 自由发挥。
当 Engine R 命中了带 mapped_asset_id 的术语(如"GMV" → metric_gmv),这个绑定作为强路由信号贯穿全管道五个环节:
# 示意:术语绑定数据结构
_term_bindings = [
{
"term_id": "term_gmv",
"canonical_term": "GMV",
"mapped_asset_type": "metric",
"mapped_asset_id": "metric_gmv", # 核心意图:业务术语→技术资产,强路由绑定
},
]
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart LR
TERM["用户提到"GMV""] --> BIND[术语绑定<br/>GMV → metric_gmv]
BIND --> PROPAGATE[全链路传播]
PROPAGATE --> R1[① Reranker<br/>绑定列/指标加分]
PROPAGATE --> R2[② Prompt Assembler<br/>注入术语绑定约束]
PROPAGATE --> R3[③ SQL 生成<br/>强制使用 metric_gmv 定义]
PROPAGATE --> R4[④ Guardrails<br/>校验术语一致性]
PROPAGATE --> R5[⑤ Corrective Retrieval<br/>违规时拉取正确表]
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
classDef bpError fill:#fff1f1,stroke:#da1e28,stroke-width:2px,color:#161616
classDef bpExternal fill:#f2f4f8,stroke:#697077,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
classDef bpGroup fill:#ffffff,stroke:#0f62fe,stroke-width:2px,color:#161616
class TERM bpInfo
class BIND bpProcess
class PROPAGATE bpProcess
class R1,R2,R3,R4,R5 bpProcess
linkStyle default stroke:#697077,stroke-width:2px
图 41-3 术语绑定强路由:业务术语全链路传播
| 环节 | 术语绑定的作用 |
|---|---|
| ① Reranker | 绑定列/指标加分(0.95),其父表提升(+0.25),不含绑定列的表降权(-0.10) |
| ② Prompt Assembler | 注入"## 术语绑定约束",明确告知 LLM 必须从哪取该列 |
| ③ SQL 生成 | 强制使用 metric_gmv 的定义(SUM(amount) WHERE status='completed') |
| ④ Guardrails | Layer 4 术语绑定语义校验,拦截引用到错误表的 SQL |
| ⑤ Corrective Retrieval | 检测到绑定违规时,优先按绑定关系拉取正确表 |
表 41-3 术语绑定全链路传播的五个环节
术语绑定的价值¶
| 场景 | 无术语绑定 | 有术语绑定 |
|---|---|---|
| 用户问"GMV 趋势" | LLM 可能猜错 GMV 定义 | 强制使用 metric_gmv 的精确定义 |
| 用户问"华东 GMV" | 可能 join 错区域表 | G 引擎沿 metric_gmv 的表路径找区域维度 |
| 生成 SQL 后 | 护栏不知道"GMV"该用什么 | 护栏校验 SQL 中的 GMV 计算是否符合定义 |
| 检索失败时 | 硬生成,可能幻觉列 | Corrective Retrieval 按绑定关系补充正确表 |
表 41-4 术语绑定的价值
引申
术语绑定强路由把"术语消歧"从"LLM 的自觉"变为"全链路强制的硬约束"——这是 NewtonData 提升 SQL 准确性的核心手段。术语绑定的资产定义在 Ch 40 的 L2 术语治理层(term: "GMV" → metric: metric_gmv),校验在 Ch 44 的第四层护栏(术语语义校验),自愈在 Ch 42 的修复回路(corrective_retrieval)。一个术语绑定信号贯穿三章四个环节——这是 Agentic BI "受控自治"的微观体现。
41.4 Corrective-RAG:检索质量评估与回退¶
检索回来的上下文不一定都靠谱——可能召回不全、可能相关度低。不评估检索质量就直接生成 SQL,错误会一路传播到下游。Corrective-RAG(CRAG)的核心思路:检索质量不够时别硬来,先评估结果,质量差就纠正——改写查询重搜或者补搜。
| 检索质量 | 判据 | 策略 |
|---|---|---|
| 高(相关度分数高) | 术语绑定命中 + 向量 top-k 分数 > 0.8 | 直接使用 |
| 中(部分相关) | 部分术语命中 + 分数 0.65-0.8 | Reranker 重排后使用 |
| 低(不相关) | 无术语命中 + 分数 < 0.65 | CRAG 回退:扩大范围 / 补充检索 |
表 41-5 Corrective-RAG 检索质量三级评估
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TD
RETRIEVE[检索结果] --> EVAL{评估检索质量}
EVAL -->|高质量|USE[直接使用]
EVAL -->|中质量|RERANK[Reranker 重排后使用]
EVAL -->|低质量|CRAG[Corrective-RAG<br/>回退策略]
CRAG --> EXPAND[扩大检索范围<br/>降低 threshold / 增加 top_k]
CRAG --> SUPPLEMENT[补充检索<br/>按错误信息拉取正确资产]
EXPAND --> REGEN[重新检索+重排]
SUPPLEMENT --> REGEN
REGEN --> USE2[使用修正后结果]
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
classDef bpError fill:#fff1f1,stroke:#da1e28,stroke-width:2px,color:#161616
classDef bpExternal fill:#f2f4f8,stroke:#697077,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
classDef bpGroup fill:#ffffff,stroke:#0f62fe,stroke-width:2px,color:#161616
class RETRIEVE bpProcess
class EVAL bpDecision
class USE bpSuccess
class RERANK bpProcess
class CRAG bpProcess
class EXPAND,SUPPLEMENT bpProcess
class REGEN bpProcess
class USE2 bpSuccess
linkStyle default stroke:#697077,stroke-width:2px
图 41-4 Corrective-RAG 回退与重排
引申:CRAG 与 Self-RAG 理论
CRAG(Corrective Retrieval Augmented Generation,arxiv.org/abs/2401.15884)的核心思想:检索后自评估,质量差时触发重新检索或改写。它与 Self-RAG(arxiv.org/abs/2310.11511)一脉相承——Self-RAG 让 LLM 自主决定何时检索、检索什么、是否采纳检索结果。
NewtonData 的 corrective_retrieval 是 CRAG 的简化版:不评估检索质量(无 retrieval confidence score),而是在护栏失败后才触发补充检索——检测到术语绑定违规时优先按绑定关系拉取正确表,检测到列引用错误时拉取可用列清单。改进方向是把检索评估前置(pre-generation),而非等生成失败后才纠正。
41.5 Token 预算分配与上下文压缩¶
检索结果经过 Reranker 重排后,仍然可能超出 LLM 的上下文窗口。Token 预算分配这个模块是被一次线上事故逼出来的——有一次用户问了一个复杂问题,四引擎检索回来的上下文加起来超过 12K tokens,直接把 System Prompt 撑爆,LLM 输出乱码。从那以后,我们加了按类别分配预算的机制。
为什么要按类别分配而不是按相关度裁剪¶
最初的想法是"按相关度分数裁剪"——分数低的直接丢掉。但试了一段时间发现有问题:有些资产分数不高但不可或缺(比如 join 规则,分数可能不高但没有它就生成不了正确的 join SQL)。所以改成了"按类别分配预算"——每个类别有固定比例的 token 配额,类别内部再按相关度排序裁剪。
| 类别 | 预算占比 | 裁剪优先级 | 说明 |
|---|---|---|---|
| tables | 30% | 术语绑定的表 > certified > 其他 | 表定义是 NL2SQL 的基础,占最大预算 |
| columns | 25% | metric/dimension/filter 相关 > PK/FK/时间 > 其他 | 列属性次之,动态裁剪无关列 |
| metrics | 15% | 术语绑定的指标 > QU 匹配的 > 其他 | 指标定义与计算规则 |
| few_shots | 10% | 复杂度分级:simple=2/medium=4/complex=6 | 动态 few-shot 示例 |
| join_rules | 10% | Steiner 树规划所需的路径 > 其他 | Join 路径规则 |
| business_rules | 10% | 术语绑定的规则 > 其他 | 业务规则约束 |
表 41-6 Token 预算分配(含裁剪优先级)
裁剪的核心逻辑是优先保留高信号内容:术语绑定的资产(命中 GMV → metric_gmv 相关的所有资产)、certified 状态的资产、与查询理解(QU)匹配的 metric——这些信号越强的资产越优先保留。这和 Ch 40 的 build_few_shot() 分级注入(simple=2/medium=4/complex=6)同出一辙——按查询复杂度动态控制注入量。
Trade-off
Token 预算分配本质上是"信息密度"与"覆盖范围"的 trade-off。预算卡得太紧,可能丢掉关键上下文(比如一个不常见但必要的 join 规则);放得太宽,又会稀释关键信号(LLM 在 12K tokens 的上下文里找关键信息,不如在 4K tokens 的精简上下文里找)。我们当前的 30/25/15/10/10/10 分配比例是经过 200+ 条测试查询调出来的——不是理论最优,但在这个业务场景下表现稳定。如果换一个业务领域,这个比例可能需要重新调。
41.6 引申:Naive→Advanced→Modular RAG 演进谱系¶
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart LR
subgraph RAG演进["RAG 演进三阶段"]
N@{ icon: "codicon:search", form: "rounded", label: "Naive RAG<br/>单次检索→生成<br/>简单但效果差", pos: "b", h: 36 }
A@{ icon: "codicon:search", form: "rounded", label: "Advanced RAG<br/>检索前优化+检索后重排<br/>改善质量", pos: "b", h: 36 }
M@{ icon: "codicon:refresh", form: "rounded", label: "Modular RAG<br/>多引擎+回退+自愈<br/>NewtonData 方案", pos: "b", h: 36 }
end
N --> A --> M
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
classDef bpError fill:#fff1f1,stroke:#da1e28,stroke-width:2px,color:#161616
classDef bpExternal fill:#f2f4f8,stroke:#697077,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
classDef bpGroup fill:#ffffff,stroke:#0f62fe,stroke-width:2px,color:#161616
class N bpProcess
class A bpProcess
class M bpSuccess
linkStyle default stroke:#697077,stroke-width:2px
图 41-5 Naive→Advanced→Modular RAG 演进谱系
| 阶段 | 特征 | 代表 |
|---|---|---|
| Naive | 单次向量检索→生成;无重排、无质量评估、上下文冗余 | 早期 ChatGPT 插件 |
| Advanced | 检索前优化(查询改写)+ 检索后重排(rerank)+ 上下文压缩(compress)+ 多路召回 | LangChain RAG、LlamaIndex |
| Modular | 多引擎并行 + CRAG 回退 + 术语绑定 + 可插拔模块(Router/Fusion/Corrective/Self-RAG) | Microsoft GraphRAG、NewtonData |
表 41-7 Naive→Advanced→Modular RAG 演进谱系
引申:RAG 范式演进理论
RAG(Retrieval-Augmented Generation)技术经历了清晰的三个范式阶段(参考 survey: arxiv.org/abs/2312.10997):
- Naive RAG:Index → Retrieve → Generate,把文档切块、向量化、检索 top-k、拼进 prompt。问题:召回不准、无重排、上下文冗余、无质量评估。
- Advanced RAG:在检索前(pre-retrieval)做 query 改写/扩展;检索后(post-retrieval)做重排、压缩;多路召回。NewtonData 的 R+V 多路召回 + Reranker 重排 + Token 预算压缩属于这一层。
- Modular RAG:把 RAG 拆为可插拔模块——Router(决定检索什么)、Fusion(多查询结果融合,如 RRF)、Corrective RAG(检索后自评估纠错)、Self-RAG(LLM 自主决定何时检索)。NewtonData 的 G 图增强借了 GraphRAG 思想,corrective_retrieval 是 CRAG 工程实现,术语绑定是 NL2SQL 特有的强路由信号。NewtonData 其实横跨了 Advanced 到 Modular RAG。
当前实现可改进之处¶
Trade-off:四引擎 RAG 的架构局限
- 检索阶段缺乏查询分解:复杂问题(如"对比华东和华北的 GMV 趋势")单次检索召回不全——架构上缺少 query decomposer 模块做子查询分解与并行检索。可以考虑引入多查询生成与结果融合(参考 RAG-Fusion,arxiv.org/abs/2402.03367)。
- 重排策略规则化而非模型化:当前 Reranker 是基于领域信号的规则重排,精度不及 cross-encoder 模型。改进方向:让架构支持可插拔的 Reranker 模型,在精度要求高的场景启用 BGE-reranker / Cohere Rerank 等。
- 检索质量评估未常态化:检索后自评估仅在特定路由启用,未形成"评估→低分自动纠错"的闭环。改进方向:把 Self-RAG 的自评估机制常态化(arxiv.org/abs/2310.11511),每次检索后评估,低分自动触发纠正。
- 向量引擎规模上限:单机向量检索在百万级 embedding 尚可,千万级会退化。改进方向:抽象 VectorStore 接口,生产态可切换专用向量数据库(Qdrant/Milvus),保持检索层接口不变。
本章小结¶
- 四引擎 RAG:R(关系精确)/ V(向量语义)/ G(图遍历)/ D(动态 few-shot)——R+V+D 并行(asyncio.gather),G 串行(依赖上游 asset_ids),互补解决精确性/灵活性/关系推理/经验复用
- Reranker 四阶段重排:术语绑定提升 → QU 信号 → 动态列裁剪 → Join 路径简化——规则重排优先(快且可解释),cross-encoder 模型为改进方向
- 术语绑定强路由:业务术语(GMV)→ 绑定技术资产(metric_gmv)→ 全链路传播五个环节(Reranker / Prompt / SQL 生成 / Guardrails / Corrective Retrieval)——把术语消歧从"LLM 自觉"变为"硬约束"
- Corrective-RAG:检索质量低时回退扩大范围+补充检索——CRAG 的工程实现(arxiv.org/abs/2401.15884),与 Self-RAG(arxiv.org/abs/2310.11511)一脉相承
- Token 预算分配:tables 30% / columns 25% / metrics 15% / few_shots 10% / join_rules 10% / business_rules 10%——上下文压缩避免 Prompt 爆炸
- RAG 演进:Naive(单次检索)→ Advanced(优化+重排)→ Modular(多引擎+回退+术语绑定)——NewtonData 属于 Modular(arxiv.org/abs/2312.10997)
下一章
Ch 42 Agent 编排:LangGraph 与状态机 —— 检索完了,接下来看 Agent 怎么编排这些步骤。