구조화된 출력
- JSON을 프롬프트하고 바라는 것보다 스키마 강제 출력이 왜 나은지 설명하기
- JSON Schema를 제공하고 응답을 타입 객체(Pydantic / Zod)로 파싱하기
- 구조화된 출력을 도구 사용과 메커니즘이 아닌 의도로 구분하기
- 탄탄하고 신뢰할 수 있는 스키마를 위한 네 가지 팁 적용하기
- 한 가지 질문 경험칙으로 알맞은 도구 고르기
Claude의 출력이 다른 소프트웨어에 공급될 때는 신뢰할 수 있는 구조 — 매번 알려진 형태를 따르는 유효한 JSON — 가 필요합니다. "JSON으로 응답해"에 의존하고 바라지 마세요; 플랫폼의 구조화된 출력 지원을 사용하세요.
이 레슨은 프롬프트하고 기도하기가 왜 실패하는지에서 스키마를 강제하고 타입 객체로 파싱하는 법까지 안내하며 — 둘이 똑같아 보일 때 구조화된 출력을 도구 사용과 구별하는 법도 다룹니다. 위에서 아래로 진행한 뒤, 끝부분의 퀴즈로 스스로를 테스트하세요.
신뢰할 수 있는 방법
출력에 대한 JSON Schema를 제공하고 API/SDK가 그것을 강제하게 한 뒤, 타입 객체(예: Python의 Pydantic, TypeScript의 Zod)로 파싱하세요. SDK 파싱 헬퍼는 여러분이 직접 JSON.parse하고 검증해야 하는 문자열 대신 타입이 지정된 결과를 건네줍니다.
- 필요한 출력을 JSON Schema로 모델링하세요 — Python에서는 Pydantic BaseModel로, TypeScript에서는 Zod 스키마로.
- 모델에게 그 스키마를 따르는 데이터를 반환하도록 요청하여, 운에 맡기는 대신 API/SDK가 그것을 강제하게 하세요.
- SDK 파싱 헬퍼로 타입이 지정된 결과를 직접 얻으세요 — 수동 JSON.parse에 손수 만든 검증을 더할 필요 없이.
# Conceptual shape — see the official docs for the current API surface.
from pydantic import BaseModel
class Ticket(BaseModel):
title: str
priority: str # "low" | "medium" | "high"
tags: list[str]
# Request the model to return data conforming to Ticket's JSON schema,
# then parse the response into a Ticket instance.
적용할 구체적인 요청이 필요한가요? 여기 모델에 건네는 것의 형태가 있습니다 — 모델을 여러분 자신의 스키마로 교체하세요.
Ask for schema-conforming output
Return the data conforming to this JSON Schema:
{
"title": "string",
"priority": "low | medium | high",
"tags": ["string"]
}
Do not include any prose outside the JSON.왜 그냥 JSON을 프롬프트하지 않나?
프롬프트에서 JSON을 요청할 수도 있고, 단순한 경우에는 작동합니다 — 하지만 표류할 수 있습니다: 불필요한 산문, 후행 쉼표, 누락된 필드. 스키마 강제 출력은 그 부류의 버그를 제거하는데, 이는 다운스트림 시스템이 그것에 의존하는 순간 중요해집니다.
- 프롬프트된 JSON은 데모에서는 작동하고 프로덕션에서는 깨집니다: 실패는 다운스트림 시스템이 그것을 파싱할 때만 드러납니다.
- 주의해야 할 세 가지 고전적 표류: JSON 주변의 불필요한 산문, 후행 쉼표, 누락된 필수 필드.
구조화된 출력 vs. 도구 사용
두 기능 모두 모델에 JSON Schema를 건네므로 비슷해 보입니다 — 그리고 사람들은 잘못된 것을 고릅니다. 차이는 메커니즘이 아니라 의도입니다:
| 구조화된 출력 | 도구 사용 | |
|---|---|---|
| 원하는 것 | 고정된 형태의 최종 답변 | 모델이 기능을 호출하는 것 (함수 호출, 데이터 가져오기, 조치 취하기) |
| 소비하는 주체 | 여러분의 코드가 직접 | 여러분의 코드가 도구를 실행한 뒤 결과를 모델에 다시 공급 |
| 턴 형태 | 하나의 응답, 완료 | 루프: 모델이 요청하고, 여러분이 실행하고, 모델이 계속 |
| 전형적 용도 | 추출, 분류, 파싱 | 에이전트, 실시간 조회, 부작용 |
빠른 경험칙:
JSON이 산출물 그 자체라면 구조화된 출력을 사용하세요. JSON이 모델이 여러분의 코드에게 무언가를 하라고 요청하는 것이라면, 그것은 도구 사용입니다. 에이전트는 종종 둘 다 사용합니다: 행동하기 위한 도구, 깔끔한 최종 결과를 반환하기 위한 구조화된 출력.
팁
- 스키마를 탄탄하게 유지하세요 — 고정된 선택에는 enum을 사용하고, 필수 필드를 표시하세요.
- 필드를 설명하세요 — 필드 설명은 미니 프롬프트처럼 모델을 안내합니다.
- 경계에서는 어쨌든 검증하세요 — 방어적 파싱은 저렴한 보험입니다.
- 추출 작업에는 구조화된 출력 + 명확한 스키마가 매번 자유 형식을 이깁니다.
- API/SDK에 JSON Schema를 건네고 타입 객체로 파싱하세요 — 프롬프트하고 기도하지 마세요.
- JSON을 프롬프트하면 표류할 수 있습니다(불필요한 산문, 후행 쉼표, 누락 필드); 스키마 강제는 그 버그 부류를 제거합니다.
- 구조화된 출력 vs. 도구 사용은 의도로 다릅니다: JSON이 답인가 vs. JSON이 조치를 요청하는가.
- 탄탄한 스키마, 설명된 필드, 경계 검증이 추출과 분류를 신뢰할 수 있게 만듭니다.
용어 굳히기
스스로 점검하기
0/4다음
- 도구 사용 / 함수 호출 — 도구도 JSON 스키마를 사용합니다
- 첫 API 호출
- 재사용 가능한 프롬프트 템플릿