citefid 0.1.0: NLI를 사용하여 OKF 위키의 인용 충실도 검증 (코드에 대해 AUC 0.70)
요약
citefid 0.1.0은 OKF 위키 생성물의 인용 충실도를 검증하는 도구입니다. NLI(Natural Language Inference)를 활용하여 인용된 소스 조각이 실제 주장을 뒷받침하는지, 모순되는지, 혹은 중립적인지를 3단계 파이프라인을 통해 판별합니다.
핵심 포인트
- 인용의 존재 여부를 넘어 내용의 충실도(Fidelity)를 검증
- Resolve, Retrieve, Verify의 3단계 결정론적 파이프라인 제공
- NLI 모델(DeBERTa-v3-small)을 활용한 지지/반박 판별
- 정확한 검증을 위해 검색(Retrieve) 단계를 필수 과정으로 포함
citefid 0.1.0: NLI를 사용하여 OKF 위키의 인용 충실도 검증 (코드에 대해 AUC 0.70)
OKF 위키 생성기들은 인용이 존재하는지는 확인하지만, 그 내용이 주장을 뒷받침하는지는 확인하지 않습니다. citefid는 이 격차를 메웁니다: 존재 여부가 아닌 충실도(fidelity)를 검증합니다.
문제점
OKF (Open Knowledge Format) 표준을 따르는 LLM 생성 지식 위키는 코드 조각이나 문서에 대한 인용을 포함합니다. 전형적인 파이프라인은 인용된 파일이 존재하는지, 그리고 라인 범위가 유효한지를 검증합니다. 하지만 이는 해당 조각이 텍스트의 주장을 **확인(confirm)**하는지에 대해서는 아무것도 말해주지 않습니다.
기존 문헌들은 이러한 공백을 기록하고 있습니다: 주장을 뒷받침하지 않는 소스를 가리키는 인용 (CiteCheck; "Cited but Not Verified"; 기만적인 그라운딩 (grounding)). 위키를 신뢰하는 독자는 검증되지 않은 주장을 그대로 받아들이게 됩니다.
citefid는 위키를 생성하지 않습니다. 하나의 주장(claim)과 그 인용을 가져와서, 소스 조각이 이를 **확인(confirm)**하는지, **모순(contradict)**되는지, 또는 **중립(neutral)**적인지를 답변합니다.
해당하지 않는 사항
- OKF 위키를 생성하지 않습니다 (그것은 다른 도구들이 수행하며, citefid는 빌드 후에 검증합니다).
- 인용된 번들 외부의 외부 소스(외부 웹/PDF)를 해결하지 않습니다.
- 멀티홉(multi-hop) 검증이나 심층 추론을 수행하지 않습니다 (MVP: 인용당 하나의 구절).
작동 방식
3단계의 결정론적(deterministic) 파이프라인:
resolve— 인용을 소스 조각(fragment)으로 해결합니다. 코드/CRD: URLblob/<commit>/<path>#Lx-Ly→ 해당 커밋의 파일을 다운로드하고 라인을 자릅니다. 산문(Prosa):^[slug.md]→ 접두사-해시(prefix-hash) 방식으로 해결하며(실제 파일은 해시 접미사를 가짐), 유일한 일치를 요구합니다.retrieve— 검증을 수행하기 전에 관련 문단을 검색합니다. 하이브리드 방식: 키워드 우선(주장의 특징적인 토큰), 동률 발생 시 임베딩(embeddings, MiniLM)을 사용하여 결정합니다. YAML 프론트매터(frontmatter)는 건너뜁니다. 이 단계는 선택 사항이 아닌 필수 단계입니다.verify— 검색된 구절에 대해 NLI (cross-encoder/nli-deberta-v3-small, CPU, API 키 불필요)를 수행하며, $N$개의 증거에 대해 합산합니다 (지지(support) = 최대 함의(entail) − 반박(contra)). 증거별로 결정론적인 CSV/JSON 보고서를 생성합니다.
retrieve가 필수인 이유 (단순한 장식이 아님)
개발 과정에서 가장 뼈아픈 실수는 문서 전체에 대한 NLI만으로 충분하다고 믿었던 것이었습니다. span[:1500](절단됨)에 대한 NLI는 산문에서 0.92라는 기만적인 AUC를 보여주었습니다. 실제 사실은 1,500번째 문자 너머에 있었고, 모델은 프론트매터(frontmatter)만을 보고 주제적 맥락에 따라
- AUC = P(충실한 쌍 지원 > 불충실한 쌍 지원). NLI 레이블은 하드코딩된 인덱스가 아니라 모델의
id2label이름을 통해 해결됩니다 (구현 과정에서 발견한 인덱스 버그로 인해, 주제가 다른 텍스트에 대해서도 entail 0.99가 나오는 현상이 있었습니다). - 긴 산문: 신뢰할 수 있는 수치 없음. 데이터셋 구축 결함으로 인해 세 번의 측정 시도가 무효화되었습니다. 산문에 대한 AUC는 공개하지 않습니다.
- 검색(retrieve)에서 나타난 +0.019는 신뢰 구간이 없는 노이즈 수준입니다. 이는 수치로서가 아니라 질적으로(텍스트를 자르지 않음, 프론트매터(frontmatter) 건너뛰기) 정당화됩니다.
재현성 (Reproducibility)
인용된 AUC는 누구나 재현할 수 있습니다. 데이터셋(206개 쌍)과 스크립트는 evaluation/에 있습니다:
pip install -e ".[dev]"
python evaluation/evaluate.py
# AUC (검색된 구절에 대한 NLI) = 0.7219
프로젝트 상태
3단계 중 1단계 — 기능적이고 검증된 MVP. 솔직하게 남아있는 과제는 다음과 같습니다:
- 2단계: 코드/CRD 및 수치적 회색 지대를 위한 LLM-as-judge 레이어. 아직 검증되지 않음.
- 신뢰할 수 있는 AUC가 없는 긴 산문 (결함이 있는 데이터셋으로 인해 세 번의 시도가 무효화됨).
빌드 사이클은 구현 → 깨끗한 클론에서의 독립적 감사 → 수정 순으로 진행되었습니다. NLI 레이블의 치명적인 버그는 자체 보고가 아닌 감사 과정에서 발견되었으며, 가공되지 않은 데이터와 함께 문서화되었습니다.
스택 (Stack)
- Python ≥ 3.12, CPU 전용, API 키 불필요.
sentence-transformers(all-MiniLM-L6-v2, nli-deberta-v3-small),scikit-learn.- CI: ruff + pytest + bandit→SARIF + gitleaks + SonarCloud (조건부).
- 라이선스: AGPL-3.0-or-later.
링크 (Links)
- Repo: https://github.com/amurlaniakea/citefid
- RESEARCH.md: 전체 방법론 및 스파이크(spike) 결과
라이선스: AGPL-3.0-or-later — Copyright (C) 2026 Pedro Sordo Martínez amurlaniakea@gmail.com
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기