代码中使用 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 theLangGraph documentation <https://langchain-ai.github.io/langgraph/>
_ as well as guides forMigrating from AgentExecutor <https://python.langchain.com/docs/how_to/migrate_agent/>
_ and LangGraph’sPre-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
的迁移。
官方建议参考以下资源:
迁移步骤
以下是将基于 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
# 定义工具
def search_web(query):
# 模拟网络搜索 API
return f"搜索 {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
# 定义工具
@tool
def search_web(query: str) -> str:
"""搜索网络以获取信息。"""
# 模拟网络搜索 API
return f"搜索 {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
# 定义工具
@tool
def search_web(query: str) -> str:
"""搜索网络以获取信息。"""
return f"搜索 {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 教程。
- 简单 ReAct 代理用
常见问题
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 模型访问。