환각 채점 — 150문항 중 5건 이하
무엇을
생성 카드의 환각을 규칙으로 채점한다. 검수 기준은 150문항 중 5건 이하 · 출처 표시율 100% 다.
어떻게 — LLM 에게 묻지 않는다
절대 원칙 1: LLM 을 채점자로 쓰지 않는다. 「이 카드가 환각인가요?」를 모델에게 물으면 재현 가능하지 않고, 채점자와 피채점자가 같은 실패 모드를 공유한다.
규칙으로 잴 수 있는 것부터 고정한다 —
- 출처가 붙어 있는가 (있다/없다 — 규칙)
- 카드에 나온 고유표현이 근거 조항 안에 있는가 (문자열 대조 — 규칙)
- 근거 부족일 때 「관련 문서 없음」을 실제로 반환했는가 (규칙)
규칙으로 못 재는 몫은 사람이 센다. 그때는 센 사람·기준·날짜를 함께 적는다 — 「150문항 중 5건」은 사람이 세는 지표라고 6.1절이 이미 적고 있다.
완료 조건
- 출처 표시율이 100% 가 아니면 그 숫자 그대로 적는다(절대 원칙 2)
- 환각 건수에 판정 기준과 센 방법이 붙는다 — 안 붙으면 그 숫자는 쓸 수 없다
- 150문항을 못 채우면 표본 수를 적고 「150 기준 미달」로 적는다 — 30문항에서 1건을 150 환산하지 않는다
2026-09-15 — 규칙으로 쟀다. 원출력 기준으로는 기준을 못 넘는다
판정 기준과 센 방법
ai/apps/evaluation/metrics/generation.py — 생성기 필터를 import 하지 않고 따로 세웠다(자기 필터로 자기를 채점하면 필터의 구멍이 채점에도 난다. .importlinter 계약 2 도 막는다).
| 지표 | 규칙 |
|---|---|
| 출처 표시율 | 카드마다 source.doc_id 가 비어 있지 않다 |
| 원출력 환각 | 모델 원출력의 줄·쉼표·JSON 원소 조각 중 근거 조항 본문에 문자 그대로 없는 것(공백·문장부호·마크다운만 무시). 괄호 설명도 센다. 의미가 같은 다른 말(신분증↔주민등록증)도 센다. 「없음」·빈 배열은 0 |
| 화면 환각 | 화면에 나간 필요 서류: … 항목 중 본문에 없는 것. 스니펫 카드는 조항 원문이라 0 |
사람이 센 몫은 없다. 「맞는 이름인데 절차에 안 맞는 서류」는 규칙으로 못 재고 세지도 않았다 — 셀 때는 센 사람·기준·날짜를 함께 적는다.
실측 — 96문항, 150 기준 미달
측정일 2026-09-15 · 커밋 38f2fc3-dirty · 골든셋 v1-150 B 96문항 · 상위 1건 생성 · 로컬 Ollama 0.33.3 (Apple Silicon)
검색 결과를 파일로 고정해 모든 조건에 같은 조항을 넣었다 (rerank-dense · data/processed/generation-eval/docs-rerank-dense.json)
.venv/bin/python scripts/eval_generation.py [--no-schema] [--model …]
조건 원출력 환각 카드 환각 조각 목록 카드 「없음」 출력 토큰 p50 p95 출처 표시율 화면 환각
EXAONE-4.0-1.2B + 스키마 89/96 213 59 0 52 589ms 921ms 100% 0
EXAONE-4.0-1.2B 스키마 없음 96/96 416 44 0 80 922ms 944ms 100% 0
kanana-1.5-2.1b 스키마 없음 27/96 40 74 14 24 526ms 977ms 100% 0
- 출처 표시율 100% (세 조건 모두 96/96)
- 화면 환각 0 — 그러나 이건 거의 동어반복이다. 필터와 채점기가 독립 구현이어도 개념(본문 문자 대조)이 같아 필터가 통과시킨 것은 채점도 통과한다
- 의미 있는 수치는 원출력 환각이다: 기본 모델 kanana 27/96 카드(조각 40개). 검수 기준 「150문항 중 5건 이하」를 필터 없이는 못 넘는다. 96 을 150 으로 환산하지 않는다
- EXAONE 은 89~96/96 — 모델 대조
남는 것
- 원출력 환각 27건의 유형 분석 — 조항 표현을 줄여 쓴 것(
위임인 신분증←위임인 신분증 사본)과 진짜 지어낸 것이 섞여 있다. 규칙은 둘 다 센다 - 150문항 — 골든셋 B 항목 확장이 필요하다