智能体
智能体将语言模型与工具结合,创建能够对任务进行推理、决定使用哪些工具并迭代寻求解决方案的系统。
create_agent 提供了一个生产就绪的智能体实现。
LLM 智能体在循环中运行工具以实现目标。
智能体会一直运行,直到满足停止条件——即模型输出最终结果或达到迭代次数限制。
信息
create_agent使用 LangGraph 构建了一个基于图的智能体运行时。图由节点(步骤)和边(连接)组成,定义了智能体如何处理信息。智能体在图中移动,执行节点,如模型节点(调用模型)、工具节点(执行工具)或中间件。了解更多关于 Graph API 的信息。
核心组件
模型
模型 是智能体的推理引擎。它可以通过多种方式指定,支持静态和动态模型选择。
静态模型
静态模型在创建智能体时配置一次,并在整个执行过程中保持不变。这是最常见且直接的方法。
从 初始化静态模型:
from langchain.agents import create_agent
agent = create_agent(
"openai:gpt-5",
tools=tools
)提示
模型标识符字符串支持自动推断(例如"gpt-5"将被推断为"openai:gpt-5")。请参考参考文档 查看完整的模型标识符字符串映射列表。
为了对模型配置进行更多控制,可以直接使用提供商包初始化模型实例。在此示例中,我们使用 ChatOpenAI。请参阅 聊天模型 以了解其他可用的聊天模型类。
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="gpt-5",
temperature=0.1,
max_tokens=1000,
timeout=30
# ...(其他参数)
)
agent = create_agent(model, tools=tools)模型实例为您提供对配置的完全控制。当您需要设置特定参数,如 temperature、max_tokens、timeouts、base_url 和其他提供商特定设置时,请使用它们。请参考参考文档 查看模型上可用的参数和方法。
动态模型
动态模型在 根据当前 和上下文进行选择。这支持复杂的路由逻辑和成本优化。
要使用动态模型,请使用 @wrap_model_call 装饰器创建中间件,以修改请求中的模型:
from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
basic_model = ChatOpenAI(model="gpt-4o-mini")
advanced_model = ChatOpenAI(model="gpt-4o")
@wrap_model_call
def dynamic_model_selection(request: ModelRequest, handler) -> ModelResponse:
"""根据对话复杂性选择模型。"""
message_count = len(request.state["messages"])
if message_count > 10:
# 对较长的对话使用高级模型
model = advanced_model
else:
model = basic_model
request.model = model
return handler(request)
agent = create_agent(
model=basic_model, # 默认模型
tools=tools,
middleware=[dynamic_model_selection]
)警告
在使用结构化输出时,不支持预绑定模型(已调用bind_tools的模型)。如果您需要使用结构化输出的动态模型选择,请确保传递给中间件的模型未预绑定。
工具
工具赋予智能体执行行动的能力。智能体超越了简单的仅模型工具绑定,实现了:
- 序列中的多个工具调用(由单个提示触发)
- 适当的并行工具调用
- 基于先前结果的动态工具选择
- 工具重试逻辑和错误处理
- 工具调用之间的状态持久化
有关更多信息,请参阅 工具。
定义工具
将工具列表传递给智能体。
from langchain.tools import tool
from langchain.agents import create_agent
@tool
def search(query: str) -> str:
"""搜索信息。"""
return f"结果:{query}"
@tool
def get_weather(location: str) -> str:
"""获取位置的天气信息。"""
return f"{location} 的天气:晴朗,72°F"
agent = create_agent(model, tools=[search, get_weather])如果提供空工具列表,智能体将仅包含一个 LLM 节点,不具备工具调用能力。
工具错误处理
要自定义工具错误的处理方式,请使用 @wrap_tool_call 装饰器创建中间件:
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_tool_call
from langchain_core.messages import ToolMessage
@wrap_tool_call
def handle_tool_errors(request, handler):
"""使用自定义消息处理工具执行错误。"""
try:
return handler(request)
except Exception as e:
# 向模型返回自定义错误消息
return ToolMessage(
content=f"工具错误:请检查您的输入并重试。({str(e)})",
tool_call_id=request.tool_call["id"]
)
agent = create_agent(
model="openai:gpt-4o",
tools=[search, get_weather],
middleware=[handle_tool_errors]
)当工具失败时,智能体将返回带有自定义错误消息的 ToolMessage:
[
...
ToolMessage(
content="工具错误:请检查您的输入并重试。(division by zero)",
tool_call_id="..."
),
...
]ReAct 循环中的工具使用
智能体遵循 ReAct(“推理 + 行动”)模式,在简短的推理步骤与针对性的工具调用之间交替,并将结果观察反馈到后续决策中,直到能够提供最终答案。
提示
要了解更多关于工具的信息,请参阅 工具。
系统提示
您可以通过提供提示来塑造智能体处理任务的方式。system_prompt 参数可以作为字符串提供:
agent = create_agent(
model,
tools,
system_prompt="你是一个有帮助的助手。请简洁准确。"
)当未提供 system_prompt 时,智能体将直接从消息中推断其任务。
动态系统提示
对于需要根据运行时上下文或智能体状态修改系统提示的高级用例,您可以使用 中间件。
@dynamic_prompt 装饰器创建中间件,根据模型请求动态生成系统提示:
from typing import TypedDict
from langchain.agents import create_agent
from langchain.agents.middleware import dynamic_prompt, ModelRequest
class Context(TypedDict):
user_role: str
@dynamic_prompt
def user_role_prompt(request: ModelRequest) -> str:
"""根据用户角色生成系统提示。"""
user_role = request.runtime.context.get("user_role", "user")
base_prompt = "你是一个有帮助的助手。"
if user_role == "expert":
return f"{base_prompt} 提供详细的技术响应。"
elif user_role == "beginner":
return f"{base_prompt} 简单解释概念,避免使用行话。"
return base_prompt
agent = create_agent(
model="openai:gpt-4o",
tools=[web_search],
middleware=[user_role_prompt],
context_schema=Context
)
# 系统提示将根据上下文动态设置
result = agent.invoke(
{"messages": [{"role": "user", "content": "解释机器学习"}]},
context={"user_role": "expert"}
)调用
您可以通过向其 State 传递更新来调用智能体。所有智能体在其状态中包含消息序列;要调用智能体,请传递一条新消息:
result = agent.invoke(
{"messages": [{"role": "user", "content": "旧金山天气如何?"}]}
)有关从智能体流式传输步骤和/或令牌的信息,请参阅流式传输指南。
否则,智能体遵循 LangGraph Graph API 并支持所有相关方法。
高级概念
结构化输出
在某些情况下,您可能希望智能体以特定格式返回输出。LangChain 通过 response_format 参数提供结构化输出策略。
ToolStrategy
ToolStrategy 使用人工工具调用生成结构化输出。这适用于任何支持工具调用的模型:
from pydantic import BaseModel
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy
class ContactInfo(BaseModel):
name: str
email: str
phone: str
agent = create_agent(
model="openai:gpt-4o-mini",
tools=[search_tool],
response_format=ToolStrategy(ContactInfo)
)
result = agent.invoke({
"messages": [{"role": "user", "content": "从以下内容提取联系信息:John Doe, john@example.com, (555) 123-4567"}]
})
result["structured_response"]
# ContactInfo(name='John Doe', email='john@example.com', phone='(555) 123-4567')ProviderStrategy
ProviderStrategy 使用模型提供商的原生结构化输出生成。这更可靠,但仅适用于支持原生结构化输出的提供商(例如 OpenAI):
from langchain.agents.structured_output import ProviderStrategy
agent = create_agent(
model="openai:gpt-4o",
response_format=ProviderStrategy(ContactInfo)
)注意
从langchain 1.0开始,不再支持直接传递模式(例如response_format=ContactInfo)。您必须明确使用ToolStrategy或ProviderStrategy。
提示
要了解结构化输出,请参阅 结构化输出。
记忆
智能体通过消息状态自动维护对话历史。您还可以配置智能体使用自定义状态模式,在对话期间记住额外信息。
存储在状态中的信息可以被视为智能体的短期记忆:
自定义状态模式必须扩展 AgentState 作为 TypedDict。
定义自定义状态有两种方式:
- 通过 中间件(推荐)
- 通过
create_agent上的state_schema
注意
推荐通过中间件定义自定义状态,而不是通过create_agent上的state_schema,因为它允许您将状态扩展概念上限定在相关中间件和工具的范围内。
state_schema仍支持用于向后兼容,在create_agent上。
通过中间件定义状态
当您的自定义状态需要被特定中间件钩子和附加到该中间件的工具访问时,使用中间件定义自定义状态。
from langchain.agents import AgentState
from langchain.agents.middleware import AgentMiddleware
class CustomState(AgentState):
user_preferences: dict
class CustomMiddleware(AgentMiddleware):
state_schema = CustomState
tools = [tool1, tool2]
def before_model(self, state: CustomState, runtime) -> dict[str, Any] | None:
...
agent = create_agent(
model,
tools=tools,
middleware=[CustomMiddleware()]
)
# 智能体现在可以跟踪消息之外的额外状态
result = agent.invoke({
"messages": [{"role": "user", "content": "我更喜欢技术性解释"}],
"user_preferences": {"style": "technical", "verbosity": "detailed"},
})通过 state_schema 定义状态
使用 state_schema 参数作为快捷方式,定义仅在工具中使用的自定义状态。
from langchain.agents import AgentState
class CustomState(AgentState):
user_preferences: dict
agent = create_agent(
model,
tools=[tool1, tool2],
state_schema=CustomState
)
# 智能体现在可以跟踪消息之外的额外状态
result = agent.invoke({
"messages": [{"role": "user", "content": "我更喜欢技术性解释"}],
"user_preferences": {"style": "technical", "verbosity": "detailed"},
})注意
从langchain 1.0开始,自定义状态模式必须是TypedDict类型。不再支持 Pydantic 模型和数据类。有关更多详细信息,请参阅 v1 迁移指南。
流式传输
我们已经看到如何使用 invoke 调用智能体以获取最终响应。如果智能体执行多个步骤,这可能需要一段时间。为了显示中间进度,我们可以随着消息的发生而流式传回。
for chunk in agent.stream({
"messages": [{"role": "user", "content": "搜索 AI 新闻并总结发现"}]
}, stream_mode="values"):
# 每个块包含该时间点的完整状态
latest_message = chunk["messages"][-1]
if latest_message.content:
print(f"智能体:{latest_message.content}")
elif latest_message.tool_calls:
print(f"正在调用工具:{[tc['name'] for tc in latest_message.tool_calls]}")提示
有关流式传输的更多详细信息,请参阅 流式传输。
中间件
中间件 为在执行的不同阶段自定义智能体行为提供了强大的扩展性。您可以使用中间件来:
- 在调用模型之前处理状态(例如消息裁剪、上下文注入)
- 修改或验证模型的响应(例如防护栏、内容过滤)
- 使用自定义逻辑处理工具执行错误
- 基于状态或上下文实现动态模型选择
- 添加自定义日志、监控或分析
中间件无缝集成到智能体的执行图中,允许您在关键点拦截和修改数据流,而无需更改核心智能体逻辑。
提示
有关全面的中间件文档,包括装饰器如@before_model、@after_model和@wrap_tool_call,请参阅 中间件。