LangChain Agents:智能体使用完全指南
LangChainAgents是结合大语言模型与工具的强大智能系统,能够自主推理、选择工具并迭代执行任务。该系统通过create_agent函数实现生产级应用,基于LangGraph构建图式运行时,遵循ReAct循环工作模式。核心组件包括模型(推理引擎)、工具(行动载体)和系统提示词(行为准则),均支持静态配置和运行时动态定制。文章详细解析了Agent调用方法、高级功能(结构化输出、记忆管理和流式
LangChain Agents:智能体使用完全指南
LangChain Agents是将大语言模型(LLM) 与工具深度结合的智能系统,能够自主推理任务需求、选择合适工具、迭代执行操作,直至达成目标并输出结果。create_agent函数提供了生产级的Agent实现,其底层基于LangGraph构建为图式运行时(由「节点/执行步骤」和「边/节点连接」构成),Agent会沿预设的图执行模型调用、工具运行、中间件处理等逻辑,遵循ReAct(Reasoning + Acting,推理+行动) 循环工作,直至满足停止条件(模型输出最终结果/达到迭代次数限制)。
本文将从核心组件、Agent调用、高级概念、核心扩展能力-中间件四个维度,全面解析LangChain Agents的使用方法,所有代码示例均附带逐行详解,同时标注生产环境中的关键注意事项。
一、Agent 核心组件
Agent的核心能力由模型(推理引擎)、工具(行动载体)、系统提示词(行为准则) 三大组件支撑,三者均支持静态一次性配置(基础开发首选)和运行时动态定制(生产环境复杂需求),是搭建Agent的基础。
1. 模型(Model):Agent的推理核心
模型是Agent的“大脑”,负责任务推理、工具选择、结果整合,LangChain支持静态模型和动态模型两种配置方式,适配不同开发场景。
1.1 静态模型
创建Agent时一次性配置完成,执行过程中模型保持不变,是最常用、最简洁的方式,支持两种初始化方法,可根据需求选择简洁版或精细配置版。
方法1:模型标识字符串初始化(简洁版)
直接传入厂商+模型的标识字符串,LangChain会自动推断并初始化模型,无需手动导入模型类。
from langchain.agents import create_agent
# 初始化Agent,模型为OpenAI GPT-5,tools为预定义的工具列表
agent = create_agent("openai:gpt-5", tools=tools)
代码详解:
-
导入生产级Agent创建核心函数
create_agent; -
模型标识字符串支持自动推断厂商,如直接传入
"gpt-5",LangChain会默认解析为"openai:gpt-5"; -
tools为预定义的工具列表,若传入空列表,Agent将退化为纯LLM节点,无工具调用能力。
方法2:模型实例化初始化(精细配置版)
直接通过模型厂商的包实例化模型类,可自定义temperature、max_tokens等所有参数,实现生产级的精细化配置。
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
# 精细配置OpenAI模型参数
model = ChatOpenAI(
model="gpt-5", # 模型名称
temperature=0.1, # 输出随机性,0为完全确定,1为最大随机
max_tokens=1000, # 单次输出最大令牌数
timeout=30 # 请求超时时间,单位秒
# 可添加厂商专属参数,如base_url、api_key等
)
# 传入模型实例创建Agent
agent = create_agent(model, tools=tools)
代码详解:
-
从
langchain_openai导入OpenAI的聊天模型类ChatOpenAI(其他厂商模型需导入对应类,如Anthropic的ChatAnthropic); -
模型实例化支持所有厂商专属参数,实现对模型的完全控制,适配生产环境的稳定性、一致性需求;
-
最终将模型实例传入
create_agent,替代简洁版的标识字符串。
1.2 动态模型
根据运行时状态/上下文(如对话长度、用户角色、任务复杂度)动态选择模型,实现请求路由优化和成本控制(简单任务用轻量模型,复杂任务用高级模型)。需通过@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-4.1-mini")
advanced_model = ChatOpenAI(model="gpt-4.1")
# 装饰器创建动态模型选择中间件
@wrap_model_call
def dynamic_model_selection(request: ModelRequest, handler) -> ModelResponse:
"""根据对话复杂度选择模型:消息数>10用高级模型,否则用轻量模型"""
# 获取当前对话的消息数量,判断复杂度
message_count = len(request.state["messages"])
# 根据条件选择模型
model = advanced_model if message_count > 10 else basic_model
# 覆盖请求中的模型并执行后续处理
return handler(request.override(model=model))
# 创建Agent,指定默认模型,挂载中间件
agent = create_agent(
model=basic_model, # 基础默认模型
tools=tools,
middleware=[dynamic_model_selection] # 挂载动态模型中间件
)
代码详解:
-
初始化两个不同规格的模型,分别适配简单/复杂任务,实现成本与效果的平衡;
-
@wrap_model_call装饰器将普通函数转为模型调用中间件,函数接收ModelRequest(模型请求对象)和handler(后续处理函数)两个核心参数; -
从
request.state中获取当前Agent的状态(如对话消息数),作为模型选择的依据; -
request.override(model=model)覆盖请求中的默认模型,handler()执行后续的模型调用逻辑; -
创建Agent时,将中间件传入
middleware参数,中间件会在模型调用前自动执行。
生产注意事项:使用结构化输出时,不支持预绑定工具的模型(即已调用bind_tools方法的模型),若需结合动态模型和结构化输出,需保证传入中间件的模型未做工具预绑定。
2. 工具(Tools):Agent的行动载体
工具让Agent具备执行具体实际操作的能力(如搜索、查天气、计算),LangChain的Agent工具体系远超简单的模型-工具绑定,原生支持:
-
单提示触发多工具序列调用;
-
合适场景下的多工具并行调用;
-
基于前序结果的动态工具选择;
-
工具执行的重试逻辑与错误处理;
-
工具调用间的状态持久化。
工具支持静态定义和运行时动态定制,以下从工具定义、错误处理、ReAct循环使用、动态工具四个方面详解。
2.1 定义工具
工具可定义为普通Python函数或协程,通过@tool装饰器自定义工具名称、描述、参数schema等元数据,LangChain会自动将元数据传递给模型,让模型理解工具的用途和使用方式。
from langchain.tools import tool
from langchain.agents import create_agent
# 装饰器定义工具1:搜索工具
@tool
def search(query: str) -> str:
"""Search for information.(工具描述:用于搜索信息)"""
return f"Results for: {query}"
# 装饰器定义工具2:天气查询工具
@tool
def get_weather(location: str) -> str:
"""Get weather information for a location.(工具描述:查询指定地点的天气)"""
return f"Weather in {location}: Sunny, 72°F"
# 创建Agent,传入工具列表
agent = create_agent(model, tools=[search, get_weather])
代码详解:
-
@tool装饰器是LangChain工具定义的核心,会自动为函数添加工具元数据(名称、描述、参数),无需手动配置; -
函数的文档字符串是模型识别工具的关键,需简洁清晰地说明工具用途,模型会根据该描述判断是否调用工具;
-
工具函数支持类型注解(如
query: str),LangChain会自动解析为参数schema,限制模型传入的参数类型; -
创建Agent时,将工具以列表形式传入
tools参数,支持同时传入多个工具。
基础注意事项:若传入tools=[]空列表,Agent将仅为纯LLM节点,失去工具调用能力。
2.2 工具错误处理
工具执行过程中可能出现异常(如参数错误、网络问题),可通过@wrap_tool_call装饰器创建中间件,自定义异常处理逻辑,捕获异常后返回ToolMessage给模型,让模型感知错误并做出后续决策(如重试、提示用户)。
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_tool_call
from langchain.messages import ToolMessage
# 装饰器创建工具错误处理中间件
@wrap_tool_call
def handle_tool_errors(request, handler):
"""自定义工具错误处理:捕获异常并返回友好提示"""
try:
# 正常执行工具调用
return handler(request)
except Exception as e:
# 捕获所有异常,返回自定义ToolMessage
return ToolMessage(
content=f"Tool error: Please check your input and try again. ({str(e)})",
tool_call_id=request.tool_call["id"] # 绑定工具调用ID,让模型关联错误
)
# 创建Agent,挂载错误处理中间件
agent = create_agent(
model="gpt-4.1",
tools=[search, get_weather],
middleware=[handle_tool_errors]
)
代码详解:
-
@wrap_tool_call装饰器将普通函数转为工具调用中间件,拦截工具的执行过程; -
try-except块捕获工具执行的所有异常,避免Agent因工具错误直接中断; -
异常时返回
ToolMessage,包含自定义错误提示和tool_call_id(工具调用唯一ID),tool_call_id能让模型将错误与对应的工具调用关联,实现精准的错误处理; -
中间件挂载到
middleware参数,工具执行时会自动触发。
错误返回示例:工具执行触发除零错误时,Agent会返回以下ToolMessage:
[
ToolMessage(
content="Tool error: Please check your input and try again. (division by zero)",
tool_call_id="xxx"
)
]
2.3 ReAct循环中的工具使用
Agent的核心工作模式是ReAct循环,即推理→行动→观测的迭代过程:模型先推理是否需要调用工具、调用哪个工具,再执行工具获取观测结果,最后将观测结果融入下一轮推理,直至能给出最终答案。
ReAct循环实战示例:查询「当前最受欢迎的无线耳机并验证库存」
-
人类提问:Find the most popular wireless headphones right now and check if they're in stock
-
推理:热度具有时效性,需要调用搜索工具→行动:调用
search_products("wireless headphones") -
观测:工具返回热门耳机列表,榜首为WH-1000XM5
-
推理:需要验证榜首产品的库存→行动:调用
check_inventory("WH-1000XM5") -
观测:工具返回WH-1000XM5有10件库存
-
推理:已获取核心信息,可输出最终答案→行动:生成自然语言回答
整个过程中,Agent无需人工干预,自主完成工具选择、调用和结果整合,是ReAct循环的典型应用。
2.4 动态工具
实际开发中,常需要运行时调整Agent的可用工具(而非创建时一次性定义),LangChain支持两种动态工具方案,适配不同的业务场景。
方案1:过滤预注册工具
适用场景:所有可能的工具在Agent创建时已注册,需根据运行时状态/权限/上下文过滤可用工具(如管理员可用所有工具,普通用户仅可用只读工具)。 通过@wrap_model_call中间件,在模型调用前过滤请求中的工具列表即可实现。
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
from typing import Callable
# 中间件:根据用户权限过滤工具
@wrap_model_call
def filter_tools(
request: ModelRequest,
handler: Callable[[ModelRequest], ModelResponse],
) -> ModelResponse:
"""管理员可用所有工具,普通用户仅可用以read_开头的只读工具"""
# 从运行时上下文中获取用户角色
user_role = request.runtime.context.user_role
# 过滤工具
if user_role == "admin":
tools = request.tools # 管理员:所有工具
else:
tools = [t for t in request.tools if t.name.startswith("read_")] # 普通用户:只读工具
# 覆盖请求中的工具列表并执行后续处理
return handler(request.override(tools=tools))
# 创建Agent,预注册所有工具(读/写/删),挂载过滤中间件
agent = create_agent(
model="gpt-4o",
tools=[read_data, write_data, delete_data], # 预注册所有工具
middleware=[filter_tools],
)
核心逻辑:通过request.override(tools=tools)覆盖请求中的工具列表,模型仅能看到过滤后的工具,从而实现权限管控。
方案2:运行时注册工具
适用场景:工具在运行时动态发现/生成(如从MCP服务器加载、根据用户数据生成、从远程注册中心获取),Agent创建时未注册该工具。 需同时实现两个中间件钩子:wrap_model_call(将动态工具添加到请求)和wrap_tool_call(处理动态工具的执行),缺一不可。
from langchain.tools import tool
from langchain.agents import create_agent
from langchain.agents.middleware import AgentMiddleware, ModelRequest, ToolCallRequest
# 定义动态工具:小费计算工具(Agent创建时不注册)
@tool
def calculate_tip(bill_amount: float, tip_percentage: float = 20.0) -> str:
"""Calculate the tip amount for a bill.(计算账单的小费金额)"""
tip = bill_amount * (tip_percentage / 100)
return f"Tip: ${tip:.2f}, Total: ${bill_amount + tip:.2f}"
# 自定义中间件类,实现动态工具的添加和执行
class DynamicToolMiddleware(AgentMiddleware):
"""注册并处理动态工具的中间件"""
# 钩子1:模型调用前,将动态工具添加到请求中
def wrap_model_call(self, request: ModelRequest, handler):
# 合并原有工具和动态工具,覆盖请求的工具列表
updated_tools = [*request.tools, calculate_tip]
updated_request = request.override(tools=updated_tools)
return handler(updated_request)
# 钩子2:工具调用时,处理动态工具的执行
def wrap_tool_call(self, request: ToolCallRequest, handler):
# 判断是否调用动态工具
if request.tool_call["name"] == "calculate_tip":
# 覆盖请求中的工具,指定动态工具执行
return handler(request.override(tool=calculate_tip))
# 非动态工具,按原有逻辑执行
return handler(request)
# 创建Agent,仅注册静态工具(查天气),挂载动态工具中间件
agent = create_agent(
model="gpt-4o",
tools=[get_weather], # 仅注册静态工具
middleware=[DynamicToolMiddleware()],
)
# 运行Agent:可同时使用静态工具get_weather和动态工具calculate_tip
result = agent.invoke({
"messages": [{"role": "user", "content": "Calculate a 20% tip on $85"}]
})
代码详解:
-
先定义动态工具
calculate_tip,该工具在Agent创建时不传入tools参数,属于运行时注册; - 自定义
DynamicToolMiddleware类继承AgentMiddleware,实现两个核心钩子:-
wrap_model_call:模型调用前,将动态工具与原有静态工具合并,更新请求的工具列表,让模型“看到”动态工具; -
wrap_tool_call:工具调用时,判断是否为动态工具,若是则覆盖请求中的工具,指定动态工具执行,否则按原有逻辑处理;
-
-
挂载中间件后,Agent可同时使用静态工具和动态工具,实现工具的运行时扩展。
关键注意事项:wrap_tool_call钩子是必需的,因为Agent无法执行创建时未注册的工具,该钩子让Agent明确动态工具的执行逻辑。
3. 系统提示词(System prompt):Agent的行为准则
系统提示词用于定义Agent的角色、工作方式、响应规范,是塑造Agent行为的核心,支持静态配置和运行时动态生成,同时可利用模型厂商的专属特性(如Anthropic的提示词缓存)。
3.1 静态系统提示词
直接传入字符串或SystemMessage对象创建静态提示词,字符串为简洁版,SystemMessage为精细版,支持厂商专属特性(如Anthropic的cache_control提示词缓存,降低延迟和调用成本)。
方式1:字符串简洁版
# 创建Agent时,传入字符串格式的系统提示词
agent = create_agent(
model,
tools,
system_prompt="You are a helpful assistant. Be concise and accurate.(贴心助手,回答简洁准确)"
)
方式2:SystemMessage精细版(支持厂商特性)
from langchain.agents import create_agent
from langchain.messages import SystemMessage, HumanMessage
# 创建SystemMessage,启用Anthropic的提示词缓存
literary_agent = create_agent(
model="anthropic:claude-sonnet-4-5",
system_prompt=SystemMessage(
content=[
{
"type": "text",
"text": "You are an AI assistant tasked with analyzing literary works.(文学分析助手)",
},
{
"type": "text",
"text": "<《傲慢与偏见》全本内容>",
"cache_control": {"type": "ephemeral"} # 缓存该内容块
}
]
)
)
# 调用Agent分析《傲慢与偏见》
result = literary_agent.invoke(
{"messages": [HumanMessage("Analyze the major themes in 'Pride and Prejudice'.(分析《傲慢与偏见》的核心主题)")]}
)
代码详解:
-
从
langchain.messages导入SystemMessage和HumanMessage,分别用于定义系统提示词和人类提问; -
SystemMessage的content支持多文本块配置,为每个文本块设置专属属性; -
cache_control={"type": "ephemeral"}是Anthropic的专属特性,告诉厂商缓存该文本块,当重复使用相同系统提示词时,无需重复传输大文本(如《傲慢与偏见》全本),大幅降低调用延迟和token成本; -
该方式适用于系统提示词包含大文本内容且需要重复调用的场景。
基础注意事项:若不传入system_prompt,Agent会直接从用户消息中自动推断任务目标,适用于简单的通用对话场景。
3.2 动态系统提示词
适用场景:需要根据运行时上下文/Agent状态(如用户角色、任务类型)动态生成系统提示词(如对专家返回技术细节,对新手用通俗解释)。 通过@dynamic_prompt装饰器创建中间件,根据模型请求生成个性化的系统提示词。
from typing import TypedDict
from langchain.agents import create_agent
from langchain.agents.middleware import dynamic_prompt, ModelRequest
# 定义运行时上下文的schema:包含用户角色
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 = "You are a helpful assistant."
# 根据用户角色定制提示词
if user_role == "expert":
return f"{base_prompt} Provide detailed technical responses.(提供详细的技术化回答)"
elif user_role == "beginner":
return f"{base_prompt} Explain concepts simply and avoid jargon.(用简单的语言解释,避免专业术语)"
# 普通用户返回基础提示词
return base_prompt
# 创建Agent,挂载动态提示词中间件,指定上下文schema
agent = create_agent(
model="gpt-4.1",
tools=[web_search],
middleware=[user_role_prompt],
context_schema=Context # 绑定上下文schema
)
# 调用Agent:传入运行时上下文(用户角色为专家)
result = agent.invoke(
{"messages": [{"role": "user", "content": "Explain machine learning(解释机器学习)"}]},
context={"user_role": "expert"}
)
代码详解:
-
用
TypedDict定义运行时上下文schemaContext,指定上下文包含的字段(如user_role),让Agent能解析传入的上下文; -
@dynamic_prompt装饰器将普通函数转为动态提示词中间件,从request.runtime.context中获取运行时上下文; -
根据上下文的
user_role生成个性化的系统提示词,实现Agent的自适应响应; -
创建Agent时,通过
context_schema绑定上下文schema,调用时通过context参数传入具体的上下文信息。
二、Agent 调用(Invocation)
LangChain Agent的核心调用方式为**invoke方法,通过向Agent的状态(State)** 传入新消息触发执行,所有Agent的状态中均包含消息序列,这是Agent处理请求的核心依据。
基础调用示例
# 调用Agent,传入用户消息
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?(旧金山的天气如何?)"}]}
)
核心逻辑:invoke方法接收一个字典参数,其中messages为消息列表,每个消息包含role(角色:user/ai/tool等)和content(内容),Agent会根据消息序列执行推理和工具调用,返回最终结果。
扩展调用能力
LangChain Agent底层基于LangGraph构建,完全兼容LangGraph的Graph API,除invoke(同步获取最终结果)外,还支持:
-
stream:流式获取执行过程和结果(详见「高级概念-流式输出」); -
batch:批量处理多个请求; -
ainvoke/astream:异步调用方法,适配异步开发框架。
三、Agent 高级概念
基础的核心组件和调用方式可满足简单开发需求,LangChain还提供了结构化输出、记忆、流式输出三大高级特性,适配生产环境的结果可解析、上下文记忆、实时反馈需求。
1. 结构化输出
实际开发中,常需要Agent返回固定格式的结构化结果(如提取联系人信息、解析数据),而非无格式的自然语言,LangChain通过response_format参数实现结构化输出,提供两种核心策略,适配不同的模型能力。
结构化输出的schema可通过Pydantic BaseModel或dataclass定义,以下以Pydantic为例讲解。
策略1:ToolStrategy(工具调用策略)
核心原理:借助模型的工具调用能力生成结构化输出,将结构化schema转为虚拟工具,模型通过调用虚拟工具输出符合schema的结果。 适用场景:模型不支持厂商原生结构化输出,或原生能力不可靠,该策略兼容所有支持工具调用的模型,通用性最强。
from pydantic import BaseModel
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy
# 定义结构化输出的schema:联系人信息
class ContactInfo(BaseModel):
name: str # 姓名(必选)
email: str # 邮箱(必选)
phone: str # 电话(必选)
# 创建Agent,指定结构化输出策略为ToolStrategy
agent = create_agent(
model="gpt-4.1-mini",
tools=[search_tool],
response_format=ToolStrategy(ContactInfo) # 绑定schema和策略
)
# 调用Agent:提取联系人信息
result = agent.invoke({
"messages": [{"role": "user", "content": "Extract contact info from: John Doe, john@example.com, (555) 123-4567"}]
})
# 获取结构化结果
print(result["structured_response"])
# 输出:ContactInfo(name='John Doe', email='john@example.com', phone='(555) 123-4567')
代码详解:
-
用Pydantic
BaseModel定义结构化schema,指定字段名和类型,实现数据校验; -
将schema传入
ToolStrategy,再将其赋值给response_format参数,Agent会自动将schema转为虚拟工具; -
调用后,从
result["structured_response"]中获取强类型的结构化结果,可直接通过属性访问(如result["structured_response"].name)。
策略2:ProviderStrategy(厂商原生策略)
核心原理:使用模型厂商的原生结构化输出能力(如OpenAI的response_format、Anthropic的output_schema)生成结果,无需借助工具调用。 适用场景:模型支持厂商原生结构化输出,该策略更高效、更可靠,是生产环境的首选。
from langchain.agents.structured_output import ProviderStrategy
# 创建Agent,指定结构化输出策略为ProviderStrategy
agent = create_agent(
model="gpt-4.1",
response_format=ProviderStrategy(ContactInfo) # 绑定schema和策略
)
代码详解:仅需将ToolStrategy替换为ProviderStrategy,其余逻辑与工具调用策略一致,Agent会自动调用厂商的原生结构化输出能力。
LangChain 1.0 版本简化特性
在LangChain 1.0及以上版本中,无需手动指定策略,直接传入schema即可:
# 1.0+版本简化写法
agent = create_agent(model="gpt-4.1", response_format=ContactInfo)
Agent会自动检测模型能力:若模型支持原生结构化输出,默认使用ProviderStrategy;若不支持,自动回退为ToolStrategy,大幅简化开发。
2. 记忆(Memory)
Agent默认通过消息状态自动维护对话历史(短期记忆),可实现基础的多轮对话上下文关联。对于复杂场景,还可通过自定义状态schema,让Agent记忆对话历史之外的额外信息(如用户偏好、任务配置),实现高级记忆能力。
核心规则(LangChain 1.0+)
-
自定义状态schema必须继承
AgentState,且为TypedDict类型; -
不再支持Pydantic模型和dataclasses,仅兼容TypedDict;
-
自定义状态有两种定义方式,中间件方式为官方推荐。
方式1:通过中间件定义自定义状态(推荐)
适用场景:自定义状态需要被特定中间件/工具访问,该方式可将状态扩展与相关的中间件/工具作用域绑定,实现模块化开发。
from langchain.agents import AgentState
from langchain.agents.middleware import AgentMiddleware
from typing import Any, TypedDict
# 1. 定义自定义状态schema,继承AgentState(TypedDict)
class CustomState(AgentState):
user_preferences: dict # 新增状态:用户偏好(字典类型)
# 2. 自定义中间件,绑定自定义状态schema
class CustomMiddleware(AgentMiddleware):
state_schema = CustomState # 绑定自定义状态
tools = [tool1, tool2] # 该中间件关联的工具
# 可选:模型调用前的状态处理逻辑
def before_model(self, state: CustomState, runtime) -> dict[str, Any] | None:
# 可在此处处理自定义状态(如修改/校验用户偏好)
pass
# 3. 创建Agent,挂载中间件
agent = create_agent(
model,
tools=tools,
middleware=[CustomMiddleware()]
)
# 4. 调用Agent,传入自定义状态
result = agent.invoke({
"messages": [{"role": "user", "content": "I prefer technical explanations(我喜欢技术化的解释)"}],
"user_preferences": {"style": "technical", "verbosity": "detailed"} # 自定义状态
})
方式2:通过state_schema参数定义(快捷方式)
适用场景:自定义状态仅在工具中使用,无需中间件处理,是快速实现自定义状态的方式。
from langchain.agents import AgentState, create_agent
from typing import TypedDict
# 1. 定义自定义状态schema
class CustomState(AgentState):
user_preferences: dict
# 2. 创建Agent,直接指定state_schema
agent = create_agent(
model,
tools=[tool1, tool2],
state_schema=CustomState # 绑定自定义状态
)
# 3. 调用Agent,传入自定义状态
result = agent.invoke({
"messages": [{"role": "user", "content": "I prefer technical explanations"}],
"user_preferences": {"style": "technical", "verbosity": "detailed"}
})
3. 流式输出(Streaming)
invoke方法会等待Agent完成所有步骤后返回最终结果,若Agent需要执行多轮工具调用,会出现较长的等待时间。LangChain提供**stream方法实现流式输出,可实时捕获Agent的中间执行步骤(如模型推理、工具调用)和渐进式结果**,提升用户体验。
流式输出核心示例
from langchain.messages import AIMessage, HumanMessage
# 调用stream方法,stream_mode="values"表示按状态值流式返回
for chunk in agent.stream({
"messages": [{"role": "user", "content": "Search for AI news and summarize the findings(搜索AI新闻并总结)"}]
}, stream_mode="values"):
# 每个chunk包含当前Agent的完整状态,取最新的一条消息
latest_message = chunk["messages"][-1]
# 处理普通文本消息(用户/Agent的自然语言)
if latest_message.content:
if isinstance(latest_message, HumanMessage):
print(f"User: {latest_message.content}")
elif isinstance(latest_message, AIMessage):
print(f"Agent: {latest_message.content}")
# 处理工具调用消息(Agent的工具调用行为)
elif latest_message.tool_calls:
# 输出正在调用的工具名称
print(f"Calling tools: {[tc['name'] for tc in latest_message.tool_calls]}")
代码详解:
-
agent.stream()返回生成器,通过for循环迭代获取流式数据; -
stream_mode="values"是最常用的流式模式,表示按Agent的状态值流式返回,每个chunk包含当前的完整状态; -
从
chunk["messages"][-1]获取最新的一条消息,区分普通文本消息和工具调用消息,分别做个性化输出; -
latest_message.tool_calls包含工具调用的详细信息(如工具名称、参数、调用ID),可实时展示Agent的行动过程。
流式输出效果:实时打印「调用搜索工具→返回搜索结果→Agent总结结果」的全过程,而非等待所有步骤完成后一次性输出。
四、中间件(Middleware):Agent的核心扩展能力
中间件是LangChain Agent最强大的扩展机制,为Agent提供了无侵入式的行为定制能力,可在Agent执行的不同阶段拦截并修改数据流向,实现自定义逻辑,而无需改动Agent的核心代码。
中间件的核心作用
中间件可在Agent的模型调用前、工具调用前、状态处理前/后等关键节点执行自定义逻辑,典型应用场景包括:
-
实现动态模型选择、动态工具过滤、动态系统提示词;
-
自定义工具错误处理、模型响应校验(如内容风控、输出过滤);
-
处理状态预处理(如消息裁剪、上下文注入);
-
添加自定义日志、监控、埋点(如记录模型调用耗时、工具调用次数);
-
实现请求/响应的格式转换。
中间件的核心特性
-
无侵入式:无需修改Agent的核心代码,仅需通过
middleware参数挂载,符合“开闭原则”; -
可组合性:支持同时挂载多个中间件,按顺序执行;
-
场景化:提供
@wrap_model_call、@wrap_tool_call、@dynamic_prompt等专用装饰器,适配不同的扩展场景; -
可自定义:可继承
AgentMiddleware类,实现自定义的中间件类,适配复杂的扩展需求。
中间件与Agent的融合
本文中讲解的动态模型、动态工具、动态提示词、工具错误处理等功能,均是通过中间件实现的,中间件是连接基础组件和高级特性的桥梁,也是LangChain Agent适配生产环境复杂需求的核心。
五、核心总结
LangChain Agents是构建LLM智能应用的核心框架,其设计核心是「基础能力标准化,高级能力可扩展」:
-
基于
create_agent可快速搭建生产级Agent,模型、工具、系统提示词三大核心组件支持极简的静态配置,满足基础开发需求; -
基于中间件实现全维度的动态定制,覆盖模型、工具、提示词、状态等所有核心环节,适配生产环境的复杂需求;
-
ReAct循环是Agent的核心工作模式,实现自主的推理-行动-观测迭代,无需人工干预;
-
结构化输出、记忆、流式输出三大高级特性,解决了生产环境中结果可解析、上下文记忆、实时反馈的核心痛点;
-
底层基于LangGraph构建,兼容Graph API的所有调用方式,可无缝扩展为更复杂的图式智能体。
LangChain Agents的设计让开发者可以快速上手,同时也为生产级定制留下了充足的扩展空间,是目前最主流的LLM智能体开发框架之一。
更多推荐


所有评论(0)