Skip to content

RAG(检索增强生成)

RAG(Retrieval-Augmented Generation,检索增强生成)是一种将信息检索与大语言模型生成相结合的技术,可以让 AI 基于外部知识库回答问题。

为什么需要 RAG

LLM 的局限性

大语言模型存在以下问题:

  • 知识截止: 训练数据有时间限制
  • 幻觉问题: 可能生成虚假信息
  • 领域限制: 缺乏专业领域知识
  • 无法更新: 知识无法实时更新

RAG 的解决方案

RAG 通过外部检索来增强 LLM:

  • 提供最新信息
  • 基于真实文档回答
  • 支持私有知识库
  • 可追溯来源

工作原理

基本流程

用户问题 → 问题向量化 → 向量检索 → 获取相关文档 → 构建提示词 → LLM 生成 → 回答

详细步骤

  1. 文档预处理

    • 加载文档(PDF、Word、网页等)
    • 文本分块(Chunking)
    • 生成向量嵌入
  2. 索引构建

    • 将向量存入向量数据库
    • 建立检索索引
  3. 查询处理

    • 用户问题向量化
    • 相似度检索
    • 获取 Top-K 相关文档
  4. 生成回答

    • 将检索结果加入提示词
    • LLM 基于上下文生成回答

关键组件

1. 文本分块策略

策略说明适用场景
固定大小按字符数分割通用场景
语义分块按段落/章节分割结构化文档
递归分块多级分隔符混合内容
重叠分块块间有重叠保持上下文

2. 嵌入模型

常用的 Embedding 模型:

  • OpenAI text-embedding-3-large
  • Cohere embed-v3
  • BGE-M3(开源多语言)
  • Jina Embeddings

3. 向量数据库

数据库特点
Milvus开源、分布式、高性能
Pinecone托管服务、易用
Chroma轻量、Python 友好
QdrantRust 编写、高性能
pgvectorPostgreSQL 扩展

4. 检索策略

  • 向量检索: 语义相似度
  • 关键词检索: BM25 等传统方法
  • 混合检索: 结合两者优势
  • 重排序: 对检索结果二次排序

代码示例

基础 RAG 实现

from openai import OpenAI  
import chromadb  
  
# 初始化  
client = OpenAI(api_key="your-api-key", base_url="http://122.51.35.238:5170/v1")  
chroma_client = chromadb.Client()  
collection = chroma_client.create_collection("docs")  
  
# 添加文档  
def add_documents(texts, ids):  
    # 生成嵌入  
    embeddings = []  
    for text in texts:  
        response = client.embeddings.create(  
            model="text-embedding-3-small",  
            input=text  
        )  
        embeddings.append(response.data[0].embedding)  
      
    # 存入向量数据库  
    collection.add(  
        embeddings=embeddings,  
        documents=texts,  
        ids=ids  
    )  
  
# RAG 查询  
def rag_query(question):  
    # 问题向量化  
    q_embedding = client.embeddings.create(  
        model="text-embedding-3-small",  
        input=question  
    ).data[0].embedding  
      
    # 检索相关文档  
    results = collection.query(  
        query_embeddings=[q_embedding],  
        n_results=3  
    )  
      
    # 构建提示词  
    context = "\n".join(results['documents'][0])  
    prompt = f"""基于以下信息回答问题:  
  
{context}  
  
问题:{question}  
"""  
      
    # 生成回答  
    response = client.chat.completions.create(  
        model="gpt-4o",  
        messages=[{"role": "user", "content": prompt}]  
    )  
      
    return response.choices[0].message.content

进阶技术

1. 查询改写

优化用户查询以提高检索效果:

  • HyDE: 生成假设文档再检索
  • 多查询: 生成多个变体查询
  • 查询扩展: 添加同义词和相关词

2. 上下文压缩

减少冗余信息:

  • 摘要提取: 只保留关键信息
  • 相关性过滤: 删除无关内容
  • 动态分块: 根据查询调整

3. 多跳推理

处理复杂问题:

  • 迭代检索: 多轮检索逐步深入
  • 子问题分解: 拆分复杂问题
  • 推理链: 显式推理步骤

评估指标

指标说明
Recall@K前 K 个结果的召回率
MRR平均倒数排名
NDCG归一化折损累计增益
答案正确性生成答案的准确性
忠实度答案是否基于检索内容

最佳实践

  1. 分块大小: 通常 200-500 tokens
  2. 重叠比例: 10%-20% 的重叠
  3. Top-K 选择: 3-5 个文档通常足够
  4. 混合检索: 结合向量和关键词检索
  5. 来源引用: 在回答中标注信息来源

本页内容来自文档知识库整理,已按 ArmNet 字元服务 服务命名统一更新。