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:模型实例化初始化(精细配置版)

直接通过模型厂商的包实例化模型类,可自定义temperaturemax_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]  # 挂载动态模型中间件
)

代码详解

  1. 初始化两个不同规格的模型,分别适配简单/复杂任务,实现成本与效果的平衡;

  2. @wrap_model_call装饰器将普通函数转为模型调用中间件,函数接收ModelRequest(模型请求对象)和handler(后续处理函数)两个核心参数;

  3. request.state中获取当前Agent的状态(如对话消息数),作为模型选择的依据;

  4. request.override(model=model)覆盖请求中的默认模型,handler()执行后续的模型调用逻辑;

  5. 创建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])

代码详解

  1. @tool装饰器是LangChain工具定义的核心,会自动为函数添加工具元数据(名称、描述、参数),无需手动配置;

  2. 函数的文档字符串是模型识别工具的关键,需简洁清晰地说明工具用途,模型会根据该描述判断是否调用工具;

  3. 工具函数支持类型注解(如query: str),LangChain会自动解析为参数schema,限制模型传入的参数类型;

  4. 创建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]
)

代码详解

  1. @wrap_tool_call装饰器将普通函数转为工具调用中间件,拦截工具的执行过程;

  2. try-except块捕获工具执行的所有异常,避免Agent因工具错误直接中断;

  3. 异常时返回ToolMessage,包含自定义错误提示tool_call_id(工具调用唯一ID),tool_call_id能让模型将错误与对应的工具调用关联,实现精准的错误处理;

  4. 中间件挂载到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循环实战示例:查询「当前最受欢迎的无线耳机并验证库存」

  1. 人类提问:Find the most popular wireless headphones right now and check if they're in stock

  2. 推理:热度具有时效性,需要调用搜索工具→行动:调用search_products("wireless headphones")

  3. 观测:工具返回热门耳机列表,榜首为WH-1000XM5

  4. 推理:需要验证榜首产品的库存→行动:调用check_inventory("WH-1000XM5")

  5. 观测:工具返回WH-1000XM5有10件库存

  6. 推理:已获取核心信息,可输出最终答案→行动:生成自然语言回答

整个过程中,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"}]
})

代码详解

  1. 先定义动态工具calculate_tip,该工具在Agent创建时不传入tools参数,属于运行时注册;

  2. 自定义DynamicToolMiddleware类继承AgentMiddleware,实现两个核心钩子:
    • wrap_model_call:模型调用前,将动态工具与原有静态工具合并,更新请求的工具列表,让模型“看到”动态工具;

    • wrap_tool_call:工具调用时,判断是否为动态工具,若是则覆盖请求中的工具,指定动态工具执行,否则按原有逻辑处理;

  3. 挂载中间件后,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'.(分析《傲慢与偏见》的核心主题)")]}
)

代码详解

  1. langchain.messages导入SystemMessageHumanMessage,分别用于定义系统提示词和人类提问;

  2. SystemMessagecontent支持多文本块配置,为每个文本块设置专属属性;

  3. cache_control={"type": "ephemeral"}是Anthropic的专属特性,告诉厂商缓存该文本块,当重复使用相同系统提示词时,无需重复传输大文本(如《傲慢与偏见》全本),大幅降低调用延迟token成本

  4. 该方式适用于系统提示词包含大文本内容且需要重复调用的场景。

基础注意事项:若不传入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"}
)

代码详解

  1. TypedDict定义运行时上下文schemaContext,指定上下文包含的字段(如user_role),让Agent能解析传入的上下文;

  2. @dynamic_prompt装饰器将普通函数转为动态提示词中间件,从request.runtime.context中获取运行时上下文;

  3. 根据上下文的user_role生成个性化的系统提示词,实现Agent的自适应响应

  4. 创建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 BaseModeldataclass定义,以下以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')

代码详解

  1. 用Pydantic BaseModel定义结构化schema,指定字段名和类型,实现数据校验

  2. 将schema传入ToolStrategy,再将其赋值给response_format参数,Agent会自动将schema转为虚拟工具;

  3. 调用后,从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+)
  1. 自定义状态schema必须继承AgentState,且为TypedDict类型

  2. 不再支持Pydantic模型和dataclasses,仅兼容TypedDict;

  3. 自定义状态有两种定义方式中间件方式为官方推荐

方式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]}")

代码详解

  1. agent.stream()返回生成器,通过for循环迭代获取流式数据;

  2. stream_mode="values"是最常用的流式模式,表示按Agent的状态值流式返回,每个chunk包含当前的完整状态;

  3. chunk["messages"][-1]获取最新的一条消息,区分普通文本消息工具调用消息,分别做个性化输出;

  4. latest_message.tool_calls包含工具调用的详细信息(如工具名称、参数、调用ID),可实时展示Agent的行动过程。

流式输出效果:实时打印「调用搜索工具→返回搜索结果→Agent总结结果」的全过程,而非等待所有步骤完成后一次性输出。

四、中间件(Middleware):Agent的核心扩展能力

中间件是LangChain Agent最强大的扩展机制,为Agent提供了无侵入式的行为定制能力,可在Agent执行的不同阶段拦截并修改数据流向,实现自定义逻辑,而无需改动Agent的核心代码。

中间件的核心作用

中间件可在Agent的模型调用前、工具调用前、状态处理前/后等关键节点执行自定义逻辑,典型应用场景包括:

  • 实现动态模型选择动态工具过滤动态系统提示词

  • 自定义工具错误处理模型响应校验(如内容风控、输出过滤);

  • 处理状态预处理(如消息裁剪、上下文注入);

  • 添加自定义日志、监控、埋点(如记录模型调用耗时、工具调用次数);

  • 实现请求/响应的格式转换

中间件的核心特性

  1. 无侵入式:无需修改Agent的核心代码,仅需通过middleware参数挂载,符合“开闭原则”;

  2. 可组合性:支持同时挂载多个中间件,按顺序执行;

  3. 场景化:提供@wrap_model_call@wrap_tool_call@dynamic_prompt等专用装饰器,适配不同的扩展场景;

  4. 可自定义:可继承AgentMiddleware类,实现自定义的中间件类,适配复杂的扩展需求。

中间件与Agent的融合

本文中讲解的动态模型、动态工具、动态提示词、工具错误处理等功能,均是通过中间件实现的,中间件是连接基础组件和高级特性的桥梁,也是LangChain Agent适配生产环境复杂需求的核心。

五、核心总结

LangChain Agents是构建LLM智能应用的核心框架,其设计核心是「基础能力标准化,高级能力可扩展」

  1. 基于create_agent可快速搭建生产级Agent,模型、工具、系统提示词三大核心组件支持极简的静态配置,满足基础开发需求;

  2. 基于中间件实现全维度的动态定制,覆盖模型、工具、提示词、状态等所有核心环节,适配生产环境的复杂需求;

  3. ReAct循环是Agent的核心工作模式,实现自主的推理-行动-观测迭代,无需人工干预;

  4. 结构化输出、记忆、流式输出三大高级特性,解决了生产环境中结果可解析、上下文记忆、实时反馈的核心痛点;

  5. 底层基于LangGraph构建,兼容Graph API的所有调用方式,可无缝扩展为更复杂的图式智能体。

LangChain Agents的设计让开发者可以快速上手,同时也为生产级定制留下了充足的扩展空间,是目前最主流的LLM智能体开发框架之一。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐