共计 2286 个字符,预计需要花费 6 分钟才能阅读完成。
背景与痛点
传统生成式模型(如 GPT 系列)在开放域对话中表现优秀,但在知识密集型任务(如专业领域问答)中常出现 ” 幻觉 ” 现象——即生成看似合理但实际错误的内容。我曾在一个医疗问答项目中,发现基础 GPT- 3 模型会凭空编造药物剂量信息,这对实际应用是致命的。

RAG(Retrieval-Augmented Generation)通过将信息检索与文本生成结合,有效解决了这个问题:
- 知识更新难题 :传统模型训练后知识固化,而 RAG 可随时更新知识库
- 可解释性提升 :生成答案时能引用具体来源文档
- 成本优势 :比持续微调大模型更经济
技术架构图解
典型 RAG 系统包含三个核心组件:
graph LR
A[用户问题] --> B[检索器]
B --> C[相关文档片段]
C --> D[生成器]
D --> E[最终答案]
F[知识库] --> B
- 检索器 :将用户查询和文档都编码为向量,通过相似度检索(常用 cosine 相似度)
- 知识库 :通常包含分块后的文本片段及其向量表示
- 生成器 :接收原始问题 + 检索结果,生成最终回复
提示词设计实战
检索阶段提示词
检索质量直接决定最终效果。关键是要让查询向量尽可能匹配潜在答案的表述方式。例如在法律场景中:
# 错误示范 - 过于简短
query = "劳动合同解除条件"
# 优化方案 - 包含领域语境
query = "根据中国劳动法,在什么情况下用人单位可以单方面解除劳动合同?请列出具体法律条款"
好的检索提示词应:
- 包含领域限定词(如 ” 根据网络安全法 ”)
- 明确需要的答案类型(条款 / 案例 / 数据)
- 保留原始问题的核心意图
生成阶段模板
我常用的模板结构:
请基于以下上下文回答问题。如果无法找到答案,请如实说明。上下文:{context_str}
问题:{query_str}
要求:1. 回答不超过 3 句话
2. 如引用法律条款需注明条目
3. 避免主观推测
上下文窗口利用技巧
- 分块策略 :知识库文档建议按语义分块(如每段法律条款单独存储)
- 重排序 :使用 MMR(Maximal Marginal Relevance)平衡相关性与多样性
- 动态截断 :根据 token 限制优先保留相似度高的片段
完整代码示例
使用 LangChain 实现的基础流程:
from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
# 1. 加载知识库
docs = TextLoader("legal_docs.txt").load()
# 2. 文档分块(法律条款适合按段落分)text_splitter = RecursiveCharacterTextSplitter(
chunk_size=300,
chunk_overlap=30,
separators=["\n\n", "\n", "。", ";"]
)
splits = text_splitter.split_documents(docs)
# 3. 构建向量库
embeddings = HuggingFaceEmbeddings(model_name="paraphrase-multilingual-MiniLM-L12-v2")
db = FAISS.from_documents(splits, embeddings)
# 4. 定义检索器
retriever = db.as_retriever(
search_type="mmr", # 使用 MMR 算法
search_kwargs={"k": 3} # 返回 3 个最相关片段
)
# 5. 配置生成环节
qa_chain = RetrievalQA.from_chain_type(llm=ChatOpenAI(temperature=0), # 温度参数设为 0 减少随机性
chain_type="stuff",
retriever=retriever,
return_source_documents=True
)
# 6. 提问示例
result = qa_chain("劳动合同试用期最长几个月?")
print(result["result"])
print("来源:", result["source_documents"][0].metadata["source"])
性能优化方案
- 批量处理 :
- 对集中到达的查询先做批量向量化
-
使用 Redis 缓存高频查询结果
-
索引优化 :
- 对数值型字段(如发布日期)单独建立标量索引
-
使用 HNSW 等近似搜索算法加速检索
-
分级存储 :
- 热点文档保存在内存
- 历史数据存于磁盘
生产环境五大坑
- 冷启动问题 :
-
解决方案:预生成常见问题的答案缓存
-
领域术语漂移 :
- 现象:”APP” 在法律文档中指 ” 上诉 ” 而非应用程序
-
方案:构建领域同义词词典
-
长尾查询失效 :
-
监控机制:记录低置信度回答人工复审
-
版本不一致 :
-
严格同步:知识库更新后立即重建索引
-
超时风险 :
- 设置熔断机制:检索超时自动降级到基础模型
进阶方向
- 混合检索策略:结合关键词搜索与向量检索(如 Elasticsearch + FAISS)
- 动态提示词:根据检索结果自动调整生成指令
- 反馈闭环:将用户修正的答案反哺知识库
思考题
- 如何设计评估体系量化 RAG 系统的改进效果?
- 当知识库包含矛盾信息时,生成器应如何处理?
- 在实时性要求高的场景(如股票查询),如何优化 RAG pipeline 的延迟?
正文完
