LangChain 中主流的 RAG 实现方式

文章目录

  • **一、基础流程实现**
    • 1. **全自动索引构建(VectorstoreIndexCreator)**
    • 2. **标准问答链(RetrievalQA)**
    • 3. **Document Chain + 手动检索**
    • 4. **load_qa_chain(传统方式)**
  • **二、高级定制化实现**
    • 1. **自定义提示工程**(RetrievalQA)
    • 2. **混合检索策略**
  • **三、性能优化实现**
    • 1. **重排序(Re-ranking)**
    • 2. **上下文压缩(Context Compression)**
  • **四、扩展功能实现**
    • 1. **多模态 RAG**
    • 2. **多步检索(Multi-hop Retrieval)**
  • **五、生产级实现(基于 LCEL)**
    • 1. **链式组合(LCEL Pipeline)**
    • **总结对比**

以下是 LangChain 中主流的 RAG 实现方式及其核心原理、应用场景和代码示例,综合多篇技术文档的实践经验整理而成:


一、基础流程实现

1. 全自动索引构建(VectorstoreIndexCreator)

原理:封装文档加载→分块→向量化→存储→检索全流程,适合快速原型开发。通过指定向量
存储类型(如 FAISS)和嵌入模型,自动完成索引构建。
特点:自动处理文本分块和向量索引,但灵活性较低
代码示例

from langchain.indexes import VectorstoreIndexCreator
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import FAISSindex_creator = VectorstoreIndexCreator(vectorstore_cls=FAISS,embedding=OpenAIEmbeddings()  # 需提前配置
)
loader = WebBaseLoader("https://example.com")
index = index_creator.from_loaders([loader])  # 自动完成分块+索引
result = index.query("文章主题是什么?", llm=ChatOpenAI())  # 需显式传入LLM

2. 标准问答链(RetrievalQA)

原理:基于内置模板实现检索增强生成,支持stuff(文档拼接)、map_reduce(分块处理)等链类型。
优化点:通过search_kwargs控制检索数量和质量(如过滤低分文档)。
代码示例
内置默认模板:
LangChain 的 RetrievalQA 默认使用以下隐式模板(未显式声明时自动应用):

template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.{context}Question: {question}
Helpful Answer:"""

特点

  • 仅包含 {context}{question} 两个占位符
  • 无语言或格式约束,依赖 LLM 的通用生成能力
  • 未明确处理文档来源或回答规范(易产生幻觉)
    示例(修改prompt):
from langchain_core.prompts import PromptTemplate
# 修改默认template
template = """你是一个专业的知识库助手。根据以下检索到的文档内容回答问题:
{context}问题:{question}
回答要求:
1. 用中文简洁回答,引用来源编号(如[来源1])
2. 若文档不相关,回答“知识库中无相关信息”
3. 禁止编造未提及的内容"""QA_PROMPT = PromptTemplate(template=template, input_variables=["context", "question"]
)
from langchain.chains import RetrievalQA
from langchain_community.vectorstores import FAISS
from langchain_openai import ChatOpenAI, OpenAIEmbeddings# 初始化组件
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.load_local("db", embeddings)
llm = ChatOpenAI(model="gpt-4", temperature=0.2)# 构建问答链
qa_chain = RetrievalQA.from_chain_type(llm=llm,chain_type="stuff",retriever=vectorstore.as_retriever(search_kwargs={"k": 3, "score_threshold": 0.7} #注意score_threshold的设置可能会过滤所有文档,应该进行测试以确定是否用该参数。),chain_type_kwargs={"prompt": QA_PROMPT},  # 注入自定义模板return_source_documents=True  # 必须启用以显示来源
)# 提问与回答示例
question = "如何优化RAG系统的检索精度?"
result = qa_chain.invoke({"query": question})# 解析结果
print(f"问题:{question}")
print(f"回答:{result['result']}\n")print("=== 参考来源 ===")
for i, doc in enumerate(result['source_documents'][:3], 1):print(f"[来源{i}] 文件:{doc.metadata.get('source', '未知')}")print(f"内容片段:{doc.page_content[:150]}...\n")

3. Document Chain + 手动检索

原理:分离检索与生成步骤,适合需要预处理文档的场景
优势:可手动过滤/排序检索结果

from langchain.chains.combine_documents import create_stuff_documents_chaindocument_chain = create_stuff_documents_chain(llm=ChatOpenAI(),prompt=prompt  # 需提前定义
)
docs = vectorstore.similarity_search("问题", k=4, filter={"source": "权威.pdf"})
answer = document_chain.invoke({"input": "问题","context": [d.page_content for d in docs]  # 可手动处理文档
})

4. load_qa_chain(传统方式)

原理:直接传入文档列表,适合小规模数据
注意:文档需预先处理好分块 ,该方法的result是字符串,没有metadata信息。

from langchain.chains.question_answering import load_qa_chainchain = load_qa_chain(llm=ChatOpenAI(),chain_type="map_reduce"  # 支持stuff/map_reduce/refine
)
result = chain.run(input_documents=chunks,  # 需自行加载文档question="核心观点是什么?"
)

二、高级定制化实现

1. 自定义提示工程(RetrievalQA)

原理:通过设计模板控制生成风格,强制 LLM 基于上下文回答,减少幻觉。
关键:模板需包含{context}{question}变量,支持中文指令约束。
优化点

  • 引用标注:强制显示来源文档编号(需配合 return_source_documents=True
  • 语言约束:限定中文回答(适配中文知识库)
  • 防幻觉指令:明确禁止编造答案(降低错误率)
    代码示例
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA
import os# 配置OpenAI API(需提前设置环境变量)
os.environ["OPENAI_API_KEY"] = "sk-xxx"  # 替换为您的API密钥# 初始化组件(假设vectorstore已提前创建)
vectorstore = ...  # 您的向量存储实例# 创建自定义提示模板
template = """基于以下上下文(请严格依据给出内容):
{context}问题:{question}
回答要求:
1. 用中文回答,保持专业严谨
2. 每个观点标注来源编号(如[1])
3. 若上下文不相关,回答「该问题不在知识库范围内」"""
prompt = ChatPromptTemplate.from_template(template)# 构建问答链
qa_chain = RetrievalQA.from_chain_type(llm=ChatOpenAI(temperature=0.3, model="gpt-4-turbo"),  # 控制生成稳定性chain_type="stuff",chain_type_kwargs={"prompt": prompt},retriever=vectorstore.as_retriever(search_kwargs={"k": 5, "score_threshold": 0.65}  #  #注意score_threshold的设置可能会过滤所有文档,应该进行测试以确定是否用该参数。),return_source_documents=True
)# ------------------- 提问与获取答案 ------------------- #
def ask_question(question: str):try:# 执行问答result = qa_chain.invoke({"query": question})# 解析结果print(f"\n=== 问题 ===\n{question}")print(f"\n=== 回答 ===\n{result['result']}")# 显示参考来源(前3个)print("\n=== 参考来源 ===")for i, doc in enumerate(result['source_documents'][:3], 1):print(f"[来源{i}] {doc.metadata.get('source', '未知文件')}")print(f"内容片段: {doc.page_content[:150]}...\n")except Exception as e:print(f"请求失败: {str(e)}")# 示例提问
if __name__ == "__main__":questions = ["LangChain的核心组件有哪些?",  # 知识库相关问题"如何实现混合检索策略?",       # 技术细节问题"2024年世界杯冠军是谁?"       # 知识库范围外问题]for q in questions:ask_question(q)print("="*60)

2. 混合检索策略

原理:结合语义搜索(向量相似度)与关键词检索(BM25),提升召回率。
适用场景:处理专业术语或模糊查询时,兼顾语义和字面匹配。
代码示例

from langchain.retrievers import BM25Retriever, EnsembleRetriever# 初始化混合检索器
bm25_retriever = BM25Retriever.from_documents(docs)
vector_retriever = vectorstore.as_retriever()
hybrid_retriever = EnsembleRetriever(retrievers=[bm25_retriever, vector_retriever],weights=[0.3, 0.7]
)

三、性能优化实现

1. 重排序(Re-ranking)

原理:对初筛结果用交叉编码器(如 Cohere Rerank)重新排序,提升精准度。
代码示例

from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import CohereRerankcompressor = CohereRerank(cohere_api_key="YOUR_KEY", top_n=5)
compression_retriever = ContextualCompressionRetriever(base_retriever=vectorstore.as_retriever(search_kwargs={"k": 20}),base_compressor=compressor
)

2. 上下文压缩(Context Compression)

原理:提取检索文档中的关键片段,减少无关信息输入。
实现方式

  • 抽取式:用 LLM 提取与问题相关的句子
  • 摘要式:生成文档摘要后检索
    代码示例
from langchain.chains import LLMChainExtractorextractor = LLMChainExtractor.from_llm(ChatOpenAI())
compression_retriever = ContextualCompressionRetriever(base_retriever=vectorstore.as_retriever(),base_compressor=extractor
)

四、扩展功能实现

1. 多模态 RAG

原理:支持图片、表格等非文本数据,需结合 OCR(如 Tesseract)和专用解析器(如 DeepDoc)。
代码示例

# 图片处理流程示例
from langchain.document_loaders import UnstructuredImageLoader
from paddleocr import PaddleOCRloader = UnstructuredImageLoader("report.png", ocr_tool=PaddleOCR())
documents = loader.load()

2. 多步检索(Multi-hop Retrieval)

原理:通过迭代检索优化结果,例如先检索大纲再定位细节。
代码示例

from langchain.agents import AgentExecutor, Toolretriever_tool = Tool(name="DocumentRetriever",func=vectorstore.as_retriever().invoke,description="检索技术文档"
)
agent = initialize_agent([retriever_tool], llm, agent="conversational")
result = agent.run("某功能的使用场景是什么?请分步骤说明。")

五、生产级实现(基于 LCEL)

1. 链式组合(LCEL Pipeline)

原理:利用 LangChain 表达式语言构建可扩展的流式处理管道,支持批处理和异步。
代码示例

from langchain_core.runnables import RunnablePassthroughrag_chain = ({"context": retriever | format_docs, "question": RunnablePassthrough()}| prompt| llm| StrOutputParser()
)# 流式输出
for chunk in rag_chain.stream("最新技术趋势是什么?"):print(chunk, end="")

总结对比

实现方式核心优势适用场景复杂度
全自动索引快速原型开发技术验证、小规模数据
自定义Prompt控制生成风格专业领域问答(法律、医疗)
混合检索提升召回率模糊查询、多义词处理
LCEL 管道支持流式/批处理高并发生产环境最高

建议选择路径

  • 快速验证 → VectorstoreIndexCreator 或 RetrievalQA
  • 专业问答 → 自定义提示 + 重排序
  • 生产部署 → LCEL 管道 + 混合检索

更多细节可参考 LangChain 官方文档及实践案例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/78129.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决:springmvc工程 响应时,将实体类对象 转换成json格式数据

问题:一直无法将user对象转成json格式 按理来说,我在类上使用RestController注解,就可以实现将实体类对象写入响应体中,并作为json格式传递到客户端,但现实是没有生效,并且出现404,406&#xf…

【踩坑记录】stm32 jlink程序烧录不进去

最近通过Jlink给STM32烧写程序时一直报错,但是换一个其他工程就可以烧录,对比了一下jink配置,发现是速率选太高了“SW Device”,将烧录速率调整到10MHz以下就可以了

运维打铁:Mysql 分区监控以及管理

文章目录 一、简介二、设计逻辑1、配置文件检查2、创建逻辑3、 删除逻辑4、重建表分区逻辑5、recognize maxvalue分区表逻辑6、创建多个未来分区逻辑7、定时检测分区是否创建成功,否则发送告警邮件。 三、解决的问题四、配置例子与介绍 一、简介 操作数据库&#xf…

Appium自动化开发环境搭建

自动化 文章目录 自动化前言 前言 Appium是一款开源工具,用于自动化iOS、Android和Windows桌面平台上的本地、移动web和混合应用程序。原生应用是指那些使用iOS、Android或Windows sdk编写的应用。移动网页应用是通过移动浏览器访问的网页应用(appum支持iOS和Chrom…

《R语言SCI期刊论文绘图专题计划》大纲

今天开始,我将和大家分享系统且详细的《R语言SCI期刊绘图专题教程》,内容会从基础到高阶应用,从配色美学到顶刊风格复现,确保大家可以学到高质量内容!下面是大纲。 📚《R语言SCI期刊论文绘图专题计划》 第…

STUN协议 与 TURN协议

STUN(Session Traversal Utilities for NAT,NAT会话穿越应用程序)是一种网络协议, STUN(Simple Traversal of User Datagram Protocol through Network Address Translators (NATs),NAT的UDP简单穿越&#…

在vscode终端中运行npm命令报错

解决方案 这个错误信息表明,你的系统(可能是 Windows)阻止了 PowerShell 执行脚本,这是由于 PowerShell 的执行策略导致的。PowerShell 的执行策略控制着在系统上运行哪些 PowerShell 脚本。默认情况下,Windows 可能…

手搓雷达图(MATLAB)

看下别人做出来什么效果 话不多说,咱们直接开始 %% 可修改 labels {用户等级, 发帖数, 发帖频率, 点度中心度, 中介中心度, 帖子类型计分, 被列为提案数}; cluster_centers [0.8, 4.5, 3.2, 4.0, 3.8, 4.5, 4.2; % 核心用户0.2, 0.5, 0.3, 0.2, 0.1, 0.0, 0.0;…

ViViT: 一种视频视觉Transformer

摘要 我们提出了基于纯transformer的视频分类模型,借鉴了这种模型在图像分类中的成功经验。我们的模型从输入视频中提取时空token,然后通过一系列transformer层进行编码。为了处理视频中遇到的长序列token,我们提出了几种高效的模型变种,这些变种将输入的空间和时间维度进…

嵌入式鸿蒙系统环境搭建与配置要求实现01

各位开发者大家好,今天主要给大家分享一下,鸿蒙系统的环境配置实现。 第一:鸿蒙配置基本要求 对电脑的要求,虚拟机配置建议 200GB 硬盘大小,10GB 内存,4*2CPU。 安装必要的依赖文件方法: sudo apt-get update && sudo apt-get install binutils git git-lfs g…

【多目标进化算法】常见多目标进化算法一览

算法全称核心特点备注NSGA-IINon-dominated Sorting Genetic Algorithm II非支配排序 拥挤度最经典,应用最广NSGA-IIINon-dominated Sorting Genetic Algorithm III支撑向量引导,适合高维(3目标以上)NSGA-II 的高维扩展版MOEA/DM…

创意无限,从这些视频素材开始你的创作!

在视频创作的世界里,找到合适的素材就像是挖掘宝藏,不仅能节省时间,还能让作品瞬间提升一个档次。今天,就来给大家分享一些超实用的视频素材网站,无论是国内的宝藏平台,还是国外的优质资源,都能…

QT创建新项目(13)

文章目录 一、本章说明二、QT组件简介及相关笔记三、项目创建四、QT学习建议一、本章说明 注:本节为【基于STM的环境监测系统(节点+云服务器存储+QT界面设计)】项目第13篇文章,前面已安装了QT软件,本章主要介绍新项目创建及注意事项,QT的初学者相关学习资料 二、QT组件…

Langgraph实战-Agent-ReAct(Reason+Act)概述

Langgraph实战-Agent-ReAct(ReasonAct)概述 概述 ReAct 架构将推理与动作相结合,使Agent能够通过生成想法并基于这些想法执行动作。这种决策透明度使Agent能够更负责地执行任务,因为它会记录每一步的推理过程。 这种架构最适合…

论文笔记(七十九)STOMP: Stochastic Trajectory Optimization for Motion Planning

STOMP: Stochastic Trajectory Optimization for Motion Planning 文章概括摘要一、引言二、相关工作三、STOMP 算法A. 探索B. 轨迹更新 四、机械臂的运动规划A. 设置B. 代价函数1)障碍物代价:2)约束代价:3)扭矩代价&a…

MCU开发学习记录9 - 通用定时器学习与实践(HAL库) -RGBLED控制、定时器输入捕获、主从定时器移相控制-STM32CubeMX

本文将介绍通用定时器的概念、相关函数以及STM32CubeMX生成定时器的配置函数以及对生成定时器的配置函数进行分析(包括结构体配置、相关寄存器配置)。 本文以TIM2/TIM5、TIM3/TIM4为基础介绍通用定时器(包含通用定时器全部功能&#…

Java学习手册:TCP 协议基础

一、TCP 协议概述 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,它在 IP 协议的基础上提供了可靠的 数据传输服务。TCP 通过三次握手建立连接,通过四次挥手…

删除排序数组中的重复项--LeetCode

题目 给你一个非严格递增排列的数组 nums ,请你原地删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k &#xff0c…

【Elasticsearch】入门篇

Elasticsearch 入门 前言 官方地址:Elastic — 搜索 AI 公司 | Elastic ES 下载地址:Past Releases of Elastic Stack Software | Elastic 文档:什么是 Elasticsearch?|Elasticsearch 指南 简介 Elasticsearch 是一个分布式、…

2024新版仿蓝奏云网盘源码,已修复已知BUG,样式风格美化,可正常运营生产

说起网盘源码,网络上出现的也很多,不过可真正正能够用于运营的少之又少。今天将的蓝奏云网盘源码,其实网络上也有,不过是残缺版,bug很多。我今天分享的仿蓝奏云模板是经过长时间测试修复后的源码,源码实测可…