AI에게 고객 리뷰 100개를 분석해 달라고 했을 때, 자유로운 에세이 형식으로 답변이 돌아오면 그 내용을 데이터베이스에 저장하거나 다른 시스템에 넘기기가 어렵습니다. 이때 필요한 것이 구조화된 출력(structured output)입니다. 모델이 항상 정해진 JSON 형태로 답하게 강제하면, 사람이 개입하지 않아도 다음 단계로 데이터가 자동으로 흘러갑니다.
왜 자유 형식 텍스트가 문제일까요?
LLM은 본래 자유로운 텍스트를 생성합니다. 같은 요청을 보내도 오늘은 '분류: 긍정'이라고 쓰고 내일은 '이 리뷰는 긍정적입니다'라고 다르게 답할 수 있습니다. 파싱(parsing) 코드를 아무리 잘 짜도 이런 변동에 언제든 깨집니다. 구조화된 출력은 이 변동성을 없애 줍니다.
JSON 모드와 스키마 강제
주요 AI API는 두 가지 방식으로 출력 형식을 고정해 줍니다. 첫 번째는 JSON 모드로, 모델이 반드시 유효한 JSON만 출력하도록 강제하지만 필드 이름이나 구조는 프롬프트로 유도합니다. 두 번째는 스키마 강제(structured output)로, JSON Schema를 직접 정의하면 모델이 해당 스키마에 100% 맞는 JSON을 출력합니다. 자동화가 목적이라면 스키마 강제가 훨씬 안정적입니다.
JSON 스키마 강제 예시 — 리뷰 감성 분석
// 시스템 프롬프트 방식 (모든 API에 공통 적용 가능)
// 스키마 정의와 예시를 함께 제공하면 정확도가 올라갑니다
[시스템 프롬프트]
당신은 고객 리뷰 분석 전문가입니다.
반드시 아래 JSON 형식으로만 답하세요. JSON 이외의 내용은 절대 포함하지 마세요.
{
"sentiment": "positive | negative | mixed",
"score": 1~5 사이 정수,
"topics": ["언급된 주제 목록"],
"summary": "한 문장 요약"
}
[사용자 입력]
리뷰: "배송이 너무 느려서 실망했어요. 제품 자체는 괜찮은데."
[기대 출력]
{"sentiment": "mixed", "score": 3, "topics": ["배송", "제품 품질"], "summary": "배송은 불만족, 제품 품질은 만족"}
Claude API — tool_use로 스키마 강제하기
// tool_use 패턴: 가장 안정적인 구조화 출력 방법
const response = await anthropic.messages.create({
model: "claude-opus-4-5",
max_tokens: 1024,
tools: [{
name: "analyze_review",
description: "고객 리뷰를 분석해 구조화된 데이터를 반환합니다",
input_schema: {
type: "object",
properties: {
sentiment: { type: "string", enum: ["positive", "negative", "mixed"] },
score: { type: "integer", minimum: 1, maximum: 5 },
topics: { type: "array", items: { type: "string" } },
summary: { type: "string" }
},
required: ["sentiment", "score", "topics", "summary"]
}
}],
tool_choice: { type: "tool", name: "analyze_review" },
messages: [{ role: "user", content: reviewText }]
});
어디에 활용할 수 있을까요?
구조화된 출력의 대표 활용 사례
- 데이터 추출: 비정형 이메일·문서에서 날짜, 금액, 담당자 같은 필드를 JSON으로 뽑아 데이터베이스에 저장합니다.
- 자동 분류: 고객 문의·리뷰·이슈를 정해진 카테고리와 우선순위로 분류해 CRM이나 티켓 시스템에 자동 입력합니다.
- 콘텐츠 파이프라인: 긴 글을 요약·태그·SEO 메타데이터까지 한 번에 뽑아 CMS에 자동 등록합니다.
- AI 에이전트: 에이전트가 다음에 호출할 도구 이름과 파라미터를 JSON으로 결정해 다음 단계를 자동 실행합니다.
프롬프트만으로도 어느 정도 가능합니다
API를 직접 쓰지 않는 챗 환경에서도 '반드시 다음 JSON 형식으로만 답해 주세요'라는 지시와 함께 원하는 스키마 예시를 보여주면 대부분 그 형식을 따릅니다. 단, 이 방법은 가끔 형식을 벗어나는 경우가 있으므로, 자동화 파이프라인에서는 API의 스키마 강제 기능을 쓰는 것이 훨씬 안전합니다.
구조화된 출력을 설계할 때는 '이 JSON을 받는 다음 시스템이 무엇을 필요로 하는가?'부터 역으로 생각하세요. 필드가 많을수록 좋은 것이 아니라, 다음 단계에 꼭 필요한 필드만 정의할수록 모델 정확도와 처리 속도가 올라갑니다.
스키마를 강제하더라도 각 필드 값의 내용 자체가 정확한지는 보장되지 않습니다. score 필드가 숫자 형식으로 오더라도 그 점수가 실제로 맞는지는 별개입니다. 구조는 보장되지만 의미적 정확성은 여전히 검증이 필요합니다.