Get structured output from agents 获取来自智能体的结构化输出
Return validated JSON from agent workflows using JSON Schema, Zod, or Pydantic. Get type-safe, structured data after multi-turn tool use.
通过 JSON Schema、Zod 或 Pydantic,从智能体工作流中返回经过验证的 JSON。在多轮工具调用后,获取类型安全的结构化数据。
Structured outputs let you define the exact shape of data you want back from an agent. The agent can use any tools it needs to complete the task, and you still get validated JSON matching your schema at the end. Define a JSON Schema for the structure you need, and the SDK validates the output against it, re-prompting on mismatch. If validation does not succeed within the retry limit, the result is an error instead of structured data; see Error handling.
结构化输出允许您精确定义希望从智能体返回的数据结构。智能体可以使用完成任务所需的任何工具,而您最终仍能获得符合预设模式(Schema)的、经过验证的 JSON。您只需为您需要的结构定义一个 JSON Schema,SDK 就会根据该模式验证输出;如果输出不匹配,SDK 会重新向智能体发起提示。如果在重试次数限制内未能校验成功,结果将返回错误而非结构化数据;详见错误处理。
For full type safety, use Zod (TypeScript) or Pydantic (Python) to define your schema and get strongly-typed objects back.
为了实现完全的类型安全性,您可以使用 Zod (TypeScript) 或 Pydantic (Python) 来定义您的模式,并获取强类型的对象。
Why structured outputs? 为什么需要结构化输出?
Agents return free-form text by default, which works for chat but not when you need to use the output programmatically. Structured outputs give you typed data you can pass directly to your application logic, database, or UI components.
智能体默认返回的是自由格式的文本,这适用于聊天场景,但当您需要以编程方式处理输出时则不适用。结构化输出为您提供类型化的数据,您可以将其直接传递给应用程序逻辑、数据库或 UI 组件。
Consider a recipe app where an agent searches the web and brings back recipes. Without structured outputs, you get free-form text that you'd need to parse yourself. With structured outputs, you define the shape you want and get typed data you can use directly in your app.
以一个食谱应用为例,其中智能体会搜索网页并带回食谱。如果没有结构化输出,您得到的是需要自行解析的自由文本。有了结构化输出,您只需定义所需的结构,即可获得能直接在应用中使用的类型化数据。
- Without structured outputs(不使用结构化输出)
Here's a classic chocolate chip cookie recipe!
**Chocolate Chip Cookies**
Prep time: 15 minutes | Cook time: 10 minutes
Ingredients:
- 2 1/4 cups all-purpose flour
- 1 cup butter, softened
...
To use this in your app, you'd need to parse out the title, convert "15 minutes" to a number, separate ingredients from instructions, and handle inconsistent formatting across responses.
要在您的应用中使用它,您需要解析出标题,转换“15 分钟”...
- With structured outputs(使用结构化输出)
{
"name": "Chocolate Chip Cookies",
"prep_time_minutes": 15,
"cook_time_minutes": 10,
"ingredients": [
{ "item": "all-purpose flour", "amount": 2.25, "unit": "cups" },
{ "item": "butter, softened", "amount": 1, "unit": "cup" }
// ...
],
"steps": ["Preheat oven to 375°F", "Cream butter and sugar" /* ... */]
}
Typed data you can use directly in your UI.
您可以直接在 UI 中使用的类型化数据。
Quick start 快速上手
To use structured outputs, define a JSON Schema describing the shape of data you want, then pass it to query() via the outputFormat option (TypeScript) or output_format option (Python). When the agent finishes, the result message includes a structured_output field with validated data matching your schema.
要使用结构化输出,请定义一个描述所需数据结构的 JSON Schema,然后通过 outputFormat 选项(TypeScript)或 output_format 选项(Python)将其传递给 query()。当智能体完成任务后,结果消息将包含一个 structured_output 字段,其中包含符合您模式的、经过验证的数据。
The example below asks the agent to research Anthropic and return the company name, year founded, and headquarters as structured output.
下方的示例要求智能体研究 Anthropic 公司,并以结构化输出的形式返回公司名称、成立年份和总部地点。
import { query } from "@anthropic-ai/claude-agent-sdk";
// Define the shape of data you want back
const schema = {
type: "object",
properties: {
company_name: { type: "string" },
founded_year: { type: "number" },
headquarters: { type: "string" }
},
required: ["company_name"]
};
for await (const message of query({
prompt: "Research Anthropic and provide key company information",
options: {
outputFormat: {
type: "json_schema",
schema: schema
}
}
})) {
// The result message contains structured_output with validated data
if (message.type === "result" && message.subtype === "success" && message.structured_output) {
console.log(message.structured_output);
// { company_name: "Anthropic", founded_year: 2021, headquarters: "San Francisco, CA" }
}
}
Type-safe schemas with Zod and Pydantic 使用 Zod 和 Pydantic 实现类型安全模式
Instead of writing JSON Schema by hand, you can use Zod (TypeScript) or Pydantic (Python) to define your schema. These libraries generate the JSON Schema for you and let you parse the response into a fully-typed object you can use throughout your codebase with autocomplete and type checking.
与其手动编写 JSON Schema,不如使用 Zod (TypeScript) 或 Pydantic (Python) 来定义您的模式。这些库会自动为您生成 JSON Schema,并允许您将响应解析为完全类型化的对象,从而在整个代码库中利用自动补全和类型检查功能。
The example below defines a schema for a feature implementation plan with a summary, list of steps (each with complexity level), and potential risks. The agent plans the feature and returns a typed FeaturePlan object. You can then access properties like plan.summary and iterate over plan.steps with full type safety.
下方的示例为一个功能实现计划定义了模式,包含摘要(summary)、步骤列表(steps,每个步骤包含复杂度等级)以及潜在风险(potential risks)。智能体会规划该功能并返回一个类型化的 FeaturePlan 对象。随后,您可以访问 plan.summary 等属性,并以完全的类型安全性遍历 plan.steps。
import { z } from "zod";
import { query } from "@anthropic-ai/claude-agent-sdk";
// Define schema with Zod
const FeaturePlan = z.object({
feature_name: z.string(),
summary: z.string(),
steps: z.array(
z.object({
step_number: z.number(),
description: z.string(),
estimated_complexity: z.enum(["low", "medium", "high"])
})
),
risks: z.array(z.string())
});
type FeaturePlan = z.infer<typeof FeaturePlan>;
// Convert to JSON Schema
const schema = z.toJSONSchema(FeaturePlan);
// Use in query
for await (const message of query({
prompt:
"Plan how to add dark mode support to a React app. Break it into implementation steps.",
options: {
outputFormat: {
type: "json_schema",
schema: schema
}
}
})) {
if (message.type === "result" && message.subtype === "success" && message.structured_output) {
// Validate and get fully typed result
const parsed = FeaturePlan.safeParse(message.structured_output);
if (parsed.success) {
const plan: FeaturePlan = parsed.data;
console.log(`Feature: ${plan.feature_name}`);
console.log(`Summary: ${plan.summary}`);
plan.steps.forEach((step) => {
console.log(`${step.step_number}. [${step.estimated_complexity}] ${step.description}`);
});
}
}
}
Benefits(优势):
- Full type inference (TypeScript) and type hints (Python)
- 全面的类型推断(TypeScript)和类型提示(Python)
- Runtime validation with
safeParse()ormodel_validate() - 使用
safeParse()或model_validate()进行运行时校验 - Better error messages
- 更好的错误信息
- Composable, reusable schemas
- 可组合、可重用的模式(Schemas)
Output format configuration 输出格式配置
The outputFormat (TypeScript) or output_format (Python) option accepts an object with:
outputFormat(TypeScript)或 output_format(Python)选项接受一个包含以下属性的对象:
type: Set to"json_schema"for structured outputstype:对于结构化输出,请设置为"json_schema"。schema: A JSON Schema object defining your output structure. You can generate this from a Zod schema withz.toJSONSchema()or a Pydantic model with.model_json_schema()schema:一个定 义输出结构的 JSON Schema 对象。您可以使用z.toJSONSchema()从 Zod 模式生成,或使用.model_json_schema()从 Pydantic 模型生成。
The SDK supports standard JSON Schema features including all basic types (object, array, string, number, boolean, null), enum, const, required, nested objects, and $ref definitions. For the full list of supported features and limitations, see JSON Schema limitations.
该 SDK 支持标准的 JSON Schema 特性,包括所有基本类型(对象、数组、字符串、数字、布尔值、空值)、enum、const、required、嵌套对象以及 $ref 定义。有关受支持功能和限制的完整列表,请参阅 JSON Schema 限制。
Example: TODO tracking agent (示例:TODO 追踪智能体)
This example demonstrates how structured outputs work with multi-step tool use. The agent needs to find TODO comments in the codebase, then look up git blame information for each one. It autonomously decides which tools to use (Grep to search, Bash to run git commands) and combines the results into a single structured response.
本示例演示了结构化输出如何与多步工具调用协同工作。智能体需要查找代码库中的 TODO 注释,然后查询每一条注释的 git blame 信息。它会自主决定使用哪些工具(使用 Grep 进行搜索,使用 Bash 运行 git 命令),并将结果整合到单个结构化响应中。
The schema includes optional fields (author and date) since git blame information might not be available for all files. The agent fills in what it can find and omits the rest.
由于并非所有文件都能获取 git blame 信息,因此模式中包含了可选字段(author 和 date)。智能体会填入它能找到的信息,并忽略其余部分。
import { query } from "@anthropic-ai/claude-agent-sdk";
// Define structure for TODO extraction
const todoSchema = {
type: "object",
properties: {
todos: {
type: "array",
items: {
type: "object",
properties: {
text: { type: "string" },
file: { type: "string" },
line: { type: "number" },
author: { type: "string" },
date: { type: "string" }
},
required: ["text", "file", "line"]
}
},
total_count: { type: "number" }
},
required: ["todos", "total_count"]
};
// Agent uses Grep to find TODOs, Bash to get git blame info
for await (const message of query({
prompt: "Find all TODO comments in this codebase and identify who added them",
options: {
outputFormat: {
type: "json_schema",
schema: todoSchema
}
}
})) {
if (message.type === "result" && message.subtype === "success" && message.structured_output) {
const data = message.structured_output as { total_count: number; todos: Array<{ file: string; line: number; text: string; author?: string; date?: string }> };
console.log(`Found ${data.total_count} TODOs`);
data.todos.forEach((todo) => {
console.log(`${todo.file}:${todo.line} - ${todo.text}`);
if (todo.author) {
console.log(` Added by ${todo.author} on ${todo.date}`);
}
});
}
}
Error handling 错误处理
Structured output generation can fail when the agent cannot produce valid JSON matching your schema. This typically happens when the schema is too complex for the task, the task itself is ambiguous, or the agent hits its retry limit trying to fix validation errors.
当智能体无法生成符合您模式(Schema)的有效 JSON 时,结构化输出的生成可能会失败。这通常发生在模式对于任务而言过于复杂、任务本身存在歧义,或者智能体在尝试修复校验错误时达到了重试次数限制。
When an error occurs, the result message has a subtype indicating what went wrong:
当错误发生时,结果消息中会包含一个 subtype 字段,用以指示出错原因:
| Subtype | Meaning (含义) |
|---|---|
success | Output was generated and validated successfully 输出已成功生成并通过校验 |
error_max_structured_output_retries | Agent couldn't produce valid output after multiple attempts 经过多次尝试后,智能体仍无法生成有效的输出 |
The example below checks the subtype field to determine whether the output was generated successfully or if you need to handle a failure:
下方的示例演示了如何通过检查 subtype 字段,来确定输出是成功生成了,还是需要处理失败情况:
for await (const msg of query({
prompt: "Extract contact info from the document",
options: {
outputFormat: {
type: "json_schema",
schema: contactSchema
}
}
})) {
if (msg.type === "result") {
if (msg.subtype === "success" && msg.structured_output) {
// Use the validated output
console.log(msg.structured_output);
} else if (msg.subtype === "error_max_structured_output_retries") {
// Handle the failure - retry with simpler prompt, fall back to unstructured, etc.
console.error("Could not produce valid output");
}
}
}
Tips for avoiding errors(避免错误的建议):
- Keep schemas focused. Deeply nested schemas with many required fields are harder to satisfy. Start simple and add complexity as needed.
- 保持模式精简(Keep schemas focused)。 包含大量必填字段的深层嵌套模式较难满足。建议从简单开始,根据需要逐步增加复杂度。
- Match schema to task. If the task might not have all the information your schema requires, make those fields optional.
- 确保模式与任务匹配。 如果任务可能无法提供模式要求的所有信息,请将这些字段设为可选。
- Use clear prompts. Ambiguous prompts make it harder for the agent to know what output to produce.
- 使用清晰的提示词。 模糊的提示词会增加智能体确定输出内容的难度。