跳转至

Agents

Abstract

LangChain 中的 Agent 是把 语言模型工具 组合起来的运行系统。

  • 模型负责理解任务、推理下一步动作。
  • 工具负责执行搜索、数据库查询、API 调用、计算等外部动作。
  • Agent 会在“模型决策 -> 调用工具 -> 观察结果 -> 继续决策”的循环中工作,直到模型给出最终答案,或达到迭代上限。

%%{
init: {
    "fontFamily": "monospace",
    "flowchart": {
    "curve": "curve"
    }
}
}%%
graph TD
%% Outside the agent
QUERY([input])
LLM{model}
TOOL(tools)
ANSWER([output])

%% Main flows (no inline labels)
QUERY --> LLM
LLM --"action"--> TOOL
TOOL --"observation"--> LLM
LLM --"finish"--> ANSWER

classDef blueHighlight fill:#E5F4FF,stroke:#006DDD,color:#030710;
classDef greenHighlight fill:#F6FFDB,stroke:#6E8900,color:#2E3900;
class QUERY blueHighlight;
class ANSWER blueHighlight;
class LLM greenHighlight;
class TOOL greenHighlight;

官方推荐使用 create_agent 创建生产可用的 Agent。它底层基于 LangGraph 构建图式运行时:模型调用、工具执行、middleware 等步骤都可以看作图中的节点,节点之间的边决定了 Agent 如何流转。


基本循环

Agent 常见执行流程可以理解为:

  1. 用户输入任务。
  2. 模型判断是否需要调用工具。
  3. 如果需要,模型生成 tool call。
  4. 工具执行并返回 observation。
  5. 模型基于 observation 继续推理。
  6. 当信息足够时,模型输出 final answer。

这类模式通常被称为 ReAct,即 Reasoning + Acting。它不是一次性生成答案,而是通过多轮“思考与行动”逐步逼近结果。


核心组件

Model

Model 是 Agent 的推理引擎,可以用字符串标识,也可以传入具体模型实例。

from langchain.agents import create_agent

agent = create_agent(
    model="openai:gpt-5.4",
    tools=tools,
)

如果需要更精细的配置,例如 temperaturemax_tokenstimeoutbase_url 等,可以直接初始化 provider 对应的模型类:

from langchain_openai import ChatOpenAI

model = ChatOpenAI(
    model="gpt-5.4",
    temperature=0.1,
    max_tokens=1000,
)

agent = create_agent(model, tools=tools)

模型也可以动态选择。例如简单对话用便宜模型,长上下文或复杂任务切换到更强模型。这通常通过 middleware 在运行时根据 statecontext 修改 model。

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-5.4-mini")
advanced_model = ChatOpenAI(model="gpt-5.4")

@wrap_model_call
def dynamic_model_selection(request: ModelRequest, handler) -> ModelResponse:
    """Choose model based on conversation complexity."""
    message_count = len(request.state["messages"])

    if message_count > 10:
        # Use an advanced model for longer conversations
        model = advanced_model
    else:
        model = basic_model

    return handler(request.override(model=model))

agent = create_agent(
    model=basic_model,  # Default model
    tools=tools,
    middleware=[dynamic_model_selection]
)

Tools

Tools 让 Agent 具备行动能力。普通 LLM 只能生成文本,而 Agent 可以借助工具完成外部操作,例如搜索、查天气、读写数据库、调用业务 API。

from langchain.agents import create_agent
from langchain.tools import tool

@tool
def search(query: str) -> str:
    """Search for information."""
    return f"Results for: {query}"

@tool
def get_weather(location: str) -> str:
    """Get weather information for a location."""
    return f"Weather in {location}: Sunny"

agent = create_agent(
    model="openai:gpt-5.4",
    tools=[search, get_weather],
)

工具可以是静态的,也可以动态筛选。

动态 tools 适合这些场景

  • 根据用户权限暴露不同工具。
  • 根据会话阶段隐藏高级工具,减少模型误用。
  • 根据 feature flag 或用户配置启用工具。
  • 从 MCP server、远程 registry 或业务系统中运行时加载工具。

Warning

Tools 越多不一定越好。过多 tools 会占用上下文,也可能增加模型选择错误的概率。实践中应该尽量保持工具描述清晰、名称稳定,并只暴露当前任务真正需要的工具。


System Prompt

system_prompt 用来定义 Agent 的角色、边界和任务风格。

agent = create_agent(
    model="openai:gpt-5.4",
    tools=tools,
    system_prompt="You are a helpful assistant. Be concise and accurate.",
)

如果不提供 system prompt,Agent 会主要从用户消息中推断任务。

对于复杂 Agent,建议显式写清楚

  • Agent 的职责是什么。
  • 什么时候应该调用工具。
  • 什么时候必须确认信息。
  • 输出格式或语气要求。
  • 不确定时如何处理。

System prompt 也可以动态生成。例如根据用户角色切换解释深度:初学者用简单语言,专家用户提供更技术化的回答。

Name

Agent 可以设置 name,在多 Agent 系统中作为子图或节点标识。

agent = create_agent(
    model="openai:gpt-5.4",
    tools=tools,
    name="research_assistant",
)

名称建议使用 snake_case,避免空格和特殊字符,因为部分模型供应商会拒绝不兼容的名称。工具名称也应遵循类似规则。

调用方式

Agent 通过 invoke 调用,输入通常是一个包含 messages 的状态更新:

result = agent.invoke(
    {
        "messages": [
            {"role": "user", "content": "What's the weather in San Francisco?"}
        ]
    }
)

如果任务需要多个步骤,或者希望前端展示中间进度,可以使用 stream 流式获取 Agent 的状态变化、消息和工具调用。

进阶能力

Structured Output

当需要 Agent 返回固定结构时,可以使用 response_format。常见方式有两种:

  • ProviderStrategy:使用模型供应商原生结构化输出,通常更可靠,但依赖 provider 支持。
  • ToolStrategy:通过工具调用模拟结构化输出,适用范围更广。

在 LangChain 1.0 中,直接传入 schema 时,如果模型支持原生结构化输出,会优先使用 provider 原生能力,否则回退到 tool strategy。

Memory

Agent 默认通过 message state 保存对话历史,相当于短期记忆。对于额外状态,例如用户偏好、任务阶段、工具使用统计等,可以扩展 AgentState

自定义 state 主要有两种方式:

  • 通过 middleware 定义:更推荐,状态和相关逻辑放在一起。
  • 通过 state_schema 传给 create_agent:适合简单场景或兼容旧代码。

LangChain 1.0 要求自定义 state schema 使用 TypedDict

Middleware

Middleware 是扩展 Agent 行为的关键机制,可以在模型调用、工具调用、状态更新等阶段插入自定义逻辑。常见用途包括:

  • 在调用模型前裁剪消息或注入上下文。
  • 动态选择模型。
  • 动态筛选工具。
  • 处理工具异常。
  • 增加日志、监控、评估或 guardrails。

如果把 create_agent 看作一个默认可用的 Agent 运行时,middleware 就是对这个运行时做工程化定制的主要入口。

小结

LangChain Agent 的关键不在于“让模型自己完成所有事”,而在于把模型放进一个可控的执行循环中:模型负责决策,工具负责行动,state 负责保存上下文,middleware 负责工程化约束。对于真实应用,Agent 的可靠性往往取决于工具设计、状态管理、错误处理和可观测性,而不只是模型本身。