晴天技术
AI6 min read

RAG 技术详解:让大模型拥有你的私有知识

RAG 技术详解:让大模型拥有你的私有知识

RAG大模型向量数据库AI开发

RAG(Retrieval-Augmented Generation)是当前最热门的 AI 应用技术,让大模型能基于你的私有数据回答问题。

什么是 RAG?

RAG = 检索 + 生成

用户提问 → 检索相关文档 → 文档 + 问题 → 大模型 → 回答

为什么需要 RAG?

大模型的问题:

  1. 知识截止:不知道最新信息
  2. 没有私有数据:不知道你公司的文档
  3. 会编造答案:幻觉问题

RAG 解决这些问题:先检索相关文档,再让大模型基于文档回答。

RAG 架构

┌─────────────────────────────────────────┐
│                 RAG 系统                  │
├─────────────────────────────────────────┤
│                                         │
│  离线阶段(索引构建)                      │
│  ┌─────┐   ┌──────┐   ┌──────────────┐ │
│  │文档 │ → │分块  │ → │向量化(Embedding)│ │
│  └─────┘   └──────┘   └──────┬───────┘ │
│                              ↓          │
│                       ┌──────────┐      │
│                       │向量数据库 │      │
│                       └──────────┘      │
│                                         │
│  在线阶段(查询)                          │
│  ┌─────┐   ┌──────┐   ┌──────────────┐ │
│  │问题 │ → │向量化│ → │相似度检索     │ │
│  └─────┘   └──────┘   └──────┬───────┘ │
│                              ↓          │
│              ┌──────────────────────┐   │
│              │相关文档 + 问题 → LLM │   │
│              └──────────┬───────────┘   │
│                         ↓               │
│                    ┌────────┐           │
│                    │  回答  │           │
│                    └────────┘           │
└─────────────────────────────────────────┘

实现 RAG

1. 文档分块

from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,      # 每块 500 字符
    chunk_overlap=50     # 重叠 50 字符
)

chunks = splitter.split_documents(documents)

2. 向量化

from langchain.embeddings import OpenAIEmbeddings

embeddings = OpenAIEmbeddings()
vectors = embeddings.embed_documents([chunk.page_content for chunk in chunks])

3. 存储到向量数据库

from langchain.vectorstores import FAISS

vectorstore = FAISS.from_documents(chunks, embeddings)
vectorstore.save_local("my_index")

4. 检索和回答

from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o")
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=vectorstore.as_retriever(search_kwargs={"k": 3})
)

answer = qa_chain.run("公司的年假政策是什么?")

向量数据库选择

数据库特点适合场景
FAISSFacebook 开源,本地运行原型开发、小规模
Chroma轻量级,易上手原型开发
Pinecone云托管,易扩展生产环境
Weaviate开源,功能丰富中大规模
Milvus开源,高性能大规模生产

分块策略

固定长度分块

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,
    chunk_overlap=50
)

按段落分块

splitter = RecursiveCharacterTextSplitter(
    separators=["\n\n", "\n", "。", "!"],
    chunk_size=500
)

按语义分块

from langchain.text_splitter import SemanticChunker

splitter = SemanticChunker(embeddings)
chunks = splitter.split_text(document)

Prompt 工程

RAG 的 Prompt 很关键:

prompt_template = """
基于以下文档内容回答用户问题。
如果文档中没有相关信息,请说"我无法根据现有文档回答这个问题"。
不要编造信息。

相关文档:
{context}

用户问题:{question}

回答:
"""

优化技巧

1. 优化分块大小

  • 太小:丢失上下文
  • 太大:检索不精确
  • 推荐:300-1000 字符

2. 增加重叠

重叠确保跨块信息不丢失:

chunk_overlap = chunk_size * 0.1  # 10% 重叠

3. 混合检索

结合关键词检索和向量检索:

from langchain.retrievers import EnsembleRetriever

retriever = EnsembleRetriever(
    retrievers=[vector_retriever, bm25_retriever],
    weights=[0.7, 0.3]
)

4. 重排序

对检索结果重新排序:

from langchain.retrievers import ContextualCompressionRetriever
from langchain_cohere import CohereRerank

reranker = CohereRerank()
retriever = ContextualCompressionRetriever(
    base_compressor=reranker,
    base_retriever=vectorstore.as_retriever()
)

实际应用

1. 企业知识库问答

员工问:公司的报销流程是什么?
RAG 检索到《财务报销制度》相关段落
LLM 基于文档回答具体流程

2. 客服机器人

用户问:如何退货?
RAG 检索到《退货政策》相关段落
LLM 基于政策回答退货流程

3. 代码文档问答

开发者问:这个 API 怎么用?
RAG 检索到 API 文档相关段落
LLM 基于文档给出使用示例

常见问题

1. 检索不到相关内容

  • 检查分块是否合理
  • 增加检索数量 k
  • 尝试不同的 Embedding 模型

2. 回答不准确

  • 优化 Prompt,要求基于文档回答
  • 增加重排序步骤
  • 检查文档质量

3. 响应太慢

  • 减少检索数量
  • 使用更快的 Embedding 模型
  • 缓存常见问题

总结

RAG 是让大模型拥有私有知识的关键技术:

  1. 离线:文档分块 → 向量化 → 存储
  2. 在线:问题向量化 → 检索 → LLM 回答

掌握 RAG,就能构建基于企业私有数据的 AI 应用。