← 빌드 일지
빌드 로그2026-08-01·4분 읽기

장난감 테스트가 가리고 있던 고장난 엔진: 모순 검출을 통째로 다시 세운 하루

짧은 테스트에서 잘 되던 법률 문서 모순 검출 기능이, 케이스를 실제 서면 수준으로 늘리자 무너졌다. 단어 몇 개를 더 인식시키는 패치가 아니라 비교 방식 자체를 뜯어고쳐야 하는 문제였고, 그 판단과 재설계의 하루를 정리한다.

3줄 요약

  • 짧은 테스트 케이스에서는 잘 돌던 법률 문서 모순 검출 기능이, 케이스를 실제 서면 수준으로 늘리자 검출 0건으로 무너졌다. 원인을 파고드니 단어를 더 인식시키는 패치가 아니라 비교 방식 자체를 다시 짜야 하는 구조 문제였고, 하루 만에 주장과 반박을 그래프로 다루는 새 방식으로 다시 세워 첫 검출에 성공했다.
  • 이게 중요한 이유는 그동안 통과하던 테스트가 사실은 도구가 알아듣는 표현만 골라 써서 통과한 것, 곧 거짓 자신감이었기 때문이다. 안전이 목적인 도구에서 이 거짓 자신감이 가장 위험하다.
  • 빌더에게 남는 교훈은 하나다. 장난감 테스트를 통과했다고 기능이 완성된 게 아니다. 테스트를 실제만큼 어렵게 만들 때 비로소 진짜 구조 결함이 드러난다.

통과하던 테스트가 사실은 아무것도 증명하지 못했다

짧은 테스트가 다 통과한다는 것은 기능이 된다는 뜻이 아니라 테스트가 쉽다는 뜻일 수 있다. 이 도구는 소장과 답변서 같은 문서를 읽어 금액이나 사실관계의 모순을 찾아준다. 그동안 두세 문장짜리 케이스는 전부 통과했다. 그런데 실제 서면 분량과 문체를 본뜬 케이스를 만들어 엔진에 넣자 결과가 충격적이었다. 금액은 다 뽑아냈는데 모순 검출은 0건이었다. 원고가 5천만 원을 주장하고 피고가 3천만 원이라 반박하는 정면 대립을 하나도 연결하지 못했다.

진단해보니 원인은 분명했다. 엔진이 알아듣는 다툼 표현은 "다툰다", "초과하지 아니한다" 같은 정형화된 몇 개뿐이었고, 실제 서면에서 훨씬 자연스러운 "원고 주장 5천만 원이 아니다" 같은 부정 표현은 못 알아들었다. 지금까지 통과한 짧은 케이스는 전부 엔진이 이해하는 그 표현만 골라 써서 잘 되는 것처럼 보였을 뿐이다. 케이스가 장난감이라 결함이 가려져 있었다.

패치로 될 일이 아니었다

부정 표현 하나를 더 인식시키는 수정으로 시작했지만, 곧 이게 표면일 뿐임을 확인했다. 자연스러운 금액 부정을 인식하도록 고치자 격리된 단순 케이스는 검출됐다. 그러나 실무급 케이스는 여전히 0건이었다. 더 깊은 세 겹의 구멍이 드러났다. 다툼 표현이 다양하다는 것이 첫 겹, "그 금액은" 같은 지시어가 어느 금액을 가리키는지 못 잡는다는 것이 둘째 겹, 그리고 실제 답변서가 "받은 건 3천만이고 1천만은 갚아 2천만이 남았으며 별도 2천만은 무관하다"처럼 여러 금액이 얽힌 다단계 논증이라 핵심 다툼을 골라내지 못한다는 것이 셋째 겹이었다.

여기서 판단이 갈렸다. 다툼 표현을 계속 추가하는 것은 두더지 잡기였다. 진짜 문제는 엔진이 금액을 단순한 목록으로 놓고 값만 비교한다는 데 있었다. 실제 서면은 같은 금액이 누구의 주장인지, 원금인지 잔액인지 이미 갚은 돈인지에 따라 의미가 완전히 달라진다. 값만 비교하는 방식으로는 이 맥락을 절대 담을 수 없었다. 비교 방식 자체를 버려야 했다.

주장과 반박을 그래프로 다시 세우다

새 아키텍처는 금액을 목록이 아니라 주장과 반박의 관계망으로 다룬다. 문서에 나오는 금액 하나하나에 그것이 어떤 쟁점에 대한 것인지, 누구의 주장인지, 원금인지 파생된 잔액인지, 긍정인지 부정인지 한정인지를 붙였다. 그런 다음 같은 쟁점에서 당사자가 갈리고 최소한 한쪽이 최종 입장을 밝힌 경우만 확정 모순으로 판정한다. 애매하면 조용히 넘기지 않고 "확인이 필요한 후보"로 올린다.

하루 안에 두 단계를 구현했다. 먼저 문장 하나하나가 주장인지 부정인지 한정인지 인정인지를 가르는 파서를 세웠다. 그 위에 쟁점별로 당사자 입장을 모아 대립을 판정하는 분석기를 얹었다. 검증에서 구엔진이 0건으로 놓치던 실무급 케이스가 실제로 잡혔다. 원고와 피고의 원금 주장 대립을 잡아내면서, 이미 변제한 돈이나 절차 비용 같은 잡음은 걸러냈다. 정상 문서를 넣은 대조군에서는 오탐이 0이었다. 새 방식이 옛 방식의 실패 케이스를 실제로 잡는다는 개념 증명이 선 것이다.

오늘 하루를 관통한 판단

핵심 원칙 하나를 확정했다. 재현율 하한이 정밀도 상한보다 위다. 진짜 모순을 놓치는 것이 애매한 것까지 후보로 올리는 것보다 위험하다는 뜻이다. 사람의 권리가 걸린 문서를 다루는 도구에서, 조용히 아무것도 없다고 넘기는 것은 최악의 실패다. 그래서 숫자와 쟁점과 대립 구조가 보이면 확신이 없어도 일단 후보로 올리도록 설계했다.

오늘 배운 것은 결국 테스트의 정직함이다. 장난감 케이스로 초록불을 받는 것은 쉽지만 아무것도 증명하지 못한다. 테스트를 실제 서면만큼 어렵게 만들 때 비로소 엔진의 진짜 상태가 드러나고, 그제야 무엇을 다시 세워야 하는지가 보인다. 이 재설계는 코어를 통째로 건드리는 큰 작업이라 여러 세션에 걸쳐 이어진다. 완료 선언은 실무급 케이스 전부를 통과하고 독립 검증까지 끝난 뒤에만 할 것이다. 출시는 그때까지 멈춰 있다.

빌드 일지 구독

1인 빌더의 매일 작업 일지 — 새로 만든 것, 깨진 것, 배운 것.

이메일만 넣으면 끝. 매주 1–2회 빌드 일지만 보냅니다. 광고 없음, 언제든 해지.

Wildeconforce

매일 만들고, 매일 분석하고, 매일 기록합니다.
© 2026 wildeconforce · build-in-public

이 사이트는 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.