AI가 보기 좋은 표를 만드는 것과 시스템에 맞는 데이터를 보내는 것은 다르다

챗봇이 주문 내용을 자연스럽게 정리하는 것과 회계 시스템이 읽을 수 있는 주문 레코드를 생성하는 것은 요구 조건이 다릅니다. 필드 이름이 틀리거나 금액을 문자열로 보내면 자동 처리 단계에서 오류가 생길 수 있습니다. OpenAI의 구조화 출력 가이드는 정의된 JSON Schema에 맞는 형태를 생성하도록 제약하는 기능을 설명합니다. [1]

기존 JSON 모드는 출력이 JSON 형식인지를 중심으로 다루는 반면, 구조화 출력은 필수 필드·자료형·선택값 같은 규칙을 더 직접적으로 지정합니다. 다만 올바른 모양의 데이터가 곧 사실이 맞는 데이터라는 뜻은 아닙니다. “계약 금액” 필드에 900000이 들어 있어도 실제 계약서에는 90000이라고 적혀 있을 수 있습니다.

구조화 출력을 설계할 때 실제로 정해야 할 것

가상의 견적서에서 고객명, 합계 금액, 통화, 품목 목록을 추출한다고 해보겠습니다. 고객명은 텍스트, 합계는 음수가 아닌 수, 통화는 KRW·USD 중 하나, 품목은 이름과 수량을 가진 배열로 규정할 수 있습니다. 누락된 값을 모델이 임의로 채우지 않도록 “알 수 없음” 또는 null의 의미도 정의해야 합니다.

함수 호출에는 입력 스키마가 필요하며 OpenAI 가이드는 strict 모드의 요구사항, 예를 들면 객체의 추가 속성을 허용하지 않는 설정과 필수 항목 처리 등을 설명합니다. 도구 호출 스키마가 유효하지 않으면 요청 자체가 거절될 수 있으므로 실제 API에 맞춰 테스트해야 합니다. [2]

스키마 검증과 사실 검증을 둘 다 해야 한다

첫 번째 검증은 문법과 구조입니다. 필드가 모두 있는지, 값이 정해진 유형인지, 허용되지 않은 속성이 들어오지 않았는지를 검사합니다. 두 번째 검증은 업무 의미입니다. 수량 곱하기 단가가 금액 합계와 일치하는지, 환불 금액이 결제 금액보다 큰지, 주문 날짜가 미래로 입력되었는지를 별도로 확인해야 합니다.

예를 들어 품목이 3개이고 각각 2개×10,000원, 1개×9,000원, 4개×2,500원이라면 합계는 39,000원입니다. 모델이 40,000원을 반환해도 자료형은 숫자라서 스키마 검사에는 합격할 수 있습니다. 이 예시는 직접 만든 가상 계산이며 실제 거래 데이터가 아닙니다. 결국 합계 재계산은 코드가 담당하는 편이 안전합니다.

모델과 도구를 연결하는 경계에 대한 비교

Anthropic의 도구 사용 문서는 모델이 도구 호출을 요청하면 클라이언트 측에서 실행한 후 결과를 모델에 반환하는 과정을 명시합니다. Google Gemini의 구조화 출력 문서 역시 지원되는 모델과 특정 도구의 결합 조건을 별도로 설명합니다. 공급자마다 API 형식과 기능 조건이 다르므로 “JSON을 지원한다”는 문구만 보고 동일하게 구현해서는 안 됩니다. [3] [4]

특정 도구에서 결과를 받았다고 해서 웹사이트에 즉시 게시하거나 자금을 집행하면 위험합니다. 모델 출력은 실행 지시의 후보이고, 실제 실행은 권한 검사·한도 검사·로그 저장을 거친 별도 코드가 담당하는 것이 바람직합니다.

운영 전 확인할 다섯 가지 실패 사례

빈 입력, 모호한 통화 표기, 쉼표가 들어간 숫자, 여러 주문이 합쳐진 문서, 원문과 모델의 합계가 다른 경우를 테스트해 보세요. 같은 문서를 여러 번 처리해 결과가 안정적인지도 검사하면 좋습니다. 점수가 높더라도 드물지만 비용이 큰 오류를 놓치지 않도록 예외 목록을 별도로 유지해야 합니다.

결론적으로 구조화 출력은 자동화의 안전성과 유지보수성을 높이는 중요한 구성요소이지만 그것만으로 사실 확인이나 승인 절차가 해결되지는 않습니다. 개발자는 스키마 오류율과 실제 내용 오류율을 따로 측정해야 시스템의 위험을 정확히 볼 수 있습니다.