핵심 요약
- 모델 응답은 JSON으로 파싱되지만 필드 이름과 자료형이 매번 달라집니다.
- 가장 빠른 해법은 사람에게 보여줄 답변은 자연어로 두고, 화면·데이터베이스·워크플로·도구가 소비하는 결과에만 JSON Schema 기반 Structured Output을 적용하는 것입니다.
- 형식이 맞아도 사실이 맞거나 실행 권한이 생기는 것은 아니므로, 마지막에는 반드시 업무 규칙과 권한 검사를 추가해야 합니다.
- 이 글은 세 개념을 처음 구분해야 하는 AI 애플리케이션 입문자, 모델 출력을 백엔드에서 검증해야 하는 개발자, 도구 매개변수와 최종 응답을 함께 설계하는 Agent 아키텍트를 위한 글입니다.
모델 응답은 JSON으로 파싱되지만 필드 이름과 자료형이 매번 달라집니다.
가장 빠른 해법은 사람에게 보여줄 답변은 자연어로 두고, 화면·데이터베이스·워크플로·도구가 소비하는 결과에만 JSON Schema 기반 Structured Output을 적용하는 것입니다. 형식이 맞아도 사실이 맞거나 실행 권한이 생기는 것은 아니므로, 마지막에는 반드시 업무 규칙과 권한 검사를 추가해야 합니다.
이 글은 세 개념을 처음 구분해야 하는 AI 애플리케이션 입문자, 모델 출력을 백엔드에서 검증해야 하는 개발자, 도구 매개변수와 최종 응답을 함께 설계하는 Agent 아키텍트를 위한 글입니다.
필드가 흔들리는 일반 JSON 문제
예를 들어 고객 문의를 다음처럼 추출한다고 가정해 보겠습니다.
{
"customer": "홍길동",
"priority": "high",
"issue": "로그인 실패"
}
이 응답은 문법적으로는 정상적인 JSON입니다. 하지만 다음 요청에서는 customer_name, urgent, problem처럼 키 이름이 바뀔 수 있습니다. priority가 문자열이 아니라 숫자나 null로 반환될 수도 있습니다. 프런트엔드는 필드가 없을 때마다 예외 처리를 추가해야 하고, 데이터베이스 적재 단계에서는 변환 실패와 재처리가 발생합니다.
이 차이를 먼저 분리해야 합니다.
- 일반 JSON은 객체와 배열, 문자열, 숫자, 불리언,
null을 표현하는 데이터 형식입니다. - JSON mode는 모델 응답을 유효한 JSON으로 유도하는 기능입니다. 어떤 키가 반드시 있어야 하는지, 자료형이 무엇인지까지 자동으로 정하는 기능은 아닙니다.
- JSON Schema는 다른 JSON 데이터의 구조와 제약 조건을 설명하는 문서입니다. 자체도 JSON으로 작성되지만, 일반 JSON 데이터와 같은 역할을 하지는 않습니다. 스키마는 데이터 구조와 자료형, 검증 규칙을 기술하는 선언적 형식입니다. JSON Schema의 기본 개념
- Structured Output은 모델이 지정한 스키마에 맞는 결과를 만들도록 출력 형식을 제한하는 모델 기능입니다.
따라서 “JSON Schema가 JSON 형식인가요?”라는 질문에는 “JSON으로 작성될 수 있지만, 다른 JSON을 설명하고 검증하는 규칙 문서”라고 답하는 편이 정확합니다.
사람이 읽기만 하는 답변이라면 이 제약은 오히려 부담이 될 수 있습니다. 설명, 상담, 긴 문서 작성에서는 자연어가 더 유연하고 읽기 쉽습니다. 모든 답변을 고정된 스키마에 넣으면 선택적 문장, 예외 상황, 추가 설명을 담기 위한 필드가 늘어나 설계 복잡도가 커집니다.
추출 파이프라인의 제약 수준
문서에서 이름, 날짜, 분류, 금액을 추출하는 작업은 자연어보다 구조화된 결과가 유리합니다. 다만 프롬프트에 “JSON으로만 답하라”고 적는 것과 스키마를 적용하는 것은 같은 수준이 아닙니다.
프롬프트 기반 JSON은 모델의 지시 이해에 의존합니다. JSON mode는 파싱 가능한 JSON을 얻는 데 도움을 주지만, 필수 필드와 허용된 값까지 보장하는지는 별도로 확인해야 합니다. 반면 Structured Output은 지원되는 스키마 범위 안에서 필드와 자료형을 더 강하게 고정합니다. OpenAI 공식 문서는 json<em>object를 이전 방식으로 설명하고, 지원 모델에서는 json</em>schema 사용을 권장합니다. 엄격한 설정에서도 지원되는 JSON Schema의 일부만 사용할 수 있다는 제한이 있습니다. OpenAI 응답 형식 공식 문서
다른 플랫폼도 지원 범위가 동일하지 않습니다. Google의 공식 문서는 구조화된 출력이 JSON Schema의 일부를 지원한다고 명시하며, 문자열·숫자·정수·불리언·객체·배열·null 등 지원되는 형식과 제약을 따로 안내합니다. 그러므로 하나의 스키마를 여러 플랫폼에서 그대로 재사용하기보다, 각 플랫폼의 호환 목록과 거부되는 키워드를 먼저 확인해야 합니다. Google 구조화된 출력 공식 문서
데이터 추출에서는 다음 조건이 충족될 때 스키마를 우선 적용하는 것이 좋습니다.
- 데이터베이스 컬럼과 응답 필드가 일대일로 대응합니다.
- 필드 이름과 자료형이 고정되어야 합니다.
- 분류값이 정해진 목록 안에 있어야 합니다.
- 누락된 값과 알 수 없는 값을 구분해야 합니다.
- 실패한 항목을 재처리하거나 운영 로그로 추적해야 합니다.
반대로 탐색 단계에서 결과 구조가 아직 바뀌고 있다면 처음부터 매우 엄격한 스키마를 만들지 않는 편이 낫습니다. 먼저 자연어 또는 느슨한 JSON으로 실제 결과를 관찰하고, 운영 계약이 정해진 필드만 스키마로 승격하는 방식이 유지보수에 유리합니다.
도구 호출과 권한 검증
Tool Calling에서는 출력 형식보다 실행 경계가 더 중요합니다. 모델이 다음과 같은 도구 매개변수를 만들었다고 가정해 보겠습니다.
{
"user_id": "u_1042",
"action": "delete",
"resource": "invoice_77"
}
이 값이 스키마를 통과했다는 사실은 세 가지만 의미합니다.
- 필드가 기대한 이름과 자료형을 사용했습니다.
- 허용된 형식으로 데이터를 읽을 수 있습니다.
- 애플리케이션이 다음 검증 단계로 넘길 수 있습니다.
반대로 다음을 보장하지는 않습니다.
- 해당 사용자가 실제로 존재합니다.
- 해당 청구서가 그 사용자의 소유입니다.
- 삭제 작업을 수행해도 됩니다.
- 현재 계정이 삭제 권한을 가지고 있습니다.
- 같은 요청이 이미 처리되지 않았습니다.
따라서 도구 실행 전에는 스키마 검증과 업무 검증을 분리해야 합니다. 스키마 검증은 자료형, 필수 여부, 열거값, 문자열 형식을 확인합니다. 업무 검증은 대상 리소스 조회, 소유권 확인, 권한 확인, 중복 요청 방지, 위험 작업 승인 여부를 확인합니다.
도구 호출을 제공하는 API도 이 경계를 명확히 둡니다. Anthropic의 공식 도구 사용 문서에서는 input_schema를 도구가 받을 매개변수를 정의하는 JSON Schema 객체로 설명하고, 도구 호출 결과의 식별자와 입력을 애플리케이션이 받아 실제 코드를 실행하도록 안내합니다. 도구 사용 구현 공식 문서
실무에서는 다음 순서로 구현하면 됩니다.
- 도구 이름과 목적을 한 문장으로 고정합니다.
- 매개변수의 자료형, 필수 여부, 허용값을 스키마에 선언합니다.
- 모델이 만든 인자를 서버 측 검증기로 검사합니다.
- 사용자 인증과 리소스 소유권을 다시 확인합니다.
- 삭제·결제·배포처럼 위험한 작업은 별도 승인 또는 제한된 권한으로 실행합니다.
- 호출 ID, 입력, 검증 결과, 실행 결과를 로그로 저장합니다.
- 실패하면 모델에 원문 오류를 그대로 노출하지 말고, 재시도 가능 여부와 사용자 안내를 분리합니다.
이 구조를 적용하면 “형식이 맞으니 실행한다”는 위험한 설계를 피할 수 있습니다.
화면 생성과 다단계 상태 전달
동적 화면에서는 모델이 만든 구조가 폼, 카드, 표, 버튼의 입력으로 사용됩니다. 이때 Structured Output은 화면 구성 요소를 일정한 형태로 전달하는 데 도움이 됩니다. 하지만 스키마를 바꾸면 모바일 클라이언트, 웹 클라이언트, 서버 렌더러가 동시에 영향을 받습니다.
예를 들어 label을 title로 바꾸거나 items의 자료형을 객체에서 배열로 바꾸면 새 클라이언트는 정상 작동해도 이전 버전이 실패할 수 있습니다. 운영 스키마에는 버전 필드, 기본값, 선택적 필드, 알 수 없는 필드 처리 규칙을 함께 정의해야 합니다. JSON Schema의 default 같은 주석 키워드는 문서화나 생성 도구에 힌트를 줄 수 있지만, 검증기가 누락값을 자동으로 채운다는 뜻은 아닙니다. JSON Schema 주석과 기본값 설명
다단계 AI Agent에서는 중간 상태와 최종 답변을 같은 객체로 취급하지 않는 것이 좋습니다.
중간 상태에는 다음 정보가 필요합니다.
- 현재 단계와 다음 단계
- 도구 호출 ID
- 호출한 도구 이름
- 도구 입력과 결과
- 재시도 횟수와 오류 상태
- 사용자 승인 대기 여부
최종 답변에는 사용자에게 보여줄 설명과 필요한 결과 객체를 함께 둘 수 있습니다. 다만 모델의 내부 추론 과정 자체를 모두 JSON 필드로 저장하도록 설계해서는 안 됩니다. 운영에 필요한 상태, 근거 링크, 실행 결과, 오류 코드만 명시적으로 전달하는 편이 안전하고 비용도 관리하기 쉽습니다.
구현 순서는 다음처럼 나누면 됩니다.
- 사람이 읽는 최종 문장과 기계가 읽는 결과 객체를 분리합니다.
- 중간 이벤트에는 안정적인 이벤트 이름과 호출 ID를 부여합니다.
- 각 단계의 입력과 출력에 버전을 기록합니다.
- 도구 결과를 받은 뒤 업무 검증을 거쳐 다음 상태로 전환합니다.
- 일부 구조화가 실패해도 사용자에게 보여줄 대체 문장을 준비합니다.
- 이전 버전 클라이언트가 이해하지 못하는 필드는 무시하거나 변환합니다.
소비 환경별 선택표
아래 표에서 “구조화된 출력”은 단순히 JSON 문자열을 반환하는 것이 아니라, 모델 응답을 정해진 스키마에 맞추려는 방식을 뜻합니다.
| 소비 대상 | 권장 방식 | 강점 | 주의할 점 |
|---|---|---|---|
| 사람만 읽는 설명 | 자연어 | 표현이 유연하고 예외 설명이 쉽습니다 | 자동 처리에는 부적합합니다 |
| 로그나 약한 계약의 데이터 교환 | 일반 JSON | 빠르게 연결하고 구조를 바꾸기 쉽습니다 | 키와 자료형이 흔들릴 수 있습니다 |
| 고정 필드 데이터 추출 | Structured Output과 JSON Schema | 필드, 자료형, 열거값을 명시할 수 있습니다 | 플랫폼별 지원 범위를 확인해야 합니다 |
| 도구 입력 | 엄격한 스키마와 서버 검증 | 잘못된 인자 형태를 줄일 수 있습니다 | 권한과 리소스 검증을 대체하지 못합니다 |
| 동적 화면 구성 | 버전이 있는 스키마 | 폼과 카드 생성을 자동화할 수 있습니다 | 이전 클라이언트와의 호환이 필요합니다 |
| 장기 실행 Agent | 상태 이벤트 스키마와 최종 응답 스키마 분리 | 재시도와 복구 흐름을 추적하기 쉽습니다 | 상태 계약과 보관 정책을 별도로 운영해야 합니다 |
“AI Agent가 왜 일반 JSON만 출력하면 안 되나요?”에 대한 답은 일반 JSON이 쓸모없어서가 아닙니다. 일반 JSON은 문법만 맞으면 통과할 수 있어, 여러 단계가 연결된 생산 환경에서 필드 이동과 자료형 변화를 막기 어렵기 때문입니다.
“구조화된 출력이 내용의 정확성도 보장하나요?”라는 질문에는 아니라고 답해야 합니다. Structured Output은 정해진 형식과 일부 제약을 관리하지만, 모델이 잘못된 사실을 올바른 필드 안에 넣는 문제까지 해결하지 않습니다. 실제 데이터베이스 조회, 중복 검증, 업무 규칙, 사람 승인 또는 별도 평가 절차가 필요합니다. JSON Schema 자체도 구조 검증과 의미 검증을 모두 코드 없이 표현할 수 있는 것은 아닙니다. JSON Schema가 다루는 구조 검증의 범위
“도구 매개변수와 최종 답변 모두에 스키마가 필요한가요?”에는 소비 방식에 따라 답이 달라집니다. 도구 매개변수는 실행 전에 서버가 읽고 검증해야 하므로 스키마를 우선 적용하는 편이 좋습니다. 최종 답변은 사람이 읽는 설명이 핵심이면 자연어를 유지하고, 프런트엔드나 워크플로가 직접 소비할 결과만 별도 객체로 구조화하면 됩니다.
실제 운영 환경에서는 개발용 노트북에서 단순히 호출하는 것보다, 고정된 실행 환경과 로그 수집, 재시도 정책, 비밀키 관리가 더 중요합니다. 특히 여러 개발자가 서로 다른 라이브러리 버전과 권한으로 테스트하면 같은 스키마라도 실패 원인을 재현하기 어렵습니다. 먼저 kvmboot의 서비스 안내를 확인하고, 필요한 실행 환경과 원격 접속 방식을 정한 뒤 도움말 센터에서 운영 조건을 점검하는 순서가 안전합니다.
현재 방식이 개인 노트북이나 공유 클라우드 환경이라면 의존성 버전이 달라지고, 장시간 배치 중 화면 잠금·네트워크 단절·권한 만료가 발생하며, 여러 사용자가 같은 개발 환경을 건드리는 문제가 생길 수 있습니다. 반면 Mac 환경을 임시로 대여하면 특정 작업용 실행 공간을 분리하고, 테스트와 배치 작업을 같은 조건에서 반복하기가 수월합니다. 장기간 고정 부하를 직접 운영하거나 물리 장비와 특수 인터페이스가 반드시 필요하다면 직접 구매가 더 적합하지만, 구조화된 출력 검증·도구 실행·단기 워크플로 테스트가 목적이라면 kvmboot Mac 환경 이용 안내를 확인해 보는 편이 현실적입니다.