结构化输出允许代理以特定的、可预测的格式返回数据。您无需解析自然语言响应,而是以 JSON 对象、Pydantic 模型 或数据类的形式获取结构化数据,您的应用程序可以直接使用这些数据。
本页面涵盖使用 create_agent 的代理的结构化输出。要直接在模型上使用结构化输出(代理之外),请参阅模型 - 结构化输出。
LangChain 的 create_agent 自动处理结构化输出。用户设置所需的结构化输出模式,当模型生成结构化数据时,数据会被捕获、验证并返回在代理状态的 'structured_response' 键中。
def create_agent(
...
response_format: Union[
ToolStrategy[StructuredResponseT],
ProviderStrategy[StructuredResponseT],
type[StructuredResponseT],
None,
]
响应格式
使用 response_format 来控制代理返回结构化数据的方式:
ToolStrategy[StructuredResponseT]:使用工具调用进行结构化输出
ProviderStrategy[StructuredResponseT]:使用提供商原生的结构化输出
type[StructuredResponseT]:模式类型 - 根据模型能力自动选择最佳策略
None:不明确请求结构化输出
当直接提供模式类型时,LangChain 会自动选择:
原生结构化输出功能的支持是从模型的配置数据中动态读取的(如果使用 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。
定义结构化输出格式的模式。支持:
- Pydantic 模型:带有字段验证的
BaseModel 子类。返回验证后的 Pydantic 实例。
- 数据类:带类型注解的 Python 数据类。返回字典。
- TypedDict:类型化字典类。返回字典。
- JSON Schema:带 JSON Schema 规范的字典。返回字典。
启用严格模式遵守的可选布尔参数。某些提供商支持(例如 OpenAI 和 xAI)。默认为 None(禁用)。
当您直接将模式类型传递给 create_agent.response_format 并且模型支持原生结构化输出时,LangChain 会自动使用 ProviderStrategy:
from pydantic import BaseModel, Field
from langchain.agents import create_agent
class ContactInfo(BaseModel):
"""联系人的联系信息。"""
name: str = Field(description="联系人的姓名")
email: str = Field(description="联系人的电子邮件地址")
phone: str = Field(description="联系人的电话号码")
agent = create_agent(
model="gpt-5",
response_format=ContactInfo # 自动选择 ProviderStrategy
)
result = agent.invoke({
"messages": [{"role": "user", "content": "从以下信息中提取联系信息:张三, zhangsan@example.com, (555) 123-4567"}]
})
print(result["structured_response"])
# ContactInfo(name='张三', email='zhangsan@example.com', phone='(555) 123-4567')
提供商原生结构化输出提供高可靠性和严格验证,因为模型提供商会强制执行模式。在可用时使用它。
如果提供商原生支持您的模型选择的结构化输出,它在功能上等同于写 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],
]
定义结构化输出格式的模式。支持:
- Pydantic 模型:带有字段验证的
BaseModel 子类。返回验证后的 Pydantic 实例。
- 数据类:带类型注解的 Python 数据类。返回字典。
- TypedDict:类型化字典类。返回字典。
- JSON Schema:带 JSON Schema 规范的字典。返回字典。
- 联合类型:多个模式选项。模型将根据上下文选择最合适的模式。
生成结构化输出时返回的对话历史中的自定义内容。
如果未提供,默认为显示结构化响应数据的消息。
结构化输出验证失败时的错误处理策略。默认为 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):
"""产品评论分析。"""
rating: int | None = Field(description="产品的评分", ge=1, le=5)
sentiment: Literal["positive", "negative"] = Field(description="评论的情感倾向")
key_points: list[str] = Field(description="评论的要点。每个要点小写,1-3 个单词。")
agent = create_agent(
model="gpt-5",
tools=tools,
response_format=ToolStrategy(ProductReview)
)
result = agent.invoke({
"messages": [{"role": "user", "content": "分析此评论:'很棒的产品:5 星好评。发货快,但价格贵'"}]
})
result["structured_response"]
# ProductReview(rating=5, sentiment='positive', key_points=['发货快', '价格贵'])
自定义工具消息内容
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):
"""从会议记录中提取的行动项目。"""
task: str = Field(description="要完成的特定任务")
assignee: str = Field(description="负责此任务的人员")
priority: Literal["low", "medium", "high"] = Field(description="优先级")
agent = create_agent(
model="gpt-5",
tools=[],
response_format=ToolStrategy(
schema=MeetingAction,
tool_message_content="操作项目已捕获并添加到会议记录中!"
)
)
agent.invoke({
"messages": [{"role": "user", "content": "从我们的会议中:张三需要尽快更新项目时间表"}]
})
================================ 用户消息 =================================
从我们的会议中:张三需要尽快更新项目时间表
None
================================== AI 消息 ==================================
工具调用:
MeetingAction (call_1)
调用 ID: call_1
参数:
task: 更新项目时间表
assignee: 张三
priority: high
================================= 工具消息 =================================
名称: MeetingAction
操作项目已捕获并添加到会议记录中!
如果没有 tool_message_content,我们的最终 ToolMessage 将是:
================================= 工具消息 =================================
名称: MeetingAction
返回结构化响应:{'task': '更新项目时间表', 'assignee': '张三', '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="姓名")
email: str = Field(description="电子邮件地址")
class EventDetails(BaseModel):
event_name: str = Field(description="事件名称")
date: str = Field(description="事件日期")
agent = create_agent(
model="gpt-5",
tools=[],
response_format=ToolStrategy(Union[ContactInfo, EventDetails]) # 默认:handle_errors=True
)
agent.invoke({
"messages": [{"role": "user", "content": "提取信息:张三 (zhangsan@email.com) 正在组织 3 月 15 日的技术会议"}]
})
================================ 用户消息 =================================
提取信息:张三 (zhangsan@email.com) 正在组织 3 月 15 日的技术会议
None
================================== AI 消息 ==================================
工具调用:
ContactInfo (call_1)
调用 ID: call_1
参数:
name: 张三
email: zhangsan@email.com
EventDetails (call_2)
调用 ID: call_2
参数:
event_name: 技术会议
date: 3 月 15 日
================================= 工具消息 =================================
名称: ContactInfo
错误:模型错误地返回了多个结构化响应(ContactInfo, EventDetails),而预期只有一个。
请修正您的错误。
================================= 工具消息 =================================
名称: EventDetails
错误:模型错误地返回了多个结构化响应(ContactInfo, EventDetails),而预期只有一个。
请修正您的错误。
================================== AI 消息 ==================================
工具调用:
ContactInfo (call_3)
调用 ID: call_3
参数:
name: 张三
email: zhangsan@email.com
================================= 工具消息 =================================
名称: ContactInfo
返回结构化响应:{'name': '张三', 'email': 'zhangsan@email.com'}
模式验证错误
当结构化输出与预期模式不匹配时,代理提供具体的错误反馈:
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="评分从 1-5", ge=1, le=5)
Returning structured response: {'name': 'John Doe', 'email': 'john@email.com'}
模式验证错误
当结构化输出与预期模式不匹配时,代理会提供具体的错误反馈:
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="评分从 1-5", ge=1, le=5)
comment: str = Field(description="评论内容")
agent = create_agent(
model="gpt-5",
tools=[],
response_format=ToolStrategy(ProductRating), # 默认:handle_errors=True
system_prompt="你是一个有用的助手,解析产品评论。不要编造任何字段或值。"
)
agent.invoke({
"messages": [{"role": "user", "content": "解析这个:很棒的产品,10/10!"}]
})
================================ 用户消息 =================================
解析这个:很棒的产品,10/10!
================================== AI 消息 ==================================
工具调用:
ProductRating (call_1)
调用 ID: call_1
参数:
rating: 10
comment: 很棒的产品
================================= 工具消息 =================================
名称: ProductRating
错误:无法解析工具 'ProductRating' 的结构化输出:1 个验证错误 for ProductRating.rating
输入应该小于或等于 5 [type=less_than_equal, input_value=10, input_type=int]。
请修正您的错误。
================================== AI 消息 ==================================
工具调用:
ProductRating (call_2)
调用 ID: call_2
参数:
rating: 5
comment: 很棒的产品
================================= 工具消息 =================================
名称: ProductRating
返回结构化响应:{'rating': 5, 'comment': '很棒的产品'}
错误处理策略
您可以使用 handle_errors 参数自定义错误处理方式:
自定义错误消息:
ToolStrategy(
schema=ProductRating,
handle_errors="请提供 1-5 之间的有效评分,并包含评论。"
)
如果 handle_errors 是字符串,代理将始终提示模型重试,并使用固定的消息:
================================= 工具消息 =================================
名称: ProductRating
请提供 1-5 之间的有效评分,并包含评论。
仅处理特定异常:
ToolStrategy(
schema=ProductRating,
handle_errors=ValueError # 仅在 ValueError 时重试,其他异常会抛出
)
如果 handle_errors 是异常类型,代理仅在引发的异常是指定类型时才重试(使用默认错误消息)。在其他所有情况下,异常将被抛出。
处理多个异常类型:
ToolStrategy(
schema=ProductRating,
handle_errors=(ValueError, TypeError) # 在 ValueError 和 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 "格式有问题,请重试。"
elif isinstance(error, MultipleStructuredOutputsError):
return "返回了多个结构化输出,请选择最相关的一个。"
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
) # 默认:handle_errors=True
)
result = agent.invoke({
"messages": [{"role": "user", "content": "提取信息:张三 (zhangsan@email.com) 正在组织 3 月 15 日的技术会议"}]
})
for msg in result['messages']:
# 如果消息实际上是 ToolMessage 对象(不是字典),检查其类名
if type(msg).__name__ == "ToolMessage":
print(msg.content)
# 如果消息是字典或您想要后备方案
elif isinstance(msg, dict) and msg.get('tool_call_id'):
print(msg['content'])
关于 StructuredOutputValidationError:
================================= 工具消息 =================================
名称: ToolStrategy
格式有问题,请重试。
关于 MultipleStructuredOutputsError:
================================= 工具消息 =================================
名称: ToolStrategy
返回了多个结构化输出,请选择最相关的一个。
关于其他错误:
================================= 工具消息 =================================
名称: ToolStrategy
错误:<错误消息>
无错误处理:
response_format = ToolStrategy(
schema=ProductRating,
handle_errors=False # 所有错误都会被抛出
)
通过 MCP 将这些文档连接到 Claude、VSCode 等,获取实时答案。