프로덕션 애플리케이션과 효율적인 워크플로우를 위해서는 일관되고 잘 포맷된 출력을 얻는 것이 필수적입니다. 이 장에서는 AI 모델이 응답을 어떻게 포맷할지 정확하게 제어하는 기법을 다룹니다.

<Callout type="info" title="산문에서 데이터로">
구조화된 출력은 AI 응답을 자유 형식 텍스트에서 실행 가능하고 파싱 가능한 데이터로 변환합니다.
</Callout>

## 구조가 중요한 이유

<StructuredOutputDemo />

## 기본 포맷팅 기법

### 목록

목록은 단계별 지침, 순위가 있는 항목, 또는 관련 포인트의 모음에 완벽합니다. 스캔하고 파싱하기 쉽습니다. 순서가 중요할 때(단계, 순위)는 **번호 목록**을 사용하고, 순서가 없는 모음에는 **글머리 기호**를 사용하세요.

<TryIt 
  compact
  title="목록 포맷팅"
  prompt={`더 나은 수면을 위한 5가지 팁을 제공하세요.

형식: 각각에 대한 간략한 설명이 포함된 번호 목록.
각 팁은 굵게 표시하고, 대시와 설명을 이어서 작성하세요.`}
/>

<Callout type="tip" title="목록 모범 사례">
원하는 항목의 정확한 개수, 설명 포함 여부, 항목을 굵게 표시할지 또는 특정 구조를 따를지 명시하세요.
</Callout>

### 표

표는 동일한 차원에서 여러 항목을 비교하는 데 탁월합니다. 기능 비교, 데이터 요약, 일관된 속성을 가진 모든 정보에 이상적입니다. 항상 열 헤더를 명시적으로 정의하세요.

<TryIt 
  compact
  title="표 포맷팅"
  prompt={`상위 4개의 Python 웹 프레임워크를 비교하세요.

다음 열로 마크다운 표 형식으로 작성하세요:
| 프레임워크 | 적합한 용도 | 학습 곡선 | 성능 |`}
/>

<Callout type="tip" title="표 모범 사례">
열 이름, 예상 데이터 유형(텍스트, 숫자, 등급), 필요한 행 수를 명시하세요. 복잡한 비교의 경우 가독성을 위해 4-6개 열로 제한하세요.
</Callout>

### 제목과 섹션

제목은 명확한 문서 구조를 만들어 긴 응답을 스캔 가능하고 체계적으로 만듭니다. 보고서, 분석, 또는 여러 부분으로 된 응답에 사용하세요. 계층적 제목(##, ###)은 섹션 간의 관계를 보여줍니다.

```
이 사업 제안서를 분석하세요.

다음 섹션으로 응답을 구조화하세요:
## 요약
## 강점
## 약점
## 권장 사항
## 위험 평가
```

<Callout type="tip" title="섹션 모범 사례">
원하는 순서대로 섹션을 나열하세요. 일관성을 위해 각 섹션에 포함되어야 할 내용을 명시하세요(예: "요약: 2-3문장만").
</Callout>

### 대문자 지시어로 강조하기

대문자 단어는 모델에게 중요한 제약이나 요구 사항을 강조하는 강력한 신호 역할을 합니다. 최대 효과를 위해 아껴서 사용하세요—과도하게 사용하면 효과가 희석됩니다.

**일반적인 대문자 지시어:**

<InfoGrid items={[
  { label: "NEVER", description: "절대 금지: \"NEVER include personal opinions\"", color: "red" },
  { label: "ALWAYS", description: "필수 요구: \"ALWAYS cite sources\"", color: "green" },
  { label: "IMPORTANT", description: "중요 지침: \"IMPORTANT: Keep responses under 100 words\"", color: "amber" },
  { label: "DO NOT", description: "강한 금지: \"DO NOT make up statistics\"", color: "red" },
  { label: "MUST", description: "필수 동작: \"Output MUST be valid JSON\"", color: "blue" },
  { label: "ONLY", description: "제한: \"Return ONLY the code, no explanations\"", color: "purple" },
]} />

```
이 기사를 요약하세요.

IMPORTANT: 요약을 100단어 이내로 유지하세요.
NEVER 원본에 없는 정보를 추가하세요.
ALWAYS 원래의 어조와 관점을 유지하세요.
DO NOT 자신의 의견이나 분석을 포함하세요.
```

<Callout type="warning" title="아껴서 사용하세요">
모든 것이 대문자이거나 중요하다고 표시되면 아무것도 두드러지지 않습니다. 이러한 지시어는 진정으로 중요한 제약에만 사용하세요.
</Callout>

## JSON 출력

JSON (JavaScript Object Notation)은 구조화된 AI 출력에 가장 인기 있는 형식입니다. 기계가 읽을 수 있고, 프로그래밍 언어에서 널리 지원되며, API, 데이터베이스, 자동화 워크플로우에 완벽합니다. 신뢰할 수 있는 JSON의 핵심은 명확한 스키마를 제공하는 것입니다.

### 기본 JSON 요청

원하는 정확한 구조를 보여주는 템플릿으로 시작하세요. 필드 이름, 데이터 유형, 예시 값을 포함하세요. 이것은 모델이 따를 계약 역할을 합니다.

<TryIt 
  title="JSON 추출"
  description="비구조화된 텍스트에서 구조화된 데이터를 추출합니다."
  prompt={`이 텍스트에서 정보를 추출하고 JSON으로 반환하세요:

{
    "company_name": "string",
    "founding_year": number,
    "headquarters": "string",
    "employees": number,
    "industry": "string"
}

텍스트: "Apple Inc., founded in 1976, is headquartered in Cupertino, California. The technology giant employs approximately 164,000 people worldwide."`}
/>

### 복잡한 JSON 구조

중첩된 데이터의 경우, 객체 안의 객체, 객체 배열, 혼합 유형으로 계층적 JSON을 사용하세요. 각 수준을 명확하게 정의하고 TypeScript 스타일 주석(`"positive" | "negative"`)을 사용하여 값을 제한하세요.

```
이 제품 리뷰를 분석하고 JSON으로 반환하세요:

{
  "review_id": "string (고유하게 생성)",
  "sentiment": {
    "overall": "positive" | "negative" | "mixed" | "neutral",
    "score": 0.0-1.0
  },
  "aspects": [
    {
      "aspect": "string (예: 'price', 'quality')",
      "sentiment": "positive" | "negative" | "neutral",
      "mentions": ["리뷰에서 정확한 인용"]
    }
  ],
  "purchase_intent": {
    "would_recommend": boolean,
    "confidence": 0.0-1.0
  },
  "key_phrases": ["주목할 만한 문구의 string 배열"]
}

유효한 JSON만 반환하고, 추가 텍스트는 없습니다.

리뷰: "[리뷰 텍스트]"
```

### 유효한 JSON 보장하기

모델은 때때로 JSON 주위에 설명 텍스트나 마크다운 포맷팅을 추가합니다. 출력 형식에 대한 명시적인 지침으로 이를 방지하세요. 원시 JSON 또는 코드 블록 안의 JSON을 요청할 수 있습니다—파싱 필요에 따라 선택하세요.

명시적인 지침을 추가하세요:

```
IMPORTANT:
- JSON 객체만 반환하고, 마크다운 코드 블록은 없습니다
- 모든 문자열이 올바르게 이스케이프되었는지 확인하세요
- 누락된 값에는 undefined가 아닌 null을 사용하세요
- 출력이 파싱 가능한 JSON인지 검증하세요
```

또는 모델에게 출력을 감싸도록 요청하여 코드 블록을 요청하세요:

````
결과를 JSON 코드 블록으로 반환하세요:
```json
{ ... }
```
````

## YAML 출력

YAML은 괄호 대신 들여쓰기를 사용하여 JSON보다 사람이 읽기 쉽습니다. 구성 파일(Docker, Kubernetes, GitHub Actions)의 표준이며 출력이 사람이 읽거나 DevOps 컨텍스트에서 사용될 때 잘 작동합니다. YAML은 들여쓰기에 민감하므로 포맷팅 요구 사항을 구체적으로 명시하세요.

<TryIt 
  compact
  title="YAML 생성"
  prompt={`Node.js 프로젝트를 위한 GitHub Actions 워크플로우를 생성하세요.

유효한 YAML로 반환하세요:
- 포함: install, lint, test, build 단계
- Node.js 18 사용
- npm 종속성 캐시
- main으로 push와 pull request에서 실행`}
/>

## XML 출력

XML은 여전히 많은 엔터프라이즈 시스템, SOAP API, 레거시 통합에 필요합니다. JSON보다 더 장황하지만 복잡한 데이터를 위한 속성, 네임스페이스, CDATA 섹션 같은 기능을 제공합니다. 요소 이름, 중첩 구조, 속성 대 자식 요소를 사용할 위치를 명시하세요.

```
이 데이터를 XML 형식으로 변환하세요:

요구 사항:
- 루트 요소: <catalog>
- 각 항목은 <book> 요소에
- 적절한 곳에 속성 포함
- 설명 텍스트에 CDATA 사용

데이터: [도서 데이터]
```

## 커스텀 형식

때때로 표준 형식이 필요에 맞지 않을 수 있습니다. 명확한 템플릿을 제공하여 어떤 커스텀 형식이든 정의할 수 있습니다. 커스텀 형식은 보고서, 로그, 또는 사람이 읽을 도메인 특정 출력에 잘 작동합니다.

### 구조화된 분석 형식

구분자(===, ---, [SECTION])를 사용하여 섹션 간에 명확한 경계가 있는 스캔 가능한 문서를 만드세요. 이 형식은 코드 리뷰, 감사, 분석에 적합합니다.

```
이 코드를 다음 정확한 형식으로 분석하세요:

=== CODE ANALYSIS ===

[SUMMARY]
한 단락 개요

[ISSUES]
• CRITICAL: [이슈] — [파일:라인]
• WARNING: [이슈] — [파일:라인]  
• INFO: [이슈] — [파일:라인]

[METRICS]
Complexity: [Low/Medium/High]
Maintainability: [점수]/10
Test Coverage: [추정 %]

[RECOMMENDATIONS]
1. [우선순위 1 권장 사항]
2. [우선순위 2 권장 사항]

=== END ANALYSIS ===
```

### 빈칸 채우기 형식

빈칸(___)이 있는 템플릿은 모델이 정확한 포맷팅을 유지하면서 특정 필드를 채우도록 안내합니다. 이 접근 방식은 일관성이 중요한 양식, 브리프, 표준화된 문서에 탁월합니다.

```
주어진 제품에 대해 이 템플릿을 완성하세요:

PRODUCT BRIEF
─────────────
Name: _______________
Tagline: _______________
Target User: _______________
Problem Solved: _______________
Key Features:
  1. _______________
  2. _______________
  3. _______________
Differentiator: _______________

제품: [제품 설명]
```

## 타입 지정 응답

타입 지정 응답은 모델이 인식하고 레이블을 지정해야 하는 카테고리나 엔티티 유형을 정의합니다. 이 기법은 Named Entity Recognition (NER), 분류 작업, 정보를 일관되게 분류해야 하는 모든 추출에 필수적입니다. 예시와 함께 유형을 명확하게 정의하세요.

<TryIt 
  compact
  title="엔티티 추출"
  prompt={`이 텍스트에서 엔티티를 추출하세요.

엔티티 유형:
- PERSON: 사람의 전체 이름
- ORG: 조직/회사 이름
- LOCATION: 도시, 국가, 주소
- DATE: ISO 형식의 날짜 (YYYY-MM-DD)
- MONEY: 통화가 포함된 금액

각각을 다음 형식으로: [TYPE]: [값]

텍스트: "Tim Cook announced that Apple will invest $1 billion in a new Austin facility by December 2024."`}
/>

## 다중 파트 구조화 응답

여러 측면을 다루는 포괄적인 출력이 필요할 때, 명확한 경계를 가진 구별되는 파트를 정의하세요. 각 파트에 들어갈 내용—형식, 길이, 콘텐츠 유형—을 정확하게 명시하세요. 이렇게 하면 모델이 섹션을 혼합하거나 파트를 생략하는 것을 방지합니다.

```
이 주제를 조사하고 다음을 제공하세요:

### PART 1: 요약
[2-3문장 개요]

### PART 2: 주요 발견
[정확히 5개의 글머리 기호]

### PART 3: 데이터 표
| 지표 | 값 | 출처 |
|------|-----|------|
[최소 5행 포함]

### PART 4: 권장 사항
[실행 가능한 3가지 권장 사항의 번호 목록]

### PART 5: 추가 자료
[간략한 설명이 있는 3개의 추천 리소스]
```

## 조건부 포맷팅

조건부 포맷팅을 사용하면 입력의 특성에 따라 다른 출력 형식을 정의할 수 있습니다. 이것은 모델이 감지한 내용에 따라 응답 형식이 달라져야 하는 분류, 트리아지, 라우팅 시스템에 강력합니다. 각 경우에 대한 명시적인 출력 템플릿과 함께 명확한 if/then 로직을 사용하세요.

<TryIt 
  compact
  title="티켓 분류"
  prompt={`이 지원 티켓을 분류하세요.

URGENT인 경우 (시스템 다운, 보안 이슈, 데이터 손실):
  반환: 🔴 URGENT | [카테고리] | [제안 조치]

HIGH인 경우 (여러 사용자 영향, 수익 영향):
  반환: 🟠 HIGH | [카테고리] | [제안 조치]

MEDIUM인 경우 (단일 사용자 영향, 해결 방법 있음):
  반환: 🟡 MEDIUM | [카테고리] | [제안 조치]

LOW인 경우 (질문, 기능 요청):
  반환: 🟢 LOW | [카테고리] | [제안 조치]

티켓: "I can't login to my account. I've tried resetting my password twice but still getting an error. This is blocking my entire team from accessing the dashboard."`}
/>

## JSON의 배열과 목록

여러 항목을 배열로 추출하려면 신중한 스키마 정의가 필요합니다. 배열 구조, 각 항목에 포함되어야 할 내용, 엣지 케이스(빈 배열, 단일 항목) 처리 방법을 명시하세요. count 필드를 포함하면 완전성을 검증하는 데 도움이 됩니다.

```
이 회의 녹취록에서 모든 액션 항목을 추출하세요.

JSON 배열로 반환하세요:
{
  "action_items": [
    {
      "task": "작업을 설명하는 string",
      "assignee": "사람 이름 또는 'Unassigned'",
      "deadline": "언급된 경우 날짜, 아니면 null",
      "priority": "high" | "medium" | "low",
      "context": "녹취록에서 관련 인용"
    }
  ],
  "total_count": number
}

녹취록: "[회의 녹취록]"
```

## 검증 지침

자체 검증은 모델이 응답하기 전에 자신의 출력을 확인하도록 프롬프트합니다. 이것은 누락된 섹션, 플레이스홀더 텍스트, 또는 제약 위반과 같은 일반적인 문제를 잡아냅니다. 모델은 내부적으로 반복하여 문제를 수정하고, 추가 API 호출 없이 출력 품질을 향상시킵니다.

```
보고서를 생성한 후:

VALIDATION CHECKLIST:
□ 모든 필수 섹션 존재
□ 플레이스홀더 텍스트 없음
□ 모든 통계에 출처 포함
□ 단어 수 500-700단어 이내
□ 결론이 서론과 연결됨

검사 실패 시, 응답 전에 수정하세요.
```

## 선택적 필드 처리

실제 데이터에는 종종 누락된 값이 있습니다. 선택적 필드를 처리하는 방법을 명시적으로 지시하세요—`null`을 사용하는 것이 빈 문자열보다 깔끔하고 프로그래밍적으로 처리하기 쉽습니다. 또한 모델이 절대로 정보를 지어내지 않아야 함을 강조하여 누락된 데이터의 "환각"을 방지하세요.

```
연락처 정보를 추출하세요. 누락된 필드에는 null을 사용하세요.

{
  "name": "string (필수)",
  "email": "string 또는 null",
  "phone": "string 또는 null", 
  "company": "string 또는 null",
  "role": "string 또는 null",
  "linkedin": "URL string 또는 null"
}

IMPORTANT: 
- 소스에 없는 정보를 절대로 지어내지 마세요
- 누락된 데이터에는 빈 문자열이 아닌 null을 사용하세요
- 가능하면 전화번호는 E.164 형식으로
```

## 요약

<Callout type="tip" title="핵심 기법">
형식에 대해 명시적으로 작성하고, 예시를 사용하고, 유형을 명시하고, 엣지 케이스를 null 값으로 처리하고, 모델에게 자체 출력을 검증하도록 요청하세요.
</Callout>

<Quiz 
  question="비구조화된 텍스트보다 구조화된 출력의 주요 장점은 무엇인가요?"
  options={[
    "토큰을 더 적게 사용합니다",
    "AI가 생성하기 더 쉽습니다",
    "프로그래밍적으로 파싱하고 검증할 수 있습니다",
    "항상 정확한 정보를 생성합니다"
  ]}
  correctIndex={2}
  explanation="JSON과 같은 구조화된 출력은 코드로 파싱할 수 있고, 쿼리 간에 비교할 수 있고, 워크플로우에 통합할 수 있으며, 완전성을 검증할 수 있습니다—자유 형식 텍스트로는 어렵거나 불가능한 것들입니다."
/>

구조화된 출력은 신뢰할 수 있는 AI 기반 애플리케이션을 구축하는 데 필수적입니다. 다음 장에서는 복잡한 추론 작업을 위한 사고 연쇄 프롬프팅을 탐구합니다.
