Skip to content

高级 RAG 技术

基础 RAG 的流程是「用户问题 → 向量检索 → LLM 生成」。但现实中这个流程有很多不足:

  • 用户提问模糊或不完整
  • 检索到的文档排序不够精准
  • 单次检索无法回答需要综合多个文档的复杂问题

高级 RAG 技术就是在基础流程的各个环节做优化。

flowchart LR
    Q1["用户问题"] -->|"Query Rewriting / HyDE"| Q2["更好的查询"]
    R1["检索结果"] -->|"Re-ranking"| R2["更精准的排序"]
    S1["单次检索"] -->|"Multi-hop"| S2["多步推理检索"]
    U1["非结构化"] -->|"GraphRAG"| U2["知识图谱增强"]

用户的问题往往不适合直接用来检索。Query Rewriting 让 LLM 先优化查询,再去检索。

def rewrite_query(original_query: str) -> list[str]:
"""将用户问题改写为多个检索友好的查询"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{
"role": "system",
"content": "将用户问题改写为 3 个不同角度的搜索查询,每行一个。"
}, {
"role": "user",
"content": original_query,
}],
)
return response.choices[0].message.content.strip().split("\n")
# 示例
# 原始:"为什么我的 RAG 效果不好?"
# 改写:
# 1. "RAG 检索质量低的常见原因"
# 2. "提升 RAG 准确率的方法"
# 3. "RAG pipeline 调优最佳实践"

核心想法:用户的问题是「问句」,但数据库里存的是「陈述句」。两者语义空间不同,直接匹配效果差。

HyDE 的做法:先让 LLM 生成一个假设性的回答文档,用这个文档的向量去检索,效果往往更好。

普通检索:
问题 "什么是 RAG?" → embedding → 检索
(问句向量 vs 答案向量,语义空间不同)

HyDE:
问题 → LLM 生成假设答案 → "RAG 是一种将检索与生成结合的技术..." → embedding → 检索
(答案向量 vs 答案向量,语义空间一致)
def hyde_retrieve(question: str, top_k: int = 5):
# 1. 生成假设文档
hypo_response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{
"role": "system",
"content": "请直接回答以下问题,写一段简洁的解释。"
}, {
"role": "user", "content": question,
}],
)
hypo_doc = hypo_response.choices[0].message.content
# 2. 用假设文档的向量去检索
hypo_embedding = get_embedding(hypo_doc)
results = vector_db.query(query_embeddings=[hypo_embedding], n_results=top_k)
return results

向量检索返回的 Top-K 结果排序不够精准。Re-ranker 用更精确(但更慢)的模型对结果重新排序。

flowchart TD
    DB["100 万文档"] --> Stage1["阶段 1:向量检索(快但粗)\n找出 Top-20"]
    Stage1 --> Stage2["阶段 2:Re-ranking(慢但精)\nCross-Encoder 精排"]
    Stage2 --> Final["输出 Top-5"]

常用 Re-ranker:

  • Cohere Reranker —— API 服务,效果好
  • bge-reranker —— 开源,可本地部署
  • Cross-Encoder —— 基于 sentence-transformers
import cohere
co = cohere.Client("your-api-key")
results = co.rerank(
model="rerank-v3.5",
query="什么是 RAG?",
documents=["RAG 是检索增强生成...", "CNN 是卷积神经网络...", "RAG 通过外部知识..."],
top_n=2,
)
for r in results.results:
print(f"Score: {r.relevance_score:.4f} | {r.document.text[:50]}")

有些问题无法一次检索回答,需要多步推理:

问题:"LangChain 的创始人之前在哪家公司工作?"
第1步检索 → "LangChain 由 Harrison Chase 创立"
第2步检索 → "Harrison Chase 之前在 Robust Intelligence 工作"
合并回答 → "Harrison Chase 之前在 Robust Intelligence 工作"

实现思路:让 LLM 判断检索结果是否足以回答问题,不够则生成后续查询继续检索。

微软提出的 GraphRAG 将文档中的实体和关系提取为知识图谱,然后在图上做检索。

传统 RAG
文档 → 分块 → 向量 → 语义检索
擅长:局部事实查询
GraphRAG
文档 → 提取实体关系 → 构建图 → 社区摘要
擅长:全局总结、关系推理
graph LR
    Zhang["张三"] -->|works_at| CompA["公司A"]
    Zhang -->|knows| Li["李四"]
    CompA -->|located_in| Beijing["北京"]

GraphRAG 特别适合需要「全局理解」的问题,如「这个数据集中的主要主题是什么?」

技术适用场景何时使用提升幅度复杂度
Query Rewriting用户问题模糊用户群体多样、提问质量参差不齐时+10-20%
HyDE问答语义鸿沟大知识库以长篇陈述文为主、用户以短问句检索时+5-15%
Re-ranking检索排序不准Top-K 中有相关文档但排序靠后时(先验证此问题存在)+15-25%
Multi-hop复杂推理问题答案散布在多个文档中、需要链式推理时必需
GraphRAG全局总结、关系推理需要回答「主要主题是什么」「X 和 Y 什么关系」类问题时场景依赖

自测题 1:HyDE 的核心思想是什么?为什么有效?
先用 LLM 生成假设答案,用答案的向量去检索。有效是因为答案和文档都是陈述句,语义空间一致,匹配更准。
自测题 2:Re-ranking 为什么不直接用于全量检索?
Re-ranker(如 Cross-Encoder)计算复杂度是 O(n),对每个候选文档都要与查询做交叉编码,速度太慢。所以先用向量检索粗筛,再用 Re-ranker 精排。
自测题 3:GraphRAG 相比传统 RAG 的优势是什么?
传统 RAG 擅长局部事实检索,GraphRAG 通过知识图谱和社区摘要能回答需要全局理解的问题(如主题总结、关系推理)。
  • 盲目堆叠技术:不是所有项目都需要 HyDE + Re-ranking + GraphRAG。每增加一层都会增加延迟和成本。先用评估指标确认瓶颈在哪,再针对性优化。
  • HyDE 的假设答案误导检索:当 LLM 对领域知识不足时,生成的假设答案可能偏离事实,反而检索到错误的文档。建议对专业领域先评估 HyDE 是否真的提升了 Recall@K。
  • Re-ranking 的成本被低估:Cross-Encoder 对每对(query, doc)做推理,Top-20 的 Re-ranking 就需要 20 次模型推理。在高并发场景下要做好延迟预算。