개념 노트 2026년 10월 3일7분 읽기

JSON 형식이 맞아도 답은 틀릴 수 있습니다

칸이 다 채워졌다는 것과 칸 안의 값이 맞다는 것은 다른 이야기입니다. 형식은 기능에 맡기고, 값은 원본과 대조할 자리를 따로 만들어야 합니다.

책상 위에 칸이 모두 채워진 경비 카드와 영수증이 놓여 있고, 금액 칸에만 붉은 실과 놋쇠 꼬리표가 달려 있습니다. 제목 ‘형식은 맞아도, 값은 틀릴 수 있다’와 부제 ‘칸이 채워진 것과 칸이 맞는 것은 다르다’가 적혀 있습니다.

AI가 내놓은 결과를 표나 시스템에 바로 넣으려면 모양이 일정해야 합니다. 그래서 “항상 정해 둔 JSON 형식으로 답하게 하자”는 결정을 많이 합니다. JSON은 이름표와 값을 짝지어 적는 데이터 형식입니다. 형식이 일정해지면 결과를 받아 쓰기는 훨씬 편해집니다. 그런데 형식이 맞았다는 사실이 값까지 맞았다는 뜻으로 읽히기 쉽습니다.

가상의 경비 처리 기능으로 생각해 보겠습니다. 직원이 영수증 사진을 올리면 AI가 날짜, 금액, 분류, 상호 네 칸을 채워 경비 표에 넣습니다. 결과는 매번 네 칸이 빠짐없이 채워진 같은 모양으로 돌아옵니다. 하지만 금액 칸에 합계 대신 부가세를 뺀 금액이 들어가도 모양은 똑같이 맞습니다.

OpenAI API의 Structured Outputs 가이드를 예로 들어, 이 기능이 무엇을 약속하고 무엇을 약속하지 않는지 나누어 보겠습니다. Structured Outputs는 개발자가 앱에 연결하는 기능입니다. 하지만 AI 결과를 표나 양식으로 받아 쓰는 사람이라면 누구나 같은 질문을 할 수 있습니다. 이 칸이 채워졌다는 것과 이 칸이 맞다는 것을 구분하고 있는지 말입니다. 이런 기능 없이 대화형 AI에게 표를 받아 쓴다면, 칸이 다 있는지 보는 일과 값이 맞는지 보는 일을 둘 다 사람이 맡게 됩니다.

PART 01형식의 약속

Structured Outputs는 정해 둔 모양을 지키게 합니다

OpenAI의 Structured Outputs 가이드는 이 기능이 개발자가 준 JSON Schema를 모델이 항상 따르게 한다고 설명합니다. JSON Schema는 어떤 이름표가 있어야 하고 각 값이 어떤 종류여야 하는지 적어 둔 설계도입니다. 가이드가 밝힌 예외는 둘입니다. 모델이 안전상의 이유로 요청을 거절하면 설계도 대신 거절 표시(refusal 항목)가 붙고, 답의 길이 한도에 걸려 응답이 중간에 끊기면 설계도에 맞지 않는 결과가 올 수 있습니다. 가이드는 그 덕분에 필수 이름표가 빠지거나, 미리 정해 둔 선택지 밖의 값이 나오는 문제를 걱정하지 않아도 된다고 말합니다.

영수증 예라면 분류 칸에 ‘교통비, 식비, 숙박비’ 세 가지만 허용해 두었을 때, ‘기타 비용’처럼 목록에 없는 값이 나오지 않습니다. 날짜 칸이 통째로 빠진 결과도 나오지 않습니다. 결과를 받는 시스템 입장에서는 모양이 어긋나 처리가 멈추는 일이 줄어듭니다.

가이드는 예전부터 있던 JSON 모드와의 차이도 짚습니다. JSON 모드는 문법상 올바른 JSON이 나오게 해 줄 뿐이고, 정해 둔 설계도를 따르는지까지는 보장하지 않습니다. Structured Outputs는 설계도를 따르는 데까지 약속합니다. 가이드는 가능하면 JSON 모드 대신 Structured Outputs를 쓰라고 권합니다.

형식 검사 내용 검사 이름표가 다 있나 허용된 값인가 원본과 같은가 모르면 비웠나 기능이 맡는다 거절·중단은 예외 기획에서 따로 만든다
Structured Outputs가 맡는 것은 형식 검사입니다. 값이 원본과 같은지는 내용 검사로 따로 봐야 합니다.
OpenAI 공식 가이드의 설명을 바탕으로 만든 개념도입니다.
PART 02값의 빈칸

모양이 맞아도 칸 안의 값은 틀릴 수 있습니다

같은 가이드의 ‘Handling mistakes’ 항목은 짧게 적습니다. Structured Outputs를 써도 결과에 실수가 있을 수 있다는 것입니다. 약속한 것은 모양이고, 칸에 들어간 내용이 사실과 맞는지는 약속 범위 밖입니다.

날짜·분류·상호·금액 칸이 모두 채워진 경비 카드의 ‘금액 40,000원’ 칸에서 붉은 실이 영수증의 ‘합계 44,000원’ 줄로 이어져 있습니다.
칸은 모두 채워졌지만, 금액 칸의 값은 영수증과 다릅니다.
그림은 AI 이미지 생성으로 만들었습니다.

여기에 한 가지 조건이 더 붙습니다. 가이드에 따르면 이 기능을 쓰려면 모든 칸을 필수로 지정해야 하고, 모델은 칸마다 값을 돌려줍니다. 영수증에서 상호가 흐려 읽을 수 없어도 상호 칸에는 무언가가 들어갑니다. 비어 있어야 할 자리가 그럴듯한 값으로 채워질 수 있다는 뜻입니다.

가이드는 극단적인 경우도 설명합니다. 입력이 설계도와 전혀 관계없을 때, 모델이 설계도를 지키려다 없는 내용을 지어낼 수 있다고 합니다. 직원이 영수증 대신 회의실 사진을 잘못 올렸다면, 결과는 여전히 날짜·금액·분류·상호가 다 채워진 모양으로 돌아올 수 있습니다. 모양만 보면 정상 처리된 영수증과 구분되지 않습니다.

AI가 채운 결과 원본과 대조 날짜 10월 2일 같음 금액 40,000원 합계 44,000원 분류 교통비 사람이 판단 상호 ○○역 매표소 같음
네 칸이 모두 채워져 형식 검사는 통과했지만, 금액 칸에는 부가세를 뺀 값이 들어가 원본 합계와 다릅니다.
가상의 영수증 결과로 만든 예시입니다.
PART 03모를 때의 자리

모를 때 비워 둘 자리를 먼저 만들어야 합니다

그렇다면 기획 단계에서 할 일이 생깁니다. 값을 모를 때 AI가 무엇을 돌려줄지 미리 정하는 것입니다. 가이드는 모든 칸이 필수여도 ‘값 없음(null)’을 함께 허용해 선택 항목처럼 쓸 수 있다고 안내합니다. 상호를 읽을 수 없을 때 ‘값 없음’을 돌려받을 자리를 설계도에 만들어 둘 수 있습니다. 다만 자리를 만들어 두는 것만으로 모델이 그 자리를 쓰는 것은 아닙니다. 언제 비워야 하는지도 지시문에 함께 적어야 합니다. 지시문은 모델에게 미리 주는 작업 안내입니다.

경비 카드의 ‘상호’ 칸이 ‘값 없음’으로 비어 있고 ‘사람이 채울 칸’ 꼬리표가 달려 있습니다. 옆에는 영수증 대신 회의실 사진이 놓여 있고 ‘영수증이 아닙니다’ 메모가 붙어 있습니다.
읽지 못한 값도, 영수증이 아닌 사진이 올라온 경우도 칸을 억지로 채우지 않고 사람이 볼 자리로 남깁니다.
그림은 AI 이미지 생성으로 만들었습니다.

입력이 엉뚱할 때를 위한 지시도 필요합니다. 가이드는 사용자가 직접 올린 자료를 받는 앱이라면, 처리할 수 없는 입력이 들어왔을 때 어떻게 할지 지시문에 적어 두라고 권합니다. 빈 값을 돌려주거나 정해 둔 문장을 돌려주라고 지시하는 방식입니다. 회의실 사진이 들어오면 ‘영수증이 아닙니다’라는 표시가 돌아오게 하면, 경비 표에 가짜 행이 생기는 일을 막을 수 있습니다.

PART 04확인할 것

형식 검사와 내용 검사를 따로 기획합니다

정리하면 검사는 두 층입니다. 형식 검사는 이름표가 다 있는지, 값이 허용된 종류인지를 봅니다. Structured Outputs가 이 층을 맡아 줍니다. 내용 검사는 값이 원본과 같은지, 모르는 칸을 비워 두었는지를 봅니다. 이 층은 기능이 대신해 주지 않으므로 기획에서 따로 자리를 만들어야 합니다.

내용 검사는 값의 성격에 따라 방법이 다릅니다. 금액처럼 다시 계산할 수 있는 값은 원본의 합계와 대조합니다. 영수증이라면 제출 화면에 영수증 사진과 AI가 읽은 금액을 나란히 띄워, 제출하는 사람이 그 자리에서 확인하게 할 수 있습니다. 분류처럼 판단이 들어간 값은 기능을 막 열었을 때 사람이 결과를 원본과 나란히 놓고 봅니다. 몇 건, 몇 주 동안 볼지는 팀이 먼저 정해 두고, 그 기간에 틀린 값이 더 나오지 않으면 검토 범위를 줄입니다. ‘값 없음’이 돌아온 칸은 실패가 아니라 사람이 채울 자리로 다룹니다.

검사에서 틀린 값이 계속 나온다면 가이드의 제안을 참고할 수 있습니다. 지시문을 고치거나, 지시문에 예시를 넣거나, 한 번에 하던 일을 더 작은 단계로 나누는 방법입니다. 영수증이라면 ‘글자 읽기’와 ‘분류 판단’을 나누어 각각 확인하는 식입니다.

AI 결과를 표로 받는 기능을 기획한다면 칸마다 두 줄을 적어 보시길 권합니다. ‘이 칸의 값은 무엇과 대조하나’, ‘모르면 무엇을 돌려받나’. 이 두 줄이 비어 있는 칸은 형식이 아무리 잘 맞아도 확인되지 않은 값입니다.

이 글은 AI의 도움을 받아 작성했습니다.

참고 자료

이 글의 기능 설명은 2026년 10월 3일 공식 문서 기준입니다.

  1. OpenAI Structured model outputs: https://developers.openai.com/api/docs/guides/structured-outputs
이 글 공유하기
LinkedIn Threads X Facebook
다음 문