RAG 每日一技(十四):化繁为简,统揽全局——用LangChain构建高级RAG流程

前情回顾

欢迎回来!经过十三天的学习,我们已经不再是RAG领域的新手。我们的武器库里装满了各种精良的武器:ChromaDB向量库、BM25关键词搜索、BGE-ReRanker精排器、HyDE查询生成器......

但一个严峻的现实摆在面前:这些武器都是独立存在的。如果我们想构建一个"先用HyDE改写查询,然后进行混合搜索,再对结果进行精排,最后把上下文喂给LLM"的复杂流程,我们就必须手动编写大量的**"胶水代码"**来连接每一步。

这种手动操作,就像在没有图纸和标准卡扣的情况下,用胶水去粘乐高积木。它不仅繁琐、易错,而且每当你想更换一个零件(比如换个LLM模型),就得把粘好的结构拆开重做,毫无效率可言。

我们需要一个"乐高底板"和一套"标准接口",来帮我们轻松地编排和管理这一切。这个"底板",就是大名鼎鼎的AI应用开发框架------LangChain

LangChain是什么?为什么需要它?

LangChain是一个开源框架,旨在简化由大型语言模型(LLM)驱动的应用程序的开发。它不是要取代我们学过的任何一个组件,而是要成为它们的**"指挥家""编排者"**。

它的核心价值在于:

  1. 标准化:为LLM、向量数据库、检索器等各种组件提供了统一的、标准化的接口。
  2. 可组合性:提供了一种优雅的方式,将这些标准化的组件像链条一样"链接"起来,形成复杂的工作流。
  3. 生态丰富:集成了市面上几乎所有主流的模型、工具和数据库。

而实现这一切的现代核心,就是LangChain表达式语言(LCEL) ,它允许我们用一种极其简洁、类似管道符 | 的语法来构建"链(Chain)"。

上手实战:用LCEL构建"检索-精排-生成"链

我们将用LCEL来构建一个包含检索、精排、生成三个步骤的高级RAG流程,让你亲身感受它的魅力。

首先,确保你安装了所有相关的库:

bash 复制代码
pip install langchain langchain-openai langchain_community chromadb sentence-transformers
1. 准备标准化的组件

在LangChain中,我们需要将之前的工具都用LangChain的"包装器"来初始化。

python 复制代码
import os
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_community.cross_encoders import BgeReranker
from langchain.retrievers.contextual_compression import ContextualCompressionRetriever
from langchain.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnablePassthrough
from langchain.schema.output_parser import StrOutputParser

# 设置你的OpenAI API Key
# os.environ["OPENAI_API_KEY"] = "sk-..."

# 准备一些示例文档
docs = [
    "LangChain是一个强大的AI编排框架。",
    "RAG系统的关键在于检索的质量。",
    "BgeReranker是一个性能优秀的精排模型。",
    "LCEL是LangChain中用于构建链的表达式语言。"
]

# --- 组件1: 向量库与检索器 ---
# 使用OpenAI的Embedding模型
embeddings = OpenAIEmbeddings()
# 使用Chroma向量库
vectorstore = Chroma.from_texts(docs, embeddings)
# 基础检索器
base_retriever = vectorstore.as_retriever(search_kwargs={"k": 3})

# --- 组件2: 精排器 ---
# 初始化BgeReranker
reranker = BgeReranker()
# 将精排器包装成一个ContextualCompressionRetriever
# 这个检索器会自动用reranker对base_retriever的结果进行精排
compression_retriever = ContextualCompressionRetriever(
    base_compressor=reranker, base_retriever=base_retriever
)

# --- 组件3: Prompt, LLM, 和输出解析器 ---
prompt_template = ChatPromptTemplate.from_template(
    """
    请根据以下上下文回答问题:
    ---
    上下文:
    {context}
    ---
    问题: {question}
    """
)
llm = ChatOpenAI(model="gpt-4o-mini")
output_parser = StrOutputParser()
2. 使用LCEL组合"链"

接下来是见证奇迹的时刻!我们将用 | 符号把所有组件串联起来。

python 复制代码
# LCEL的魔法!
# 这是一个字典,定义了进入Prompt的数据流
# context由精排检索器处理用户问题后提供
# question则直接来源于用户的原始输入
setup_and_retrieval = {
    "context": compression_retriever,
    "question": RunnablePassthrough() 
}

# 构建完整的链
chain = (
    setup_and_retrieval
    | prompt_template
    | llm
    | output_parser
)

解读这条链:

  1. setup_and_retrieval 负责准备数据。当它运行时,它会并行地:
    • compression_retriever 处理输入,得到精排后的上下文 context
    • RunnablePassthrough() 将原始输入(也就是用户问题)原封不动地传递下去,作为 question
  2. | prompt_template:上一步产生的字典 {"context": ..., "question": ...} 被送入Prompt模板,格式化成一个完整的Prompt。
  3. | llm:格式化好的Prompt被送入LLM。
  4. | output_parser:LLM的输出被送入输出解析器,提取出干净的字符串结果。
3. 调用链并查看结果
python 复制代码
# 只需一个invoke,即可驱动整条复杂的链
response = chain.invoke("LangChain的LCEL是什么?")
print(response)

输出结果(示例):

根据提供的上下文,LCEL是LangChain中用于构建链的表达式语言。

看到没有?我们用区区几行声明式的代码,就定义了一条包含并行处理、检索、精排、Prompt格式化、LLM调用、结果解析等多个步骤的复杂工作流。这背后所有的"胶水代码",LangChain都为我们处理了。这就是框架的力量!

总结与预告

今日小结:

  • 手动编写"胶水代码"来连接RAG的各个组件,是低效且难以维护的。
  • LangChain 等编排框架通过标准化接口可组合性,极大地简化了高级RAG流程的构建。
  • LCEL(LangChain表达式语言) 及其 | 语法,是当前构建和理解LangChain工作流最核心、最优雅的方式。

LangChain以其灵活性和强大的生态,成为了构建LLM应用的事实标准之一。但它并非唯一的选择。在RAG这个垂直领域,还有一个可以与LangChain分庭抗礼的强大对手。

这个框架认为,RAG的核心是"数据",一切都应该围绕如何更好地索引、组织和查询数据来构建。

明天预告:RAG 每日一技(十五):换个"引擎"看世界------以数据为中心的LlamaIndex

明天,我们将把目光投向RAG领域的另一位巨头:LlamaIndex。我们将探索它与LangChain在设计哲学上的不同,看看它以"数据为中心"的理念,为我们构建RAG系统提供了怎样的一条新路径。

相关推荐
带刺的坐椅5 分钟前
搭建基于 Solon AI 的 Streamable MCP 服务并部署至阿里云百炼
java·人工智能·ai·solon·mcp
qq_203120796 分钟前
deepseek doubao chatgpt 优缺点分析
人工智能
金融Tech趋势派12 分钟前
金融行业数智化转型:如何用企业微信AI实现高效内部协作与外部服务?
人工智能·金融·企业微信
二闹12 分钟前
循环里藏着的秘密:90%新手都不知道的else clause妙用!
后端·python
考虑考虑15 分钟前
org.springframework.boot.autoconfigure.AutoConfiguration.imports文件
spring boot·后端·spring
yinke小琪19 分钟前
如何决定使用HashMap还是TreeMap
java·后端·面试
用户2986985301420 分钟前
如何使用 Spire.PDF 从 PDF 中提取文本?
后端
天南星22 分钟前
命令大全-yt-dlp
后端
Zeluar29 分钟前
BERT实战|推理与微调
人工智能·深度学习·bert
lypzcgf30 分钟前
Coze源码分析-资源库-创建提示词-前端源码
前端·人工智能·typescript·系统架构·开源软件·react·安全架构