当前位置: 首页 > news >正文

LangChain RAG 简述

在 LangChain 中实现 RAG(检索增强生成,Retrieval-Augmented Generation)的核心思路是:让大模型在生成回答前,先从外部知识库(如文档、数据库等)中检索相关信息,再基于检索到的内容生成更准确、更可靠的回答。LangChain 提供了丰富的组件和工具链,支持多种 RAG 实现方法,适配不同场景(如简单文档问答、多源信息整合、对话式问答等)。以下是常见的方法及具体实现步骤:

一、基础 RAG:单文档/单源检索增强

适用场景:简单的文档问答(如单篇论文、手册、长文本的精准问答),核心是“加载→分割→嵌入→存储→检索→生成”的完整流程。

具体做法:
  1. 文档加载(Document Loading)
    用 LangChain 的 DocumentLoaders 加载目标文档(支持 PDF、TXT、Word、网页等多种格式),将文档转换为 LangChain 标准的 Document 对象(包含文本内容 page_content 和元数据 metadata)。
    常用工具:PyPDFLoader(PDF)、TextLoader(TXT)、UnstructuredFileLoader(多格式)、WebBaseLoader(网页)等。

    from langchain.document_loaders import PyPDFLoader  
    loader = PyPDFLoader("论文.pdf")  # 加载 PDF 文档  
    documents = loader.load()  # 得到 Document 列表  
    
  2. 文档分割(Text Splitting)
    长文档直接嵌入会丢失上下文,需用 TextSplitter 分割为短片段(chunk)。关键是控制 chunk_size(片段长度)和 chunk_overlap(片段重叠度,保留上下文关联)。
    常用工具:RecursiveCharacterTextSplitter(通用分割,按标点/换行递归分割)、CharacterTextSplitter(简单字符分割)等。

    from langchain.text_splitter import RecursiveCharacterTextSplitter  
    text_splitter = RecursiveCharacterTextSplitter(  chunk_size=1000,  # 每个片段 1000 字符  chunk_overlap=200  # 重叠 200 字符,保留上下文  
    )  
    splits = text_splitter.split_documents(documents)  # 分割后的 Document 列表  
    
  3. 文本嵌入(Embedding)
    将分割后的文本片段转换为向量(嵌入),以便后续通过向量相似度检索相关内容。需用嵌入模型生成向量。
    常用工具:OpenAIEmbeddings(OpenAI 的 embedding 模型)、HuggingFaceEmbeddings(开源模型如 BERT、Sentence-BERT)等。

    from langchain.embeddings import OpenAIEmbeddings  
    embeddings = OpenAIEmbeddings()  # 使用 OpenAI 的 embedding 模型  
    
  4. 向量存储(Vector Storage)
    将嵌入向量和对应的文本片段存储到向量数据库(VectorStore),支持高效的相似度检索。
    常用工具:轻量本地库 ChromaFAISS;云端服务 PineconeWeaviateMilvus 等。

    from langchain.vectorstores import Chroma  
    # 初始化向量库并添加文档(自动完成嵌入和存储)  
    vectorstore = Chroma.from_documents(  documents=splits,  embedding=embeddings,  persist_directory="./chroma_db"  # 本地存储路径  
    )  
    vectorstore.persist()  # 持久化存储  
    
  5. 构建检索器(Retriever)
    从向量库中检索与问题相关的文本片段,作为 RAG 的“检索”环节。LangChain 的 VectorStore 可直接转换为 Retriever

    retriever = vectorstore.as_retriever(  search_kwargs={"k": 3}  # 检索最相关的 top 3 片段  
    )  
    
  6. 生成回答(Generation)
    用大模型(LLM)结合检索到的内容生成回答,通过 RetrievalQA 链串联“检索→生成”流程。

    from langchain.chat_models import ChatOpenAI  
    from langchain.chains import RetrievalQA  llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)  # 大模型  
    qa_chain = RetrievalQA.from_chain_type(  llm=llm,  chain_type="stuff",  # 将检索到的内容全部传入模型  retriever=retriever,  return_source_documents=True  # 返回检索到的源文档(可选)  
    )  # 提问并获取回答  
    query = "这篇论文的核心创新点是什么?"  
    result = qa_chain({"query": query})  
    print(result["result"])  # 回答内容  
    print(result["source_documents"])  # 检索到的源文档  
    

二、进阶 RAG:多阶段检索与精准优化

适用场景:当基础 RAG 检索相关性不足(如文档量大、歧义问题)时,通过多阶段检索或重排序提升精度。

具体做法:
  1. 多查询检索(Multi-Query Retrieval)
    对原始问题生成多个相似查询(由 LLM 自动扩展),用多个查询检索后合并结果,覆盖更多相关片段。

    from langchain.retrievers.multi_query import MultiQueryRetriever  # 用 LLM 生成多个查询  
    retriever_from_llm = MultiQueryRetriever.from_llm(  retriever=vectorstore.as_retriever(),  llm=ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)  
    )  # 用多查询检索结果回答  
    qa_chain = RetrievalQA.from_chain_type(  llm=llm,  chain_type="stuff",  retriever=retriever_from_llm  
    )  
    
  2. 上下文压缩检索(Contextual Compression)
    先检索初步结果,再用“重排序模型(Reranker)”或“过滤模型”对结果二次筛选,保留最相关的片段。
    常用工具:ContextualCompressionRetriever 结合 CohereRerankRankGPT 等重排序工具。

    from langchain.retrievers import ContextualCompressionRetriever  
    from langchain.retrievers.document_compressors import CohereRerank  # 初始化重排序器(需 Cohere API 密钥)  
    compressor = CohereRerank(model="rerank-english-v2.0", top_n=3)  
    # 构建压缩检索器  
    compression_retriever = ContextualCompressionRetriever(  base_compressor=compressor,  base_retriever=vectorstore.as_retriever(search_kwargs={"k": 10})  # 先检索 top 10  
    )  # 用压缩后的结果生成回答  
    qa_chain = RetrievalQA.from_chain_type(  llm=llm,  chain_type="stuff",  retriever=compression_retriever  
    )  
    
  3. 混合检索(Hybrid Retrieval)
    结合“向量检索(语义相似)”和“关键词检索(精确匹配)”,兼顾语义理解和精准关键词匹配(如专业术语)。
    常用工具:PineconeWeaviate 等支持混合检索的向量库,或用 LangChainMultiRetriever 组合。

三、多源 RAG:跨类型/跨库信息整合

适用场景:需要从多个数据源(如文档、数据库、API、表格等)检索信息,整合后生成回答(如企业知识库+产品数据库的问答)。

具体做法:
  1. 多向量库检索(Multi-VectorStore Retrieval)
    为不同类型的文档(如技术手册、用户案例、API 文档)创建独立向量库,检索时并行查询并合并结果。

    # 初始化多个向量库  
    vectorstore_tech = Chroma.from_documents(tech_docs, embeddings, persist_directory="./tech_db")  
    vectorstore_case = Chroma.from_documents(case_docs, embeddings, persist_directory="./case_db")  # 构建多检索器  
    from langchain.retrievers import MultiRetriever  
    retrievers = [  vectorstore_tech.as_retriever(search_kwargs={"k": 2}),  vectorstore_case.as_retriever(search_kwargs={"k": 2})  
    ]  
    multi_retriever = MultiRetriever(retrievers=retrievers)  # 用多检索器生成回答  
    qa_chain = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=multi_retriever)  
    
  2. 结构化+非结构化混合检索
    结合非结构化文档(向量检索)和结构化数据(如 SQL 数据库、CSV 表格),用 SQLDatabaseChainTableQA 处理结构化查询,再与文档检索结果整合。

    from langchain.chains import SQLDatabaseChain  
    from langchain.sql_database import SQLDatabase  # 连接 SQL 数据库  
    db = SQLDatabase.from_uri("sqlite:///产品库存.db")  
    sql_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)  # 定义路由逻辑:判断问题需要文档检索还是数据库查询  
    from langchain.chains import RouterChain, LLMRouterChain, MultiPromptChain  
    from langchain.prompts import PromptTemplate  # 路由提示:让 LLM 判断问题类型  
    route_prompt = PromptTemplate(  template="""判断问题需要查询文档还是数据库:{input}  输出 'doc' 或 'sql'""",  input_variables=["input"]  
    )  
    router_chain = LLMRouterChain.from_llm(llm, route_prompt)  # 整合链:根据路由结果调用对应工具  
    chains = {"doc": qa_chain, "sql": sql_chain}  
    multi_chain = MultiPromptChain(router_chain=router_chain, destination_chains=chains)  # 提问(如“产品A的库存有多少?”→ 路由到 SQL;“产品A的使用场景?”→ 路由到文档)  
    result = multi_chain.run("产品A的库存和使用场景分别是什么?")  
    

四、对话式 RAG:带历史记忆的检索增强

适用场景:对话场景(如客服机器人),需要结合历史对话上下文动态检索,确保回答连贯性(如“上一个问题提到的功能如何操作?”)。

具体做法:

ConversationalRetrievalChain 替代基础 RetrievalQA,自动处理对话历史,生成包含历史上下文的检索查询。

from langchain.chains import ConversationalRetrievalChain  
from langchain.memory import ConversationBufferMemory  # 初始化对话记忆(存储历史对话)  
memory = ConversationBufferMemory(  memory_key="chat_history",  # 记忆键名  return_messages=True,  # 返回消息对象  output_key="answer"  # 输出键名(与链对齐)  
)  # 构建对话式 RAG 链  
conv_chain = ConversationalRetrievalChain.from_llm(  llm=llm,  retriever=retriever,  memory=memory,  return_source_documents=True  
)  # 多轮对话示例  
query1 = "这篇论文的研究背景是什么?"  
result1 = conv_chain({"question": query1})  
print(result1["answer"])  query2 = "基于这个背景,作者提出了什么方法?"  # 依赖上一轮历史  
result2 = conv_chain({"question": query2})  
print(result2["answer"])  

五、多模态 RAG:整合文本、图片、表格等跨类型信息

适用场景:文档包含图片、表格、公式等非文本内容(如 PDF 中的图表、PPT 中的图片),需检索多模态信息生成回答。

具体做法:
  1. 多模态文档加载:用 UnstructuredFileLoaderPyPDFLoader 加载含多模态内容的文档,保留图片/表格元数据。
  2. 多模态嵌入:对文本用常规嵌入模型,对图片用视觉嵌入模型(如 CLIP),存储到支持多模态的向量库(如 QdrantWeaviate)。
  3. 多模态检索:检索时同时匹配文本和图片向量,生成回答时引用图片内容(如“图1展示了XXX流程”)。
# 示例:加载含图片的 PDF 并保留图片元数据  
from langchain.document_loaders import PyPDFLoader  
loader = PyPDFLoader("带图片的文档.pdf", extract_images=True)  # 提取图片  
documents = loader.load()  # 多模态向量库存储(以 Qdrant 为例)  
from langchain.vectorstores import Qdrant  
from langchain.embeddings import HuggingFaceBgeEmbeddings  # 文本嵌入  
from PIL import Image  
import clip  # 视觉嵌入模型  # 文本嵌入 + 图片嵌入逻辑(需自定义处理)  
# ...(省略图片嵌入细节)  # 构建多模态检索器并生成回答  
qdrant = Qdrant.from_documents(...)  
retriever = qdrant.as_retriever()  
qa_chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever)  

总结

LangChain 实现 RAG 的核心是通过“组件化”灵活组合文档处理、检索、生成环节,关键方法可归纳为:

  • 基础流程:加载→分割→嵌入→存储→检索→生成;
  • 精度优化:多查询、重排序、混合检索;
  • 多源整合:多向量库、结构化+非结构化混合;
  • 场景适配:对话式记忆、多模态检索。

实际应用中需根据文档类型、问答场景选择合适的方法,并通过调整 chunk_size、检索 k 值、重排序策略等优化效果。

http://www.lryc.cn/news/626096.html

相关文章:

  • [激光原理与应用-309]:光学设计 - 什么是光学系统装配图,其用途、主要内容、格式与示例?
  • 47 C++ STL模板库16-容器8-关联容器-集合(set)多重集合(multiset)
  • PyTorch数据处理工具箱(utils.data简介)
  • 设计模式笔记_行为型_解释器模式
  • 【Spring Boot把日志记录到文件里面】
  • 疯狂星期四文案网第44天运营日记
  • GPT-5论文写作全流程提示词库
  • MAC 设置输入法
  • 为 Time 类实现构造函数,默认初始化成 23:59:55,也可以指定时间,要求使用初始化参数列表:C++代码解释
  • linux服务器rsyslog进程启动失败分析
  • Python 项目里的数据预处理工作(数据清洗步骤应用)续篇
  • 3D检测笔记:MMDetection3d环境配置
  • Kubernetes Pod 控制器
  • 基于uni-app的成人继续教育教务管理系统设计与实现
  • PyTorch自动求导
  • 开源 C++ QT Widget 开发(一)工程文件结构
  • vfs_statfs使用 查看当前文件系统一些信息情况
  • RocketMq消费者动态订阅topic
  • 聚合链路与软件网桥的原理及配置方法
  • 【LeetCode 热题 100】279. 完全平方数——(解法一)记忆化搜索
  • JVM原生的assert关键字
  • 手写C++ string类实现详解
  • 使用redis读写锁实现抢券功能
  • 怎样平衡NLP技术发展中数据质量和隐私保护的关系?
  • JVM 面试精选 20 题(续)
  • JVM对象创建和内存分配
  • SpringAI接入openAI配置出现的问题全解析
  • 今日行情明日机会——20250819
  • Java开发面试实战:Spring Boot微服务与数据库优化案例分析
  • 星图云开发者平台新功能速递 | 微服务管理器:无缝整合异构服务,释放云原生开发潜能