월간 보고 초안의 문장은 빨리 나왔지만, 주문 수와 증감률을 다시 확인하느라 시간이 든다고 가정해 볼게요. 이런 반복 작업은 AI에게 계산과 설명을 한꺼번에 맡기기보다 계산된 지표를 전달하고, 초안의 숫자·단위·누락을 다시 검사하는 흐름으로 만들 수 있어요. 이번 결과물은 입력 파일, 채운 초안, 정상·차단 사례가 있는 작은 검증 프로그램이에요.
첨부 링크는 이 글의 예제 ZIP으로 연결돼요. 압축을 푼 뒤 링크에 표시된 파일을 열면 입력·코드·완성 자료를 함께 사용할 수 있어요.
예제의 주문·매출·민원은 가상 자료예요. 2026년 10월 13일 현재 집필 AI 에이전트가 입력 (ZIP: input.json)을 읽고 초안 (ZIP: agent-draft.json)을 작성했고, Python 3.12.3에서 검사 코드 (ZIP: validate.py)를 실행했어요. 실제 보고 전송이나 회사 자료 공유는 하지 않았어요.

먼저 보고서에서 빠지면 안 되는 값을 정해요
가상의 9월 운영 보고에는 주문 수, 매출액, 매출 증감률, 정시 처리율, 처리율의 전월 차이, 민원 건수가 꼭 들어가야 해요. 입력은 8월 주문 100건·매출 500만 원·정시 처리 92건, 9월 주문 120건·매출 600만 원·정시 처리 108건·민원 4건이에요.
| 지표 | 계산 | 보고할 값 |
|---|---|---|
| 9월 주문 | 입력값 | 120건 |
| 9월 매출 | 입력값 | 6,000,000원 |
| 매출 증감률 | (600만/500만−1)×100 | +20.0% |
| 9월 정시 처리율 | 108/120×100 | 90.0% |
| 처리율 전월 차이 | 90.0−92.0 | −2.0%p |
| 9월 민원 | 입력값 | 4건 |
여기서 ‘2% 감소’와 ‘2%포인트 하락’을 섞지 않는 것이 중요해요. 92%에서 90%로 바뀐 두 비율의 차이는 −2%p예요. 상대 변화율을 쓰려면 (90/92−1)×100을 따로 계산해야 해요. 이번 보고의 질문은 전월 처리율과의 차이이므로 %p를 택했어요.
민원 수를 모르는 상태에서 0건으로 채우면 누락이 성과처럼 보일 수 있어요. 필수 입력이 없으면 먼저 보류하도록 정했고, 전월 매출 또는 전월·당월 주문 수가 0이어서 비율의 분모를 만들 수 없는 경우도 중단하게 했어요. 실제 업무에서는 ‘산출 불가’ 표시로 보고할지 전체를 보류할지 담당자와 정하면 돼요.

숫자마다 출처 ID를 붙인 초안을 받아요
이번 초안은 사람이 읽는 요약과 프로그램이 읽는 지표 배열을 함께 담았어요. 지표 한 개에는 id, value, unit, source_id가 들어가요. 출처 ID는 synthetic-ledger-2026-09-v1이에요. 이 ID가 나중에 수정된 원장 버전과 섞이지 않도록 기간도 별도 필드로 보관해요.
실제 작성된 요약은 다음과 같아요.
9월 주문은 120건, 매출은 6,000,000원으로 전월 대비 20.0% 늘었어요. 정시 처리율은 90.0%로 2.0%p 낮아졌어요. 민원은 4건이에요. 증가 원인은 이 자료만으로 확인하지 못했어요.
다음 행동은 ‘정시 처리 실패 12건의 원인을 담당자가 확인한다’로 적었어요. 120−108=12라는 대상은 계산할 수 있지만, ‘주문 증가로 인력이 부족했다’는 원인은 입력에 없어요. 매출 증가를 보고서의 긍정적 결론으로 정해 놓으면 처리율 하락과 미확인 원인이 지워질 수 있어서 두 방향의 변화를 함께 남겼어요.
검사 프로그램은 필수 지표 집합이 맞는지, 중복 ID가 없는지, 값과 단위·기간·출처가 입력과 일치하는지 확인해요. 현재의 0.000001 허용 오차는 소수 계산의 표현 차이를 위한 값이에요. 보고용 반올림 자릿수와는 별개이며, 금액의 잘못된 반올림을 허용하는 기준으로 쓰지 않아요.
일부러 틀린 입력도 넣어 검사 범위를 알아봐요
assets 폴더에서 python3 validate.py를 실행하면 다섯 사례가 검증 결과 (ZIP: validation-results.json)에 저장돼요. 정상 초안은 통과했어요. 매출 증감률만 20에서 30으로 바꾼 사례, 민원 지표를 삭제한 사례, 원본 민원 수를 비워 둔 사례는 차단됐어요. 이 변조들은 검사 범위를 확인하려고 코드가 의도적으로 만든 시험이에요. AI가 자연스럽게 이런 오류를 냈다고 주장하는 기록이 아니에요.
마지막 사례에서는 숫자 배열을 그대로 두고 문장만 ‘정시 처리율이 크게 개선됐어요’로 바꿨어요. 자동 검사는 통과했지만 이 문장은 실제 하락과 반대예요. 즉, 구조화된 숫자 검사가 통과해도 서술 검토가 끝난 것은 아니에요. 결과 파일에는 이 사례를 사람의 의미 검토에서 보류해야 한다고 명시했어요.


이처럼 오류를 종류별로 다루는 접근은 NIST 생성 AI 위험관리 프로파일의 사용 맥락에 맞춘 위험 관리와 연결돼요. 여기의 Python 검사는 그 문서가 정한 공식 인증 방식은 아니에요.
검사 통과 뒤에는 요약의 방향과 강도, 원인 주장, 빠진 조건을 사람이 확인해요. 숫자가 맞아도 ‘급격히’나 ‘성공적으로’ 같은 표현이 근거보다 강할 수 있어요. 매출과 주문이 함께 늘었다는 사실만으로 특정 캠페인의 효과를 확정해서도 안 돼요. 원장 자체의 정확성 역시 출처 ID 일치만으로는 알 수 없어요.
처음부터 전송까지 연결하기 어렵다면 이 흐름을 초안 폴더까지만 실행하세요. 실패한 입력과 수정 이유를 남긴 뒤 새 버전으로 다시 검사하면 돼요. 보고 자동화의 완료 기준은 문장이 생성되는 순간이 아니라, 필수 사실이 빠지지 않고 검토자가 근거와 남은 판단을 바로 찾을 수 있는 상태예요.
작성·확인: Codex가 예제 자료와 초안을 작성하고 본문에 명시한 원문 대조·계산·자동 검사를 수행했어요. 별도 사람의 사용성 검증은 하지 않았어요.
초안 검사가 실제 업무 시간을 줄였는지 판단하려면 작성·검토·재작업 시간 기록로 이어서 확인할 수 있어요.
설명 삽화 2장은 GPT로 생성한 개념 설명이에요. 실제 예제의 작업 화면과 실행 결과는 기존 그림·첨부 자료에서 따로 확인할 수 있어요.