构建LangChain应用程序的示例代码:36、基于LangGraph的检索代理实现教程

LangGraph 检索代理

我们可以在 LangGraph 中实现 检索代理

! pip install langchain_community tiktoken langchain-openai langchainhub chromadb langchain langgraph

检索器

from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings

# 需要加载的网页URL列表
urls = [
    "https://lilianweng.github.io/posts/2023-06-23-agent/",
    "https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/",
    "https://lilianweng.github.io/posts/2023-10-25-adv-attack-llm/",
]

# 从URL加载文档
docs = [WebBaseLoader(url).load() for url in urls]
# 将文档展平成单个列表
docs_list = [item for sublist in docs for item in sublist]

# 使用递归字符文本拆分器进行文本拆分
text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
    chunk_size=100,  # 每个文本块的大小
    chunk_overlap=50  # 文本块之间的重叠部分大小
)
doc_splits = text_splitter.split_documents(docs_list)

# 添加到向量数据库
vectorstore = Chroma.from_documents(
    documents=doc_splits,
    collection_name="rag-chroma",  # 向量数据库集合名称
    embedding=OpenAIEmbeddings(),  # 使用OpenAI的嵌入模型
)
# 将向量数据库作为检索器
retriever = vectorstore.as_retriever()
from langchain.tools.retriever import create_retriever_tool

# 创建检索工具
tool = create_retriever_tool(
    retriever,
    "retrieve_blog_posts",  # 工具名称
    "Search and return information about Lilian Weng blog posts.",  # 工具描述
)

tools = [tool]

from langgraph.prebuilt import ToolExecutor
# 创建工具执行器
tool_executor = ToolExecutor(tools)

代理状态

我们将定义一个图。

一个state对象会被传递给每个节点。

我们的状态将是一个messages列表。

图中的每个节点都会向它附加信息。

import operator
from typing import Annotated, Sequence, TypedDict
from langchain_core.messages import BaseMessage

# 定义代理状态类,包含消息列表
<think>我们被要求解释Langchain Chain、Langchain Agent和LangGraph之间的区别。根据引用内容,我们可以这样分析: 1. **Langchain Chain**:是LangChain中的基本构建块,用于将多个组件(如模型、提示、其他链)连接起来形成线性工作流。它按照预定义的顺序执行任务,适合确定性任务(如RAG流程)。引用[3]提到Router Chain是Chain的一种,用于根据输入将任务路由到不同的子链[^3]。 2. **Langchain Agent**:代理(Agent)是更高级的抽象,能够根据输入动态决定调用哪些工具(如搜索、计算、API等)。它通过循环的“思考-行动”过程处理复杂任务,但成本不可预测(引用[2])[^2]。Agent适合需要动态决策的场景。 3. **LangGraph**:是LangChain生态系统中的新成员,专注于构建有状态的、基于图的执行流程。它允许节点之间有任意连接,支持循环、分支和并行处理。引用[1]强调LangGraph完全集成到LangChain生态中,可利用LangSmith进行观测[^1]。引用[2]指出LangGraph在处理复杂状态(如多轮对话)时更灵活[^2]。 ### 核心区别总结: | **特性** | **LangChain Chain** | **LangChain Agent** | **LangGraph** | |------------------------|----------------------------|----------------------------|----------------------------| | **架构** | 线性顺序执行 | 代理循环(思考-行动) | 有状态图(节点+边) | | **决策能力** | 固定流程 | 动态选择工具 | 支持循环、分支、并行 | | **适用场景** | 确定性任务(如RAG) | 需要动态工具调用的任务 | 复杂状态管理(如多轮对话) | | **状态管理** | 无状态(每次执行独立) | 有状态(通过记忆机制) | 内置状态管理 | | **与LangChain集成** | 核心组件 | 核心组件 | 完全集成(LangSmith等)[^1]| | **复杂度** | 低(简单链)到中(组合链) | 中到高(依赖工具调用) | 高(需设计图结构) | ### 详细说明: 1. **LangChain Chain**: - 设计思想:通过组合预定义组件(如LLM调用、数据检索)形成**线性流程**。例如,一个典型的RAG链包括:检索文档 → 生成提示 → 调用LLM → 输出结果。 - 优势:执行高效、成本可控。 - 局限:缺乏灵活性,无法根据中间结果动态调整流程。 - 典型应用:引用[3]中的Router Chain,它根据输入将任务分配给不同的子链(如“数学问题”路由到数学链,“历史问题”路由到历史链)[^3]。 2. **LangChain Agent**: - 设计思想:代理通过**ReAct模式**(Reasoning and Acting)循环执行:解析输入 → 选择工具 → 执行工具 → 分析结果 → 决定下一步[^2]。 - 优势:动态适应复杂场景(如多工具协作)。 - 局限:工具调用次数不可预测,可能增加延迟和成本。 - 示例:用户查询“特斯拉老板的年龄”,代理可能先搜索“特斯拉老板是谁”,再搜索“埃隆·马斯克的年龄”。 3. **LangGraph**: - 设计思想:将工作流建模为**有向图**,节点代表操作(如调用LLM、工具),边定义状态流转逻辑。支持循环(如持续对话直到满足条件)和分支(如错误重试)[^1][^2]。 - 优势:处理**长期运行、有状态的任务**(如客服机器人)。 - 关键特性:状态(State)在节点间传递,可存储中间结果。 - 集成优势:无缝使用LangChain工具和LangSmith监控。 ### 何时选择? - **用Chain**:任务流程固定且无需动态决策(如文档摘要、翻译)。 - **用Agent**:需要动态调用外部工具(如实时搜索、API集成)。 - **用LangGraph**:任务涉及复杂状态流转(如多轮审批、游戏AI)或需要并行/重试逻辑[^2]。 ### 代码示例对比 #### LangChain Chain(线性RAG流程): ```python from langchain.chains import RetrievalQA from langchain_community.vectorstores import Chroma # 固定流程:检索 → 生成 qa_chain = RetrievalQA.from_chain_type( llm=ChatOpenAI(), retriever=Chroma.from_texts(["特斯拉老板是埃隆·马斯克"]).as_retriever() ) result = qa_chain.invoke("特斯拉老板是谁?") # 输出固定答案 ``` #### LangChain Agent(动态工具调用): ```python from langchain.agents import AgentExecutor, create_openai_tools_agent # 代理决定何时调用搜索工具 agent = create_openai_tools_agent(ChatOpenAI(), [TavilySearchTools()]) agent_executor = AgentExecutor(agent=agent, tools=tools) result = agent_executor.invoke("特斯拉老板的年龄?") # 可能调用两次搜索工具 ``` #### LangGraph(有状态对话): ```python from langgraph.graph import StateGraph # 定义状态和节点 class AgentState(TypedDict): input: str history: list[str] def llm_node(state: AgentState): return {"response": ChatOpenAI().invoke(state["input"])} # 构建图 → 支持循环 graph = StateGraph(AgentState) graph.add_node("llm", llm_node) graph.add_edge("llm", END) # 可添加条件分支 app = graph.compile() ``` --- ### 总结 - **Chain**:线性管道,高效处理确定性任务。 - **Agent**:动态代理,灵活调用工具解决开放性问题。 - **LangGraph**:图引擎,管理复杂状态和流程(如循环对话)[^1][^2]。 --- §§相关问题§§ 1. 如何根据任务复杂度选择Chain、Agent或LangGraph? 2. LangGraph在哪些场景下比传统Agent更有优势? 3. 如何将现有的LangChain Chain迁移到LangGraph? [^1]: Autogen 和 LangGraph 之间的另一个关键区别是 LangGraph 完全集成到 LangChain 生态系统中... [^2]: 一文彻底搞懂LangChainLangGraph该怎么选?何时选?... [^3]:AI大模型学习路线】第三阶段之RAG与LangChain——第十五章(LangChain与Chain组件)Router Chain详解...</think>### LangChain Chain、LangChain Agent 与 LangGraph 的区别详解 以下是三者的核心区别对比,基于引用内容整理: | **特性** | **LangChain Chain** | **LangChain Agent** | **LangGraph** | |-------------------------|----------------------------------------|----------------------------------------|----------------------------------------| | **架构核心** | 线性执行流程 | 动态工具调用循环 | 有状态图结构(节点+边) | | **决策机制** | 预定义顺序执行 | 基于LLM的实时工具选择 | 支持循环/分支/并行处理[^2] | | **状态管理** | 无状态(每次执行独立) | 有限状态(通过记忆机制) | 内置状态管理(跨节点传递) | | **适用场景** | 确定性任务(如RAG)[^3] | 动态工具调用(如搜索/计算) | 复杂工作流(如多轮对话/审批) | | **错误处理** | 简单异常捕获 | 有限重试逻辑 | 内置重试和错误路由[^2] | | **与LangChain集成** | 核心组件 | 核心组件 | 完全集成生态(含LangSmith)[^1] | | **典型组件** | `SequentialChain`, `RouterChain`[^3] | `ReAct Agent`, `OpenAI Functions` | 状态图(StateGraph) | --- ### 详细解析 #### 1. **LangChain Chain:线性执行引擎** - **设计思想**:通过预定义组件(LLM、工具、提示模板)构建**确定性工作流** - **核心特征**: - 固定执行顺序:`输入 → 组件A → 组件B → 输出` - 支持条件路由:如`RouterChain`根据输入选择子链[^3] - 适用场景: ```python # 示例:顺序链(文档摘要 → 翻译) chain = SequentialChain( chains=[summary_chain, translate_chain], input_variables=["document"] ) ``` - **局限**:无法动态调整流程,缺乏复杂状态管理 #### 2. **LangChain Agent:动态决策代理** - **设计思想**:基于LLM的**思考-行动循环**(ReAct模式) - **核心特征**: - 动态工具选择:根据输入实时调用工具(搜索/API/计算) - 记忆机制:维护短期对话历史 - 执行流程: ```mermaid graph LR A[用户输入] --> B{LLM决策} B -->|选择工具| C[工具执行] C --> D{是否完成?} D -->|否| B D -->|是| E[输出结果] ``` - **优势**:处理开放性问题(如“特斯拉老板的年龄?”需先查身份再查年龄) - **局限**:复杂状态处理困难,循环逻辑实现复杂[^2] #### 3. **LangGraph:图工作流引擎** - **设计思想**:**有向图结构**管理状态流转 - **核心突破**: - 节点(Node):执行单元(LLM/工具/条件判断) - 边(Edge):定义状态转移逻辑 - 状态(State):跨节点传递数据 - **关键能力**: - 循环处理:`聊天机器人`持续对话直到满足退出条件 - 并行执行:同时调用多个API - 错误重试:自动路由失败任务[^2] - **代码示例**: ```python from langgraph.graph import StateGraph class AgentState(TypedDict): user_query: str search_results: list # 构建图 graph = StateGraph(AgentState) graph.add_node("search", search_tool) graph.add_node("llm", llm_processor) graph.add_edge("search", "llm") # 搜索完成后转LLM处理 graph.set_entry_point("search") ``` --- ### 何时选择? | **场景** | **推荐方案** | **原因** | |---------------------------|---------------------|---------------------------------------| | 固定流程(如文档处理) | Chain | 高效且成本可控 | | 需动态工具调用 | Agent | 实时决策能力强大 | | 多轮对话/复杂审批流 | LangGraph | 状态管理和循环支持完善[^2] | | 需要LangSmith监控 | LangGraph | 深度集成可观测性工具[^1] | > 关键洞察:LangGraph不是替代Chain/Agent,而是**扩展**——它可封装Chain和Agent作为节点,构建更复杂的工作流[^2]。 --- ### 典型应用案例 1. **Chain**: - RAG流水线:`检索 → 生成 → 格式化输出`[^3] - 分类路由:`RouterChain`将数学问题/历史问题分发给专用链 2. **Agent**: - 实时数据分析:调用搜索引擎 + 计算工具 + 图表生成API - 客服机器人:根据问题类型选择知识库/订单系统工具 3. **LangGraph**: - 保险理赔系统: ``` 用户提交 → 文件审核 → (通过)支付 | (失败)转人工 → 通知用户 ``` - 多角色协作:销售Agent、技术Agent、审批Agent通过状态图协同[^2] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hugo_Hoo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值