AI가 준 JSON, 파싱은 됐는데 합계가 틀렸다면?

JSON.parse()가 성공했다는 것은 문자열을 JSON 문법으로 읽었다는 뜻입니다. 필요한 자료형이나 합계까지 맞다는 뜻은 아닙니다. AI 응답을 자동화에 넣는다면 ‘읽을 수 있음’과 ‘쓸 수 있는 값’을 나눠 봐야 합니다.

예를 들어 수량이 2개, 단가가 1,000원인데 합계가 1원인 주문을 생각해 보세요. 아래는 이 차이를 확인하려고 만든 합성 데이터입니다. 실제 AI 응답이나 거래 내역이 아닙니다.

const order = JSON.parse(
  '{"item":"pen","quantity":2,"unitPrice":1000,"total":1}'
);
console.log(order.total === order.quantity * order.unitPrice);
// false

이 문자열은 파싱되지만 곱셈 결과와 합계는 다릅니다. 파싱 성공을 곧바로 ‘주문 데이터 확인 완료’로 처리하면 놓치는 부분입니다.

크림색 바탕 중앙의 남색 종이 중괄호와 청록 문서, 따로 놓인 코랄색 영수증. JSON은 정상, 값도 맞을까요?라는 문구로 파싱 성공과 값의 정확성을 구분한 설명 그림.
JSON을 읽을 수 있다는 사실만으로 안의 값까지 맞는 것은 아닙니다. 이해를 돕기 위한 생성 일러스트입니다.

JSON.parse는 어디까지 확인하나요?

ECMAScript의 JSON.parse 정의는 JSON 텍스트를 읽어 JavaScript 값으로 만드는 동작을 설명합니다. JSON 문법에 맞지 않으면 SyntaxError가 납니다. 기본 호출이 주문 금액의 근거나 업무상 합계까지 알아서 판단해 주는 것은 아닙니다.

예를 들어 마지막 속성 뒤에 쉼표가 남은 JSON은 문법에서 막힙니다. 반면 수량을 "2"로 적으면 문법에는 맞습니다. 다만 숫자가 아니라 문자열이므로, 수량을 정수로 받기로 한 프로그램의 조건과는 다릅니다. JSON.parse에 별도의 reviver 함수를 넣어 변환할 수는 있지만, 그것도 작성자가 추가한 로직입니다.

위에서 내려다본 두 종이 칸. 청록색 왼쪽 칸은 쌍따옴표로 감싼 2와 문자열 라벨, 코랄색 오른쪽 칸은 따옴표 없는 2와 숫자 라벨을 담고 있다.
따옴표가 붙은 문자열과 숫자는 다른 자료형입니다. 설명용 생성 그림이며 곡선형 따옴표는 실제 JSON 코드가 아닙니다.

같은 작은 주문 네 개를 나눠 검사했습니다

2026년 10월 17일, Windows x64의 Node.js 26.5.0(V8 14.6.202.34-node.24, ICU 78.3)에서 합성 입력 네 개를 실행했습니다. 파싱 다음에 직접 만든 간이 형식 검사를 붙이고, 통과한 값에만 total === quantity * unitPrice를 비교했습니다.

입력 차이 파싱 간이 형식 곱 일치
끝에 불필요한 쉼표 실패 미실행 미실행
수량이 문자열 "2" 통과 실패 미실행
수량 2·단가 1000·합계 1 통과 통과 실패
수량 2·단가 1000·합계 2000 통과 통과 통과

간이 형식 검사는 상품명이 비어 있지 않은 문자열인지, 수량이 1 이상 정수인지, 단가·합계가 0 이상 정수인지 등을 확인했습니다. 숫자는 Number.isSafeInteger로 검사했습니다. 추가 속성까지 거부하는 완성된 JSON Schema 검증기가 아니라, 이 작은 예제의 실패 지점을 나누기 위한 코드입니다. 실제 검증 라이브러리나 OpenAI API를 시험한 결과도 아닙니다.

스키마를 지켰어도 값은 틀릴 수 있습니다

스키마는 필드와 자료형, 허용값 같은 제약을 정하는 데 쓰입니다. 숫자의 범위처럼 업무 규칙 일부를 스키마에 넣을 수도 있으므로, ‘형식 검사와 업무 검사는 완전히 별개’라고 잘라 말할 필요는 없습니다. 중요한 것은 정해 둔 제약에 맞는가와 실제 원문·계산·업무 조건에 맞는가를 구분하는 일입니다.

OpenAI의 현재 Structured model outputs 문서도 JSON 모드와 Structured Outputs를 구분합니다. JSON 모드의 유효한 JSON 출력과 Structured Outputs의 스키마 준수는 다른 약속입니다. 스키마 준수는 지원 모델에서 strict: true와 지원하는 JSON Schema를 사용하고 출력이 정상적으로 완료된 경우의 범위입니다. 문서는 strict 설정에 비지원 스키마를 보내면 오류가 난다고 설명합니다. 거절이나 출력 한도로 중단된 응답을 정상 객체와 같은 상태로 취급해서는 안 됩니다.

그 문서는 Structured Outputs에도 실수가 남을 수 있다고 명시합니다. 2024년 원발표도 JSON 객체 안에서 수학 풀이의 한 단계를 틀리는 예를 듭니다. 스키마를 따르는 기능과 내용의 정답 보장은 같은 약속이 아닙니다. 이 글은 API 연결·설정 절차를 다루지 않습니다.

수량을 뜻하는 상자 묶음과 단가를 뜻하는 태그가 곱셈 기호로 연결되고, 대각선 종이 다리가 합계 태그로 이어지는 설명 조형물. 수량 × 단가와 합계 문구가 보인다.
수량 × 단가와 합계가 맞는지는 값 사이의 관계를 확인하는 별도의 검사입니다. 실제 계산 결과가 아닌 관계 개념을 표현한 생성 그림입니다.

합계가 맞아도 가격의 근거는 남습니다

마지막 예제의 2 × 1000 = 2000이 맞아도, 펜의 실제 단가가 1,000원인지는 이 검사로 알 수 없습니다. 상품명과 수량 자체가 원문에 맞는지도 따로 남습니다. 이 시험은 작은 정수 예제의 곱 일치만 확인했으며, 큰 정수의 곱셈 중간값이나 실제 주문 처리 전체를 검증하지 않았습니다.

파싱에서 막혔다면 JSON 문법을, 수량의 타입이 다르다면 입력 계약을, 계산만 어긋났다면 해당 식과 원본 값을 보세요. 잘못된 값의 출처를 고치지 않고 ‘JSON으로만 다시 답해’라고 요청하는 것은 다른 문제를 만지는 셈입니다.

코드 수정 전체의 검수 순서가 필요하다면 AI의 완료 보고와 실제 코드 검수를 구분하는 글로 이어갈 수 있습니다.

출처 및 확인일