作者:彬彬侠
代码中使用 initialize_agent 函数(通常用于创建 LangChain 代理,如 AgentExecutor),会触发 LangChainDeprecationWarning,提示虽然 LangChain 代理仍受支持,但新用例应使用 LangGraph,因为 LangGraph 提供更灵活、功能更强大的代理构建框架,支持工具调用、状态持久化和人机交互工作流。本文基于 LangChain 0.3.x,详细解释如何将基于 initialize_agent 的代理迁移到 LangGraph,并提供代码示例。
代码废弃告警:
LangChainDeprecationWarning: LangChain agents will continue to be supported, but it is recommended for new use cases to be built with LangGraph. LangGraph offers a more flexible and full-featured framework for building agents, including support for tool-calling, persistence of state, and human-in-the-loop workflows. For details, refer to the LangGraph documentation <https://langchain-ai.github.io/langgraph/>_ as well as guides for Migrating from AgentExecutor <https://python.langchain.com/docs/how_to/migrate_agent/>_ and LangGraph’s Pre-built ReAct agent <https://langchain-ai.github.io/langgraph/how-tos/create-react-agent/>_.
agent = initialize_agent( ……
为什么需要迁移?
initialize_agent 和 AgentExecutor 是 LangChain 早期用于快速创建代理的工具,适合简单的工具调用场景,但存在以下局限:
灵活性不足:代理逻辑(如 ReAct 提示)较为固定,难以定制复杂的工作流。 状态管理有限:不支持跨会话的状态持久化或错误恢复。 工具调用兼容性:对现代聊天模型的工具调用支持不够完善(如 OpenAI 的 gpt-4o)。 扩展性差:不适合多步骤、多用户或人机交互的复杂场景。
LangGraph 是 LangChain 推荐的新框架,优势包括:
基于图的灵活性:通过节点和边定义代理工作流,支持高度定制化。 状态持久化:使用检查点(如 MemorySaver)保存对话和代理状态,支持多会话和错误恢复。 现代工具调用:与最新聊天模型的工具调用 API 无缝集成。 人机交互:支持人工干预的工作流,便于人机协作。 预构建代理:提供开箱即用的 ReAct 代理,简化从 AgentExecutor 的迁移。
官方建议参考以下资源:
LangGraph 文档 从 AgentExecutor 迁移指南 预构建 ReAct 代理教程
迁移步骤
以下是将基于 initialize_agent 的代理迁移到 LangGraph 的详细步骤,假设原代码使用 OpenAI 模型和工具调用。
1. 分析原始代码
假设你的代码使用 initialize_agent 创建一个带工具的 ReAct 代理,如下:- import os
- os.environ["OPENAI_API_KEY"]="Your OpenAI API Key"from langchain.agents import initialize_agent, AgentType
- from langchain.chat_models import ChatOpenAI
- from langchain.tools import Tool
- # 定义工具defsearch_web(query):# 模拟网络搜索 APIreturnf"搜索 {query} 的结果:[示例内容]"
- tools =[
- Tool(
- name="WebSearch",
- func=search_web,
- description="搜索网络以获取信息")]# 初始化 LLM
- llm = ChatOpenAI(temperature=0, model="gpt-4o")# 初始化代理
- agent = initialize_agent(
- tools=tools,
- llm=llm,
- agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
- verbose=True)# 调用代理
- response = agent.run("纽约的天气如何?")print(response)
复制代码 输出示例:- [代理使用 WebSearch 工具] 纽约的天气是晴天,最高气温 24°C。
复制代码 问题:
initialize_agent 已不推荐,需迁移到 LangGraph。 langchain.chat_models.ChatOpenAI 已废弃,需替换为 langchain_openai.ChatOpenAI。 需要在 LangGraph 中实现工具调用和代理逻辑。
2. 安装必要依赖
确保安装 LangChain 0.3.x、LangGraph 和 langchain-openai:- pip install --upgrade langchain langchain-openai langgraph langchain-community
复制代码 3. 迁移到 LangGraph 的预构建 ReAct 代理
LangGraph 提供了 create_react_agent 函数,可直接替代 ReAct 代理。以下是迁移后的代码:- import os
- os.environ["OPENAI_API_KEY"]="Your OpenAI API Key"from langchain_openai import ChatOpenAI
- from langchain_core.tools import tool
- from langgraph.prebuilt import create_react_agent
- # 定义工具@tooldefsearch_web(query:str)->str:"""搜索网络以获取信息。"""# 模拟网络搜索 APIreturnf"搜索 {query} 的结果:[示例内容]"
- tools =[search_web]# 初始化 LLM
- llm = ChatOpenAI(temperature=0, model="gpt-4o-mini")# 创建 LangGraph ReAct 代理
- agent = create_react_agent(llm, tools)# 调用代理
- response = agent.invoke({"messages":[{"role":"human","content":"纽约的天气如何?"}]})for message in response["messages"]:if message["role"]=="assistant":print(message["content"])
复制代码 输出示例:- [代理使用 search_web 工具] 纽约的天气是晴天,最高气温 24°C。
复制代码 代码说明
- OpenAI API 密钥:
通过 os.environ["OPENAI_API_KEY"] 设置,确保 OpenAI 模型正常调用。 将 "Your OpenAI API Key" 替换为你的实际密钥。
- LLM:
使用 langchain_openai.ChatOpenAI 替代 langchain.chat_models.ChatOpenAI。 设置 model="gpt-4o-mini",支持工具调用,性价比高。
- 工具定义:
使用 @tool 装饰器替代 Tool 类,接口更简洁。 search_web 函数逻辑不变,描述写在 docstring 中。
- 代理创建:
create_react_agent 创建 ReAct 代理,自动实现 ZERO_SHOT_REACT_DESCRIPTION 的推理+行动逻辑。
- 调用:
输入为包含 messages 的字典,消息格式为 {"role": "human", "content": "..."}。 输出为状态字典,提取 assistant 角色的消息内容。
4. 添加状态持久化(可选)
LangGraph 支持通过 MemorySaver 持久化代理状态(消息和工具调用)。以下是添加持久化的代码:- import os
- os.environ["OPENAI_API_KEY"]="Your OpenAI API Key"from langchain_openai import ChatOpenAI
- from langchain_core.tools import tool
- from langgraph.prebuilt import create_react_agent
- from langgraph.checkpoint.memory import MemorySaver
- import uuid
- # 定义工具@tooldefsearch_web(query:str)->str:"""搜索网络以获取信息。"""returnf"搜索 {query} 的结果:[示例内容]"
- tools =[search_web]# 初始化 LLM
- llm = ChatOpenAI(temperature=0, model="gpt-4o-mini")# 初始化内存
- memory = MemorySaver()# 创建 LangGraph ReAct 代理
- agent = create_react_agent(llm, tools, checkpointer=memory)# 生成唯一会话 ID
- session_id =str(uuid.uuid4())# 调用代理
- response = agent.invoke({"messages":[{"role":"human","content":"纽约的天气如何?"}]},
- config={"configurable":{"thread_id": session_id}})for message in response["messages"]:if message["role"]=="assistant":print(message["content"])# 继续对话
- response = agent.invoke({"messages":[{"role":"human","content":"明天呢?"}]},
- config={"configurable":{"thread_id": session_id}})for message in response["messages"]:if message["role"]=="assistant":print(message["content"])
复制代码 输出示例:- [代理使用 search_web 工具] 纽约的天气是晴天,最高气温 24°C。
- [代理使用 search_web 工具] 明天纽约的天气是多云,最高气温 22°C。
复制代码 说明:
MemorySaver:在每次调用后保存代理状态(消息、工具调用),通过 thread_id 区分会话。 thread_id:使用 UUID 确保多用户会话隔离。 持久化:代理跨调用保留上下文,支持连续对话。
5. 使用数据库存储(可选)
若需生产环境中持久化状态,可使用 SQLite 代替内存存储:- from langgraph.checkpoint.sqlite import SqliteSaver
- # 替换 MemorySaver 为 SqliteSaver
- memory = SqliteSaver.from_conn_string("agent_state.db")
- agent = create_react_agent(llm, tools, checkpointer=memory)
复制代码 状态将存储在 SQLite 数据库(agent_state.db),支持应用重启后恢复。
6. 测试与验证
运行迁移后的代码,确认代理正确响应并调用工具。 若启用持久化,测试同一 thread_id 的多轮对话,验证状态保留。 检查 OpenAI API 密钥有效性,避免 AuthenticationError。 对比原始 AgentExecutor 的输出,确保功能一致。
注意事项
- API 密钥安全:
- 避免硬编码密钥,推荐使用 .env 文件和 python-dotenv:
- from dotenv import load_dotenv
- load_dotenv()# 从 .env 文件加载 OPENAI_API_KEY
复制代码 确保密钥有权访问指定模型(如 gpt-4o-mini)。
- 模型选择:
gpt-4o-mini 性价比高,支持工具调用。 其他选项:gpt-4o(更高性能)或 gpt-3.5-turbo(更低成本)。 参考 OpenAI 模型文档。
- 工具兼容性:
@tool 装饰器要求工具返回字符串或 JSON 兼容输出。 复杂工具可使用 langchain_core.tools.StructuredTool。
- 日志输出:
原始代码的 verbose=True 可通过 LangGraph 的调试日志或自定义日志实现。
- LangGraph vs. AgentExecutor:
简单 ReAct 代理用 create_react_agent 即可。 复杂工作流(如条件逻辑、人机交互)需自定义 LangGraph 图,参考 LangGraph 教程。
常见问题
Q1:可以继续使用 initialize_agent 吗?
A:可以,但不建议用于新项目。它将支持到 LangChain 1.0,但缺乏 LangGraph 的灵活性和未来兼容性。
Q2:LangGraph 使用难度高吗?
A:对于简单 ReAct 代理,create_react_agent 与 initialize_agent 一样简单。复杂工作流需学习 LangGraph 的图结构,但功能更强大。
Q3:工具复杂时怎么办?
A:使用 StructuredTool 定义多输入或复杂 schema 的工具,确保输出符合模型的工具调用要求。
Q4:持久化会影响性能吗?
A:MemorySaver(内存)开销极低,数据库(如 SqliteSaver)会增加轻微延迟,但提供持久性。
总结
从 initialize_agent 迁移到 LangGraph 的步骤包括:
安装 langchain、langchain-openai 和 langgraph。 使用 langchain_openai.ChatOpenAI 替换 langchain.chat_models.ChatOpenAI。 使用 @tool 装饰器定义工具,替换 Tool 类。 使用 create_react_agent 创建 ReAct 代理。 可选添加 MemorySaver 或 SqliteSaver 实现状态持久化。 设置 OPENAI_API_KEY 确保 OpenAI 模型访问。
原文地址:https://blog.csdn.net/u013172930/article/details/147641795 |