eval-metrics의 cite_f1 ·
cite_f1_entail ·
grounded ·
recency 는
"인용이 실제로 지지되나 / 정보가 최신인가"를 재려는 지표다. 그런데 이걸 정확히 판정하는 것 자체가 어렵다.
이 페이지는 그 판정 로직을 측정 가능하게 세우는 설계와, 단계별 구현 진행을 실시간으로 기록한다.
eval_ph1 DB 실측 · 소스 src/agent_eval/research/{scorer,grounding,claim_verify,grounding_guard,recency}.py · workers/cli_verifier.pyP0(메타평가)부터 순차 구현 중. 각 단계 완료 시 실측 수치와 함께 이 표를 갱신한다.
| 단계 | 내용 | 상태 |
|---|---|---|
| P0 | 메타평가 하니스 + disagree 층 gold 라벨링 → 판정기 채점 완료 | ● 완료 (함의 κ=0 확인) |
| P1 | claim 단위 분해 + 결정적 프리필터 | ○ 예정 |
| P2 | claim별 등급 함의 + overlap−entail delta 상설 KPI | ○ 예정 |
| P3 | 저신뢰 claim 이종 다중검증 quorum | ○ 예정 |
| P4 | 시간민감도 분류 + 경계형 최신성 오라클 | ○ 예정 |
| 산출물 | 내용 |
|---|---|
| migrations/024_ citation_judge_eval.sql |
테이블 citation_gold(사람이 채우는 gold 라벨) + 뷰 v_citation_verdict_quality(fail-open 분리) + v_citation_judge_eval(판정기↔gold 혼동행렬). init-db 멱등 확인. |
| research/judge_eval.py | 혼동행렬→accuracy·precision·recall·F1·Cohen κ 순수함수 + fail-open 분리 집계 + 함의판정기(cite_f1_entail 임계) 대조. |
| research/gold_sample.py | 층화 추출(disagree≻fail_open≻entail_low≻random) 라운드로빈. run_id UNIQUE로 멱등. |
| cli.py | citation-gold-sample(적재) · citation-gold-eval(리포트). tests/test_citation_judge.py 13건. |
ok=false인데 supported=true로 집계).perf_research-xverify-observe/gate, brain-digest-corpus-observe)는 30/30 전부 fail-open → "supported=100%"가 순전히 마스킹 산물. 교정 지지율은 정직하게 N/A(모름).gold_label을 채우면 판정기 accuracy·κ가 활성화된다.인용된 출처 원문을 직접 대조해 48건 전수 라벨(labeler=claude-opus/source-read).
결과 47건 supported · 1건 misattributed. 그런데 함의 판정기는 이 48건을 전부 entail=0(지지 안 함)으로 매겼다.
| 측정 (disagree 층) | 값 | 의미 |
|---|---|---|
| 함의 판정기 accuracy | 2.1% | 거의 전부 틀림 |
| Cohen κ | 0.00 | gold와 우연 수준(=신호 없음) |
| false negative | 47/48 | 실제 지지되는데 "지지 안 함" 오판 |
claude -p 검증기가 실제로 돌았다. HotpotQA는 2개 gold 문서를 인용하고 둘 다 필요해
f1이 0/1로 갈리는데, 검증기가 2-hop 합성 답의 ~80%를 "지지 안 함"으로 오판한다
(예: "Yingkou=prefecture-level, Fuding=county-level" — 두 문서에 그대로 있는데 entail=0).
P0 결론: "판단이 어렵다"는 우려는 실재했다 — ①fail-open이 44%를 부풀리고 ②함의 판정기는
multi-hop에서 심각한 false-negative(κ=0). cite_f1_entail을 액면 그대로 신뢰하면 안 된다.
P1: 검증기 프롬프트를 2-hop 합성추론에 맞게 고치거나 per-claim 분해로 단순화 → 재측정해 κ 상승 확인. random 층도 라벨해 편향 없는 전역 accuracy 확보.
지금 한 화면에 섞여 있어 "판단이 어렵다"는 인상을 주지만, 세 질문은 정답의 출처도, 검증 방법도, 난이도도 다르다.
인용한 출처가 그 주장을 실제로 뒷받침하나. 현재: cite_f1(겹침)→cite_f1_entail(함의).
정답 출처 = 출처 텍스트(폐쇄) → 검증 가능. 실패모드: post-rationalized citation(맞는 URL, 안 지지).
정보가 현재 시점 기준 맞나. 현재: recency(연도언급 프록시).
정답 = 세계의 현재 상태(개방) → 어려움. 실패모드: recency 착시(근거 없이 "2026"을 씀).
실제 검색/증거가 있었나. 현재: grounded / grounding_guard.
정답 = 트레이스의 tool_result(폐쇄) → 검증 가능. 실패모드: 검색 실패인데 지어냄.
추상적 우려가 아니라, 실제 수치가 문제를 증명한다.
cite_f1_entail=0.616이 맞는 숫자인지 검증할 gold가 없다. 게다가 함의 판정기는
단일 claude -p·이진·fail-open이라, 인프라 실패(ok=false)가 supported=true로 떨어져
지표를 부풀린다. → 그래서 P0는 "새 판정"이 아니라 판정기를 측정하는 자를 먼저 만든다.싼 결정적 검사로 거르고, 필요한 곳만 LLM으로, 저신뢰만 다중검증으로. 그리고 모든 판정기를 gold로 채점한다.
CliVerdict.claim_id/claim_text 배선 이미 존재.cite_f1_entail를 claim 단위 + 등급화{supported/partial/misattributed/hallucinated}. leave-one-out precision은 이미 구현됨."문제가 실재하는가"를 새 판정 없이 기존 판정기를 gold로 채점해 숫자로 확정한다. 최소 비용·최대 레버.
불일치 케이스(겹침↑·함의↓ 100건) + fail-open + 랜덤을 층화 추출해 citation_gold에 적재.
사람이 supported/misattributed/unsupported/unverifiable로 라벨.
라벨이 채워지면 판정기 supported vs gold 혼동행렬 → accuracy·per-label P/R·Cohen κ.
판정기 자체의 오차율을 최초로 수치화.
ok=false를 supported가 아니라 미검증으로 분리. 순진한 지지율 vs 교정 지지율을
나란히 → 부풀림 즉시 교정. gold 없이도 즉시 산출.
산출물: 마이그레이션 024_citation_judge_eval.sql(테이블 citation_gold + 뷰
v_citation_verdict_quality·v_citation_judge_eval) ·
모듈 research/gold_sample.py·research/judge_eval.py ·
CLI citation-gold-sample·citation-gold-eval · 테스트(mock).
| 단계 | 산출 | 승격 게이트 |
|---|---|---|
| P0 | 메타평가+gold+fail-open 분리 | 문제 실재 확정(판정기-gold 격차 측정됨) |
| P1 | claim 분해 + 결정적 프리필터 | 무료 컷이 명백 날조를 잡나 |
| P2 | claim별 등급 함의 + delta KPI | 판정기-gold 일치도 ↑ |
| P3 | 이종 다중검증 quorum | 저신뢰 구간 일치도 ↑ · 비용 대비 |
| P4 | 시간민감도 + 최신성 오라클 | volatile claim에서 recency 착시 ↓ |
각 단계는 메타평가에서 판정기-gold 일치도가 실제로 오를 때만 승격한다(에이전트 개선 프로그램과 동일 철학).
cite_f1_entail·cli_verifier 채택)에 속한다.
citation_gold는 판정기를 측정하는 메타평가 산물이지 코어 판정 경로가 아니다. 코어 runs/events LLM-judge를 건드리면 즉시 중단·SPEC 충돌 보고. 내 추론supported=True, ok=False). 단 메타평가는 이를 "미검증"으로 분리 집계해야 부풀림이 안 생긴다. 코드근거