LangChain 学习笔记(七):智能体 Agent

LangChain 学习笔记(七):智能体 Agent

本文基于《尚硅谷 LangChain 1.2》第7章整理,并结合实际开发经验进行补充。

本章是 LangChain 最重要的章节,介绍了从 v0.x 碎片化 Agent 到 v1.x 统一 create_agent() 的架构变迁,以及 Agent 的完整使用方法。


一、本章学习目标

学习完本章,你应该能够:

  • 理解 Agent 的核心概念和五大组件(LLM + Planning + Tools + Memory + Action)
  • 掌握 v0.x 旧时代与 v1.x 新时代的架构差异
  • 会使用 create_agent() 一步创建 Agent
  • 理解 Agent 底层是 LangGraph 的 CompiledStateGraph
  • 掌握模型传入的两种方式(字符串 vs 模型对象)
  • 掌握 agent.invoke() 的调用方式和消息格式
  • 理解工具绑定的完整流程
  • 掌握工具调用的完整 Function Calling 执行链路
  • 会设置系统提示词和 Agent 名称
  • 掌握结构化输出的四种策略
  • 掌握流式输出的七种模式
  • 理解重试机制和常见问题
  • 能够构建完整的多功能智能助手

二、什么是 Agent?

通用人工智能(AGI)将是 AI 的终极形态,几乎已成为业界共识。

同样,构建智能体(Agent)则是 AI 工程应用当下的"终极形态"。

Agent 是大模型应用开发的核心。

1、Agent 的定义

在大模型应用开发中,智能体通常指一种:

以大语言模型为推理与决策核心,结合记忆、工具调用与环境交互能力,能够进行规划决策并执行复杂任务以达成目标的软件系统。

复制代码
                    ┌──────────────────────┐
                    │      Agent           │
                    │                      │
                    │   ┌──────────────┐   │
                    │   │   LLM (大脑)  │   │
                    │   └──────┬───────┘   │
                    │          │           │
                    │   ┌──────┴───────┐   │
                    │   │  Planning    │   │
                    │   │  (规划决策)  │   │
                    │   └──────┬───────┘   │
                    │          │           │
                    │   ┌──────┴───────┐   │
                    │   │   Tools      │   │
                    │   │  (工具调用)  │   │
                    │   └──────┬───────┘   │
                    │          │           │
                    │   ┌──────┴───────┐   │
                    │   │   Memory     │   │
                    │   │  (记忆)      │   │
                    │   └──────┬───────┘   │
                    │          │           │
                    │   ┌──────┴───────┐   │
                    │   │   Action     │   │
                    │   │  (行动)      │   │
                    │   └──────────────┘   │
                    └──────────────────────┘

2、Agent 的关键能力

Agent 必须具备以下五种核心能力:

能力 说明
理解用户问题 准确理解用户的意图和需求
拆解任务 将复杂任务分解为可执行的子步骤
判断是否需要工具 分析当前任务是否需要借助外部工具
选择调用哪些工具 从可用工具中选择最合适的工具
利用工具结果 综合工具返回的结果,生成回答或推进任务

3、Agent 的核心组件

现代 AI Agent 的架构包含以下要素:

组件 必要性 说明
Action 必须的 行动能力,Agent 必须能执行操作
Tool 几乎总是存在 工具,扩展 Agent 的能力边界
Planning 有条件存在 规划决策,复杂任务需要,简单任务可省略
Memory 最容易被省略 记忆,简单 Agent 可能不需要持久记忆

实际开发中几个要素并不需要同时出现。

一句话总结:

  • 必须的:行动(Action)
  • 几乎总是存在的:工具(Tool)
  • 有条件存在的:规划决策(Planning)
  • 最容易被省略的:记忆(Memory)

三、Agent 创建与调用的历史变迁

这是本章最重要的内容,也是理解 LangChain Agent 设计思想的关键。

1、v0.x 旧时代:碎片化的 Agent 创建

在 LangChain 0.x 时代,框架内的 Agent 系统经历了"碎片化"阶段。

当时的设计理念是"针对场景设计特定 Agent":

  • 如果要实现思维链推理(ReAct),就用 create_react_agent

  • 如果需要结构化输出,就用 create_structured_chat_agent

  • 要工具调用,则用 create_tool_calling_agent

    v0.x 时代:每种 Agent 都需要单独记忆 API

    复制代码
      create_react_agent          →  ReAct 推理
      create_structured_chat_agent →  结构化输出
      create_tool_calling_agent    →  工具调用
      create_json_agent            →  JSON 输出
      ...

v0.x 的复杂方式:

python 复制代码
# 需要多个步骤
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_react_agent
from langchain_core.prompts import PromptTemplate

# 1. 模型初始化
model = ChatOpenAI(model="gpt-4o-mini")

# 2. 创建提示词模板
prompt = PromptTemplate.from_template("""
You are a helpful assistant.
Tools: {tools}
Tool Names: {tool_names}
{agent_scratchpad}
""")

# 3. 创建 agent
agent = create_react_agent(
    llm=model,
    tools=tools,
    prompt=prompt
)

# 4. 创建 executor
executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True
)

# 5. 调用
result = executor.invoke({"input": "问题"})

这种方式带来了三个明显问题:

问题 说明
心智负担高 每种 Agent 都要单独记忆 API 与参数
可组合性差 多个 Agent 之间无法统一调度
生态碎片化 不同模块难以复用或协同演化

2、v1.x 新时代:统一的 create_agent()

LangChain 在 1.0 版本后,团队做出了彻底重构:

将所有 Agent 的创建方式统一为一个入口:create_agent()

它取代了旧版本中的 create_react_agentcreate_json_agentcreate_tool_calling_agent 等多种分支函数。

真正让开发者用一行代码即可创建任何类型的智能体。

同时在底层通过"中间件机制(Middleware)"和"标准模型接口(invoke/stream)"实现全局统一。

这让框架更轻、更稳,也更易于被集成到其他 Agent 平台中。

复制代码
v1.x 时代:一个函数,所有场景

    create_agent(model, tools, system_prompt)
                    │
                    │  统一入口
                    │
         ┌──────────┼──────────┐
         │          │          │
      ReAct     工具调用   结构化输出

v1.x 的简洁方式:

python 复制代码
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent

# 1. 初始化模型
model = init_chat_model("gpt-4o-mini", model_provider="openai")

# 2. 创建 agent(一步完成)
agent = create_agent(
    model=model,
    tools=[tool1, tool2],
    system_prompt="Agent 的行为指令"  # 可选
)

# 3. 调用
result = agent.invoke({
    "messages": [{"role": "user", "content": "问题"}]
})

v0.x 与 v1.x 对比:

维度 v0.x (旧时代) v1.x (新时代)
创建方式 多个函数,每种 Agent 不同 一个 create_agent() 统一入口
需要步骤 5 步(模型 + 提示词 + Agent + Executor + 调用) 3 步(模型 + Agent + 调用)
底层实现 AgentExecutor 包装 直接基于 LangGraph
可组合性 差,Agent 之间难协同 好,可作为子图或工具嵌套
流式输出 支持有限 原生支持多种模式
中间件 不支持 支持 Middleware 机制
人机协作 不支持 原生支持 interrupt_before/after

四、create_agent() 完整参数列表

python 复制代码
from langchain.agents import create_agent

agent = create_agent(
    model: str | BaseChatModel,                    # 必需:聊天模型
    tools: List[BaseTool],                         # 必需:工具列表
    *,
    system_prompt: str = "",                       # 系统提示词
    middleware: Sequence[AgentMiddleware[StateT_co, ContextT]] = (),  # 中间件
    interrupt_before: List[str] = None,            # 在某些工具前暂停(人机协作)
    interrupt_after: List[str] = None,             # 在某些工具后暂停
    debug: bool = False,                           # 调试模式
    name: str | None = None,                       # 设置模型名称
    response_format: Union[                        # 结构化输出
        ToolStrategy[StructuredResponseT],
        ProviderStrategy[StructuredResponseT],
        type[StructuredResponseT],
        None,
    ] = None
)
参数 类型 必需 说明
model str 或 BaseChatModel 聊天模型,Agent 的"大脑"
tools ListBaseTool 工具列表,Agent 可调用的工具
system_prompt str 系统提示词,定义 Agent 行为
middleware SequenceAgentMiddleware 中间件,动态修改工具和提示词
interrupt_before Liststr 在指定工具执行前暂停,用于人机协作
interrupt_after Liststr 在指定工具执行后暂停,用于人机协作
debug bool 调试模式,输出详细执行日志
name str Agent 名称,用于标识和归因
response_format Union 结构化输出格式,支持四种策略

更多参数参考:https://reference.langchain.com/python/langchain/agents/factory/create_agent


五、Agent 就是 LangGraph 的 CompiledStateGraph

1、核心本质

创建 Agent 后,检查其类型:

python 复制代码
from langchain.agents import create_agent

agent = create_agent("deepseek-v4-flash")
print(type(agent))

输出:

复制代码
<class 'langgraph.graph.state.CompiledStateGraph'>

Agent 本质上就是 LangGraph 的 CompiledStateGraph 实例。

底层实现是一个图结构。

复制代码
    Agent 底层图结构(ReAct 模式)

         ┌─────────────────────┐
         │     用户输入         │
         └─────────┬───────────┘
                   │
                   ▼
         ┌─────────────────────┐
         │   模型推理 (Agent)   │◄──────────────┐
         └─────────┬───────────┘               │
                   │                           │
                   ▼                           │
         ┌─────────────────────┐               │
         │   是否调用工具?     │               │
         └────┬───────────┬────┘               │
              │           │                    │
          是 │           │ 否                 │
              │           │                    │
              ▼           ▼                    │
    ┌──────────────┐  ┌──────────────┐         │
    │  调用工具     │  │  生成最终答案 │         │
    └──────┬───────┘  └──────────────┘         │
           │                                    │
           ▼                                    │
    ┌──────────────┐                            │
    │  工具返回结果  │─────────────────────────┘
    └──────────────┘

2、可视化 Agent 图结构

python 复制代码
from langchain.agents import create_agent
from IPython.display import Image, display

agent = create_agent(model)
display(Image(agent.get_graph().draw_mermaid_png()))

通过 agent.get_graph().draw_mermaid_png() 可以可视化 Agent 内部的图结构。

这是一个经典的 ReAct 结构:一个具备"思考-行动-观察"不断循环的自主工作者。


六、模型的传入方式

模型是 Agent 的"大脑",负责决策和推理。根据模型传入方式的不同,分为两种方式。

1、传入模型字符串(快捷方式)

python 复制代码
from langchain.agents import create_agent

agent = create_agent("deepseek-v4-flash")

Agent 根据传入的模型字符串,自主创建模型对象。

这种方式最简洁,适合快速原型开发。

2、传入模型对象(推荐方式)

python 复制代码
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent

# 以 init_chat_model 为例
model = init_chat_model(
    model="gpt-5.4-mini",
    model_provider="openai",
    api_key=os.getenv("CLOSEAI_API_KEY"),
    base_url=os.getenv("CLOSEAI_BASE_URL")
)

agent = create_agent(model)

也可以直接使用具体模型类:

python 复制代码
from langchain_deepseek import ChatDeepSeek

model = ChatDeepSeek(model="deepseek-v4-flash")
agent = create_agent(model)

3、两种方式对比

方式 优点 缺点 推荐场景
传入字符串 简洁,一行代码 无法自定义 API Key、URL 等 快速测试、Demo
传入对象 可完全控制模型参数 代码稍多 生产环境 ★★★★★

七、Agent 的基本用法:invoke() 调用

agent.invoke() 是 Agent 最基本的同步调用方法,它会阻塞程序执行直到返回最终结果。

1、输入格式

输入参数为字典类型,字典内通过 messages 字段传递消息列表。

python 复制代码
response = agent.invoke({
    "messages": [{"role": "user", "content": "你好"}]
})

也可以直接传字符串列表(默认自动识别为 HumanMessage):

python 复制代码
agent.invoke({"messages": ["你好"]})  # 默认是 HumanMessage

2、输出格式

通过 invoke 调用 Agent,底层可能会经历多轮交互,返回的是完整的消息列表,被封装在字典中。

python 复制代码
response = agent.invoke({"messages": [...]})

# response 是字典类型
{
    "messages": [
        HumanMessage(...),       # 用户问题
        AIMessage(...),          # AI 工具调用
        ToolMessage(...),        # 工具返回结果
        AIMessage(...)           # 最终回答  ← 通常取这个
    ]
}

# 获取最终回答
final_answer = response['messages'][-1].content

3、完整调用示例

python 复制代码
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model

model = init_chat_model(
    model="gpt-5.4-mini",
    model_provider="openai",
    api_key=os.getenv("CLOSEAI_API_KEY"),
    base_url=os.getenv("CLOSEAI_BASE_URL")
)

agent = create_agent(model=model)

response = agent.invoke({"messages": ["你好"]})
print(type(response))  # <class 'dict'>

# 获取最终答案
print(response['messages'][-1].content)

4、带 System Message 的调用

可以在 message 列表的开头加入 "system" 角色的消息来定义 Agent 的行为:

python 复制代码
resp = agent.invoke({
    "messages": [
        {"role": "system", "content": "你是一个小学数学老师,耐心,幽默,讲解深入浅出"},
        {"role": "user", "content": "100加上50等于多少?"}
    ]
})

八、绑定工具

只有接入了一些工具,create_agent 完成 Agent 创建才算完整。

Agent 支持静态和动态绑定工具,后者需要用到中间件。

1、工具来源

工具可以是 LangChain 内置的,也可以是自定义的。

LangChain 生态中已经内置集成了非常多的实用工具。

LangChain 内置工具列表:https://docs.langchain.com/oss/python/integrations/tools

典型内置工具:

工具 功能
TavilySearch 网络搜索
WikipediaQueryRun 维基百科查询
PythonREPL Python 代码执行
Calculator 数学计算
ArxivQueryRun 学术论文搜索

2、绑定一个工具

python 复制代码
from langchain.agents import create_agent
from langchain.tools import tool

@tool(parse_docstring=True)
def get_weather(city: str) -> str:
    """
    天气查询工具
    Args:
        city: 城市名称
    """
    return f"{city}的天气为晴朗,25°C。"

agent = create_agent(
    model=model,
    tools=[get_weather]
)

resp = agent.invoke({
    "messages": [
        {"role": "system", "content": "你是一个天气查询助手,只回答天气相关的问题。"},
        {"role": "user", "content": "北京的天气怎么样?"}
    ]
})

3、绑定内置工具(TavilySearch)

python 复制代码
from langchain_tavily import TavilySearch

web_search = TavilySearch(
    tavily_api_key=os.getenv("TAVILY_API_KEY"),
    max_results=2
)

agent = create_agent(
    model=model,
    tools=[web_search],
    system_prompt="你是一名多才多艺的智能助手,可以调用工具帮助用户解决问题。"
)

result = agent.invoke({
    "messages": [{"role": "user", "content": "请帮我查询2024年诺贝尔物理学奖得主是谁?"}]
})

print(result['messages'][-1].content)

4、绑定多个工具

python 复制代码
agent = create_agent(
    model,
    tools=[get_weather, get_news]
)

response = agent.invoke({
    "messages": ["你好,杭州今天的天气如何?今天有哪些新闻?"]
})

5、工具数量建议

注意:只给 Agent 需要的工具,工具太多会混淆。

一般 2-5 个工具最佳。

python 复制代码
# ✅ 好:只给需要的工具
agent = create_agent(
    model=model,
    tools=[get_weather, calculator]  # 2-5 个工具最佳
)

# ❌ 不好:工具太多
agent = create_agent(
    model=model,
    tools=[tool1, tool2, ..., tool20]  # 会混淆
)

九、工具调用流程分析

1、完整流程

LangChain 的 Agent 会将模型与工具结合起来,在实现上由一个基于 LangGraph 的图结构来编排执行流程。

当用户提出一个复杂需求时,Agent 会像人类一样:

先理解任务 -> 规划步骤 -> 使用合适的工具获取信息 -> 反复调用直到不再需要工具 -> 综合所有信息给出最终答案。

复制代码
用户问题
    │
    ▼
AI 思考
    │
    ▼
调用工具
    │
    ▼
观察结果
    │
    ▼
继续思考 ──→ 需要更多工具?──→ 是 ──→ 调用工具 ──→ 观察结果
    │                                            │
    │ 否                                         │
    ▼                                            │
最终答案 ←─────────────────────────────────────┘

2、完整 Function Calling 执行流程

一次完整的 Function Calling 执行流程包含 4 条消息:

复制代码
① HumanMessage        ← 用户首次发起消息
② AIMessage           ← 涉及 function call message
③ ToolMessage         ← 涉及 function response message
④ AIMessage           ← 涉及 final response

具体示例:用户问题"找出当前最流行的无线耳机并检查库存"

复制代码
步骤 1:输入解析与初始推理
    LLM 分析任务:"要找出'最流行'的产品,需要最新的市场信息,
    我应该先使用搜索工具。"

步骤 2:第一次行动 (action) 与观察 (observation)
    行动:Agent 调用 search_products 工具,参数为 "wireless headphones"
    观察:工具返回结果:"找到 5 款匹配产品。Top 结果:WH-1000XM5, ..."

步骤 3:迭代推理
    LLM 根据搜索结果分析:"WH-1000XM5 是排名第一的型号。
    现在需要确认其库存状态才能回答用户问题。"

步骤 4:第二次行动 (action) 与观察 (observation)
    行动:Agent 调用 check_inventory 工具,参数为 "WH-1000XM5"
    观察:工具返回:"产品 WH-1000XM5:库存 10 件。"

步骤 5:最终输出
    LLM 综合所有信息:"已获得所需信息,可以生成最终答案。"
    模型生成最终答案,不再调用工具。

十、重试机制

Agent 可以在工具调用结果不满足要求时,自主重试。

python 复制代码
from langchain.agents import create_agent
from langchain.tools import tool
from langchain.messages import SystemMessage, HumanMessage

flag = 0

@tool
def get_weather(city: str):
    """
    天气查询工具
    Args:
        city: 城市名称
    """
    global flag
    flag += 1
    if flag < 3:
        return "TEMP_UNAVAILABLE: 天气服务暂时不可用,请稍后重试"
    return f"{city}今天天气挺好"

messages = [
    SystemMessage("""
    你是一个天气助手。
    当工具返回以 'TEMP_UNAVAILABLE:' 开头的结果时,
    说明是临时故障,不要立即放弃;
    你应再次调用同一个工具,最多重试 3 次。
    如果 3 次后仍失败,再向用户说明服务暂时不可用。
    """),
    HumanMessage("你好,杭州今天的天气如何?")
]

agent = create_agent(model, tools=[get_weather])
response = agent.invoke({"messages": messages})

模型会三次调用 get_weather,最终获得满意的结果。


十一、常见问题

问题 1:Agent 如何选择工具?

依据:工具的 docstring

AI 会根据:

  1. 问题内容
  2. 每个工具的描述
  3. 自动选择最匹配的工具
python 复制代码
@tool
def get_weather(city: str) -> str:
    """获取指定城市的天气信息"""  # ← AI Agent 读这个!
    ...

@tool
def calculator(operation: str, a: float, b: float) -> str:
    """执行基本的数学计算"""  # ← AI Agent 也读这个!
    ...

问题 2:Agent 为什么没有调用工具?

原因:

  • 工具的 docstring 不清晰
  • 问题表述不明确
  • 模型认为不需要工具

解决:

  • 写清楚 docstring
python 复制代码
# ❌ 不好
@tool
def tool1(x: str) -> str:
    """做一些事情"""  # 太模糊

# ✅ 好
@tool
def get_weather(city: str) -> str:
    """
    获取指定城市的实时天气信息
    Args:
        city: 城市名称,如 "北京"、"上海"
    """

问题 3:Agent 选错工具?

原因:

  • 多个工具的功能描述相似
  • 工具太多导致混淆

解决:

  • 只给必要的工具
  • 工具描述要有明确区分
  • 在 system_prompt 中说明工具使用场景

问题 4:如何知道 Agent 何时完成?

当 AIMessage 不包含 tool_calls 时:

python 复制代码
for msg in response['messages']:
    if isinstance(msg, AIMessage):
        if hasattr(msg, 'tool_calls') and msg.tool_calls:
            print("还在调用工具...")
        else:
            print("完成!最终答案:", msg.content)

问题 5:Agent 可以调用多少次工具?

默认没有限制,直到得到最终答案。

但可能会:

  • 超时
  • 达到 token 限制
  • 模型决定停止

问题 6:如何限制工具调用次数?

LangChain 1.0 的 create_agent 默认使用 LangGraph,可以通过配置限制:

python 复制代码
config = {
    "recursion_limit": 5  # 最多 5 步
}
response = agent.invoke(input, config=config)

十二、设置 Agent 名称

创建 Agent 时,LangChain 允许用户指定其名称。

1、基本用法

python 复制代码
agent = create_agent(
    model=model,
    name="chat_assistant"
)

response = agent.invoke({"messages": ["你好"]})

输出的 AI Message 带有 Name 信息:

复制代码
================================== Ai Message ==================================
Name: chat_assistant
你好!有什么我可以帮你的吗?

2、经典使用场景

使用场景 说明
流式输出归因 在启用流式输出时,name 可用于标识当前输出内容来自哪个 Agent
消息身份标记 Agent 产生的 AIMessage 会携带对应的 name 信息
调试与 trace 可读性 name 可以作为 Agent 的稳定标识,帮助快速判断执行的 Agent
组件化封装 有助于在模块注册、运行监控、日志归档和能力复用时保持身份标识
前端展示 name 可直接作为运行时展示标识使用
运行时身份标识 作为 Agent 在系统中的"运行时身份 ID"

十三、系统提示词

使用 create_agent 创建 Agent 时,需传入模型和工具、可选地传入系统提示词。

提示词为 Agent 提供了任务背景、行为准则和操作指南。

1、设置方式

系统指令,即 SystemMessage,通过 system_prompt 设置,定义 Agent 行为。

这个参数可以是 str 或者 SystemMessage 类型。

方式一:传入字符串

python 复制代码
agent = create_agent(
    model=model,
    tools=[get_weather],
    system_prompt="你是天气助手。可以调用 get_weather 获取天气信息。"
)

方式二:传入 SystemMessage 对象

python 复制代码
from langchain_core.messages import SystemMessage

agent = create_agent(
    model=model,
    tools=[add_numbers],
    system_prompt=SystemMessage(content="你是一个数学助手,解决日常的算术问题")
)

2、使用建议

  • 明确说明 Agent 的角色
  • 定义输出格式
  • 说明何时使用工具
python 复制代码
agent = create_agent(
    model=model,
    tools=[get_weather],
    system_prompt="""
你是天气助手。
工作流程:
1. 理解用户的城市查询
2. 使用 get_weather 工具获取数据
3. 简洁清晰地回答

输出格式:
- 天气状况
- 温度
- 注意事项(如有)
"""
)

十四、结构化输出

结构化输出是 Agent 的核心功能之一,它允许 Agent 以特定、可预测的格式返回数据。

1、模型 vs Agent 的结构化输出对比

维度 模型的结构化输出 Agent 结构化输出
操作对象 作用于大模型对象 作用于 Agent
解析时机 每次模型调用生成 AIMessage 时进行解析 仅在 Agent 决定"任务结束"并输出最终答案时解析
数据流转 模型 -> 结构化对象 模型 -> 工具 -> 反思 -> ... -> 结构化对象
绑定方式 使用 with_structured_output 使用 response_format 参数
适用场景 单次、确定性的任务(如提取字段、翻译、分类) 多步、复杂推理的任务(如查文档后汇总报表)

2、结构化输出的 4 种策略

create_agent 函数中的 response_format 参数支持四种不同的策略:

python 复制代码
def create_agent(
    ...
    response_format: Union[
        ToolStrategy[StructuredResponseT],
        ProviderStrategy[StructuredResponseT],
        type[StructuredResponseT],
        None,
    ]
)

(1)ProviderStrategy

使用模型提供商的原生结构化输出功能实现结构化输出。

适用于支持原生结构化输出的模型,比如 OpenAI、Anthropic Claude 或 xAI Grok 等。

python 复制代码
from pydantic import BaseModel, Field
from langchain.agents.structured_output import ProviderStrategy

class ContactInfo(BaseModel):
    """用户的联系方式"""
    name: str = Field(description="用户姓名")
    email: str = Field(description="用户邮箱地址")
    phone: str = Field(description="用户的手机号")

agent = create_agent(
    model=model,
    response_format=ProviderStrategy(ContactInfo)
)

(2)ToolStrategy(★★★★★ 推荐)

对于不支持原生结构化输出的模型,LangChain 采用工具调用的方式实现结构化输出。

此策略兼容绝大多数支持工具调用的现代模型。

核心原理:动态创建一个"虚拟工具",该工具的输入参数对应着期望的数据结构。

当模型需要生成最终答案时,系统会引导模型"调用"这个虚拟工具,从而间接产生符合要求的结构化数据。

python 复制代码
from langchain.agents.structured_output import ToolStrategy

agent = create_agent(
    model=model,
    response_format=ToolStrategy(ContactInfo)
)

ToolStrategy 的配置包含三个主要参数:

参数 说明
schema (必需) 支持 Pydantic 模型、TypedDict、JSON Schema、@dataclass、Union
tool_message_content (可选) 自定义生成结构化输出时的提示信息
handle_errors (可选) 数据校验失败时的重试策略,默认值为 True

(3)type / AutoStrategy

直接传入一个定义类型时,LangChain 会自动包装为 AutoStrategy,触发自动选择策略:

  • 如果模型支持原生结构化输出(如 OpenAI、Anthropic Claude 或 xAI Grok),则优先使用 ProviderStrategy
  • 否则使用 ToolStrategy
python 复制代码
agent = create_agent(
    model=model,
    response_format=ContactInfo  # 自动选择 ProviderStrategy 或 ToolStrategy
)

(4)None

默认配置,表示不以结构化输出,以自然语言响应用户问题。

3、四种输出模式(Schema 类型)

ToolStrategy 支持四种 Schema 定义方式:

输出模式 1:Pydantic 类型(★★★★★ 推荐)

Pydantic 类型的 Schema 支持数据验证,是优先推荐使用的方式。

python 复制代码
from pydantic import BaseModel, Field
from langchain.agents.structured_output import ToolStrategy

class ContactInfo(BaseModel):
    """用户的联系方式"""
    name: str = Field(description="用户姓名")
    email: str = Field(description="用户邮箱地址")
    phone: str = Field(description="用户的手机号")

agent = create_agent(
    model=model,
    response_format=ToolStrategy(ContactInfo)
)

输出模式 2:TypedDict 类型

python 复制代码
from typing import TypedDict, Annotated

class ContactInfo(TypedDict):
    """用户的联系方式"""
    name: Annotated[str, ..., "用户姓名"]
    email: Annotated[str, ..., "用户邮箱地址"]
    phone: Annotated[str, ..., "用户的手机号"]

agent = create_agent(
    model=model,
    response_format=ToolStrategy(ContactInfo)
)

TypedDict 字段定义采用 Annotated[类型, 默认值, "描述"] 格式,不支持运行时验证。

输出模式 3:JsonSchema 类型

python 复制代码
json_schema = {
    "title": "ContactInfo",
    "description": "用户的联系方式",
    "type": "object",
    "properties": {
        "name": {"description": "用户姓名", "type": "string"},
        "email": {"description": "用户邮箱地址", "type": "string"},
        "phone": {"description": "用户的手机号", "type": "string"}
    },
    "required": ["name", "email", "phone"]
}

agent = create_agent(
    model=model,
    response_format=ToolStrategy(json_schema)
)

输出模式 4:@dataclass 类型

python 复制代码
from dataclasses import dataclass

@dataclass
class ContactInfo:
    """用户的联系方式"""
    name: str = Field(description="用户姓名")
    email: str = Field(description="用户邮箱地址")
    phone: str = Field(description="用户的手机号")

agent = create_agent(
    model=model,
    response_format=ToolStrategy(ContactInfo)
)

4、多 Schema 联合模式

ToolStrategy 允许指定多个类型 Union[类型1, 类型2],LLM 能够根据输入文本的内容智能选择最合适的一个数据模型。

python 复制代码
from typing import Union

class ContactInfo(BaseModel):
    """用户的联系方式"""
    name: str = Field(description="用户姓名")
    email: str = Field(description="用户邮箱地址")
    phone: str = Field(description="用户的手机号")

class EventInfo(BaseModel):
    """事件详情"""
    event_name: str = Field(description="事件名称")
    date: str = Field(description="事件发生日期")

agent = create_agent(
    model=model,
    response_format=ToolStrategy(
        Union[ContactInfo, EventInfo]
    )
)

5、获取结构化输出结果

python 复制代码
result = agent.invoke({"messages": [...]})

if "structured_response" in result:
    analysis = result["structured_response"]
    print(analysis)

6、自定义工具消息:tool_message_content

当不设置 tool_message_content 时,模型收到的 ToolMessage 里包含具体数据。

当设置了 tool_message_content 时,模型收到的 ToolMessage 只是一个预定义的确认信息,节省上下文窗口的 token 消耗。

python 复制代码
agent = create_agent(
    model=model,
    response_format=ToolStrategy(
        ContactInfo,
        tool_message_content="已成功抽取信息"
    )
)

7、错误处理:handle_errors

handle_errors 值 说明
True (默认) 捕获所有异常,使用内置错误消息模板提示模型重试
False 关闭自动重试机制,任何异常都会直接抛出
"自定义字符串" 捕获所有异常,使用预设固定字符串作为错误消息
ExceptionType 仅捕获指定类型的异常并进行重试,其他异常直接抛出
callable 使用自定义函数处理异常,可根据不同异常类型返回差异化的提示信息
python 复制代码
def custom_error_handler(error: Exception) -> str:
    """自定义错误处理器"""
    error_str = str(error)
    if isinstance(error, StructuredOutputValidationError):
        return "数据格式有误,请检查字段是否符合要求。"
    elif isinstance(error, MultipleStructuredOutputsError):
        return "检测到多个响应,请选择最相关的一个进行返回。"
    else:
        return f"Error: {error_str}"

agent = create_agent(
    model=model,
    response_format=ToolStrategy(
        Union[ContactInfo, EventDetails],
        tool_message_content="提取完成!",
        handle_errors=custom_error_handler
    )
)

两类常见异常:

异常类型 说明
MultipleStructuredOutputsError 多结构化输出错误,工具调用请求数量大于 1 时抛出
StructuredOutputValidationError 输出结构化验证错误,格式不符合要求时抛出

十五、流式输出及模式

1、为什么需要流式输出?

通过 invoke 调用 Agent 时,内部可能经历多次调用,长时间看不到调用情况,用户体验不好。

流式输出好处:

  • 大型语言模型生成完整响应通常需要几秒钟,流式传输让等待过程更加可控
  • 可以立即显示文字逐渐出现的效果,大幅降低用户的等待焦虑

2、设置方式

通过 agent.stream(stream_mode=指定模式) 来指定。

python 复制代码
for chunk in agent.stream(
    {"messages": [{"role": "user", "content": "..."}]},
    stream_mode="values"
):
    # 处理 chunk

3、七种输出模式详解

(1)values 模式

每个步骤执行后,都会输出完整的状态信息。

适用于每一步都要获取完整状态、状态持久化场景。

python 复制代码
for chunk in agent.stream(
    {"messages": [...]},
    stream_mode="values"
):
    rprint(chunk)

(2)updates 模式(默认)

每个步骤执行后,只增量更新状态中发生变化的内容。

用于监控 Agent 执行进度,例如观察 Agent 决定调用工具、工具执行结果等步骤。

python 复制代码
for chunk in agent.stream(
    {"messages": [...]},
    stream_mode="updates"
):
    rprint(chunk)

(3)messages 模式(★★★★★ 推荐用于聊天)

输出流式返回的 Token 以及相关的元数据(如:来自哪个节点 model/tool)。

实现类似 ChatGPT 的打字机效果,为聊天机器人等交互式应用提供最佳的实时体验。

python 复制代码
for chunk in agent.stream(
    {"messages": [...]},
    stream_mode="messages"
):
    print(chunk[0].content, end="", flush=True)

(4)tasks 模式

输出当前 task 任务开始和结束的时间,包含任务的结果和错误信息。

用于监控任务的生命周期。

python 复制代码
for chunk in agent.stream(
    {"messages": [...]},
    stream_mode="tasks"
):
    print(chunk)

(5)debug 模式

与 tasks 模式类似,比 task 模式多输出任务步骤、时间戳、task 类型(task/task_result)。

用于调试、监控 task 任务的生命周期。

python 复制代码
for chunk in agent.stream(
    {"messages": [...]},
    stream_mode="debug"
):
    print(chunk)

(6)checkpoints 模式

每当检查点(checkpoint)被创建时会触发输出,输出包含检查点中的状态。

用于需要状态持久化、工作流恢复或分布式执行跟踪的高级场景。

python 复制代码
from langgraph.checkpoint.memory import InMemorySaver

checkpointer = InMemorySaver()

agent = create_agent(
    model=model,
    tools=[...],
    checkpointer=checkpointer  # 启用检查点
)

config = {"configurable": {"thread_id": "session01"}}

for chunk in agent.stream(
    {"messages": [...]},
    config=config,
    stream_mode="checkpoints"
):
    print(chunk)

(7)custom 模式

开发者通过 get_stream_writer 在工具或节点内部自定义发送的数据。

用于输出业务逻辑相关的进度信息(如"已处理 10/100 条记录")、自定义日志或指标。

python 复制代码
from langgraph.config import get_stream_writer

@tool
def generate_sales_report() -> str:
    """生成销售报告"""
    writer = get_stream_writer()
    writer({"type": "生成销售报告", "message": "开始生成销售报告"})
    # 模拟数据处理
    for i in range(1, 4):
        time.sleep(0.5)
        writer({"type": "生成销售报告", "message": f"生成销售报告进度百分比:{i * 25}%"})
    writer({"type": "生成销售报告", "message": "报告生成完成"})
    return f"销售报告:总收入 150 万元,同比增长 12%"

4、流式输出模式总结

模式 输出内容 使用场景
values 每个步骤执行后,都会输出完整的状态信息 获取完整状态、状态持久化
updates 每个步骤执行后,只增量更新状态中发生变化的内容 监控 Agent 执行进度(默认模式)
messages 输出流式返回的 Token 以及相关的元数据 实现打字机效果,聊天机器人 ★★★★★
tasks 输出当前 task 任务开始和结束的时间,包含结果和错误信息 监控任务的生命周期
debug 比 tasks 多输出任务步骤、时间戳、task 类型 调试、监控 task 任务
checkpoints 检查点被创建时触发输出,输出包含检查点中的状态 状态持久化、工作流恢复
custom 通过 get_stream_writer 在工具或节点内部自定义发送的数据 输出业务逻辑相关的进度信息、自定义日志

选择建议:

  • 实现实时对话交互 ,优先选择 messages 模式
  • 观察 Agent 的思考与执行步骤 ,优先选择 updates 模式
  • 需要查看每一步状态 优先选择 values/tasks/debug 模式
  • 在工具执行时输出自定义业务日志 优先选择 custom 模式

5、多模式组合

可以同时指定多个模式:

python 复制代码
for stream_mode, chunk in agent.stream(
    {"messages": [...]},
    stream_mode=["tasks", "updates"]
):
    print(f"当前流模式: {stream_mode}, 当前数据: {chunk}")

十六、人机协作(Human-in-the-Loop)

通过 interrupt_beforeinterrupt_after 参数实现。

python 复制代码
agent = create_agent(
    model=model,
    tools=[...],
    interrupt_before=["get_weather"],     # 在调用 get_weather 前暂停
    interrupt_after=["send_email"],       # 在 send_email 执行后暂停
)

这在需要人工审批敏感操作(如发送邮件、执行数据库写入)时非常有用。


十七、Agent 状态管理

Agent 支持通过 checkpointer 进行状态管理。

python 复制代码
from langgraph.checkpoint.memory import InMemorySaver

# 创建内存检查点存储
checkpointer = InMemorySaver()

# 创建 Agent
agent = create_agent(
    model=model,
    tools=[...],
    checkpointer=checkpointer  # 启用检查点
)

# 创建唯一的会话 ID
config = {"configurable": {"thread_id": "session01"}}

# 调用 Agent
result = agent.invoke(
    {"messages": [...]},
    config=config
)

通过 thread_id,可以在后续调用中恢复之前的对话状态。


十八、多 Agent 协作概念

虽然本章没有深入展开多 Agent 编排,但 Agent 的 name 参数为多 Agent 协作奠定了基础。

在 Multi-Agent 场景中:

  • name 用于区分不同的 Agent
  • 每个 Agent 可以作为独立的节点
  • Agent 之间可以通过消息传递进行协作
  • Agent 可以包装为工具供其他 Agent 调用

十九、Agent vs Chain vs 简单 LLM 调用对比

维度 简单 LLM 调用 Chain Agent
决策能力 固定流程 自主决策
工具使用 不支持 预定义工具 动态选择工具
任务分解 不支持 硬编码分解 自主规划分解
执行流程 一次调用,一个回答 线性流程 循环迭代,直到完成
适用场景 翻译、总结、分类 固定的多步骤流水线 复杂的、开放式的任务
灵活性
可控性 需要精心设计系统提示词
成本 可能较高(多次模型调用)

二十、最佳实践和注意事项

1、工具设计

  • 每个工具的 docstring 必须清晰描述功能和参数
  • 工具数量控制在 2-5 个最佳
  • 工具功能要互相有明确区分

2、系统提示词设计

  • 明确 Agent 的角色和职责
  • 说明什么情况下使用什么工具
  • 定义输出格式和风格
  • 设定边界(什么能做,什么不能做)

3、模型选择

  • 确保模型支持工具调用(Function Calling)
  • 简单任务用小模型,复杂任务用大模型
  • 优先选择支持原生结构化输出的模型

4、成本控制

  • 设置 recursion_limit 限制工具调用次数
  • 注意每次工具调用都会消耗 token
  • 合理使用 tool_message_content 减少 token 消耗

5、生产环境建议

  • 使用 checkpointer 实现状态持久化
  • 使用 interrupt_before/interrupt_after 实现敏感操作审批
  • 为 Agent 设置明确的 name 用于日志和监控
  • 使用 stream_mode="messages" 提供良好的用户体验

二十一、实战:多功能智能助手

项目需求:开发一个多功能智能助手,支持:

  1. 天气查询:查询城市天气
  2. 数学计算:复杂数学运算
  3. 时间查询:获取当前时间、日期计算
  4. 货币转换:多种货币之间转换
  5. 信息搜索:搜索产品、新闻等信息

完整代码

python 复制代码
import os
import math
from datetime import datetime, timedelta
from dotenv import load_dotenv
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
from langchain_core.tools import tool

load_dotenv(override=True)

# ==================== 模型的初始化 ====================

model = init_chat_model(
    model="gpt-5.4-mini",
    model_provider="openai",
    api_key=os.getenv("CLOSEAI_API_KEY"),
    base_url=os.getenv("CLOSEAI_BASE_URL")
)

# ==================== 工具定义 ====================

@tool
def get_weather(city: str) -> str:
    """获取指定城市的实时天气信息
    支持中国主要城市的天气查询
    Args:
        city: 城市名称,如 "北京"、"上海"、"深圳" 等
    Returns:
        包含温度、天气状况、空气质量的详细信息
    """
    weather_db = {
        "北京": "多云,15-22℃,空气质量良,湿度 45%",
        "上海": "晴天,18-25℃,空气质量优,湿度 60%",
        "深圳": "小雨,22-28℃,空气质量优,湿度 75%",
        "成都": "阴天,16-23℃,空气质量良,湿度 70%",
        "杭州": "晴天,17-24℃,空气质量优,湿度 55%",
        "广州": "多云,21-29℃,空气质量良,湿度 72%"
    }
    result = weather_db.get(city)
    if result:
        return f"{city}:{result}"
    else:
        return f"抱歉,暂不支持查询 {city} 的天气信息。当前支持:北京、上海、深圳、成都、杭州、广州"

@tool
def calculator(expression: str) -> str:
    """执行数学计算
    支持基本运算符(+、-、*、/、**)和常用数学函数
    Args:
        expression: 数学表达式
    Returns:
        计算结果或错误信息
    """
    try:
        safe_functions = {
            "sqrt": math.sqrt, "pow": pow, "abs": abs, "round": round,
            "sin": math.sin, "cos": math.cos, "tan": math.tan,
            "log": math.log, "pi": math.pi, "e": math.e
        }
        result = eval(expression, {"__builtins__": {}}, safe_functions)
        return f"{expression} = {result}"
    except Exception as e:
        return f"计算出错:{str(e)}"

@tool
def get_time_info(query_type: str = "current") -> str:
    """获取时间相关信息
    Args:
        query_type: 查询类型 ("current"/"date"/"tomorrow"/"yesterday"/"weekday")
    Returns:
        时间信息字符串
    """
    now = datetime.now()
    if query_type == "current":
        return now.strftime("当前时间:%Y年%m月%d日 %H:%M:%S")
    elif query_type == "date":
        return now.strftime("今天是:%Y年%m月%d日")
    elif query_type == "tomorrow":
        tomorrow = now + timedelta(days=1)
        return tomorrow.strftime("明天是:%Y年%m月%d日")
    elif query_type == "yesterday":
        yesterday = now - timedelta(days=1)
        return yesterday.strftime("昨天是:%Y年%m月%d日")
    elif query_type == "weekday":
        weekdays = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
        return f"今天是{weekdays[now.weekday()]}"
    else:
        return f"不支持的查询类型:{query_type}。支持:current, date, tomorrow, yesterday, weekday"

@tool
def convert_currency(amount: float, from_curr: str, to_curr: str) -> str:
    """货币转换工具,支持主要货币之间的实时汇率转换
    Args:
        amount: 金额数值
        from_curr: 源货币代码(CNY/USD/EUR/GBP/JPY/HKD)
        to_curr: 目标货币代码(CNY/USD/EUR/GBP/JPY/HKD)
    Returns:
        转换结果
    """
    exchange_rates = {
        "CNY": 1.0, "USD": 0.14, "EUR": 0.13,
        "GBP": 0.11, "JPY": 20.8, "HKD": 1.09
    }
    currency_names = {
        "CNY": "人民币", "USD": "美元", "EUR": "欧元",
        "GBP": "英镑", "JPY": "日元", "HKD": "港币"
    }
    from_curr = from_curr.upper()
    to_curr = to_curr.upper()
    if from_curr not in exchange_rates:
        return f"不支持的源货币:{from_curr}。支持的货币:CNY, USD, EUR, GBP, JPY, HKD"
    if to_curr not in exchange_rates:
        return f"不支持的目标货币:{to_curr}。支持的货币:CNY, USD, EUR, GBP, JPY, HKD"
    cny_amount = amount / exchange_rates[from_curr]
    result_amount = cny_amount * exchange_rates[to_curr]
    return f"{amount} {currency_names[from_curr]}({from_curr})= {result_amount:.2f} {currency_names[to_curr]}({to_curr})"

@tool
def search_info(keyword: str, category: str = "all") -> str:
    """搜索各类信息
    Args:
        keyword: 搜索关键词
        category: 搜索分类 ("product"/"news"/"all")
    Returns:
        搜索结果
    """
    products = {
        "手机": "iPhone 15 (¥5999), 小米 14 (¥3999), 华为 Mate60 (¥6999)",
        "笔记本": "MacBook Pro (¥12999), ThinkPad X1 (¥9999), 华为 MateBook (¥7999)",
        "耳机": "AirPods Pro (¥1999), Sony WH-1000XM5 (¥2499)"
    }
    news = {
        "AI": "1. GPT-5 即将发布  2. AI 芯片市场增长 30%  3. 新 AI 法规出台",
        "科技": "1. 量子计算新突破  2. 6G 技术测试  3. 新能源汽车销量创新高"
    }
    results = []
    if category in ["product", "all"]:
        for key, value in products.items():
            if keyword in key:
                results.append(f"【产品】{key}:{value}")
    if category in ["news", "all"]:
        for key, value in news.items():
            if keyword in key or keyword in value:
                results.append(f"【新闻】{key}相关:{value}")
    if results:
        return "\n".join(results)
    else:
        return f"未找到关于 '{keyword}' 的 {category} 信息"

# ==================== Agent 创建 ====================

class SmartAssistant:
    """多功能智能助手"""

    def __init__(self):
        self.model = model
        self.tools = [
            get_weather,
            calculator,
            get_time_info,
            convert_currency,
            search_info
        ]
        system_prompt = """你是一个多功能智能助手,可以帮助用户:
         🌤 查询天气:使用 get_weather 工具
         🔢 数学计算:使用 calculator 工具
         ⏰ 时间查询:使用 get_time_info 工具
         💱 货币转换:使用 convert_currency 工具
         🔍 信息搜索:使用 search_info 工具
         重要提示:
         1. 仔细阅读用户问题,确定需要使用哪个工具
         2. 如果需要多个工具,按顺序调用
         3. 总是用友好、专业的语气回答
         4. 如果工具返回了数据,要用通俗易懂的语言解释给用户
         5. 如果无法完成任务,诚实地告诉用户原因
         请始终使用中文回答。"""

        self.agent = create_agent(
            model=self.model,
            tools=self.tools,
            system_prompt=system_prompt
        )
        self.messages = []

    def chat(self, user_input: str) -> str:
        """对话接口"""
        self.messages.append({"role": "user", "content": user_input})
        result = self.agent.invoke({"messages": self.messages})
        self.messages = result["messages"]
        for msg in reversed(self.messages):
            if msg.type == "ai" and msg.content:
                return msg.content
        return "抱歉,我无法处理这个请求。"

    def reset(self):
        """重置对话历史"""
        self.messages = []

# ==================== 主程序 ====================

def main():
    assistant = SmartAssistant()

    print("=" * 40)
    print(" 🤖 多功能智能助手(LangChain 1.2)")
    print("=" * 40)
    print("\n我可以帮你:")
    print("  🌤 查询天气")
    print("  🔢 数学计算")
    print("  ⏰ 时间查询")
    print("  💱 货币转换")
    print("  🔍 信息搜索")
    print("\n输入 'quit' 退出,输入 'reset' 重置对话\n")

    # 演示示例
    demos = [
        "北京今天天气怎么样?",
        "帮我算一下 (25 + 17) * 3",
        "现在几点了?",
        "100 美元等于多少人民币?"
    ]
    for demo in demos:
        print(f" 👤 {demo}")
        response = assistant.chat(demo)
        print(f" 🤖 {response}\n")

    assistant.reset()

    # 交互模式
    print("=" * 40)
    print(" 💬 进入交互模式")
    print("=" * 40)

    while True:
        user_input = input("\n 👤 你: ")
        if user_input.lower() == 'quit':
            print("再见!👋")
            break
        if user_input.lower() == 'reset':
            assistant.reset()
            print(" ✅ 对话已重置")
            continue
        if not user_input.strip():
            continue
        response = assistant.chat(user_input)
        print(f" 🤖 助手: {response}")

if __name__ == "__main__":
    main()

二十二、本章总结

主题 核心要点
Agent 定义 LLM + Planning + Tools + Memory + Action,五大组件协作
v0.x vs v1.x v0.x 碎片化(create_react_agent 等),v1.x 统一为 create_agent()
create_agent() 一站式创建,底层基于 LangGraph 的 CompiledStateGraph
Agent 本质 本质是 LangGraph 图结构,经典 ReAct 模式:"思考-行动-观察" 循环
模型传入 字符串(快捷)和模型对象(推荐),两种方式各有适用场景
invoke() 调用 输入为 {"messages": ...} 字典,输出包含完整消息列表
工具绑定 支持自定义工具和内置工具,建议 2-5 个工具最佳
工具调用流程 Function Calling 流程:HumanMessage -> AIMessage -> ToolMessage -> AIMessage
重试机制 Agent 可在工具调用失败时自主重试,通过 system_prompt 控制
Agent 名称 用于流式归因、消息身份标记、调试追踪、组件化封装等场景
系统提示词 定义 Agent 角色、输出格式、工具使用时机,支持 str 和 SystemMessage
结构化输出 支持 4 种策略(ProviderStrategy/ToolStrategy/AutoStrategy/None)+ 4 种 Schema 类型
ToolStrategy 通过虚拟工具实现结构化输出,推荐方式,兼容所有支持工具调用的模型
流式输出 支持 7 种模式(values/updates/messages/tasks/debug/checkpoints/custom)
人机协作 interrupt_before/interrupt_after 实现敏感操作审批
状态管理 checkpointer 实现状态持久化和会话恢复
最佳实践 清晰 docstring、合理工具数量、精心设计 system_prompt、限制递归次数

二十三、面试常见问题

Q1:Agent 的核心组件有哪些?

Agent 包含五个核心组件:

  • LLM(大脑):负责推理和决策
  • Planning(规划):将任务分解为子步骤
  • Tools(工具):扩展 Agent 的能力边界
  • Memory(记忆):保存上下文和历史信息
  • Action(行动):执行操作

其中 Action 是必须的,Planning 和 Memory 是可选的。

Q2:LangChain v0.x 和 v1.x 的 Agent 有什么区别?

v0.x 时代有多个创建函数(create_react_agent、create_tool_calling_agent 等),需要 5 步创建(模型 + 提示词 + Agent + Executor + 调用),心智负担高、可组合性差、生态碎片化。

v1.x 统一为 create_agent() 一个函数,3 步完成(模型 + Agent + 调用),底层直接基于 LangGraph,支持中间件、流式输出、人机协作等高级功能。

Q3:Agent 的底层实现是什么?

Agent 本质上是 LangGraph 的 CompiledStateGraph 实例,底层是一个图结构,采用经典的 ReAct 模式:一个"思考-行动-观察"不断循环的自主工作者。

Q4:Agent 如何选择工具?

Agent 根据工具的 docstring(描述文档)来选择工具。AI 会阅读每个工具的 docstring,结合用户的问题内容,自动选择最匹配的工具。

Q5:如何控制 Agent 的工具调用次数?

可以通过 LangGraph 的配置来限制:

python 复制代码
config = {"recursion_limit": 5}
response = agent.invoke(input, config=config)

Q6:Agent 什么时候停止调用工具?

当 AIMessage 不包含 tool_calls 时,说明 Agent 认为任务已完成,开始生成最终答案。

Q7:结构化输出有哪些策略?推荐哪种?

有四种策略:

  1. ProviderStrategy:使用模型原生结构化输出
  2. ToolStrategy:通过虚拟工具实现(★★★★★ 推荐)
  3. AutoStrategy:自动选择 ProviderStrategy 或 ToolStrategy
  4. None:不启用结构化输出

推荐使用 ToolStrategy,因为它兼容所有支持工具调用的现代模型。

Q8:Agent 的流式输出有哪些模式?如何选择?

有七种模式:

  • values:获取完整状态
  • updates:监控执行进度(默认)
  • messages:实现打字机效果(推荐用于聊天)
  • tasks:监控任务生命周期
  • debug:调试模式
  • checkpoints:状态持久化
  • custom:自定义业务日志

聊天机器人推荐 messages 模式,调试推荐 updatesdebug 模式。

Q9:Agent 和 Chain 有什么区别?

Chain 是固定流程的线性执行,Agent 是自主决策的循环执行。

Agent 可以动态选择工具、自主分解任务、在循环中迭代直到完成,而 Chain 的流程是硬编码的。

Q10:如何优化 Agent 的性能?

  • 控制工具数量在 2-5 个
  • 写清晰的工具 docstring
  • 精心设计 system_prompt
  • 设置 recursion_limit 限制递归次数
  • 使用合适的模型(大模型用于复杂任务,小模型用于简单任务)
  • 使用 checkpointer 避免重复计算

本章是 LangChain 最核心的章节。Agent 是 LLM 应用开发的"终极形态",理解 Agent 的设计思想和使用方法,是成为一名合格的 AI 应用开发者的关键一步。

相关推荐
其实防守也摸鱼1 小时前
红队技能总结导图:从入门到精通的完整知识体系
开发语言·人工智能·学习·安全·web安全
zjnlswd1 小时前
C# 学习笔记
笔记·学习
远离UE41 小时前
UE5 显存 虚拟内存 深入学习笔记
笔记·学习·ue5
我是慎独2 小时前
VulkanSceneGraph学习教程(十一)
c++·学习
HY小宝F2 小时前
从 APP 层打穿到传感器:树莓派 FFmpeg 底层学习笔记(一)V4L2/ALSA 踩坑与认知重构
笔记·学习·ffmpeg
超爱西西鸭2 小时前
思维导图编辑体验:触摸交互与节点操作(ArkTS)
学习·华为·harmonyos
向上的车轮2 小时前
GitHub开源破圈方法论:一个小白的实战成长笔记
笔记·开源·github
Accerlator2 小时前
从 Demo 到生产级别的 Agent 项目
学习
不会代码的小猴2 小时前
4. 控件学习2
开发语言·c++·笔记·qt
GISer_Jing2 小时前
全栈AI实战:基于 TypeScript + LangChain + MCP 的企业级智能研发助手
前端·后端·ai·langchain·前端框架