← 기술 블로그

다시는 틀리지 않겠다는 약속 — 데이터 무결성 3원칙

Phase: 3 — 매칭 시리즈: AI 협업 개발기 대응 스토리: 운영 블로그 13화

이 글의 배경이 되는 이야기는 13화: 다시는 틀리지 않겠다는 약속에서 읽을 수 있습니다.

이 글을 읽으면 알 수 있는 것


배경: 2,434건이 남긴 질문

이전 글에서 이야기한 새우깡 사건. 이름 기반 매칭 2,434건의 정확도가 0%였다는 것. 1,045개 제품이 잘못된 영양정보를 표시하고 있었다는 것.

이 사건이 남긴 질문은 “왜 틀렸는가”가 아니었습니다. 그건 이미 답이 나왔습니다. 이름 유사도로 매칭하면 안 된다는 것.

진짜 질문은 이것이었습니다. “왜 발견하지 못했는가?”

2,434건을 넣을 때, 한 건도 검증하지 않았습니다. 매칭률 99.5%라는 숫자를 보고 안심했습니다. 누군가가 직접 새우깡을 검색해보기 전까지, 시스템에는 아무 이상이 없었습니다.

이 경험에서 세 가지 원칙을 만들었습니다.


원칙 1: 연결하기 전에 교차검증한다

새로운 방법으로 데이터를 연결하기 전에, 반드시 독립된 식별자로 교차 확인합니다.

“이름으로 연결했다”면, 그 연결이 맞는지를 이름이 아닌 다른 기준으로 확인하는 것입니다. 품목보고번호, 바코드, 인허가번호 등.

새우깡 사건에서 교차검증 한 번이면 즉시 발견됐을 문제였습니다. 이름으로 연결한 2,434건을 품목보고번호로 확인했더니 일치하는 건이 0건이었으니까요.

구체적인 기준도 정했습니다.

새 매칭 로직 적용 전:
  - 독립 키로 샘플 최소 100건 교차검증
  - 불일치율 5% 초과 시 적용하지 않음

100건만 확인했어도 새우깡 사건은 막을 수 있었습니다. 2,434건의 불일치율은 100%였으니까요.


원칙 2: 연결한 후에 전체 검증을 돌린다

매칭을 적용한 후에는, 자동으로 데이터 정합성을 확인하는 검증을 실행합니다.

이 검증은 다섯 가지 항목을 확인합니다.

검증 항목확인 내용
보고번호 역검증영양정보와 제품의 보고번호가 실제로 일치하는가
중복 매칭 감지하나의 제품에 두 개 이상의 영양정보가 연결되지 않았는가
FK 유효성매칭 결과가 가리키는 대상이 실제로 존재하는가
메타데이터 일관성매칭 방법과 신뢰도 점수가 논리적으로 맞는가
HACCP 보고번호 일치HACCP 데이터와 제품의 보고번호가 일치하는가

시험을 보고 답안지를 제출하기 전에 한 번 더 훑어보는 것과 같습니다.

중요한 점은, 이 검증이 자동이라는 것입니다. 사람이 “확인해야지” 하고 기억하는 것이 아니라, 매칭 커맨드 실행 후 반드시 실행하도록 프로세스에 넣었습니다.


원칙 3: 검증 없는 매칭은 저장하지 않는다

아무리 그럴듯해 보여도, 교차검증을 거치지 않은 매칭 결과는 데이터베이스에 반영하지 않습니다.

이 원칙은 불편합니다. “일단 넣어놓고 나중에 확인하자”가 훨씬 편합니다. 하지만 새우깡 사건이 보여줬듯이, 한번 잘못 들어간 데이터는 발견하기가 정말 어렵습니다.

프로그램은 정상적으로 동작합니다. 에러도 없고, 매칭률도 높습니다. 잘못된 데이터가 들어가 있다는 사실은, 누군가가 우연히 해당 제품을 검색해보지 않는 한 드러나지 않습니다.

차라리 넣기 전에 확인하는 것이 낫습니다.


검증 시스템의 설계

전체 검증 커맨드는 이런 구조로 동작합니다.

검증 실행

CHECK-01부터 CHECK-05까지 순차 실행

각 체크: [PASS] 또는 [FAIL] + 상세 메시지

전체 결과: "5/5 PASS" 또는 "4/5 PASS, 1 FAIL"

FAIL이 하나라도 있으면 즉시 보고합니다. “아마 괜찮을 것이다”라고 넘기지 않습니다.

특히 CHECK-01(보고번호 역검증)이 핵심입니다. 영양정보가 연결된 모든 건에 대해, 영양정보 쪽의 보고번호와 제품 쪽의 보고번호가 실제로 일치하는지 전수 확인합니다. 새우깡 사건과 같은 종류의 오매칭을 잡아내는 검증입니다.

--fix 옵션을 사용하면 자동 수정이 가능한 문제를 즉시 수정합니다. 예를 들어, 보고번호가 불일치하는 매칭은 FK를 해제하고 매칭 방법을 “invalid”로 표시합니다.


3원칙이 개발 프로세스에 미친 영향

이 원칙들은 단순히 “조심하자”는 다짐이 아니라, 코드와 프로세스에 녹아 있습니다.

프로젝트 규칙으로 명문화했습니다. 개발 가이드에 데이터 매칭 무결성 규칙을 넣었습니다. “FK 연결 전 교차검증 필수”, “검증 없는 매칭은 커밋하지 않는다” 등이 규칙으로 정해져 있습니다.

두 번째 시선을 도입했습니다. 코드를 만든 AI와 검토하는 AI를 분리했습니다. 자기가 만든 코드의 문제를 자기가 발견하기는 어렵습니다. 다른 시선으로 메모리 사용, DB 접근 패턴, 데이터 정합성을 검토합니다.

교훈을 코드베이스에 기록했습니다. 새우깡 사건의 경위와 수치를 프로젝트 문서에 남겼습니다. 날짜, 건수, 영향 범위까지. 나중에 비슷한 판단을 해야 할 때, 이 기록이 브레이크 역할을 합니다.


갈림길: 검증의 수준을 어디까지 할 것인가

수준방법비용리스크
샘플 검증100건만 확인빠름드문 패턴의 오류를 놓칠 수 있음
전수 자동 검증모든 건을 자동으로 확인DB 쿼리 비용시간이 걸리지만 놓치지 않음
수동 전수 검증사람이 전부 확인현실적으로 불가능700만 건을 사람이 볼 수 없음

가운데를 선택했습니다.

700만 건을 사람이 확인할 수는 없습니다. 하지만 100건 샘플만으로는 불안합니다. 자동 검증 스크립트가 전체를 훑으면서, 정해진 규칙에 어긋나는 건을 찾아내는 방식이 현실적이었습니다.


결과

항목내용
검증 항목 수5개 (보고번호, 중복, FK, 메타데이터, HACCP)
실행 시점매 ETL/매칭 작업 후 필수
자동 수정--fix 옵션으로 FK 해제, 상태 표시 변경
이후 오매칭 사고0건

한계

검증 항목이 커버하지 못하는 영역이 있습니다. 현재 검증은 “연결이 논리적으로 맞는가”를 확인하지만, “영양정보 수치 자체가 합리적인가”는 확인하지 않습니다. 열량이 음수이거나, 나트륨이 10만mg이거나 하는 이상값 감지는 아직 포함되어 있지 않습니다.

검증을 실행하지 않으면 소용없습니다. 자동 검증 시스템이 있어도, 실행하는 것은 사람(또는 프로세스)입니다. 이를 위해 프로젝트 규칙에 “매칭 후 반드시 검증 실행”을 명시했지만, 규칙이 지켜지지 않을 가능성은 항상 있습니다.

한 줄 교훈

잘못된 데이터가 들어가도 에러는 나지 않습니다. 에러가 나지 않는 문제를 잡으려면, “에러가 아닌 것”을 찾는 검증을 직접 만들어야 합니다.


다음 글: 영양정보 완전도 0.1% — 다중 소스 병합 전략