这个所谓的 RAPTOR 是怎么优化 RAG 的?
RAPTOR优化RAG的核心在于递归构建摘要树结构。它将文档分块后,通过聚类和摘要生成多层抽象节点,形成树状索引。检索时不仅匹配原始分块,还会沿树结构展开相关上下文,从而获取更全面的信息覆盖。相比普通RAG仅检索原始分块,RAPTOR能通过摘要节点捕捉宏观关联,提升长文档和多步推理的表现,但构建成本较高,需进行聚类、摘要和多层embedding处理。
·
这个所谓的 RAPTOR 是怎么优化 RAG 的?
RAPTOR 的核心思想就是在文档预处理阶段,用递归构建一棵树,每个节点是更高抽象的文本摘要,每个叶子节点是原始分块。这个过程一般是下面几步:
(1) 分块(Chunking)
-
目标:把长文档切成比较短的片段(便于 embedding + 检索)
-
实现方式:
- 按句子或段落分
- 按固定 token 长度分(常见 200~500 tokens)
-
产出:
[chunk_1, chunk_2, chunk_3, ...]
(2) 聚类(Clustering)
-
目标:把语义上相似的 chunks 放到同一组
-
实现方式:
- 对每个 chunk 生成 embedding(向量表示)
- 用聚类算法(常见的有
KMeans、Agglomerative Clustering、Spectral Clustering)按语义距离分组 - 每组就相当于未来树的一层子节点
-
例子:
chunks: [A, B, C, D, E, F] 聚类后: cluster1: [A, C] cluster2: [B, E, F] cluster3: [D]
(3) 摘要(Summarization)
-
目标:用 LLM 对每个 cluster 的文本生成一个“更高层次的摘要”
-
实现方式:
- 直接拼接 cluster 内的 chunk,然后交给 LLM 做摘要
- 摘要结果是上层节点的文本
-
产出:
cluster1 → 摘要1 cluster2 → 摘要2 cluster3 → 摘要3
(4) 递归(Recursion)
-
目标:继续对摘要做 embedding → 聚类 → 摘要,直到树的层数达到目标(通常 2~3 层)
-
例子:
第0层:原始 chunk 第1层:cluster 摘要 第2层:更高抽象的总摘要
最终树结构(示例):
Level 2: 总摘要
├─ Level 1: 摘要1
│ ├─ Level 0: Chunk A
│ └─ Level 0: Chunk C
├─ Level 1: 摘要2
│ ├─ Level 0: Chunk B
│ ├─ Level 0: Chunk E
│ └─ Level 0: Chunk F
└─ Level 1: 摘要3
└─ Level 0: Chunk D
构建好分块后是怎么检索的?
这里有两个关键点:检索对象 和 检索路径。
(1) 检索对象
-
普通 RAG:
只 对原始 chunks 建索引,查询时直接检索 chunks -
RAPTOR:
- 同时 对各层摘要和原始 chunks 建索引(树的所有节点都有 embedding)
- 检索时既可能命中摘要节点,也可能命中原始 chunk
(2) 检索路径
RAPTOR 检索的逻辑不是“一次命中直接返回”,而是:
- 对 整棵树的所有节点 做向量相似度检索(可以限制为 top-k)
- 如果命中的是摘要节点(Level 1 或 Level 2),沿树往下走,把该节点下面的所有叶子 chunk 加入候选集合
- 如果命中的是 chunk 节点(Level 0),直接加入候选集合
- 最后合并候选集合,去重,交给 LLM 生成回答
(3) 举例
假设用户问:
“RAPTOR 在 RAG 中的优势是什么?”
检索过程可能是:
- 在树中找到 Level 1 的“RAPTOR 优势”摘要节点(相似度最高)
- 展开这个节点的所有原始 chunks
- 把它们作为上下文传给 LLM
和普通 RAG 的区别
| 特性 | 普通 RAG | RAPTOR RAG |
|---|---|---|
| 检索范围 | 只检索原始 chunks | 检索所有层级节点(摘要+chunks) |
| 上下文覆盖 | 可能只拿到一小段 | 能覆盖整个相关主题的所有片段 |
| 长文表现 | 可能漏掉远程关联信息 | 摘要节点能抓到宏观关联 |
| 多步推理 | 容易缺上下文链 | 有摘要层做主题聚合,推理更连贯 |
| 构建成本 | 简单,embedding + 向量库 | 需要聚类、摘要、多层 embedding |
更多推荐
所有评论(0)