04.4 - RAPTOR 与分层检索
定位: 通过递归摘要构建分层知识树,从"细节"到"概览"多粒度检索——解决"单层分块"的深度不足问题 面试高频度: ⭐⭐⭐ 考查方式: RAPTOR 原理、树状结构、分层检索策略
一、这是什么?为什么需要它?
是什么
RAPTOR(Recursive Abstractive Processing for Tree-Organized Retrieval)是一种分层检索架构,通过递归摘要将文档组织成树状结构,实现从细节到概览的多粒度检索。
传统分块: RAPTOR 树状结构:
[块1] [块2] [块3] [根节点:全书摘要]
/ \
(所有块在同一层) [章摘要] [章摘要]
/ \ / \
[节摘要] [节摘要] [节摘要] [节摘要]
| | | | | | | |
块... 块... 块... 块...为什么需要分层检索?
传统 RAG 的问题:
检索只在一个粒度上工作——文档块的大小是固定的。
问题 1:粒度过细
"简述公司的发展历史" -> 检索到的可能是一段细节,而非整体概述
你需要的是"宏观层次"的摘要信息,但检索到的只有"微观层次"的碎块
问题 2:粒度过粗
"公司2023年第3季度在北京的营收是多少?" -> 在整段概述中找不到
你需要的是"微观层次"的具体数据
RAPTOR 的解法:
构建不同粒度的索引层
- 顶层:概括性摘要(回答宏观问题)
- 中层:章节摘要(回答中等粒度问题)
- 底层:原始块(回答具体细节问题)
检索时:在多层中同时检索,根据问题自动匹配最合适的粒度二、原理拆解
2.1 RAPTOR 树构建流程
+------------------------------------------------------------------+
| RAPTOR 树构建流程 |
| |
| 原始文档(假设是整个公司知识库) |
| |
| 步骤 1:分块(最底层) |
| 将文档切成基础块(chunks) |
| [块1] [块2] [块3] [块4] [块5] [块6] ... |
| |
| 步骤 2:聚类 |
| 用 Embedding 对块进行聚类(相似内容的块分成一组) |
| 组1: [块1, 块2, 块3] 组2: [块4, 块5, 块6] |
| 组3: [块7, 块8] ... |
| |
| 步骤 3:生成摘要 |
| 每组 -> LLM 生成摘要 |
| 组摘要1: "3个块的综合摘要..." |
| 组摘要2: "3个块的综合摘要..." |
| |
| 步骤 4:递归 |
| 把生成的摘要作为新一层的节点 |
| 对新层再次聚类+摘要 -> 更高层的摘要 |
| |
| 重复直到聚类结果只剩一组 -> 根节点(全书摘要) |
| |
| 结果:一个多层次的树状结构 |
| 根节点:全书摘要 |
| ├ 中间层1: 章节摘要A ├ 中间层B: 章节摘要B |
| ├ 底层1: [块1, 块2, 块3] ├ 底层2: [块4, 块5, 块6] |
+------------------------------------------------------------------+2.2 RAPTOR 检索策略
RAPTOR 支持两种检索模式:
模式 1:自顶向下(Top-down)
从根节点开始检索:
1. 在根节点层检索 -> 找到最相关的摘要
2. 进入该摘要的子节点 -> 在子节点中检索
3. 继续向下 -> 直到找到最具体的块
特点:
- 先看宏观,再找微观
- 适合先理解背景再深入的问题模式 2:全层检索(All-layer)
同时在所有层检索:
根节点检索 + 中间层检索 + 底层检索
合并各层的结果 -> Top-K
特点:
- 一次获得多个粒度的信息
- 适合综合性问题2.3 RAPTOR vs 传统分块对比
| 维度 | 传统分块 | RAPTOR |
|---|---|---|
| 知识粒度 | 单一粒度 | 多层粒度 |
| 宏观问题 | 找不到摘要 | 顶层摘要直接命中 |
| 微观问题 | 精确命中 | 底层块精确命中 |
| 构建成本 | 低(一次分块) | 高(多次 LLM 摘要) |
| 存储成本 | 低 | 较高(多层) |
| 检索延迟 | 低 | 略高(多层检索) |
| 上下文利用率 | 底层可能信息过载 | 层级自动匹配 |
三、图解全景
分层检索如何工作
用户提问:"简述公司的发展历史和主要业务"
传统检索:
[块 xx: 公司成立于2010年...] <- 只找到细节,没有整体观
[块 yy: 主要业务包括AI和云...] <- 没有历史全貌
RAPTOR 分层检索:
[根节点:公司整体发展概述]
(找到了!综合了历史和业务)
/ \
[早期发展摘要] [业务转型摘要] <- 中间层
/ \ / \
[2010成立] [2015融资] [2020AI业务] [2023云业务] <- 底层细节
检索结果:
顶层:公司整体概述(适合回答"简述")
中层:发展阶段和业务线(补充细节)
底层:具体事件(如果需要)四、实战验证
4.1 RAPTOR 的简化实现思路
python
# RAPTOR 的简化实现:递归摘要树
from langchain_openai import ChatOpenAI
from langchain.text_splitter import RecursiveCharacterTextSplitter
import numpy as np
class SimpleRAPTOR:
def __init__(self, documents, embedding_model, llm):
self.llm = llm
self.embedding_model = embedding_model
self.tree = self._build_tree(documents)
def _summarize(self, texts):
"""生成摘要"""
combined = "\n\n".join(texts)
prompt = f"请对以下内容生成一段综合摘要(保留关键信息):\n\n{combined}"
return self.llm.invoke(prompt).content
def _cluster(self, texts, embeddings, n_clusters=3):
"""简化版:按内容相似度聚类"""
# 实际实现可用 KMeans 或社区检测
# 这里简化为固定大小分组
if len(texts) <= n_clusters:
return [texts]
chunk_size = max(1, len(texts) // n_clusters)
return [texts[i:i+chunk_size] for i in range(0, len(texts), chunk_size)]
def _build_tree(self, texts, depth=0):
"""递归构建摘要树"""
if len(texts) <= 3 or depth > 3:
return {"level": depth, "nodes": texts, "summary": self._summarize(texts)}
clusters = self._cluster(texts, None)
children = []
for cluster in clusters:
child = self._build_tree(cluster, depth + 1)
children.append(child)
summaries = [c["summary"] for c in children]
node_summary = self._summarize(summaries)
return {
"level": depth,
"summary": node_summary,
"children": children
}
def retrieve(self, query, top_k=3):
"""多层检索:同时检索所有层"""
results = []
query_emb = self.embedding_model.encode([query])[0]
self._search_tree(self.tree, query_emb, results)
results.sort(key=lambda x: x[1], reverse=True)
return [r[0] for r in results[:top_k]]
def _search_tree(self, node, query_emb, results):
node_emb = self.embedding_model.encode([node["summary"]])[0]
sim = np.dot(query_emb, node_emb)
results.append((node["summary"], sim))
if "children" in node:
for child in node["children"]:
self._search_tree(child, query_emb, results)五、面试视角
| 问题 | 答案要点 |
|---|---|
| RAPTOR 解决了什么核心问题? | 传统 RAG 只有单一粒度(文档块),无法满足"宏观概览"和"微观细节"的不同需求。RAPTOR 通过多层树状结构,提供从全局到细节的多粒度知识 |
| RAPTOR 的构建成本有多高? | 较高。每层需要 LLM 生成摘要,N 个文档构建深度为 d 的树需要约 (层节点数) 次 LLM 调用。对于大型知识库,构建成本可能是传统索引的 5-20 倍 |
| RAPTOR 适合什么场景? | 文档结构清晰、内容有层次关系(如教科书、技术文档、公司制度)、问题粒度多样化(从概况到细节都可能被问到)。不适合:碎片化知识、简短文档集合 |
| RAPTOR 和 Graph RAG 的区别? | RAPTOR 用树状结构组织文本摘要(层次化压缩)。Graph RAG 用图结构组织实体关系(结构化推理)。两者可结合使用 |
📚 相关链接
- **文本分块策略** — 分块是 RAPTOR 的基础
- **GraphRAG** — 另一种结构化增强方案
- **上下文窗口管理** — 分层摘要也是窗口管理的高级策略
- <- 返回 **进阶RAG索引**