现在位置: 首页 > LangChain 教程 > 正文

LangChain 输出策略

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


三种策略概述

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

ToolStrategy——工具调用模式

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

实例

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

运行结果:

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

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

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

handle_errors——错误重试

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

实例

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 参数)。不是所有模型都支持。

实例

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 少

运行结果:

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

消息数: 2

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

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


AutoStrategy——自动选择

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

实例

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 课程内容系统且免费,但缺乏视频教学和高级内容
评分: 7/10
优点: 内容系统全面, 实例丰富, 完全免费
缺点: 视频教程较少, 高级内容覆盖不够

三种策略选择指南

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

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