Skip to content

LangChain 输出策略

LangChain 提供了三种结构化输出策略,理解它们的区别和工作原理,能帮助你在不同场景下做出最佳选择。


三种策略概述

策略原理模型支持响应速度
ToolStrategy将 Schema 伪装成工具,模型"调用"这个工具来输出结构化数据所有支持 function calling 的模型较慢(多一次工具调用)
ProviderStrategy使用模型原生的结构化输出能力(如 OpenAI 的 response_format)部分模型(GPT-4o+、Claude 3+等)较快(直接输出)
AutoStrategy自动检测模型能力,选择最佳策略自动适配自动选择最优

ToolStrategy——工具调用模式

ToolStrategy 是兼容性最好的方式。它将你的 Schema 转换为一个"假工具",模型通过调用这个工具来输出结构化数据。

实例

python

from pydantic import BaseModel, Field

from langchain.agents import create_agent

from langchain.agents.structured_output import ToolStrategy

from langchain.chat_models import init_chat_model

from langchain.messages import HumanMessage

class WeatherReport(BaseModel):

    """天气报告"""

    city: str = Field(description="城市名称")

    temperature: float = Field(description="温度(摄氏度)")

    condition: str = Field(description="天气状况")

    humidity: int = Field(description="湿度百分比")

model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)

# 显式指定使用 ToolStrategy

agent = create_agent(

    model=model,

    response_format=ToolStrategy(schema=WeatherReport),

    system_prompt="你是天气助手,根据用户描述生成结构化天气报告。",

)

result = agent.invoke({

    "messages": [HumanMessage(content="杭州今天晴天,温度25度,湿度60%")]

})

report = result["structured_response"]

print(f"城市: {report.city}")

print(f"温度: {report.temperature}°C")

print(f"状况: {report.condition}")

print(f"湿度: {report.humidity}%")

# 查看执行过程——可以发现多了一条工具调用的消息

print(f"\n消息总数: {len(result['messages'])}")

for msg in result["messages"]:

    print(f"  [{msg.type}]", end="")

    if hasattr(msg, 'tool_calls') and msg.tool_calls:

        print(f" 调用: {[tc['name'] for tc in msg.tool_calls]}")

    elif msg.type == "tool":

        print(f" {msg.content[:60]}")

    else:

        print(f" {str(msg.content)[:60]}")

运行结果:

python
城市: 杭州
温度: 25.0°C
状况: 晴天
湿度: 60%

消息总数: 4
  [human] 杭州今天晴天,温度25度,湿度60%
  [ai] 调用: ['WeatherReport']
  [tool] Returning structured response: ...
  [ai]

可以看到 ToolStrategy 多了一个工具调用步骤(调用名为 WeatherReport 的"假工具"),然后才有结构化输出。

handle_errors——错误重试

ToolStrategy 支持在结构化输出出错时自动重试:

实例

python

from langchain.agents.structured_output import ToolStrategy

# handle_errors=True:输出格式错误时,将错误信息反馈给模型重试

strategy_with_retry = ToolStrategy(

    schema=WeatherReport,

    handle_errors=True,  # 默认 False

)

# handle_errors 也可以是一个自定义错误消息模板

strategy_custom_error = ToolStrategy(

    schema=WeatherReport,

    handle_errors="格式有误,请按 {error} 修正后重新输出",

)

ProviderStrategy——原生结构化输出

ProviderStrategy 使用模型提供商的原生能力(如 OpenAI 的 response_format 参数)。不是所有模型都支持。

实例

python

from pydantic import BaseModel, Field

from langchain.agents import create_agent

from langchain.agents.structured_output import ProviderStrategy

from langchain.chat_models import init_chat_model

from langchain.messages import HumanMessage

class CourseInfo(BaseModel):

    """课程信息"""

    name: str = Field(description="课程名称")

    level: str = Field(description="难度:入门/进阶/高级")

    price: str = Field(description="价格信息")

model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)

# 显式指定 ProviderStrategy

agent = create_agent(

    model=model,

    response_format=ProviderStrategy(schema=CourseInfo),

    system_prompt="你是菜鸟教程 RUNOOB 的课程助手。",

)

result = agent.invoke({

    "messages": [HumanMessage(content="Python3 基础教程是入门级的免费课程")]

})

course = result["structured_response"]

print(f"课程: {course.name}")

print(f"难度: {course.level}")

print(f"价格: {course.price}")

print(f"\n消息数: {len(result['messages'])}")  # 比 ToolStrategy 少

运行结果:

python
课程: Python3 基础教程
难度: 入门
价格: 免费

消息数: 2

与 ToolStrategy 相比,ProviderStrategy 的消息数更少(2 条 vs 4 条),因为它不需要额外的工具调用步骤。

ProviderStrategy 目前主要被 OpenAI 的 GPT-4o 及以上和 Claude 3 及以上支持。如果模型不支持,LangChain 会自动降级到 ToolStrategy。检查模型是否支持可以用 model.profile 查看。


AutoStrategy——自动选择

这是最推荐的方式。传入 Pydantic 模型(而不是策略对象),LangChain 会自动选择最佳策略:

实例

python

from pydantic import BaseModel, Field

from langchain.agents import create_agent

from langchain.chat_models import init_chat_model

from langchain.messages import HumanMessage

class Analysis(BaseModel):

    """分析结果"""

    summary: str = Field(description="一句话总结")

    score: int = Field(description="评分 1~10")

    pros: list[str] = Field(description="优点列表")

    cons: list[str] = Field(description="缺点列表")

# 直接传入 Pydantic 模型——LangChain 自动选择策略

model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)

agent = create_agent(

    model=model,

    response_format=Analysis,  # 直接传模型,自动选择策略

    system_prompt="你是课程评估专家,评估用户描述的课程。",

)

result = agent.invoke({

    "messages": [HumanMessage(

        content="菜鸟教程 RUNOOB 的 Python 课程:内容系统全面,"

                "实例丰富,而且完全免费。但视频教程较少,"

                "高级内容覆盖不够。"

    )]

})

analysis = result["structured_response"]

print(f"总结: {analysis.summary}")

print(f"评分: {analysis.score}/10")

print(f"优点: {', '.join(analysis.pros)}")

print(f"缺点: {', '.join(analysis.cons)}")

运行结果:

python
总结: 菜鸟教程 Python 课程内容系统且免费,但缺乏视频教学和高级内容
评分: 7/10
优点: 内容系统全面, 实例丰富, 完全免费
缺点: 视频教程较少, 高级内容覆盖不够

三种策略选择指南

场景推荐策略原因
不确定模型是否支持原生输出AutoStrategy(直接传 Pydantic)自动选择最优策略
需要兼容各种模型ToolStrategy所有支持 function calling 的模型都可用
追求极致性能ProviderStrategy跳过工具调用环节,速度更快
需要错误重试ToolStrategy(handle_errors=True)只有 ToolStrategy 支持 handle_errors

大多数情况下,直接传入 Pydantic 模型(即使用 AutoStrategy)就够了。只有在需要错误重试或明确控制策略行为时,才需要显式指定 ToolStrategy 或 ProviderStrategy。

AI 思考中...

LangChain 结构化输出

LangChain 中间件(Middleware)

基于 VitePress 构建,部署于 GitHub Pages