结构化输出允许代理以特定的、可预测的格式返回数据。您无需解析自然语言响应,而是获取类型化的结构化数据。
LangChain 预构建的 ReAct 代理 createAgent 自动处理结构化输出。用户设置他们期望的结构化输出模式,当模型生成结构化数据时,它会被捕获、验证并返回到代理状态的 structuredResponse 键中。
type ResponseFormat = (
| ZodSchema < StructuredResponseT > // a Zod schema
| 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 键中返回。
提供商策略
一些模型提供商通过其 API 原生支持结构化输出(目前仅 OpenAI 和 Grok)。当可用时,这是最可靠的方法。
要使用此策略,请配置一个 ProviderStrategy:
function providerStrategy < StructuredResponseT >(
schema : ZodSchema < StructuredResponseT > | JsonSchemaFormat
) : ProviderStrategy < StructuredResponseT >
定义结构化输出格式的模式。支持:
Zod 模式 :一个 zod 模式
JSON 模式 :一个 JSON 模式对象
当您将模式类型直接传递给 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: "openai:gpt-5" ,
tools: tools ,
responseFormat: providerStrategy ( ContactInfo )
});
const result = await agent . invoke ({
messages: [{ "role" : "user" , "content" : "Extract contact info from: John Doe, [email protected] , (555) 123-4567" }]
});
result . structuredResponse ;
// { name: "John Doe", email: "[email protected] ", phone: "(555) 123-4567" }
提供商原生的结构化输出提供了高可靠性和严格的验证,因为模型提供商会强制执行模式。在可用时请使用它。
如果提供商对您选择的模型原生支持结构化输出,那么编写 responseFormat: contactInfoSchema 与编写 responseFormat: toolStrategy(contactInfoSchema) 在功能上是等效的。在任何一种情况下,如果不支持结构化输出,代理将回退到工具调用策略。
工具调用策略
对于不支持原生结构化输出的模型,LangChain 使用工具调用来实现相同的结果。这适用于所有支持工具调用的模型,也就是大多数现代模型。
要使用此策略,请配置一个 ToolStrategy:
function toolStrategy < StructuredResponseT >(
responseFormat :
| JsonSchemaFormat
| ZodSchema < StructuredResponseT >
| ( ZodSchema < StructuredResponseT > | JsonSchemaFormat )[]
options ?: ToolStrategyOptions
) : ToolStrategy < StructuredResponseT >
定义结构化输出格式的模式。支持:
Zod 模式 :一个 zod 模式
JSON 模式 :一个 JSON 模式对象
options.toolMessageContent
生成结构化输出时返回的工具消息的自定义内容。
如果未提供,则默认为显示结构化响应数据的消息。
包含可选 handleError 参数的选项参数,用于自定义错误处理策略。
true :使用默认错误模板捕获所有错误(默认)
False :不重试,让异常传播
(error: ToolStrategyError) => string | Promise<string> :使用提供的消息重试或抛出错误
Zod Schema
JSON Schema
Union Types
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: "openai:gpt-5" ,
tools: tools ,
responseFormat: toolStrategy ( ProductReview )
})
result = 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: "openai:gpt-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] 中提供错误反馈,并提示模型重试:
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: "openai:gpt-5" ,
tools: [],
responseFormat: toolStrategy ([ ContactInfo , EventDetails ]),
});
const result = await agent . invoke ({
messages: [
{
role: "user" ,
content:
"Extract info: John Doe ([email protected] ) is organizing Tech Conference on March 15th" ,
},
],
});
console . log ( result );
/**
* {
* messages: [
* { role: "user", content: "Extract info: John Doe ([email protected] ) is organizing Tech Conference on March 15th" },
* { role: "assistant", content: "", tool_calls: [ { name: "ContactInfo", args: { name: "John Doe", email: "[email protected] " }, 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: "[email protected] " }, id: "call_3" } ] },
* { role: "tool", content: "Returning structured response: {'name': 'John Doe', 'email': '[email protected] '}", tool_call_id: "call_3", name: "ContactInfo" }
* ],
* structuredResponse: { name: "John Doe", email: "[email protected] " }
* }
*/
模式验证错误
当结构化输出与预期模式不匹配时,代理会提供具体的错误反馈:
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: "openai:gpt-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."
)
// 错误消息变为:
// { 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 ;
}
)
// 只有验证错误会使用默认消息重试:
// { 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
)