简介:本文系统定义“高级RAG”:在传统“切块—检索—生成”流程之上,为解决长上下文割裂、检索结果无法自检、实体关系难以表达三大瓶颈而演进的技术集合。文章逐一拆解LongRAG、Self-RAG、GraphRAG的原理与示意代码,并对比三者的适用场景与选型注意事项,帮助开发者构建更可靠的检索增强问答系统。
高级RAG(Advanced Retrieval-Augmented Generation,高级检索增强生成)是对经典“文档切块—向量化—相似度检索—大模型生成”流水线进行系统性增强的一类技术方案统称。它不是某个单一算法或单一功能,而是围绕检索增强生成各环节瓶颈演进而来的工程化路线集合。当前业界讨论最多的三个代表性方向是:
理解这一定义,可以从三个视角入手:
标准的RAG流程大致是:把文档分割成小块(如512 token)、对每块做向量化、查询时通过余弦相似度取回若干块、拼接后交给大模型生成答案。这套流程对简单场景确实够用,但随着语料复杂度上升,会暴露出三个结构性限制:
高级RAG的几种变体,正是分别针对这三个问题设计的。
LongRAG的核心想法并不复杂:既然现在的大模型普遍支持32K、100K乃至百万级token的上下文窗口,为什么还要固守512 token的小块?与其把文档切碎,不如按分层的方式重新组织检索单元。
这套方案通常做三件事:
下面是一个原型级别的示意性实现(通用Python,不含任何特定厂商组件):
from typing import Listimport numpy as npclass LongRAGRetriever:"""示意性实现:大块 + 重叠 的长上下文检索器"""def __init__(self, embed_model, chunk_size=8000, overlap=1600):self.model = embed_modelself.chunk_size = chunk_size # 大块长度(示意以字符计)self.overlap = overlap # 块间重叠,约为块长的20%-30%self.chunks: List[str] = []self.embeddings = []def create_long_chunks(self, text: str) -> List[str]:"""切出带重叠的大块,避免完整逻辑链被截断"""chunks, start = [], 0step = self.chunk_size - self.overlapwhile start < len(text):chunks.append(text[start:start + self.chunk_size])start += stepreturn chunksdef index(self, text: str):for chunk in self.create_long_chunks(text):self.chunks.append(chunk)self.embeddings.append(self.model.encode(chunk))self.embeddings = np.array(self.embeddings)def search(self, query: str, top_k: int = 3) -> List[str]:"""检索返回完整、连贯的大段落,而非零散片段"""q_vec = np.array(self.model.encode(query))norm = np.linalg.norm(self.embeddings, axis=1) * np.linalg.norm(q_vec) + 1e-8scores = (self.embeddings @ q_vec) / normtop_idx = np.argsort(scores)[-top_k:][::-1]return [self.chunks[i] for i in top_idx]
这段代码的关键不在算法复杂度,而在参数取向:chunk_size放大到数千token,overlap按比例随之放大。它体现的是一种“宁可多给上下文,也不让模型猜”的工程哲学。其代价是每次调用的token消耗上升、响应延迟增加,需要结合成本预算权衡。
如果说LongRAG解决的是“给模型的上下文够不够完整”,Self-RAG解决的是“给模型的东西对不对”。它可以定义为:一种在生成过程中引入反思判断的RAG变体,通过让模型自主评估“是否需要检索”“检索内容是否相关”“生成内容是否被证据支持”,实现按需检索与质量自控。
其工作流程通常包含三类判断步骤:
其思路可以用如下伪代码表达:
# Self-RAG 思路的示意性伪代码if judge_need_retrieval(query): # 步骤1:是否需要检索passages = retrieve(query)filtered = [p for p in passagesif is_relevant(query, p)] # 步骤2:相关性过滤else:filtered = []draft = generate(query, filtered)while not is_supported(draft, filtered): # 步骤3:证据支持度自检passages = retrieve(query, retry=True)draft = generate(query, passages)
Self-RAG把传统流程中“检索一次、生成一次”的单向管线,改造成了带反馈的闭环,这对事实性要求高、对幻觉敏感的场景尤为重要。
GraphRAG可以定义为:一种先将语料中的实体与关系抽取出来构建知识图谱,再基于图结构进行检索的RAG变体。它的基本流程一般包括:从文档中识别实体、抽取实体间关系、构建并组织图谱、对图谱做主题或社区层面的聚类与摘要,最终支持两类检索:
它与向量检索的本质区别在于:向量相似度回答“哪些内容和问题感觉相近”,图结构回答“实体之间通过什么路径产生联系”。前者是相似性度量,后者是可推理的结构关系,二者互补而非替代。
| 对比维度 | LongRAG | Self-RAG | GraphRAG |
|---|---|---|---|
| 解决的核心问题 | 上下文被切碎、逻辑链断裂 | 检索质量无法自检、幻觉难拦截 | 复杂关系与全局性问题 |
| 检索单元 | 大块/整段/整篇 | 经相关性过滤的片段 | 图节点、关系路径、社区摘要 |
| 主要代价 | token消耗与延迟上升 | 多次模型调用、链路变长 | 图谱构建与维护成本高 |
| 典型短板 | 依赖长上下文模型能力 | 依赖判断环节的可靠性 | 依赖实体抽取质量 |
需要强调的是,三者并非互斥选项:一份长合同可以先用LongRAG保证上下文完整,再在生成环节套用Self-RAG的忠实度自检;涉及关联挖掘的语料,则可以在LongRAG之上叠加图谱层。
回到定义本身:高级RAG是对传统“切块—检索—生成”流水线的系统性增强,LongRAG以长上下文对抗碎片化,Self-RAG以自反思闭环治理检索质量,GraphRAG以图结构承载复杂关系。三者的共同价值,是把RAG从“能跑通的原型”推向“可交付的工程系统”。选型时的正确姿势不是追逐某一条路线,而是先诊断自身场景的主要瓶颈——上下文割裂、质量失控还是关系缺失——再据此组合相应方案,并以成本、延迟与可评估性作为最终约束条件。