구조화된 출력은 Claude의 응답을 특정 스키마를 따르도록 제한하여 다운스트림 처리를 위한 유효하고 파싱 가능한 출력을 보장합니다. 구조화된 데이터 응답을 위해 JSON 출력(output_format)을 사용하거나, 도구 이름 및 입력에 대한 보장된 스키마 검증을 위해 엄격한 도구 사용(strict: true)을 사용하세요.
구조화된 출력은 현재 Claude Sonnet 4.5 및 Claude Opus 4.1을 위한 Claude API의 공개 베타 기능으로 제공됩니다.
이 기능을 사용하려면 베타 헤더 structured-outputs-2025-11-13을 설정하세요.
이 양식을 사용하여 피드백을 공유하세요.
구조화된 출력이 없으면 Claude는 잘못된 형식의 JSON 응답이나 애플리케이션을 손상시키는 유효하지 않은 도구 입력을 생성할 수 있습니다. 신중한 프롬프팅을 사용하더라도 다음과 같은 문제가 발생할 수 있습니다:
구조화된 출력은 제한된 디코딩을 통해 스키마 준수 응답을 보장합니다:
JSON.parse() 오류 없음사용 사례에 맞는 모드를 선택하세요:
| JSON 출력을 사용할 때 | 엄격한 도구 사용을 사용할 때 |
|---|---|
| Claude의 응답이 특정 형식이어야 할 때 | 도구 호출을 위해 검증된 매개변수 및 도구 이름이 필요할 때 |
| 이미지 또는 텍스트에서 데이터 추출 | 에이전트 워크플로우 구축 |
| 구조화된 보고서 생성 | 타입 안전 함수 호출 보장 |
| API 응답 형식 지정 | 많은 및/또는 중첩된 속성이 있는 복잡한 도구 |
신뢰할 수 있는 에이전트 시스템을 구축하려면 보장된 스키마 준수가 필요합니다. 유효하지 않은 도구 매개변수는 함수 및 워크플로우를 손상시킵니다. Claude는 호환되지 않는 타입("2" 대신 2)이나 누락된 필드를 반환하여 런타임 오류를 유발할 수 있습니다.
엄격한 도구 사용은 타입 안전 매개변수를 보장합니다:
예를 들어, 예약 시스템이 passengers: int를 필요로 한다고 가정합니다. 엄격한 모드가 없으면 Claude는 passengers: "two" 또는 passengers: "2"를 제공할 수 있습니다. strict: true를 사용하면 passengers: 2가 보장됩니다.
Python 및 TypeScript SDK는 스키마 변환, 자동 검증, 인기 있는 스키마 라이브러리와의 통합을 포함하여 JSON 출력 작업을 더 쉽게 만드는 헬퍼를 제공합니다.
Python 및 TypeScript 개발자의 경우 원시 JSON 스키마를 작성하는 대신 Pydantic 및 Zod와 같은 친숙한 스키마 정의 도구를 사용할 수 있습니다.
JSON 출력만
SDK 헬퍼(Pydantic, Zod, parse())는 JSON 출력(output_format)에서만 작동합니다.
이러한 헬퍼는 Claude의 출력을 변환하고 검증합니다. 엄격한 도구 사용은 도구에 대한 Claude의 입력을 검증하며, 이는 도구 정의의 기존 input_schema 필드를 사용합니다.
엄격한 도구 사용의 경우 도구 정의에서 strict: true를 사용하여 input_schema을 직접 정의하세요.
Python: client.beta.messages.parse() (권장)
parse() 메서드는 자동으로 Pydantic 모델을 변환하고, 응답을 검증하며, parsed_output 속성을 반환합니다.
parse() 메서드는 client.messages가 아닌 client.beta.messages에서 사용 가능합니다.
Python: transform_schema() 헬퍼
스키마를 보내기 전에 수동으로 변환해야 할 때 또는 Pydantic 생성 스키마를 수정하려고 할 때 사용합니다. client.beta.messages.parse()와 달리 제공된 스키마를 자동으로 변환하는 경우, 이는 변환된 스키마를 제공하므로 추가로 사용자 정의할 수 있습니다.
Python 및 TypeScript SDK는 자동으로 지원되지 않는 기능이 있는 스키마를 변환합니다:
minimum, maximum, minLength, maxLength)additionalProperties: false 추가이는 Claude가 단순화된 스키마를 받지만 코드가 검증을 통해 모든 제약 조건을 계속 적용함을 의미합니다.
예시: minimum: 100이 있는 Pydantic 필드는 전송된 스키마에서 일반 정수가 되지만, 설명이 "최소 100이어야 함"으로 업데이트되고, SDK는 원본 제약 조건에 대해 응답을 검증합니다.
구조화된 출력은 컴파일된 문법 아티팩트를 사용한 제한된 샘플링을 사용합니다. 이는 인식해야 할 몇 가지 성능 특성을 도입합니다:
name 또는 description 필드만 변경하면 캐시가 무효화되지 않습니다구조화된 출력을 사용할 때 Claude는 자동으로 예상 출력 형식을 설명하는 추가 시스템 프롬프트를 받습니다. 이는 다음을 의미합니다:
output_format 매개변수를 변경하면 해당 대화 스레드에 대한 프롬프트 캐시가 무효화됩니다구조화된 출력은 표준 JSON Schema를 지원하지만 일부 제한 사항이 있습니다. JSON 출력과 엄격한 도구 사용 모두 이러한 제한 사항을 공유합니다.
Python 및 TypeScript SDK는 지원되지 않는 기능이 있는 스키마를 자동으로 변환하여 제거하고 필드 설명에 제약 조건을 추가할 수 있습니다. 자세한 내용은 SDK 특정 메서드를 참조하세요.
구조화된 출력이 대부분의 경우 스키마 준수를 보장하지만, 출력이 스키마와 일치하지 않을 수 있는 시나리오가 있습니다:
거부 (stop_reason: "refusal")
Claude는 구조화된 출력을 사용할 때도 안전성 및 도움이 되는 속성을 유지합니다. Claude가 안전상의 이유로 요청을 거부하는 경우:
stop_reason: "refusal"이 있습니다토큰 제한 도달 (stop_reason: "max_tokens")
max_tokens 제한에 도달하여 응답이 잘린 경우:
stop_reason: "max_tokens"이 있습니다max_tokens 값으로 재시도하세요스키마가 지원되지 않는 기능을 사용하거나 너무 복잡한 경우 400 오류가 발생합니다:
"스키마에 너무 많은 재귀 정의"
"스키마가 너무 복잡함"
strict: true로 표시된 도구 수를 줄이세요유효한 스키마의 지속적인 문제의 경우 스키마 정의와 함께 지원팀에 문의하세요.
작동하는 기능:
output_format)과 엄격한 도구 사용(strict: true)을 함께 사용호환되지 않는 기능:
output_format이 활성화된 경우 400 오류를 반환합니다.문법 범위: 문법은 Claude의 직접 출력에만 적용되며, 도구 사용 호출, 도구 결과 또는 생각 태그(확장 사고 사용 시)에는 적용되지 않습니다. 문법 상태는 섹션 간에 재설정되어 Claude가 자유롭게 생각하면서도 최종 응답에서 구조화된 출력을 생성할 수 있습니다.
from pydantic import BaseModel
from anthropic import Anthropic, transform_schema
class ContactInfo(BaseModel):
name: str
email: str
plan_interest: str
demo_requested: bool
client = Anthropic()
# With .create() - requires transform_schema()
response = client.beta.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
betas=["structured-outputs-2025-11-13"],
messages=[
{
"role": "user",
"content": "Extract the key information from this email: John Smith ([email protected]) is interested in our Enterprise plan and wants to schedule a demo for next Tuesday at 2pm."
}
],
output_format={
"type": "json_schema",
"schema": transform_schema(ContactInfo),
}
)
print(response.content[0].text)
# With .parse() - can pass Pydantic model directly
response = client.beta.messages.parse(
model="claude-sonnet-4-5",
max_tokens=1024,
betas=["structured-outputs-2025-11-13"],
messages=[
{
"role": "user",
"content": "Extract the key information from this email: John Smith ([email protected]) is interested in our Enterprise plan and wants to schedule a demo for next Tuesday at 2pm."
}
],
output_format=ContactInfo,
)
print(response.parsed_output)