为什么需要 RAG?
大语言模型(LLM)虽然强大,但有两个硬伤:
- 知识截止日期:训练完成后就不再更新,不知道最新发生的事情
- 幻觉问题:不懂的问题也会编造答案,看起来有模有样但其实在胡说
RAG(Retrieval-Augmented Generation,检索增强生成)就是解决这两个问题的标准方案。
RAG 的核心流程
一句话概括:让模型在回答问题前,先去知识库里查一下相关资料,再根据查到的资料来回答。
整个流程分三步:
1. 索引(Indexing)—— 把知识库准备好
把文档(PDF、Wiki、数据库记录等)拆成小块(Chunk),每一块用 Embedding 模型转成向量(一串数字),存入向量数据库。
"什么是RAG?" → 向量化 → [0.023, -0.154, 0.672, ...] → 存入 Milvus/Qdrant
2. 检索(Retrieval)—— 找到相关内容
用户提问时,把问题也转成向量,去向量数据库里找最相似的 Top-K 个片段。
用户问:"RAG怎么减少幻觉?"
→ 向量化:用户问题
→ 向量检索:找到知识库里最相关的3个片段
3. 生成(Generation)—— 基于资料回答
把检索到的片段和用户问题一起拼成 Prompt,交给 LLM 生成最终答案。
System: 请基于以下资料回答问题:
[资料1] RAG通过引入外部知识减少幻觉...
[资料2] 知识库的质量直接影响RAG效果...
User: RAG怎么减少幻觉?
关键细节
Chunk 策略
切块是 RAG 效果的基础。常见的切法:
- 固定长度:256/512 tokens 一段,简单但可能切断语义
- 语义切分:按段落、句子边界切,效果更好
- 递归切分:先按段落切,太大的再按句子切,LangChain 的 RecursiveCharacterTextSplitter 就是这种
经验值:中文场景下,512 tokens 左右 + 128 tokens 重叠(Overlap)是比较稳妥的配置。
Embedding 选型
| 模型 | 维度 | 适用场景 | 推荐 |
|---|---|---|---|
| text-embedding-3-small | 1536 | 通用英文 | OpenAI |
| bge-large-zh-v1.5 | 1024 | 中文场景 | BAAI |
| stella-base-zh-v3 | 768 | 中文轻量 | infgrad |
| m3e-base | 768 | 中文通用 | 国产 |
中文场景优先选中文 Embedding 模型,英文模型的 tokenizer 对中文不友好,检索效果会明显差一截。
混合检索(Hybrid Search)
向量检索擅长语义匹配("苹果"→"iPhone"),但可能忽略精确关键词("iOS 18.3")。实际生产中推荐混合检索:
- 向量检索(语义相似度)× 关键词检索(BM25/全文匹配)
- 结果用 RRF(Reciprocal Rank Fusion)合并排序
# 混合检索伪代码
vec_results = vector_search(query, k=20)
kw_results = bm25_search(query, k=20)
merged = rrf_merge(vec_results, kw_results, k=5)
Re-ranking
检索到的 Top-K 结果用 Cross-Encoder 重排序,可以大幅提升最终效果。推荐:
- BAAI/bge-reranker-v2-m3(中文)
- cohere/rerank-multilingual-v3(收费)
进阶方向
- Agentic RAG:让 Agent 决定什么时候去查知识库、查什么、查多少次
- Graph RAG:用知识图谱代替向量库,适合需要多跳推理的场景(微软开源的 GraphRAG)
- Multi-modal RAG:同时检索文本+图片,适合文档问答
- Query 改写:把用户问题改写后再检索,效果往往比直接搜好
常用工具
- LangChain / LlamaIndex:RAG 编排框架
- Milvus / Qdrant / Chroma:向量数据库
- Unstructured.io:文档解析
- Jina AI:中文 RAG 工具链
总结
RAG 并不神秘,本质就是"先查资料再回答"。做好 RAG 的核心在于三个环节:
1. 切好块(Chunking)
2. 找得准(Retrieval)
3. 回答好(Generation)
每个环节都有很多优化空间,但从最简单的实现开始,跑通流程,再逐步优化,是最高效的学习路径。