LangChain1.0智能体开发:结构化输出

阅读本文您将获得:

  • LangChain如何控制智能体最终的格式化输出?
  • 格式化输出的模型提供商原生策略
  • 格式化输出的工具调用策略
  • 格式化输出的工具调用错误处理

结构化输出能让智能体以特定、可预测的格式返回数据。无需解析自然语言响应,你就能直接获取JSON对象、Pydantic模型或数据类(dataclasses)形式的结构化数据,供应用程序直接使用。LangChain的create_agent接口会自动处理结构化输出。用户只需设置所需的结构化输出模式(schema),当模型生成结构化数据后,该数据会被捕获、验证,并最终在智能体状态的structured_response键中返回。

1、响应格式

控制智能体返回结构化数据的方式在创建智能体时给create_agent接口传递response_format参数,参数赋值类型如下:

  • ToolStrategy[StructuredResponseT]:使用工具调用获取结构化输出
  • ProviderStrategy[StructuredResponseT]:使用提供商原生的结构化输出
  • type[StructuredResponseT]:Schema类型 ------ 根据模型能力自动选择最佳策略
  • None:无结构化输出

当直接提供Schema类型时,LangChain会自动选择:

  • 对于支持原生结构化输出的模型(如OpenAI、Grok),使用ProviderStrategy;
  • 对于其他所有模型,使用ToolStrategy;

结构化响应会在智能体最终状态的structured_response键中返回。

2、ProviderStrategy(提供商原生策略)

部分模型提供商可通过其API原生支持结构化输出(目前仅支持 OpenAI 和 Grok)。在支持该功能的情况下,这是最可靠的方法。 若要使用此策略,可以给create_agent.response_format配置一个ProviderStrategy; 也可以将Schema类型直接传递给create_agent.response_format,且所用模型支持原生结构化输出时,LangChain会自动使用ProviderStrategy。

python 复制代码
class ProviderStrategy(Generic[SchemaT]):
    schema: type[SchemaT]

使用示例:

python 复制代码
from pydantic import BaseModel
from langchain.agents import create_agent


class ContactInfo(BaseModel):
    """Contact information for a person."""
    name: str = Field(description="The name of the person")
    email: str = Field(description="The email address of the person")
    phone: str = Field(description="The phone number of the person")

agent = create_agent(
    model="gpt-5",
    tools=tools,
    response_format=ContactInfo  # Auto-selects ProviderStrategy
)

result = agent.invoke({
    "messages": [{"role": "user", "content": "Extract contact info from: John Doe, john@example.com, (555) 123-4567"}]
})

result["structured_response"]
# ContactInfo(name='John Doe', email='john@example.com', phone='(555) 123-4567')

提供商原生结构化输出具有高可靠性和严格的验证能力,这是因为模型提供商会对schema进行强制约束。在支持该功能的情况下,建议使用此方式。

3、ToolStrategy(工具调用策略)

对于不支持原生结构化输出的模型,LangChain会通过工具调用来实现相同的效果。该方式适用于所有支持工具调用的模型,大多数现代模型均具备这一能力。 若要使用此策略,需要给create_agent.response_format配置一个ToolStrategy; 也可以将Schema类型直接传递给create_agent.response_format,且所用模型不支持原生结构化输出时,LangChain会自动使用ToolStrategy。

python 复制代码
class ToolStrategy(Generic[SchemaT]):
    schema: type[SchemaT]
    tool_message_content: str | None
    handle_errors: Union[
        bool,
        str,
        type[Exception],
        tuple[type[Exception], ...],
        Callable[[Exception], str],
    ]

使用示例:

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

class MeetingAction(BaseModel):
    """Action items extracted from a meeting transcript."""
    task: str = Field(description="The specific task to be completed")
    assignee: str = Field(description="Person responsible for the task")
    priority: Literal["low", "medium", "high"] = Field(description="Priority level")

agent = create_agent(
    model="gpt-5",
    tools=[],
    response_format=ToolStrategy(
        schema=MeetingAction,
        tool_message_content="Action item captured and added to meeting notes!" #可选项,输出ToolMessage的内容
    )
)

result = agent.invoke({
    "messages": [{"role": "user", "content": "From our meeting: Sarah needs to update the project timeline as soon as possible"}]
})

result["structured_response"]
# MeetingAction(task='Update project timeline', assignee='Sarah', priority='high')

3.1 错误处理

模型在通过工具调用生成结构化输出时可能会出现错误。LangChain提供了智能重试机制,可自动处理这些错误。

3.1.1 多结构化输出工具错误

当模型错误地调用多个结构化输出工具时,智能体会在ToolMessage中提供错误反馈,并提示模型进行重试,可自动处理这些错误。

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


class ContactInfo(BaseModel):
    name: str = Field(description="Person's name")
    email: str = Field(description="Email address")

class EventDetails(BaseModel):
    event_name: str = Field(description="Name of the event")
    date: str = Field(description="Event date")

agent = create_agent(
    model="gpt-5",
    tools=[],
    response_format=ToolStrategy(Union[ContactInfo, EventDetails])  # Default: handle_errors=True
)

agent.invoke({
    "messages": [{"role": "user", "content": "Extract info: John Doe (john@email.com) is organizing Tech Conference on March 15th"}]
})

3.1.2 Schema验证错误

当结构化输出与预期Schema不匹配时,智能体会提供具体的错误反馈,并提示模型进行重试,可自动处理这些错误。

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

class ProductRating(BaseModel):
    rating: int | None = Field(description="Rating from 1-5", ge=1, le=5)
    comment: str = Field(description="Review comment")

agent = create_agent(
    model="gpt-5",
    tools=[],
    response_format=ToolStrategy(ProductRating),  # Default: handle_errors=True
    system_prompt="You are a helpful assistant that parses product reviews. Do not make any field or value up."
)

agent.invoke({
    "messages": [{"role": "user", "content": "Parse this: Amazing product, 10/10!"}]
})

3.1.3 自定义错误处理策略

可以通过handle_errors参数自定义错误的处理方式:

  • True:默认值,捕获所有错误,使用默认错误模板,自动重试
  • str(字符串):捕获所有错误,使用此自定义消息,自动重试
  • type[Exception](异常类型):仅捕获该类型异常并重试,使用默认消息;其它类型错误则直接报错退出
  • tuple(type[Exception], ...)(异常类型元组):仅捕获这些类型异常,使用默认消息
  • Callable[[Exception], str](可调用对象):自定义函数,返回错误消息
  • False:不重试,让异常继续传播

示例(handle_errors传入可调用对象):

python 复制代码
# 自定义函数处理错误
def custom_error_handler(error: Exception) -> str:
    if isinstance(error, StructuredOutputValidationError):
        return "There was an issue with the format. Try again.
    elif isinstance(error, MultipleStructuredOutputsError):
        return "Multiple structured outputs were returned. Pick the most relevant one."
    else:
        return f"Error: {str(error)}"

ToolStrategy(
    schema=ToolStrategy(Union[ContactInfo, EventDetails]),
    handle_errors=custom_error_handler
)
相关推荐
文心快码BaiduComate29 分钟前
百度云与光本位签署战略合作:用AI Agent 重构芯片研发流程
前端·人工智能·架构
风象南1 小时前
Claude Code这个隐藏技能,让我告别PPT焦虑
人工智能·后端
KaneLogger1 小时前
【翻译】打造 Agent Skills 的最佳实践
agent·ai编程·claude
QCY1 小时前
「完全理解」1 分钟实现自己的 Coding Agent
前端·agent·claude
Mintopia2 小时前
OpenClaw 对软件行业产生的影响
人工智能
mCell2 小时前
从零构建一个 Mini Claude Code:面向初学者的 Agent 开发实战指南
typescript·agent·claude
雮尘2 小时前
如何在非 Claude IDE (TARE、 Cursor、Antigravity 等)下使用 Agent Skills
前端·agent·ai编程
陈广亮3 小时前
构建具有长期记忆的 AI Agent:从设计模式到生产实践
人工智能
会写代码的柯基犬3 小时前
DeepSeek vs Kimi vs Qwen —— AI 生成俄罗斯方块代码效果横评
人工智能·llm
Mintopia3 小时前
OpenClaw 是什么?为什么节后热度如此之高?
人工智能