告别 AgentExecutor:LangChain v1.0+ Agent 模块深度迁移指南与实战全解析
【个人主页:玄同765】
大语言模型(LLM)开发工程师|中国传媒大学·数字媒体技术(智能交互与游戏设计)
深耕领域:大语言模型开发 / RAG知识库 / AI Agent落地 / 模型微调
技术栈:Python / LangChain/RAG(Dify+Redis+Milvus)| SQL/NumPy | FastAPI+Docker ️
工程能力:专注模型工程化部署、知识库构建与优化,擅长全流程解决方案
「让AI交互更智能,让技术落地更高效」
欢迎技术探讨/项目合作! 关注我,解锁大模型与智能交互的无限可能!
在 LangChain 1.0 时代,Agent(智能体)模块经历了一场“脱胎换骨”的变革。如果你还在使用 initialize_agent 或者 AgentType,那么你已经站在了旧时代的边缘。
1.0+ 版本不仅是版本号的跳跃,更是从 “黑盒执行器” 向 “透明状态图” 的范式转移。本文将带你深入对比 LangChain 1.0 前后的架构差异,手把手教你完成从旧版到新版的平滑迁移。
一、 时代的分水岭:Pre-1.0 vs 1.0+
在 1.0 之前,Agent 的开发就像是在配置一个“黑盒”。你告诉它工具和模型,它在后台通过复杂的正则匹配(ReAct)来决定下一步。
1. 旧版(Pre-1.0):以 AgentExecutor 为核心
- 入口函数:
initialize_agent(已弃用)。 - 核心逻辑:依赖
AgentExecutor循环。这是一个硬编码的 Python 循环,开发者很难修改其内部逻辑。 - 交互方式:基于字符串。Agent 思考过程(Thought)和工具调用(Action)通常是通过 Prompt 强行让模型输出特定格式(如
Action: ...),然后用正则解析。 - 记忆管理:使用
ConversationBufferMemory等组件,耦合度高。
2. 新版(1.0+):以 LangGraph 为底座
- 入口函数:
create_agent(推荐)。 - 核心逻辑:基于 LangGraph。Agent 不再是一个简单的链,而是一个 状态机(State Graph)。
- 交互方式:原生 Tool Calling。利用 OpenAI 等模型自带的
tool_calls参数,输出结构化 JSON,告别正则解析的噩梦。 - 记忆管理:引入
checkpointer(检查点机制),支持持久化、断点续传和多线程会话。
二、 代码大对比:从“旧”到“新”
1. 工具定义:从基础到高级
LangChain v1.0+ 提供了多种工具定义方式,满足不同复杂度的需求:
基础工具定义
使用 @tool 装饰器是最简单直接的方式:
from langchain_core.tools import tool
@tool
def search_order(order_id: str) -> str:
"""根据订单ID查询快递状态。"""
# 模拟数据库查询
return f"订单 {order_id} 正在派送中..."
tools = [search_order]
结构化工具定义
对于需要复杂参数验证的场景,使用 StructuredTool:
from langchain_core.tools import StructuredTool
from pydantic import BaseModel, Field
# 定义参数结构
class WeatherRequest(BaseModel):
city: str = Field(description="要查询天气的城市名称")
days: int = Field(default=1, description="要查询的天数")
def get_weather_detailed(city: str, days: int = 1) -> str:
"""获取指定城市的详细天气信息"""
weather_data = {
"北京": ["晴,25℃", "多云,23℃", "阴,22℃"],
"上海": ["多云,23℃", "阴,22℃", "小雨,20℃"]
}
if city in weather_data:
return "\n".join(weather_data[city][:days])
return "未知城市"
# 创建结构化工具
weather_tool = StructuredTool.from_function(
func=get_weather_detailed,
name="get_weather_detailed",
description="获取指定城市的详细天气信息",
args_schema=WeatherRequest
)
工具集合(Toolkit)
对于相关工具的组织和管理,使用 Toolkit:
from langchain_core.tools import Toolkit
from langchain_community.tools import WikipediaQueryRun, DuckDuckGoSearchRun
from langchain_community.utilities import WikipediaAPIWrapper
class InformationToolkit(Toolkit):
"""信息查询工具集合"""
def __init__(self):
self.wikipedia_tool = WikipediaQueryRun(
api_wrapper=WikipediaAPIWrapper(lang="zh")
)
self.search_tool = DuckDuckGoSearchRun()
def get_tools(self):
"""获取工具列表"""
return [self.wikipedia_tool, self.search_tool]
# 使用工具集合
toolkit = InformationToolkit()
tools = toolkit.get_tools()
2. 初始化 Agent:配置 vs 编排
❌ 旧版写法(已不再推荐)
from langchain.agents import initialize_agent, AgentType
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo")
# 依赖 AgentType 枚举,难以自定义逻辑
agent = initialize_agent(
tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
# 字符串调用
agent.run("帮我查一下订单号 12345 的状态")
✅ 新版写法(1.0+ 推荐)
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o")
# 1.0+ 版本直接返回一个 CompiledStateGraph
agent = create_agent(
model=llm,
tools=tools,
system_prompt="你是一个专业的物流客服,必须通过工具查询信息。"
)
# 消息流调用
result = agent.invoke({
"messages": [("human", "帮我查一下订单号 12345 的状态")]
})
三、 深度解析:1.0+ 的核心改进点
1. 输入输出的标准化(Messages First)
旧版 Agent 习惯于 {"input": "..."} 和 {"output": "..."}。 新版全面拥向 Message 列表。agent.invoke 的输入和输出都是 BaseMessage 对象。 * 优势:与 ChatModel 的 API 完美对齐,天然支持多轮对话。
2. 强大的记忆力:Memory vs Checkpointer
在旧版中,如果你想实现多轮对话,需要手动维护一个列表。 在 1.0+ 中,你可以给 create_agent 传入一个 checkpointer:
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
# 此时 agent 具备了跨请求的记忆能力
agent = create_agent(model=llm, tools=tools, checkpointer=memory)
# 通过 thread_id 隔离不同用户的会话
config = {"configurable": {"thread_id": "session_001"}}
agent.invoke({"messages": [("human", "我是玄同")]}, config)
3. 中间件(Middleware):Agent 的“插件系统”
1.0+ 引入了中间件机制,允许你在“模型调用”或“工具执行”前后插入自定义逻辑。 * 场景:API 鉴权、Token 计数、敏感词过滤、自动化日志。
from langchain.agents.middleware import AgentMiddleware
class TokenCounterMiddleware(AgentMiddleware):
def wrap_model_call(self, request, handler):
# 模型调用前的处理
response = handler(request)
# 模型调用后的处理(如计数)
return response
4. Tools模块高级特性
工具参数验证
使用 Pydantic 模型对工具参数进行验证,确保参数的类型和格式正确:
from langchain_core.tools import StructuredTool
from pydantic import BaseModel, Field, field_validator
class CalculateRequest(BaseModel):
expression: str = Field(description="要计算的数学表达式")
@field_validator('expression')
def validate_expression(cls, v):
# 简单的表达式验证
allowed_chars = set("0123456789+-*/() ")
if not all(c in allowed_chars for c in v):
raise ValueError("表达式只能包含数字、运算符和括号")
return v
def calculate(expression: str) -> str:
"""计算数学表达式"""
try:
result = eval(expression)
return f"计算结果:{result}"
except Exception as e:
return f"计算错误:{str(e)}"
calculate_tool = StructuredTool.from_function(
func=calculate,
args_schema=CalculateRequest,
description="计算数学表达式"
)
工具错误处理
为工具添加错误处理机制,确保工具调用失败时能够优雅地处理:
def safe_calculate(expression: str) -> str:
"""安全计算数学表达式"""
try:
# 验证表达式安全性
if any(c in expression for c in ["__", "import", "exec", "eval"]):
return "表达式不安全"
result = eval(expression)
return f"计算结果:{result}"
except Exception as e:
return f"计算错误:{str(e)}"
工具性能优化
使用缓存减少重复调用,提高系统性能:
from functools import lru_cache
@lru_cache(maxsize=100)
def expensive_tool(query: str) -> str:
# 复杂计算或API调用
import time
time.sleep(1) # 模拟耗时操作
return f"结果:{query}"
四、 参数速查表:迁移避坑指南
| 功能点 | Pre-1.0 (旧) | 1.0+ (新) | 迁移建议 |
|---|---|---|---|
| 入口类 | AgentExecutor |
create_agent (返回 Graph) |
弃用执行器,直接使用图 |
| Agent类型 | AgentType 枚举 |
create_agent 自动适配 |
不再需要手动选 ReAct 或 OpenAI |
| 输入格式 | {"input": "..."} |
{"messages": [...]} |
统一使用 Message 列表 |
| 停止策略 | max_iterations |
create_agent 内部默认处理 |
1.0+ 更稳定,通常无需手动设 |
| 中间步骤 | agent_scratchpad |
自动维护在 Graph 状态中 | 不再需要手动在 Prompt 中预留 |
五、 总结:为什么要升级?
如果说旧版 Agent 是一个 “配置出来的工具”,那么 1.0+ 的 Agent 就是一个 “生长出来的应用”。
基于 LangGraph 的 create_agent 给了开发者前所未有的控制力:
1. 可观测性:你可以清楚地看到图中的每一个节点是如何流转的。
2. 灵活性:如果 create_agent 的默认逻辑不够用,你可以直接手动修改其底层的 Graph 结构。
3. 生产就绪:持久化记忆和中间件支持,让 Agent 真正能够落地到复杂的企业级场景。
「从 1.0 开始,Agent 不再是一个简单的 Python 循环,而是一个健壮的分布式状态机。」
下一篇预告:我们将跳出
create_agent的便捷封装,手动从零构建一个 LangGraph 复杂 Agent,挑战多 Agent 协作场景。
参考链接
更多推荐



所有评论(0)