Skip to main content
结构化输出允许代理以特定的、可预测的格式返回数据。与其解析自然语言响应,不如直接获取 JSON 对象、Pydantic 模型或数据类形式的结构化数据,供应用程序直接使用。
本页介绍使用 create_agent 的代理结构化输出。若要直接在模型上使用结构化输出(在代理之外),请参阅模型 - 结构化输出
LangChain 的 create_agent 会自动处理结构化输出。用户设置所需的结构化输出 schema,当模型生成结构化数据时,它会被捕获、验证,并以 'structured_response' 键返回到代理的状态中。
def create_agent(
    ...
    response_format: Union[
        ToolStrategy[StructuredResponseT],
        ProviderStrategy[StructuredResponseT],
        type[StructuredResponseT],
        None,
    ]

响应格式

使用 response_format 控制代理返回结构化数据的方式:
  • ToolStrategy[StructuredResponseT]:使用工具调用实现结构化输出
  • ProviderStrategy[StructuredResponseT]:使用提供商原生结构化输出
  • type[StructuredResponseT]:Schema 类型 - 根据模型能力自动选择最佳策略
  • None:未显式请求结构化输出
当直接提供 schema 类型时,LangChain 会自动选择:
  • 若所选模型和提供商支持原生结构化输出(如 OpenAIAnthropic (Claude)xAI (Grok)),则使用 ProviderStrategy
  • 对于其他所有模型,使用 ToolStrategy
使用 langchain>=1.1 时,对原生结构化输出特性的支持会从模型的配置文件数据中动态读取。如果数据不可用,请使用其他条件或手动指定:
custom_profile = {
    "structured_output": True,
    # ...
}
model = init_chat_model("...", profile=custom_profile)
如果指定了工具,模型必须支持同时使用工具和结构化输出。
结构化响应以 structured_response 键返回到代理的最终状态中。

提供商策略

部分模型提供商通过其 API 原生支持结构化输出(如 OpenAI、xAI (Grok)、Gemini、Anthropic (Claude))。这是可用时最可靠的方法。 要使用此策略,请配置 ProviderStrategy
class ProviderStrategy(Generic[SchemaT]):
    schema: type[SchemaT]
    strict: bool | None = None
strict 参数需要 langchain>=1.2
schema
required
定义结构化输出格式的 schema。支持:
  • Pydantic 模型:带字段验证的 BaseModel 子类。返回已验证的 Pydantic 实例。
  • 数据类:带类型注解的 Python 数据类。返回字典。
  • TypedDict:类型化字典类。返回字典。
  • JSON Schema:包含 JSON schema 规范的字典。返回字典。
strict
可选布尔参数,用于启用严格的 schema 遵从性。部分提供商支持(如 OpenAIxAI)。默认为 None(禁用)。
当你直接将 schema 类型传递给 create_agent.response_format 且模型支持原生结构化输出时,LangChain 会自动使用 ProviderStrategy
from pydantic import BaseModel, Field
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",
    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"}]
})

print(result["structured_response"])
# ContactInfo(name='John Doe', email='john@example.com', phone='(555) 123-4567')
提供商原生结构化输出由于模型提供商强制执行 schema,因此具有较高的可靠性和严格验证。可用时请优先使用。
如果提供商原生支持所选模型的结构化输出,则写 response_format=ProductReview 与写 response_format=ProviderStrategy(ProductReview) 在功能上等价。无论哪种情况,若不支持结构化输出,代理都会回退到工具调用策略。

工具调用策略

对于不支持原生结构化输出的模型,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
定义结构化输出格式的 schema。支持:
  • Pydantic 模型:带字段验证的 BaseModel 子类。返回已验证的 Pydantic 实例。
  • 数据类:带类型注解的 Python 数据类。返回字典。
  • TypedDict:类型化字典类。返回字典。
  • JSON Schema:包含 JSON schema 规范的字典。返回字典。
  • Union 类型:多个 schema 选项。模型将根据上下文选择最合适的 schema。
tool_message_content
生成结构化输出时在对话历史中显示的工具消息的自定义内容。 如果未提供,默认显示包含结构化响应数据的消息。
handle_errors
结构化输出验证失败时的错误处理策略。默认为 True
  • True:使用默认错误模板捕获所有错误
  • str:使用此自定义消息捕获所有错误
  • type[Exception]:仅捕获此异常类型并使用默认消息
  • tuple[type[Exception], ...]:仅捕获这些异常类型并使用默认消息
  • Callable[[Exception], str]:返回错误消息的自定义函数
  • False:不重试,让异常传播
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'}

错误处理

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

多个结构化输出错误

当模型错误地调用多个结构化输出工具时,代理会在 ToolMessage 中提供错误反馈,并提示模型重试:
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 验证错误

当结构化输出与预期的 schema 不匹配时,代理会提供具体的错误反馈:
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'}

错误处理策略

你可以使用 handle_errors 参数自定义错误处理方式: 自定义错误消息:
ToolStrategy(
    schema=ProductRating,
    handle_errors="Please provide a valid rating between 1-5 and include a comment."
)
如果 handle_errors 是字符串,代理将始终使用固定工具消息提示模型重试:
================================= Tool Message =================================
Name: ProductRating

Please provide a valid rating between 1-5 and include a comment.
仅处理特定异常:
ToolStrategy(
    schema=ProductRating,
    handle_errors=ValueError  # Only retry on ValueError, raise others
)
如果 handle_errors 是异常类型,代理仅在抛出指定类型的异常时重试(使用默认错误消息)。其他情况下,异常会被抛出。 处理多种异常类型:
ToolStrategy(
    schema=ProductRating,
    handle_errors=(ValueError, TypeError)  # Retry on ValueError and TypeError
)
如果 handle_errors 是异常元组,代理仅在抛出的异常是指定类型之一时重试(使用默认错误消息)。其他情况下,异常会被抛出。 自定义错误处理函数:

from langchain.agents.structured_output import StructuredOutputValidationError
from langchain.agents.structured_output import MultipleStructuredOutputsError

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


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

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

for msg in result['messages']:
    # If message is actually a ToolMessage object (not a dict), check its class name
    if type(msg).__name__ == "ToolMessage":
        print(msg.content)
    # If message is a dictionary or you want a fallback
    elif isinstance(msg, dict) and msg.get('tool_call_id'):
        print(msg['content'])

发生 StructuredOutputValidationError 时:
================================= Tool Message =================================
Name: ToolStrategy

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

Multiple structured outputs were returned. Pick the most relevant one.
发生其他错误时:
================================= Tool Message =================================
Name: ToolStrategy

Error: <error message>
不进行错误处理:
response_format = ToolStrategy(
    schema=ProductRating,
    handle_errors=False  # All errors raised
)