共计 2206 个字符,预计需要花费 6 分钟才能阅读完成。
背景与痛点
检索增强生成(Retrieval-Augmented Generation, RAG)技术近年来在问答系统、知识库应用等领域大放异彩。它通过结合信息检索和文本生成的优势,让 AI 既能从海量数据中精准找到相关信息,又能生成流畅准确的回答。

但在实际开发中,我们常遇到几个痛点问题:
- 检索效率低下:当文档库规模达到百万级别时,传统检索方法响应时间会显著增加
- 生成结果不准确:有时模型会 ” 编造 ” 与检索内容无关的信息(即幻觉问题)
- 系统资源消耗大:同时运行检索和生成两个模块对计算资源要求较高
技术选型对比
检索模型对比
- BM25:经典的词频统计方法
- 优点:计算速度快,无需训练,适合中小规模数据集
-
缺点:无法理解语义,对同义词和复杂查询效果有限
-
DPR(Dense Passage Retrieval):基于 BERT 的稠密检索
- 优点:理解语义,对复杂查询效果好
- 缺点:需要训练,计算资源消耗较大
生成模型对比
- GPT 系列 :
- 优点:生成文本质量高,上下文理解能力强
-
缺点:可能产生幻觉,需要大量提示工程
-
T5:
- 优点:统一文本到文本框架,微调方便
- 缺点:生成多样性相对较低
选型建议 :
– 文档量 <1M 且对延迟敏感:BM25+GPT
– 需要高精度语义理解:DPR+T5
核心实现细节
典型的 RAG 系统架构包含三个关键组件:
- 文档处理流水线
- 文档分块(通常 256-512token)
- 向量化嵌入(使用预训练模型如 sentence-transformers)
-
构建向量数据库(FAISS 或 Annoy)
-
检索模块
- 将用户查询转换为向量
- 在向量数据库中执行近似最近邻搜索
-
返回 top- k 相关文档片段
-
生成模块
- 将检索结果与原始查询拼接为 prompt
- 语言模型生成最终回复
- 可选的后处理(如事实性校验)
代码示例
以下是一个基于 HuggingFace 的简化实现(需要安装 transformers 和 faiss-cpu):
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, AutoModel
import faiss
import numpy as np
# 1. 初始化模型
retriever = AutoModel.from_pretrained('facebook/dpr-ctx_encoder-single-nq-base')
generator = AutoModelForSeq2SeqLM.from_pretrained('t5-small')
tokenizer = AutoTokenizer.from_pretrained('t5-small')
# 2. 文档处理示例
docs = ["RAG combines retrieval and generation", "FAISS is for efficient similarity search"]
doc_embeddings = retriever(**tokenizer(docs, return_tensors='pt', padding=True)).pooler_output.detach().numpy()
# 3. 构建向量索引
index = faiss.IndexFlatIP(doc_embeddings.shape[1])
index.add(doc_embeddings)
# 4. 检索生成流程
def rag_query(query, k=1):
# 检索
query_embedding = retriever(**tokenizer([query], return_tensors='pt')).pooler_output.detach().numpy()
D, I = index.search(query_embedding, k)
# 生成
retrieved_docs = [docs[i] for i in I[0]]
input_text = f"question: {query} context: {' '.join(retrieved_docs)}"
inputs = tokenizer(input_text, return_tensors="pt")
outputs = generator.generate(inputs["input_ids"])
return tokenizer.decode(outputs[0], skip_special_tokens=True)
# 使用示例
print(rag_query("What does RAG combine?")) # 输出: retrieval and generation
性能与安全考量
性能优化
- 检索阶段 :
- 使用量化技术减小向量存储(如 PQ 量化)
-
分层导航小世界图(HNSW)索引加速搜索
-
生成阶段 :
- 模型蒸馏(如 T5-small 替代 base)
- 缓存高频查询结果
安全注意事项
- 数据隐私 :
- 敏感文档需脱敏处理
-
考虑本地化部署而非 API 调用
-
模型安全 :
- 设置生成内容过滤器
- 监控异常输出(如个人身份信息泄露)
生产环境避坑指南
- 冷启动问题 :
-
方案:预加载常用查询的 embedding
-
并发竞争 :
-
方案:为向量索引实现读写锁
-
文档更新延迟 :
-
方案:增量索引构建 + 定期全量重建
-
生成质量波动 :
- 方案:设置置信度阈值,低置信度时返回 ” 我不知道 ”
实践建议与互动
建议尝试用不同大小的文档块(128/256/512token)测试效果,你会发现:
– 小块更适合精准问答
– 大块更适合需要上下文的理解任务
思考题 :当处理超长文档(如整本书)时,应该如何优化 RAG 架构?欢迎在评论区分享你的解决方案和实践心得!