本页面介绍了使用
create_agent 的智能体的结构化输出。要在模型上直接使用结构化输出(智能体外部),请参阅 模型 - 结构化输出。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:未明确请求结构化输出
ProviderStrategy如果所选模型和提供者支持原生结构化输出(例如 OpenAI、Anthropic (Claude) 或 xAI (Grok))。ToolStrategy对于所有其他模型。
JSON 模式字典必须用显式策略(
ProviderStrategy 或 ToolStrategy)包装。当直接传递给 response_format 时,它们不会被自动检测。如果使用 如果指定了工具,模型必须支持同时使用工具和结构化输出。
langchain>=1.1,对原生结构化输出功能的支持会动态地从模型的 配置数据 中读取。如果数据不可用,请使用其他条件或手动指定:custom_profile = {
"structured_output": True,
# ...
}
model = init_chat_model("...", profile=custom_profile)
structured_response 键中。
:::
:::js
结构化输出允许智能体以特定的、可预测的格式返回数据。您不再需要解析自然语言响应,而是直接获得类型化的结构化数据。
本页面介绍了使用
createAgent 的智能体的结构化输出。要在模型上直接使用结构化输出(智能体外部),请参阅 模型 - 结构化输出。createAgent 自动处理结构化输出。用户设置所需的结构化输出模式,当模型生成结构化数据时,它会被捕获、验证,并以 structuredResponse 键的形式返回到智能体的状态中。
type ResponseFormat = (
| ZodSchema<StructuredResponseT> // a Zod schema
| StandardSchema<StructuredResponseT> // any Standard Schema library
| Record<string, unknown> // a JSON Schema
)
const agent = createAgent({
// ...
responseFormat: ResponseFormat | ResponseFormat[]
})
响应格式
控制智能体如何返回结构化数据。您可以提供一个 Zod 模式、任何 标准模式 兼容的模式,或一个 JSON 模式对象。默认情况下,智能体会使用工具调用策略,其中输出由额外的工具调用创建。某些模型支持原生结构化输出,在这种情况下,智能体会使用该策略。 您可以通过将ResponseFormat 包裹在 toolStrategy 或 providerStrategy 函数调用中来控制行为:
import { toolStrategy, providerStrategy } from "langchain";
const agent = createAgent({
// use a provider strategy if supported by the model
responseFormat: providerStrategy(z.object({ ... }))
// or enforce a tool strategy
responseFormat: toolStrategy(z.object({ ... }))
})
structuredResponse 键中。
如果使用 如果指定了工具,模型必须支持同时使用工具和结构化输出。
langchain>=1.1,对原生结构化输出功能的支持会动态地从模型的 配置数据 中读取。如果数据不可用,请使用其他条件或手动指定:const customProfile: ModelProfile = {
structuredOutput: true,
// ...
}
const model = await initChatModel("...", { profile: customProfile });
提供商策略
一些模型提供商通过其 API 原生支持结构化输出(例如 OpenAI、xAI (Grok)、Gemini、Anthropic (Claude))。当可用时,这是最可靠的方法。 要使用此策略,配置一个ProviderStrategy:
:::python
class ProviderStrategy(Generic[SchemaT]):
schema: type[SchemaT]
strict: bool | None = None
The
strict param requires langchain>=1.2.required
定义结构化输出格式的模式。支持:
- Pydantic 模型:
BaseModel子类,带有字段验证。返回验证后的 Pydantic 实例。 - 数据类:带有类型注解的 Python 数据类。返回 dict。
- TypedDict:类型化字典类。返回 dict。
- JSON Schema:带有 JSON schema 规范的字典。必须包含顶层
title和description键。返回 dict。
create_agent.response_format][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.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')
from dataclasses import dataclass
from langchain.agents import create_agent
@dataclass
class ContactInfo:
"""Contact information for a person."""
name: str # The name of the person
email: str # The email address of the person
phone: str # The phone number of the person
agent = create_agent(
model="gpt-5.5",
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"]
# {'name': 'John Doe', 'email': 'john@example.com', 'phone': '(555) 123-4567'}
from typing_extensions import TypedDict
from langchain.agents import create_agent
class ContactInfo(TypedDict):
"""Contact information for a person."""
name: str # The name of the person
email: str # The email address of the person
phone: str # The phone number of the person
agent = create_agent(
model="gpt-5.5",
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"]
# {'name': 'John Doe', 'email': 'john@example.com', 'phone': '(555) 123-4567'}
from langchain.agents import create_agent
from langchain.agents.structured_output import ProviderStrategy
contact_info_schema = {
"title": "ContactInfo",
"type": "object",
"description": "Contact information for a person.",
"properties": {
"name": {"type": "string", "description": "The name of the person"},
"email": {"type": "string", "description": "The email address of the person"},
"phone": {"type": "string", "description": "The phone number of the person"}
},
"required": ["name", "email", "phone"]
}
agent = create_agent(
model="gpt-5.5",
tools=[],
response_format=ProviderStrategy(contact_info_schema)
)
result = agent.invoke({
"messages": [{"role": "user", "content": "Extract contact info from: John Doe, john@example.com, (555) 123-4567"}]
})
result["structured_response"]
# {'name': 'John Doe', 'email': 'john@example.com', 'phone': '(555) 123-4567'}
function providerStrategy<StructuredResponseT>(
schema: ZodSchema<StructuredResponseT> | SerializableSchema | JsonSchemaFormat
): ProviderStrategy<StructuredResponseT>
required
定义结构化输出格式的模式。支持:
- Zod Schema:一个 zod schema
- 标准 Schema:实现 标准 Schema 规范的任何 schema
- JSON Schema:一个 JSON schema 对象
createAgent.responseFormat 且模型支持原生结构化输出时,LangChain 会自动使用 ProviderStrategy:
import * as z from "zod";
import { createAgent, providerStrategy } from "langchain";
const ContactInfo = z.object({
name: z.string().describe("The name of the person"),
email: z.string().describe("The email address of the person"),
phone: z.string().describe("The phone number of the person"),
});
const agent = createAgent({
model: "gpt-5.5",
tools: [],
responseFormat: providerStrategy(ContactInfo)
});
const result = await agent.invoke({
messages: [{"role": "user", "content": "Extract contact info from: John Doe, john@example.com, (555) 123-4567"}]
});
console.log(result.structuredResponse);
// { name: "John Doe", email: "john@example.com", phone: "(555) 123-4567" }
import * as v from "valibot";
import { toStandardJsonSchema } from "@valibot/to-json-schema";
import { createAgent, providerStrategy } from "langchain";
const ContactInfo = toStandardJsonSchema(
v.object({
name: v.pipe(v.string(), v.description("The name of the person")),
email: v.pipe(v.string(), v.description("The email address of the person")),
phone: v.pipe(v.string(), v.description("The phone number of the person")),
})
);
const agent = createAgent({
model: "gpt-5.5",
tools: [],
responseFormat: providerStrategy(ContactInfo)
});
const result = await agent.invoke({
messages: [{"role": "user", "content": "Extract contact info from: John Doe, john@example.com, (555) 123-4567"}]
});
console.log(result.structuredResponse);
// { name: "John Doe", email: "john@example.com", phone: "(555) 123-4567" }
import { createAgent, providerStrategy } from "langchain";
const contactInfoSchema = {
"type": "object",
"description": "Contact information for a person.",
"properties": {
"name": {"type": "string", "description": "The name of the person"},
"email": {"type": "string", "description": "The email address of the person"},
"phone": {"type": "string", "description": "The phone number of the person"}
},
"required": ["name", "email", "phone"]
}
const agent = createAgent({
model: "gpt-5.5",
tools: [],
responseFormat: providerStrategy(contactInfoSchema)
});
const result = await agent.invoke({
messages: [{"role": "user", "content": "Extract contact info from: John Doe, john@example.com, (555) 123-4567"}]
});
console.log(result.structuredResponse);
// { name: "John Doe", email: "john@example.com", phone: "(555) 123-4567" }
如果提供商原生支持您选择的模型的结构化输出,编写
response_format=ProductReview 与编写 response_format=ProviderStrategy(ProductReview) 功能等效。在任何情况下,如果结构化输出不受支持,智能体将回退到工具调用策略。如果提供商原生支持您选择的模型的结构化输出,编写
responseFormat: contactInfoSchema 与编写 responseFormat: providerStrategy(contactInfoSchema) 功能等效。在任何情况下,如果结构化输出不受支持,智能体将回退到工具调用策略。工具调用策略
对于不支持原生结构化输出的模型,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],
]
required
定义结构化输出格式的模式。支持:
- Pydantic 模型:
BaseModel子类,具有字段验证。返回验证后的 Pydantic 实例。 - 数据类:带类型注解的 Python 数据类。返回字典。
- TypedDict:类型化字典类。返回字典。
- JSON Schema:带 JSON 模式规范的字典。必须包含顶层
title和description键。返回字典。 - 联合类型:多种模式选项。模型将根据上下文选择最合适的模式。
当生成结构化输出时返回的工具消息的自定义内容。
如果未提供,则默认显示结构化响应数据。
结构化输出验证失败的错误处理策略。默认为
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.5",
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'])
from dataclasses import dataclass
from typing import Literal
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy
@dataclass
class ProductReview:
"""Analysis of a product review."""
rating: int | None # The rating of the product (1-5)
sentiment: Literal["positive", "negative"] # The sentiment of the review
key_points: list[str] # The key points of the review
agent = create_agent(
model="gpt-5.5",
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"]
# {'rating': 5, 'sentiment': 'positive', 'key_points': ['fast shipping', 'expensive']}
from typing import Literal
from typing_extensions import TypedDict
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy
class ProductReview(TypedDict):
"""Analysis of a product review."""
rating: int | None # The rating of the product (1-5)
sentiment: Literal["positive", "negative"] # The sentiment of the review
key_points: list[str] # The key points of the review
agent = create_agent(
model="gpt-5.5",
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"]
# {'rating': 5, 'sentiment': 'positive', 'key_points': ['fast shipping', 'expensive']}
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy
product_review_schema = {
"title": "ProductReview",
"type": "object",
"description": "Analysis of a product review.",
"properties": {
"rating": {
"type": ["integer", "null"],
"description": "The rating of the product (1-5)",
"minimum": 1,
"maximum": 5
},
"sentiment": {
"type": "string",
"enum": ["positive", "negative"],
"description": "The sentiment of the review"
},
"key_points": {
"type": "array",
"items": {"type": "string"},
"description": "The key points of the review"
}
},
"required": ["sentiment", "key_points"]
}
agent = create_agent(
model="gpt-5.5",
tools=[],
response_format=ToolStrategy(product_review_schema)
)
result = agent.invoke({
"messages": [{"role": "user", "content": "Analyze this review: 'Great product: 5 out of 5 stars. Fast shipping, but expensive'"}]
})
result["structured_response"]
# {'rating': 5, 'sentiment': 'positive', 'key_points': ['fast shipping', 'expensive']}
from pydantic import BaseModel, Field
from typing import Literal, Union
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.")
class CustomerComplaint(BaseModel):
"""A customer complaint about a product or service."""
issue_type: Literal["product", "service", "shipping", "billing"] = Field(description="The type of issue")
severity: Literal["low", "medium", "high"] = Field(description="The severity of the complaint")
description: str = Field(description="Brief description of the complaint")
agent = create_agent(
model="gpt-5.5",
tools=[],
response_format=ToolStrategy(Union[ProductReview, CustomerComplaint])
)
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.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'}
function toolStrategy<StructuredResponseT>(
responseFormat:
| JsonSchemaFormat
| ZodSchema<StructuredResponseT>
| SerializableSchema
| (ZodSchema<StructuredResponseT> | SerializableSchema | JsonSchemaFormat)[]
options?: ToolStrategyOptions
): ToolStrategy<StructuredResponseT>
当生成结构化输出时返回的工具消息的自定义内容。
如果未提供,则默认显示结构化响应数据。
包含可选
handleError 参数以自定义错误处理策略的选项参数。true:捕获所有错误并使用默认错误模板(默认)False:不重试,让异常传播(error: ToolStrategyError) => string | Promise<string>:使用提供的消息重试或抛出错误
import * as z from "zod";
import { createAgent, toolStrategy } from "langchain";
const ProductReview = z.object({
rating: z.number().min(1).max(5).optional(),
sentiment: z.enum(["positive", "negative"]),
keyPoints: z.array(z.string()).describe("The key points of the review. Lowercase, 1-3 words each."),
});
const agent = createAgent({
model: "gpt-5.5",
tools: [],
responseFormat: toolStrategy(ProductReview)
})
const result = await agent.invoke({
"messages": [{"role": "user", "content": "Analyze this review: 'Great product: 5 out of 5 stars. Fast shipping, but expensive'"}]
})
console.log(result.structuredResponse);
// { "rating": 5, "sentiment": "positive", "keyPoints": ["fast shipping", "expensive"] }
import * as v from "valibot";
import { toStandardJsonSchema } from "@valibot/to-json-schema";
import { createAgent, toolStrategy } from "langchain";
const ProductReview = toStandardJsonSchema(
v.object({
rating: v.optional(v.pipe(v.number(), v.minValue(1), v.maxValue(5))),
sentiment: v.picklist(["positive", "negative"]),
keyPoints: v.pipe(v.array(v.string()), v.description("The key points of the review. Lowercase, 1-3 words each.")),
})
);
const agent = createAgent({
model: "gpt-5.5",
tools: [],
responseFormat: toolStrategy(ProductReview)
})
const result = await agent.invoke({
messages: [{"role": "user", "content": "Analyze this review: 'Great product: 5 out of 5 stars. Fast shipping, but expensive'"}]
})
console.log(result.structuredResponse);
// { "rating": 5, "sentiment": "positive", "keyPoints": ["fast shipping", "expensive"] }
import { createAgent, toolStrategy } from "langchain";
const productReviewSchema = {
"type": "object",
"description": "Analysis of a product review.",
"properties": {
"rating": {
"type": ["integer", "null"],
"description": "The rating of the product (1-5)",
"minimum": 1,
"maximum": 5
},
"sentiment": {
"type": "string",
"enum": ["positive", "negative"],
"description": "The sentiment of the review"
},
"key_points": {
"type": "array",
"items": {"type": "string"},
"description": "The key points of the review"
}
},
"required": ["sentiment", "key_points"]
}
const agent = createAgent({
model: "gpt-5.5",
tools: [],
responseFormat: toolStrategy(productReviewSchema)
});
const result = await agent.invoke({
messages: [{"role": "user", "content": "Analyze this review: 'Great product: 5 out of 5 stars. Fast shipping, but expensive'"}]
})
console.log(result.structuredResponse);
// { "rating": 5, "sentiment": "positive", "keyPoints": ["fast shipping", "expensive"] }
import * as z from "zod";
import { createAgent, toolStrategy } from "langchain";
const ProductReview = z.object({
rating: z.number().min(1).max(5).optional(),
sentiment: z.enum(["positive", "negative"]),
keyPoints: z.array(z.string()).describe("The key points of the review. Lowercase, 1-3 words each."),
});
const CustomerComplaint = z.object({
issueType: z.enum(["product", "service", "shipping", "billing"]),
severity: z.enum(["low", "medium", "high"]),
description: z.string().describe("Brief description of the complaint"),
});
const agent = createAgent({
model: "gpt-5.5",
tools: [],
responseFormat: toolStrategy([ProductReview, CustomerComplaint])
});
const result = await agent.invoke({
messages: [{"role": "user", "content": "Analyze this review: 'Great product: 5 out of 5 stars. Fast shipping, but expensive'"}]
})
console.log(result.structuredResponse);
// { "rating": 5, "sentiment": "positive", "keyPoints": ["fast shipping", "expensive"] }
自定义工具消息内容
toolMessageContent 参数允许您自定义在生成结构化输出时出现在对话历史中的消息:
import * as z from "zod";
import { createAgent, toolStrategy } from "langchain";
const MeetingAction = z.object({
task: z.string().describe("The specific task to be completed"),
assignee: z.string().describe("Person responsible for the task"),
priority: z.enum(["low", "medium", "high"]).describe("Priority level"),
});
const agent = createAgent({
model: "gpt-5.5",
tools: [],
responseFormat: toolStrategy(MeetingAction, {
toolMessageContent: "Action item captured and added to meeting notes!"
})
});
const result = await agent.invoke({
messages: [{"role": "user", "content": "From our meeting: Sarah needs to update the project timeline as soon as possible"}]
});
console.log(result);
/**
* {
* messages: [
* { role: "user", content: "From our meeting: Sarah needs to update the project timeline as soon as possible" },
* { role: "assistant", content: "Action item captured and added to meeting notes!", tool_calls: [ { name: "MeetingAction", args: { task: "update the project timeline", assignee: "Sarah", priority: "high" }, id: "call_456" } ] },
* { role: "tool", content: "Action item captured and added to meeting notes!", tool_call_id: "call_456", name: "MeetingAction" }
* ],
* structuredResponse: { task: "update the project timeline", assignee: "Sarah", priority: "high" }
* }
*/
toolMessageContent,我们会看到:
# console.log(result);
/**
* {
* messages: [
* ...
* { role: "tool", content: "Returning structured response: {'task': 'update the project timeline', 'assignee': 'Sarah', 'priority': 'high'}", tool_call_id: "call_456", name: "MeetingAction" }
* ],
* structuredResponse: { task: "update the project timeline", assignee: "Sarah", priority: "high" }
* }
*/
错误处理
模型在通过工具调用生成结构化输出时可能会出错。LangChain 提供智能重试机制来自动处理这些错误。多个结构化输出错误
当模型错误地调用多个结构化输出工具时,智能体会在 @[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.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'}
import * as z from "zod";
import { createAgent, toolStrategy } from "langchain";
const ContactInfo = z.object({
name: z.string().describe("Person's name"),
email: z.string().describe("Email address"),
});
const EventDetails = z.object({
event_name: z.string().describe("Name of the event"),
date: z.string().describe("Event date"),
});
const agent = createAgent({
model: "gpt-5.5",
tools: [],
responseFormat: toolStrategy([ContactInfo, EventDetails]),
});
const result = await agent.invoke({
messages: [
{
role: "user",
content:
"Extract info: John Doe (john@email.com) is organizing Tech Conference on March 15th",
},
],
});
console.log(result);
/**
* {
* messages: [
* { role: "user", content: "Extract info: John Doe (john@email.com) is organizing Tech Conference on March 15th" },
* { role: "assistant", content: "", tool_calls: [ { name: "ContactInfo", args: { name: "John Doe", email: "john@email.com" }, id: "call_1" }, { name: "EventDetails", args: { event_name: "Tech Conference", date: "March 15th" }, id: "call_2" } ] },
* { role: "tool", content: "Error: Model incorrectly returned multiple structured responses (ContactInfo, EventDetails) when only one is expected.\n Please fix your mistakes.", tool_call_id: "call_1", name: "ContactInfo" },
* { role: "tool", content: "Error: Model incorrectly returned multiple structured responses (ContactInfo, EventDetails) when only one is expected.\n Please fix your mistakes.", tool_call_id: "call_2", name: "EventDetails" },
* { role: "assistant", content: "", tool_calls: [ { name: "ContactInfo", args: { name: "John Doe", email: "john@email.com" }, id: "call_3" } ] },
* { role: "tool", content: "Returning structured response: {'name': 'John Doe', 'email': 'john@email.com'}", tool_call_id: "call_3", name: "ContactInfo" }
* ],
* structuredResponse: { name: "John Doe", email: "john@email.com" }
* }
*/
模式验证错误
当结构化输出与预期模式不匹配时,智能体会提供具体的错误反馈: :::pythonfrom 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.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.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
)
import * as z from "zod";
import { createAgent, toolStrategy } from "langchain";
const ProductRating = z.object({
rating: z.number().min(1).max(5).describe("Rating from 1-5"),
comment: z.string().describe("Review comment"),
});
const agent = createAgent({
model: "gpt-5.5",
tools: [],
responseFormat: toolStrategy(ProductRating),
});
const result = await agent.invoke({
messages: [
{
role: "user",
content: "Parse this: Amazing product, 10/10!",
},
],
});
console.log(result);
/**
* {
* messages: [
* { role: "user", content: "Parse this: Amazing product, 10/10!" },
* { role: "assistant", content: "", tool_calls: [ { name: "ProductRating", args: { rating: 10, comment: "Amazing product" }, id: "call_1" } ] },
* { role: "tool", content: "Error: Failed to parse structured output for tool 'ProductRating': 1 validation error for ProductRating\nrating\n Input should be less than or equal to 5 [type=less_than_equal, input_value=10, input_type=int].\n Please fix your mistakes.", tool_call_id: "call_1", name: "ProductRating" },
* { role: "assistant", content: "", tool_calls: [ { name: "ProductRating", args: { rating: 5, comment: "Amazing product" }, id: "call_2" } ] },
* { role: "tool", content: "Returning structured response: {'rating': 5, 'comment': 'Amazing product'}", tool_call_id: "call_2", name: "ProductRating" }
* ],
* structuredResponse: { rating: 5, comment: "Amazing product" }
* }
*/
错误处理策略
您可以使用handleErrors 参数自定义错误处理方式:
自定义错误消息:
const responseFormat = toolStrategy(ProductRating, {
handleError: "Please provide a valid rating between 1-5 and include a comment."
)
// Error message becomes:
// { role: "tool", content: "Please provide a valid rating between 1-5 and include a comment." }
import { ToolInputParsingException } from "@langchain/core/tools";
const responseFormat = toolStrategy(ProductRating, {
handleError: (error: ToolStrategyError) => {
if (error instanceof ToolInputParsingException) {
return "Please provide a valid rating between 1-5 and include a comment.";
}
return error.message;
}
)
// Only validation errors get retried with default message:
// { role: "tool", content: "Error: Failed to parse structured output for tool 'ProductRating': ...\n Please fix your mistakes." }
const responseFormat = toolStrategy(ProductRating, {
handleError: (error: ToolStrategyError) => {
if (error instanceof ToolInputParsingException) {
return "Please provide a valid rating between 1-5 and include a comment.";
}
if (error instanceof CustomUserError) {
return "This is a custom user error.";
}
return error.message;
}
)
const responseFormat = toolStrategy(ProductRating, {
handleError: false // All errors raised
)
处理链中的解析错误
:::python 上述策略,包括handle_errors 重试,适用于使用 @[create_agent] 创建的智能体。使用管道操作符(例如,prompt | model | parser)组成的链没有内置的输出解析失败重试机制。要在链中处理格式错误的模型输出,请使用以下方法之一:
- 模型级别的结构化输出:使用 @[
with_structured_output][BaseChatModel.with_structured_output] 将模式绑定到模型。当提供者支持原生结构化输出时,它会强制执行模式并避免大多数解析失败。参见 模型 - 结构化输出。当模型支持时使用此方法。 - 使用模型修复格式错误的输出:将输出解析器包装在来自
langchain-classic的OutputFixingParser中。在解析失败时,包装器将格式错误的输出、解析器的格式指令和错误消息发送给模型,并解析修正后的响应。
OutputFixingParser 需要 langchain-classic 包。在 v1 之前,它作为 langchain.output_parsers.OutputFixingParser 提供。from langchain.chat_models import init_chat_model
from langchain_classic.output_parsers import OutputFixingParser
from langchain_core.output_parsers import PydanticOutputParser
from langchain_core.prompts import ChatPromptTemplate
from pydantic import BaseModel, Field
class ProductReview(BaseModel):
"""Analysis of a product review."""
rating: int = Field(description="The rating of the product (1-5)", ge=1, le=5)
sentiment: str = Field(description="The sentiment of the review")
model = init_chat_model("gpt-5.4")
base_parser = PydanticOutputParser(pydantic_object=ProductReview)
fixing_parser = OutputFixingParser.from_llm(
parser=base_parser,
llm=model,
max_retries=3,
)
prompt = ChatPromptTemplate.from_messages([
("system", "Analyze the product review.\n{format_instructions}"),
("user", "{review}"),
]).partial(format_instructions=base_parser.get_format_instructions())
chain = prompt | model | fixing_parser
result = chain.invoke({"review": "Great product, 5 stars! Fast shipping, but expensive."})
# ProductReview(rating=5, sentiment='positive')
max_retries 控制在抛出原始 OutputParserException 之前进行的修复尝试次数。同步(invoke)和异步(ainvoke)执行都受支持。
OutputFixingParser 发送格式错误的完成内容、解析器的格式指令和错误。它不包括原始提示词。如果修正输出需要原始提示词作为上下文,请使用 RetryOutputParser 从 langchain-classic。它通过其 parse_with_prompt(completion, prompt_value) 方法调用,而不是 parse,因此不能作为链的最终步骤直接管道化。
:::
:::js
上述策略,包括 handleError 重试,适用于使用 createAgent 创建的智能体。使用 .pipe()(例如,prompt.pipe(model).pipe(parser))组成的链没有内置的输出解析失败重试机制。要在链中处理格式错误的模型输出,请使用以下方法之一:
- 模型级别的结构化输出:使用 @[
withStructuredOutput][BaseChatModel.with_structured_output] 将模式绑定到模型。当提供者支持原生结构化输出时,它会强制执行模式并避免大多数解析失败。参见 模型 - 结构化输出。当模型支持时使用此方法。 - 使用模型修复格式错误的输出:将输出解析器包装在来自
@langchain/classic的OutputFixingParser中。在解析失败时,包装器将格式错误的输出、解析器的格式指令和错误消息发送给模型,并解析修正后的响应。
OutputFixingParser 需要 @langchain/classic 包。在 v1 之前,它从 langchain/output_parsers 提供。import { OutputFixingParser } from "@langchain/classic/output_parsers";
import { StructuredOutputParser } from "@langchain/core/output_parsers";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { initChatModel } from "langchain";
import * as z from "zod";
const ProductReview = z.object({
rating: z.number().min(1).max(5).describe("The rating of the product (1-5)"),
sentiment: z.enum(["positive", "negative"]).describe("The sentiment of the review"),
});
const model = await initChatModel("gpt-5.4");
const baseParser = StructuredOutputParser.fromZodSchema(ProductReview);
const fixingParser = OutputFixingParser.fromLLM(model, baseParser);
const prompt = ChatPromptTemplate.fromMessages([
["system", "Analyze the product review.\n{format_instructions}"],
["user", "{review}"],
]);
const chain = prompt.pipe(model).pipe(fixingParser);
const result = await chain.invoke({
review: "Great product, 5 stars! Fast shipping, but expensive.",
format_instructions: baseParser.getFormatInstructions(),
});
// { rating: 5, sentiment: "positive" }
OutputFixingParser 仅重试作为 OutputParserException 抛出的错误。抛出原始错误的解析器不会被重试:例如,JsonOutputParser 在无效 JSON 上抛出普通的 SyntaxError,该错误会未捕获地传播。包装一个抛出 OutputParserException 的解析器,例如 StructuredOutputParser。官方原文:src/oss/langchain/structured-output.mdx · 非官方翻译,译文由 AI 生成,以英文原文为准。