TL;DR
충격의 5/5 FAIL: 직접 읽고 작성한 요약이 전량 FAIL 판정을 받음. 원인은
pdftotext줄바꿈, 유니코드 인코딩 차이, 그리고 과도한 Verbatim 인용 규칙 때문.가장 무서운 오류 (표 행 밀림): 숫자는 원문에 존재하지만 '누구의 수치인가'가 틀린 오출처(Misattribution) 발생. 결정론 검수기조차 pass한 이 오류 때문에 확정된 결론이 3건 뒤집힘.
2분류(PASS/FAIL)의 한계: "틀렸다(Contradicted)"와 "근거가 부족하다(Insufficient)"는 대응 방식이 완전히 다름. 3분류 체계 전환의 필요성 체감.
1. 소개 — 검수를 향한 과도한 자신감과 충격
1편에서는 논문 997편을 요약↔원문 전문 쌍으로 Ingest하고 검수 파이프라인을 구축한 과정을 다뤘습니다. 이번 글은 그 검수 시스템이 실제로 무엇을 잡아냈고, 제 착각을 어떻게 깨부쉈는지에 대한 기록입니다.
솔직히 검수 스크립트를 돌리기 전에는 반신반의했습니다. "내가 논문 원문을 직접 꼼꼼히 읽고 정리한 요약인데 설마 틀린 게 있겠어?"라는 자만심이 있었기 때문입니다.
그러나 새로 정리한 5편을 검수에 넣자마자 5편 전부 FAIL이 떴습니다. 심지어 파이프라인을 통과해 이미 완료된 산출물로 반영했던 결론 중 3건이 나중에 완전히 뒤집히는 사건까지 발생했습니다.
2. 사건 1 — 요약 5편이 전량 FAIL 난 이유
quality-validation 축을 보강하기 위해 논문 5편을 읽고 요약을 작성했습니다. 원문 PDF에서 텍스트를 추출한 뒤, 각 주장에 영어 원문 문장을 직접 인용해 근거를 달았습니다. 그 어느 때보다 철저하게 작업 했다고 자신했습니다.
그리고 검수 스크립트를 실행했습니다.
Bash
python3 verify_summaries.py --dir 40-drafts/quality-validation \
--corpus 60-data/corpus.json --source-dir 60-data/processed/fulltext
Plaintext
[FAIL] 2312.00326.md: Evidence 수치 원문 부재: '200';
Evidence 인용 문구 원문 부재: 'a survey in [89] implies that 1000 is a reasonable...';
Evidence 인용 문구 원문 부재: 'the inequality (k+1)(Ns+Nt) < Ns×Nt always holds...'
[FAIL] 2503.21813.md: Evidence 인용 문구 원문 부재: 'for some (e1,e2)∈Roaei there is...'
[FAIL] 2507.14032.md: Evidence 인용 문구 원문 부재: 'integrating knowledge retrieval with...'
[FAIL] 2507.14552.md: Evidence 인용 문구 원문 부재: 'there was a total improvement of +0.04%...'
[FAIL] 2511.07991.md: Evidence 인용 문구 원문 부재: 'we fine-tune LLaMA-3.1-8B-Instruct'
검수 결과: 파일 7 · PASS 2 · FAIL 5 · WARN 7
5/5 FAIL.
처음엔 검수 스크립트에 버그가 있는 줄 알았습니다. 원문에서 그대로 복사해 붙여넣은 문장을 기계가 "원문에 없다"고 판단했기 때문입니다.
원인 분석: 사람이 보는 문장 vs 기계가 읽는 문자열
직접 CLI에서 grep을 돌려보며 원인을 추적했습니다.
Bash
$ grep -c "1000 is a reasonable number of training samples" 2312.00326.txt
0
원인은 크게 세 가지였고, 전부 시스템이 아닌 제 작성 방식의 문제였습니다.
pdftotext추출 과정의 줄바꿈 (Line Break)PDF를 텍스트로 추출하면 원문의 한 문장이 여러 줄로 분절됩니다. 제가 인용한 문장이 추출 텍스트 상에서 줄바꿈 경계를 넘어가면서 단순 문자열 매칭에 실패했습니다. 사람 눈에는 같은 문장이지만 검수 스크립트에게는 다른 문자열이었던 것입니다.
유니코드 특수문자 인코딩 차이
수식 기호(
∈,′,×등)가 PDF 추출 시 유니코드 변환 과정에서 오차가 생겼습니다. 예컨대(e1,e2)∈Roaei같은 인용은 문자열 대조 방식으로는 매칭될 수 없었습니다.source_grade메타데이터 불일치Frontmatter에는
full_text라고 적었으나, 코퍼스 시스템 기록은api_summary였습니다. 검수기는 직접 인용(Verbatim)이 존재할 경우 원문과 동일한 grade 기준만 허용하도록 설계되어 있었습니다. "전문을 읽고 인용했다"는 제 주장과 실제 시스템 기록의 불일치를 스크립트가 정확히 적발한 것입니다.
해결책: "직접 인용"에서 "서술 + 출처 표기"로 전환
검수를 통과했던 기존 정상 요약문들의 구조를 분석해보니 스타일의 차이가 존재했습니다. 기존 방식은 영어 원문을 큰따옴표("")로 직접 인용하지 않고, 한국어로 요약 서술한 뒤 — §4.3 형태의 출처만 명시하고 있었습니다.
검수 스크립트의 코드 로직을 보니 그 이유가 명확히 드러났습니다.
Python
QUOTE = re.compile(r'"([^"\n]{12,})"|"([^"\n]{12,})"') # 12자 이상 따옴표 문구 추출
...
for q in extract_claim_quotes(ev):
if q.casefold() not in src_fold:
fails.append(f"Evidence 인용 문구 원문 부재: {q[:60]!r}")
따옴표로 감싼 12자 이상의 문자열은 검수 시스템에서 "원문 내에 동일하게 존재해야 하는 완전 일치(Verbatim) 문구"로 인식됩니다. 즉, 따옴표를 사용하는 순간 단순 주장이 아니라 엄격한 원문 대조 선언이 되는 구조였습니다.
따라서 Evidence 절의 큰따옴표를 제거하고 [한국어 요약 서술 + 출처 섹션 표기] 방식으로 전환했습니다. 내용 자체는 유지하되 인용 형식만 수정한 것입니다. 동시에 source_grade를 실제 코퍼스 기록과 일치시켰습니다.
Plaintext
수정 후 검수 결과: 파일 7 · PASS 7 · FAIL 0 · WARN 5
근거를 댈 수 없는 수치는 과감히 제거
2312.00326 논문에서 숫자 200이 지속적으로 FAIL에 걸렸습니다.
Bash
$ python3 -c "print('100-200' in src)"
False
# 원문 PDF 파싱 결과, 텍스트가 '100200'으로 붙어서 추출되어 있었음
원문 PDF의 100-200 entities라는 문구가 파싱 과정에서 하이픈이 소실되며 100200으로 뭉개졌습니다. 도메인 온톨로지가 통상 100~200개 엔티티 규모라는 사실은 맞지만, 현재 코퍼스 데이터 상으로는 숫자 200을 직접 인용할 객관적 근거가 상실된 상태였습니다.
결국 해당 수치를 제거하고 "도메인 온톨로지의 통상 엔티티 규모(수백 개 수준)"로 수치 정밀도를 낮추어 재작성했습니다. 검수 스크립트가 "현재 보유한 텍스트 뭉치로는 해당 수치를 입증할 수 없다"고 경고해 준 셈입니다.
3. 사건 2 — 통과한 검수 뒤에 숨어있던 "뒤집힌 결론 3건"
더 치명적인 문제는 그 다음이었습니다. 검수 파이프라인을 통과하고 최종 실행 플랜 문서에까지 반영했던 결론 중 3건이 나중에 오류로 밝혀졌기 때문입니다.
#
기존 판단 (오류)
원인 및 발견 계기
정정 결과
1
A 논문을 "특정 구조 설계에 대한 반대 증거"로 인용
pdftotext 파싱 시 표(Table)의 행이 3칸 밀려 출력됨. PDF를 이미지로 렌더링하여 육안 재검증
결론 반전: 반대 증거가 아님이 확인됨. 인용 근거 축소
2
"타입 추론 과정은 오프라인 처리가 기본 원칙임"
다른 논문 실측 데이터 확인 결과 지배적 비용 위치가 다름을 발견
부분 인정으로 정정. 감시 지표 자체 수정
3
"해당 데이터 세트는 구조상 역산 불가능함"
Git 변경 이력에 이전 스냅샷이 남아있어 차집합으로 복원 가능했음
전제 오류. 4축 중 2축 복원 성공
가장 아픈 사례: 표(Table) 행 밀림 현상
1번 사례는 오출처(Misattribution)의 전형적인 위험성을 보여줍니다.
PDF 내 표에 일부 빈 셀(Empty Cell)이 존재하는 경우, pdftotext는 텍스트를 추출할 때 행을 위아래로 밀어서 파싱하는 경향이 있습니다. 그 결과 A 행에 있어야 할 수치가 B 행의 수치로 뒤바뀌어 추출되었습니다.
저는 밀려난 텍스트를 바탕으로 요약을 작성했고, 스크립트 검수마저 손쉽게 통과했습니다. 인용된 숫자 자체는 원문 텍스트 파일 어딘가에 "존재"했기 때문입니다.
⚠️ Key Insight: 숫자가 원문 파일 내에 존재하더라도 "그 숫자가 정말 해당 항목의 수치인가?"는 단순 문자열 grep 스크립트가 잡지 못합니다. 이것이 바로 오출처(Misattribution)의 무서움입니다.
이 사건 이후 프로젝트 규약에 다음 항목을 즉시 추가했습니다.
Markdown
★ 표(Table) 데이터 판독 시 반드시 **라벨 수 = 값 행 수** 일치 여부를 검산할 것.
어긋날 경우 `pdftoppm`을 통해 이미지로 렌더링한 후 육안으로 직접 확인할 것.
또한 기존 결론을 몰래 수정하지 않고 교정 이력(Revision Log)을 명확히 남겼습니다. 잘못된 판독이 있었음을 밝히고, 이로 인해 영향을 받는 의사결정 범위와 영향받지 않는 범위를 명시하여 플랜의 혼선을 막았습니다.
4. 스터디 커리큘럼 프레임으로 본 실측 결과
1) 할루시네이션 3종 검증 결과
이번 프로젝트 결과를 스터디 커리큘럼의 프레임워크에 대입해보았습니다.
거짓·오출처 (False / Misattribution)
👉 부분적 방어 성공 (FAIL): 원문에 없는 수치는 단칼에 잡아내지만, '표 행 밀림'으로 인한 연관성 오출처는 검수기를 통과함 (사건 2-1).
누락 (Omission)
👉 경고 수준 방어 (WARN): 키포인트 커버율이 0.6 미만일 때 경고를 띄우지만, Exit Code에는 반영되지 않아 자동 파이프라인을 중단시키지는 못함.
부실 (Shallow Summary)
👉 경고 수준 방어 (WARN): 최소 인용 개수 미달은 FAIL 처리 가능하나, 요약 내용의 논리적 깊이감까지 판단하는 것은 불가.
2) 판정 3분류 체계의 필요성: Insufficient의 부재
현재 제가 구축한 검수 스크립트는 PASS / FAIL의 2분류 체계로 작동합니다. 그러나 실전에서는 3분류 체계의 필요성이 절실했습니다.
Supported (근거 있음) ➔ PASS
Contradicted (원문과 상충됨) ➔ FAIL
Insufficient (근거 부족/확인 불가) ➔ ? (현재는 통째로 FAIL 처리)
현재 구조에서는 "원문 내용과 다르게 틀렸다(Contradicted)"와 "사실일 수 있으나 현재 파일로는 입증이 불가능하다(Insufficient)"가 동일하게 FAIL로 처리됩니다.
하지만 이 둘의 후속 조치는 완전히 다릅니다.
Contradicted ➔ 요약 오류이므로 내용을 수정해야 함
Insufficient ➔ 내용은 사실일 수 있으므로 원문 PDF 재확인 또는 근거 수치 조율이 필요함
앞서 언급한 100200 뭉침 현상이 전형적인 Insufficient 케이스였습니다. 시스템이 이를 구분하지 못하고 단순 FAIL로만 보고했기 때문에, 사람이 직접 원인을 파악하고 수치의 표현 정밀도를 낮추는 작업을 수동으로 수행해야 했습니다.
5. 결론 및 배운 점
1. 검수는 작성자의 성실함을 평가하지 않는다
원문을 직접 읽고 정성껏 인용을 달았더라도 검수 기준에 미달하면 5/5 FAIL이 납니다. 검수 스크립트는 작성자의 노력이 아니라 "결과물 문자열이 원문에 실제로 존재하는가"라는 건조한 사실만 판정합니다. "내가 성실히 읽었으니 맞을 것"이라는 주관적 가정을 완벽히 배제하는 것이 검수 시스템의 존재 이유입니다.
2. "검수 통과"가 "100% 정답"을 의미하지는 않는다
검수를 통과했다고 해서 안심할 수 없습니다. 문자열 대조 방식의 검수는 오출처(잘못된 행의 숫자 인용)를 간과할 수 있습니다. 따라서 검수 통과는 최소한의 1차 필터로 인식하고, 표 파싱 등 오류 취약 구간에서는 별도의 검산 규약을 적용해야 합니다.
3. 교정 이력을 명확히 남길 때 신뢰도가 올라간다
잘못된 결론이 드러났을 때 이를 은폐하지 않고 ① 무엇이 틀렸는지, ② 왜 발생했는지, ③ 이로 인한 영향 범위가 어디까지인지를 투명하게 기록했습니다. 영향 범위를 명확히 통제함으로써 결론 하나가 수정되더라도 전체 실행 플랜이 흔들리는 상황을 방지할 수 있었습니다.
💡 남은 과제 및 질문
PDF 표(Table) 구조 파싱의 자동화 방안
현재는 라벨 수와 데이터 행 수를 비교하는 검산 로직을 수동으로 수행하고 있습니다.
pdfplumber나Unstructured같은 표 구조 인식 라이브러리를 적용해 행 밀림 오류를 자동 감지하는 모듈 도입을 검토 중입니다.결정론 기반의 Insufficient 판정 구현 방식
"원문에 문자열이 없다"는 사실을 넘어, 이것이 단순 파싱 오류(Insufficient)인지 명백한 거짓(Contradicted)인지를 결정론적(Zero-LLM) 코드 수준에서 어떻게 정밀하게 분리할 수 있을지 고민을 이어가고 있습니다.