【大语言模型】-- RAG
摘要: RAG(检索增强生成)通过结合大型语言模型(LLM)与外部知识库,解决了模型静态知识、幻觉和领域局限问题。其架构分为三部分: 检索器:使用密集向量(如FAISS)、稀疏检索(如BM25)或混合方法动态查找相关文档; 增强模块:通过重排序和上下文压缩优化检索结果,减少噪声; 生成器:基于Prompt工程控制LLM生成答案,确保依赖上下文且可信。示例代码展示了LangChain实现RAG的流程
·

文章目录
文章目录
RAG
尽管大型语言模型展现了惊人的通识能力,但我们深知其固有的局限性:参数化知识的静态性、事实性幻觉以及领域知识的缺失。传统的微调方案虽能注入新知识,但成本高昂、灵活性差,且难以解决知识实时性问题。在此背景下,检索增强生成 作为一种将模型参数化知识与非参数化外部知识库动态结合的范式,成为了构建高性能、高可信度AI应用的事实标准。
RAG的核心思想是在LLM的生成过程之前,引入一个检索阶段,从大规模、可信的外部知识库中动态检索相关信息,并将其作为上下文提示给LLM,从而约束和增强模型的生成结果。本质上,它让模型学会了‘在回答问题前先查阅资料’。
RAG的技术架构分解

模块一:检索器 - 寻找相关的信息
- 密集向量检索:
-
- 核心:将查询和文档映射到同一高维向量空间,通过近似最近邻搜索查找最相似的文档。
-
- 技术栈:Sentence-BERT/Contriever 等双编码器模型用于产生Embedding;FAISS, HNSW, SCANN 等库用于高效索引和检索。
-
- 关键挑战: Embedding模型的质量决定了检索效果的上限。领域适配的Embedding模型至关重要。
- 稀疏检索:
-
- 代表: BM25, 一种经典且强大的基于词频的检索算法。
-
- 优势: 对精确关键词匹配、命名实体等任务非常有效,无需训练。
- 混合检索:
-
- 策略:结合密集检索的语义理解能力和稀疏检索的精确匹配能力。
-
- 融合方法: Reciprocal Rank Fusion, 加权分数融合等。这是目前工业界的主流方案,以求在召回率和准确率之间达到最佳平衡。
模块二:增强 - 准备给模型的“参考资料”
- 重排序:
-
- 目的: 初检返回的Top-K结果中可能存在与查询语义相关但实际不有用的文档。重排序使用更精细的模型(如Cross-Encoder)对(Query, Doc)对进行精细化打分,重新排序,提升Top结果的精度。
- 上下文压缩:
-
- 问题: 检索到的完整文档可能包含大量冗余信息,消耗宝贵的上下文窗口并引入噪声。
-
- 解决方案:
-
- 抽取式: 仅提取与查询最相关的句子或段落。
-
- 抽象式: 使用一个小型模型对长文档进行摘要,再将摘要送入LLM。
模块三:生成器 - 基于上下文的答案合成
- Prompt工程:
-
- 构建清晰的指令,明确要求模型基于给定的上下文回答问题。
-
- 关键指令模式:“请严格根据以下背景信息回答问题。如果背景信息中不包含答案,请直接说‘根据已知信息无法回答该问题’。”
- 生成控制:
-
- 可以通过调整temperature等参数,控制生成的专业性和创造性。
示例代码
import os
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain import hub
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
# 设置 OpenAI API Key (请替换为您的密钥)
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
# 1. 加载文档 (这里以本地txt文件为例)
loader = TextLoader("path/to/your/document.txt")
documents = loader.load()
# 2. 文档分割
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # 块大小
chunk_overlap=200 # 块重叠
)
docs = text_splitter.split_documents(documents)
# 3. 创建向量数据库
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(docs, embeddings)
# 4. 创建检索器
retriever = vectorstore.as_retriever(
search_type="similarity", # 检索方式:相似度
search_kwargs={"k": 4} # 返回top-4个相关文档块
)
# 5. 定义Prompt模板 (使用LangChain Hub的RAG prompt)
prompt = hub.pull("rlm/rag-prompt")
# 6. 初始化LLM
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
# 7. 定义RAG处理链
def format_docs(docs):
"""将检索到的文档格式化为单个字符串"""
return "\n\n".join(doc.page_content for doc in docs)
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
# 8. 使用RAG链进行问答
question = "什么是机器学习?"
answer = rag_chain.invoke(question)
print(f"问题: {question}")
print(f"答案: {answer}")
系列文章
【大语言模型】-- OpenAI定义的五个AGI发展阶段
【大语言模型】-- Fine-tuning 微调
【大语言模型】-- 私有化部署
【大语言模型】-- Prompt Engineering 提示工程
【大语言模型】-- Function Calling函数调用
【大语言模型】-- RAG
【大语言模型】-- Agent
【大语言模型】-- 一些概念
更多推荐


所有评论(0)