구조화된 출력을 사용하면 에이전트에서 돌려받고 싶은 데이터의 정확한 형태를 정의할 수 있습니다. 에이전트는 작업을 완료하는 데 필요한 모든 도구를 사용할 수 있으며, 최종적으로 스키마와 일치하는 검증된 JSON을 받을 수 있습니다. 필요한 구조에 대한 JSON Schema를 정의하면 SDK가 출력이 이와 일치하도록 보장합니다.
완전한 타입 안전성을 위해 Zod(TypeScript) 또는 Pydantic(Python)을 사용하여 스키마를 정의하고 강력한 타입의 객체를 돌려받으세요.
에이전트는 기본적으로 자유 형식 텍스트를 반환하는데, 이는 채팅에는 적합하지만 출력을 프로그래밍적으로 사용해야 할 때는 적합하지 않습니다. 구조화된 출력은 애플리케이션 로직, 데이터베이스 또는 UI 컴포넌트에 직접 전달할 수 있는 타입이 지정된 데이터를 제공합니다.
에이전트가 웹을 검색하여 레시피를 가져오는 레시피 앱을 생각해 보세요. 구조화된 출력 없이는 직접 파싱해야 하는 자유 형식 텍스트를 받게 됩니다. 구조화된 출력을 사용하면 원하는 형태를 정의하고 앱에서 직접 사용할 수 있는 타입이 지정된 데이터를 받을 수 있습니다.
구조화된 출력을 사용하려면 원하는 데이터의 형태를 설명하는 JSON Schema를 정의한 다음, outputFormat 옵션(TypeScript) 또는 output_format 옵션(Python)을 통해 query()에 전달합니다. 에이전트가 완료되면 결과 메시지에 스키마와 일치하는 검증된 데이터가 포함된 structured_output 필드가 포함됩니다.
아래 예제는 에이전트에게 Anthropic을 조사하고 회사 이름, 설립 연도, 본사를 구조화된 출력으로 반환하도록 요청합니다.
import { query } from '@anthropic-ai/claude-agent-sdk'
// 돌려받고 싶은 데이터의 형태를 정의
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
}
}
})) {
// 결과 메시지에는 검증된 데이터가 포함된 structured_output이 있습니다
if (message.type === 'result' && message.structured_output) {
console.log(message.structured_output)
// { company_name: "Anthropic", founded_year: 2021, headquarters: "San Francisco, CA" }
}
}JSON Schema를 직접 작성하는 대신 Zod(TypeScript) 또는 Pydantic(Python)을 사용하여 스키마를 정의할 수 있습니다. 이러한 라이브러리는 JSON Schema를 자동으로 생성하고, 자동 완성과 타입 검사를 통해 코드베이스 전체에서 사용할 수 있는 완전한 타입의 객체로 응답을 파싱할 수 있게 해줍니다.
아래 예제는 요약, 단계 목록(각각 복잡도 수준 포함), 잠재적 위험이 포함된 기능 구현 계획의 스키마를 정의합니다. 에이전트가 기능을 계획하고 타입이 지정된 FeaturePlan 객체를 반환합니다. 그런 다음 plan.summary와 같은 속성에 접근하고 완전한 타입 안전성으로 plan.steps를 반복할 수 있습니다.
import { z } from 'zod'
import { query } from '@anthropic-ai/claude-agent-sdk'
// 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>
// JSON Schema로 변환
const schema = z.toJSONSchema(FeaturePlan)
// 쿼리에서 사용
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.structured_output) {
// 검증하고 완전한 타입의 결과를 얻기
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}`)
})
}
}
}장점:
safeParse() 또는 model_validate()를 사용한 런타임 검증outputFormat(TypeScript) 또는 output_format(Python) 옵션은 다음을 포함하는 객체를 받습니다:
type: 구조화된 출력을 위해 "json_schema"로 설정schema: 출력 구조를 정의하는 JSON Schema 객체. Zod 스키마에서 z.toJSONSchema()로 또는 Pydantic 모델에서 .model_json_schema()로 생성할 수 있습니다SDK는 모든 기본 타입(object, array, string, number, boolean, null), enum, const, required, 중첩 객체, $ref 정의를 포함한 표준 JSON Schema 기능을 지원합니다. 지원되는 기능과 제한 사항의 전체 목록은 JSON Schema 제한 사항을 참조하세요.
이 예제는 구조화된 출력이 다단계 도구 사용과 어떻게 작동하는지 보여줍니다. 에이전트는 코드베이스에서 TODO 주석을 찾은 다음 각각에 대한 git blame 정보를 조회해야 합니다. 에이전트는 어떤 도구를 사용할지 자율적으로 결정하고(검색을 위한 Grep, git 명령 실행을 위한 Bash) 결과를 단일 구조화된 응답으로 결합합니다.
스키마에는 선택적 필드(author와 date)가 포함되어 있는데, 이는 모든 파일에 대해 git blame 정보를 사용할 수 없을 수 있기 때문입니다. 에이전트는 찾을 수 있는 정보를 채우고 나머지는 생략합니다.
import { query } from '@anthropic-ai/claude-agent-sdk'
// TODO 추출을 위한 구조 정의
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']
}
// 에이전트가 Grep으로 TODO를 찾고, Bash로 git blame 정보를 가져옵니다
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.structured_output) {
const data = message.structured_output
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}`)
}
})
}
}에이전트가 스키마와 일치하는 유효한 JSON을 생성할 수 없을 때 구조화된 출력 생성이 실패할 수 있습니다. 이는 일반적으로 스키마가 작업에 비해 너무 복잡하거나, 작업 자체가 모호하거나, 에이전트가 검증 오류를 수정하려는 재시도 한도에 도달했을 때 발생합니다.
오류가 발생하면 결과 메시지에 무엇이 잘못되었는지 나타내는 subtype이 있습니다:
| Subtype | 의미 |
|---|---|
success | 출력이 성공적으로 생성되고 검증됨 |
error_max_structured_output_retries | 에이전트가 여러 번 시도한 후에도 유효한 출력을 생성하지 못함 |
아래 예제는 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) {
// 검증된 출력 사용
console.log(msg.structured_output)
} else if (msg.subtype === 'error_max_structured_output_retries') {
// 실패 처리 - 더 간단한 프롬프트로 재시도, 비구조화된 출력으로 대체 등
console.error('Could not produce valid output')
}
}
}오류를 피하기 위한 팁:
Was this page helpful?