结构化输出允许智能体以特定、可预测的格式返回数据。您可以获得 JSON 对象、Pydantic 模型或数据类形式的结构化数据,应用程序可以直接使用,而不是解析自然语言响应。 LangChain 的 create_agent 自动处理结构化输出。用户设置他们所需的结构化输出模式,当模型生成结构化数据时,它会被捕获、验证并在智能体状态的 'structured_response' 键中返回。
def create_agent(
    ...
    response_format: Union[
        ToolStrategy[StructuredResponseT],
        ProviderStrategy[StructuredResponseT],
        type[StructuredResponseT],
    ]

响应格式

控制智能体如何返回结构化数据:
  • ToolStrategy[StructuredResponseT]:使用工具调用进行结构化输出
  • ProviderStrategy[StructuredResponseT]:使用提供商原生结构化输出
  • type[StructuredResponseT]:模式类型 - 根据模型能力自动选择最佳策略
  • None:无结构化输出
当直接提供模式类型时,LangChain 自动选择:
  • 对于支持原生结构化输出的模型(例如 OpenAIGrok),使用 ProviderStrategy
  • 对于所有其他模型,使用 ToolStrategy
结构化响应在智能体最终状态的 structured_response 键中返回。

提供商策略

某些模型提供商通过其 API 原生支持结构化输出(目前仅 OpenAI 和 Grok)。这是可用时最可靠的方法。 要使用此策略,请配置 ProviderStrategy
class ProviderStrategy(Generic[SchemaT]):
    schema: type[SchemaT]
schema
required
The schema defining the structured output format. Supports:
  • Pydantic models: BaseModel subclasses with field validation
  • Dataclasses: Python dataclasses with type annotations
  • TypedDict: Typed dictionary classes
  • JSON Schema: Dictionary with JSON schema specification
当您直接将模式类型传递给 create_agent.response_format 且模型支持本地结构化输出时,LangChain 自动使用 ProviderStrategy
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')
提供商本地结构化输出提供高可靠性和严格验证,因为模型提供商强制执行模式。在可用时使用它。
If the provider natively supports structured output for your model choice, it is functionally equivalent to write response_format=ProductReview instead of response_format=ToolStrategy(ProductReview). In either case, if structured output is not supported, the agent will fall back to a tool calling strategy.

工具调用策略

对于不支持本地结构化输出的模型,LangChain 使用工具调用来实现相同的结果。这适用于所有支持工具调用的模型,这是大多数现代模型。 要使用此策略,请配置 ToolStrategy
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],
    ]
schema
required
The schema defining the structured output format. Supports:
  • Pydantic models: BaseModel subclasses with field validation
  • Dataclasses: Python dataclasses with type annotations
  • TypedDict: Typed dictionary classes
  • JSON Schema: Dictionary with JSON schema specification
  • Union types: Multiple schema options. The model will choose the most appropriate schema based on the context.
tool_message_content
Custom content for the tool message returned when structured output is generated. If not provided, defaults to a message showing the structured response data.
handle_errors
Error handling strategy for structured output validation failures. Defaults to True.
  • True: Catch all errors with default error template
  • str: Catch all errors with this custom message
  • type[Exception]: Only catch this exception type with default message
  • tuple[type[Exception], ...]: Only catch these exception types with default message
  • Callable[[Exception], str]: Custom function that returns error message
  • False: No retry, let exceptions propagate
from pydantic import BaseModel, Field
from typing import Literal
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy


class ProductReview(BaseModel):
    """Analysis of a product review."""
    rating: int | None = Field(description="The rating of the product", ge=1, le=5)
    sentiment: Literal["positive", "negative"] = Field(description="The sentiment of the review")
    key_points: list[str] = Field(description="The key points of the review. Lowercase, 1-3 words each.")

agent = create_agent(
    model="gpt-5",
    tools=tools,
    response_format=ToolStrategy(ProductReview)
)

result = agent.invoke({
    "messages": [{"role": "user", "content": "Analyze this review: 'Great product: 5 out of 5 stars. Fast shipping, but expensive'"}]
})
result["structured_response"]
# ProductReview(rating=5, sentiment='positive', key_points=['fast shipping', 'expensive'])

自定义工具消息内容

tool_message_content 参数允许您自定义在生成结构化输出时出现在对话历史记录中的消息:
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!"
    )
)

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

From our meeting: Sarah needs to update the project timeline as soon as possible
================================== Ai Message ==================================
Tool Calls:
  MeetingAction (call_1)
 Call ID: call_1
  Args:
    task: Update the project timeline
    assignee: Sarah
    priority: high
================================= Tool Message =================================
Name: MeetingAction

Action item captured and added to meeting notes!
如果没有 tool_message_content,我们的最终 ToolMessage 将是:
================================= Tool Message =================================
Name: MeetingAction

Returning structured response: {'task': 'update the project timeline', 'assignee': 'Sarah', 'priority': 'high'}

Error handling

Models can make mistakes when generating structured output via tool calling. LangChain provides intelligent retry mechanisms to handle these errors automatically.

Multiple structured outputs error

When a model incorrectly calls multiple structured output tools, the agent provides error feedback in a ToolMessage and prompts the model to retry:
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"}]
})
================================ Human Message =================================

Extract info: John Doe (john@email.com) is organizing Tech Conference on March 15th
None
================================== Ai Message ==================================
Tool Calls:
  ContactInfo (call_1)
 Call ID: call_1
  Args:
    name: John Doe
    email: john@email.com
  EventDetails (call_2)
 Call ID: call_2
  Args:
    event_name: Tech Conference
    date: March 15th
================================= Tool Message =================================
Name: ContactInfo

Error: Model incorrectly returned multiple structured responses (ContactInfo, EventDetails) when only one is expected.
 Please fix your mistakes.
================================= Tool Message =================================
Name: EventDetails

Error: Model incorrectly returned multiple structured responses (ContactInfo, EventDetails) when only one is expected.
 Please fix your mistakes.
================================== Ai Message ==================================
Tool Calls:
  ContactInfo (call_3)
 Call ID: call_3
  Args:
    name: John Doe
    email: john@email.com
================================= Tool Message =================================
Name: ContactInfo

Returning structured response: {'name': 'John Doe', 'email': 'john@email.com'}

Schema validation error

When structured output doesn’t match the expected schema, the agent provides specific error feedback:
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!"}]
})
================================ Human Message =================================

Parse this: Amazing product, 10/10!
================================== Ai Message ==================================
Tool Calls:
  ProductRating (call_1)
 Call ID: call_1
  Args:
    rating: 10
    comment: Amazing product
================================= Tool Message =================================
Name: ProductRating

Error: Failed to parse structured output for tool 'ProductRating': 1 validation error for ProductRating.rating
  Input should be less than or equal to 5 [type=less_than_equal, input_value=10, input_type=int].
 Please fix your mistakes.
================================== Ai Message ==================================
Tool Calls:
  ProductRating (call_2)
 Call ID: call_2
  Args:
    rating: 5
    comment: Amazing product
================================= Tool Message =================================
Name: ProductRating

Returning structured response: {'rating': 5, 'comment': 'Amazing product'}

Error handling strategies

You can customize how errors are handled using the handle_errors parameter: Custom error message:
ToolStrategy(
    schema=ProductRating,
    handle_errors="Please provide a valid rating between 1-5 and include a comment."
)
If handle_errors is a string, the agent will always prompt the model to re-try with a fixed tool message:
================================= Tool Message =================================
Name: ProductRating

Please provide a valid rating between 1-5 and include a comment.
Handle specific exceptions only:
ToolStrategy(
    schema=ProductRating,
    handle_errors=ValueError  # Only retry on ValueError, raise others
)
If handle_errors is an exception type, the agent will only retry (using the default error message) if the exception raised is the specified type. In all other cases, the exception will be raised. Handle multiple exception types:
ToolStrategy(
    schema=ProductRating,
    handle_errors=(ValueError, TypeError)  # Retry on ValueError and TypeError
)
If handle_errors is a tuple of exceptions, the agent will only retry (using the default error message) if the exception raised is one of the specified types. In all other cases, the exception will be raised. Custom error handler function:
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
)
On StructuredOutputValidationError:
================================= Tool Message =================================
Name: ToolStrategy

There was an issue with the format. Try again.
On MultipleStructuredOutputsError:
================================= Tool Message =================================
Name: ToolStrategy

Multiple structured outputs were returned. Pick the most relevant one.
On other errors:
================================= Tool Message =================================
Name: ToolStrategy

Error: <error message>
No error handling:
response_format = ToolStrategy(
    schema=ProductRating,
    handle_errors=False  # All errors raised
)

Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.