올바른 JSON은 시작일 뿐이며 필드 구조와 업무 규칙, 외부 행동 전 검증을 각각 통과해야 합니다.
자연어 답을 JSON이나 표로 바꾸면 후속 시스템이 읽기 쉬워집니다. 그러나 괄호가 맞는 문서와 사실이 맞는 문서는 다릅니다. 구조화 출력은 모델의 자유로운 문장을 계약된 인터페이스로 좁히는 방법이지, 데이터의 진실성과 권한을 자동으로 보증하는 장치가 아닙니다.
AI 핵심 지식 52편 중 22편입니다. 제품 화면이 바뀌어도 남는 원리와 판단 기준을 다룹니다.
세 단계 검증
| 단계 | 확인 대상 | 대표 실패 |
|---|---|---|
| 문법 | 파서가 문서를 읽을 수 있는가 | 따옴표·괄호·자료형 오류 |
| 스키마 | 필수 필드와 허용 구조를 지키는가 | 누락·추가 필드·범위 이탈 |
| 의미 | 값이 실제 업무와 근거에 맞는가 | 존재하지 않는 ID·허용되지 않은 행동 |
출력 계약을 만드는 순서
- 후속 소비자가 필요한 필드와 자료형을 정의한다.
- 필수·선택·추가 필드와 빈값 처리 규칙을 정한다.
- 스키마 밖의 업무 규칙과 권한 검증을 별도 함수로 둔다.
- 실패 시 재시도, 사람 검토, 중단 중 하나로 라우팅한다.
형식은 후속 시스템과의 인터페이스다
구조화 출력의 목적은 보기 좋은 괄호를 얻는 것이 아니라 다음 단계가 결과를 예측 가능하게 읽도록 만드는 것입니다. 보고서를 데이터베이스에 넣거나, 분류 결과를 작업 큐로 보내거나, 문서에서 항목을 추출할 때 필드 이름과 자료형이 고정되어야 합니다. 먼저 소비자가 무엇을 필요로 하는지 정의해야 합니다. 모델이 쓰기 편한 구조를 먼저 만들면 실제 업무에 필요 없는 필드가 늘고 중요한 상태가 빠질 수 있습니다. 문자열, 숫자, 배열, 객체의 선택은 값의 의미와 연산 방식에 맞춰야 합니다. 날짜를 자유로운 문장으로 받으면 정렬과 비교가 어렵고, 하나 또는 여러 값을 가질 수 있는 필드를 일관되지 않게 쓰면 파서 뒤의 코드가 복잡해집니다. 선택 필드에는 값이 없음, 알 수 없음, 적용되지 않음을 어떻게 구분할지도 정합니다. 출력 예시는 구조를 설명하는 데 유용하지만 예시의 값이 기본값처럼 복제되지 않도록 합니다. 구조화 출력은 자연어를 없애는 일이 아니라 자연어가 들어갈 자리와 기계가 판단할 자리를 분리하는 인터페이스 설계입니다.
스키마는 허용 가능한 모양을 선언한다
JSON Schema 같은 스키마는 객체에 어떤 필드가 있어야 하고, 각 값이 어떤 자료형과 범위를 가져야 하며, 추가 속성을 허용할지 선언할 수 있습니다. 필수 필드를 정하면 모델이 빈칸을 빼먹은 출력을 조기에 발견할 수 있습니다. 열거형은 상태 이름의 오타와 임의 표현을 줄이고, 길이와 범위 조건은 지나치게 긴 텍스트나 불가능한 숫자를 차단합니다. 배열 원소의 구조와 최소 개수를 정하면 후속 코드가 매번 형태를 추측하지 않아도 됩니다. 그러나 제약을 너무 느슨하게 두면 스키마가 사실상 아무것도 검증하지 못하고, 너무 엄격하게 두면 정상적인 예외가 모두 실패로 분류됩니다. additionalProperties를 허용할지는 확장성과 오타 탐지 사이의 결정입니다. 스키마 버전이 바뀔 때는 소비자와 생산자의 호환성을 함께 관리해야 합니다. 필드 이름을 바꾸거나 의미를 재사용하면 문법상 통과한 오래된 데이터가 잘못 해석될 수 있습니다. 따라서 스키마는 코드와 함께 버전 관리하고, 대표 정상값과 경계값, 잘못된 값을 자동 검사에 포함해야 합니다.
스키마 통과와 의미 정확성은 다르다
스키마는 customer_id가 문자열인지 확인할 수 있지만 그 ID가 실제 고객을 가리키는지는 알지 못합니다. 금액이 양수인지 검사해도 해당 거래에서 허용된 금액인지, 사용자가 그 변경을 승인했는지는 별도 문제입니다. 출처 인용 필드가 존재해도 인용문이 주장과 실제로 연결되는지 검증하지 못합니다. 이런 조건은 업무 의미 검증으로 분리해야 합니다. 허용된 식별자 목록, 데이터베이스 참조 무결성, 사용자 권한, 상태 전이 규칙, 근거 문장 존재 여부를 코드나 검토 절차로 확인합니다. 모델이 생성한 함수 인수는 스키마에 맞더라도 바로 실행하지 않고 대상과 부작용을 다시 검사합니다. 특히 삭제, 전송, 결제처럼 되돌리기 어려운 행동은 사람의 확인과 시스템 권한을 요구합니다. 의미 검증을 프롬프트 안의 ‘정확히 작성하라’는 문장에 맡기면 실패를 탐지할 독립 기준이 없습니다. 구조화 출력의 신뢰성은 생성 단계보다 생성 이후의 검증과 실패 라우팅에서 결정됩니다.
실패는 재생성보다 먼저 분류한다
구조 검증이 실패했다고 무조건 같은 요청을 다시 보내면 원인을 숨길 수 있습니다. 닫히지 않은 괄호 같은 문법 오류, 필수 필드 누락 같은 스키마 오류, 존재하지 않는 값 같은 의미 오류는 수정 방법이 다릅니다. 문법 오류는 제한된 재생성이나 안전한 파서 복구를 고려할 수 있고, 스키마 오류는 실패 메시지와 필요한 필드를 명확히 되돌려 줄 수 있습니다. 의미 오류는 원자료 조회나 사람 확인 없이는 재시도로 해결되지 않을 가능성이 큽니다. 재시도 횟수와 중단 조건을 정하지 않으면 같은 실패가 비용과 지연을 늘립니다. 실패한 원문과 검증 결과를 로그에 남기되 민감 정보는 제한합니다. 운영 지표도 ‘성공률’ 하나로 묶지 말고 문법, 스키마, 의미, 외부 실행 거부를 구분합니다. 그래야 프롬프트를 고칠지, 스키마를 바꿀지, 원자료 품질을 개선할지 결정할 수 있습니다. 구조화 출력은 실패를 없애는 기술이 아니라 실패를 일찍, 구체적으로, 안전하게 다룰 수 있게 만드는 계약입니다.
판단 체크리스트
- 후속 소비자 기준으로 필드와 자료형을 정의했는가
- 필수·선택·추가 필드와 빈값 의미를 정했는가
- 업무 의미·권한 검증이 스키마와 분리되어 있는가
- 오류 유형별 재시도·검토·중단 경로가 있는가
자주 생기는 오해
- JSON으로 나오면 사실도 검증된 것이다 — 문법과 구조가 맞아도 값의 사실성·권한·참조 무결성은 별도 검증이 필요합니다.
- 스키마를 엄격하게 만들수록 항상 안전하다 — 정상 예외와 버전 변화를 고려하지 않은 과도한 제약은 다른 우회와 수동 처리를 늘릴 수 있습니다.
통과 단계별 다음 행동
| 상황 | 해석 | 다음 행동 |
|---|---|---|
| 파싱할 수 없다 | 문법 계약 위반 | 제한 재시도 후 계속 실패하면 중단한다 |
| 파싱되지만 필드가 맞지 않는다 | 스키마 계약 위반 | 누락·추가·범위 오류를 구체적으로 반환한다 |
| 스키마는 맞지만 값이 의심스럽다 | 업무 의미와 권한 문제 | 원자료와 대상, 승인 상태를 독립 검증한다 |
자주 묻는 질문
예시 JSON만 주면 충분한가요?
예시는 관계를 보여 주지만 허용 범위를 완전히 정의하지 못합니다. 명시적 스키마와 검증이 필요합니다.
추가 필드는 모두 막아야 하나요?
안정적인 자동화 계약이면 막는 편이 오타 탐지에 유리합니다. 확장이 필요하면 버전과 허용 영역을 따로 설계합니다.
스키마 오류는 자동으로 고쳐도 되나요?
문법·형식 오류는 제한적으로 재시도할 수 있지만 의미와 권한 오류는 원자료나 사람 확인 없이 고치면 안 됩니다.
구조화 출력이 보안을 높이나요?
입력 범위를 좁히고 검증 지점을 만들지만, 도구 최소 권한과 출력 인수 검증이 함께 있어야 합니다.
관련 좌표
작성·검증 정보
- 작성·검토: AI좌표 편집부
- 원문 확인일: 2026-07-27
- 다음 재검토일: 2027-07-27
- 재검토 조건: 원 논문의 정정·철회, 표준 정의 변경, 장기 평가에서 핵심 반례가 확인될 때