6. 평가 설계

⚠ 2026-08-28 방향 전환 — 이 페이지보다 결정 기록이 우선한다

도메인을 다산콜센터 하나로 줄이고 외국인 고객 지원을 차별점으로 세웠다 (_project/decisions/201, 비공개). 아래 본문의 금융보험·쇼핑·질병관리본부 서술은 그 시점의 사실이라 지우지 않았다 — 절대 원칙 8(“실패를 지운 기록은 기록이 아니다”)과 같은 이유로, 계획이 바뀐 사실 자체가 기록이다.

이 페이지에서 바뀐 것: ① B-0 도메인 분류 정확도 지표는 폐기됐다 ② F-2 채점 케이스가 0건이다 → 2026-09-22 f2_case 99건으로 채워졌다(필요서류 체크리스트, decisions/125) ③ 이전 실측치 Recall@5 0.857 / MRR 0.702 는 무효 — 4개 도메인 14건 기준이었다. 다산 기준 재측정 전까지 이 페이지에 숫자를 다시 적지 않는다(절대 원칙 2). ④ A-3 A-5(동시 통번역 — A-3 은 WebSocket 전달이다, 2026-09-28 오기 정정) 번역 품질을 무엇으로 채점할지 아직 정하지 않았다 — LLM 채점은 절대 원칙 1이 막는다. 1차 범위(서툰 한국어 전사)는 숙련도 4등급 WER 로 2026-09-21 실측했다(하네스 밖 scripts/measure_a5_proficiency.py).

6.1 지표

⚠ 오른쪽 실측 열은 2026-08-28 전부 무효가 됐다 — 4개 도메인 골든셋 14건으로 잰 값인데 도메인이 다산 하나로 줄었다(decisions/201). 지우지 않고 취소선으로 남긴다(절대 원칙 8) — 잰 사실 자체는 기록이고, 재측정 전까지 이 자리에 새 숫자를 넣지 않는다(절대 원칙 2).

영역 지표 목표 기준선 2026-08-27 실측 무효
B-0 도메인 분류 정확도 (자동 분류, 3.2절) ≥ 0.95 지표 폐기 — 분류할 도메인이 없다 0.857 ❌ (n=14)
검색 Recall@5 ≥ 0.70 (오류 없음) / ≥ 0.60 (오류 10%) 0.857 (n=14) → 0.833 (n=96) → 2026-09-22 실측 0.971 ✅ (n=102, run_id 8 · 운영 실구성) → 2026-10-01 최종 측정(운영 노드 측정 파드 · 운영 RDS eval_run run_id 1·2 · 커밋 19b8400 · 3회 최저)에서 같은 값
검색 MRR ≥ 0.55 0.702 (n=14) → 0.666 (n=96) → 0.875 (n=102, run_id 8) → 2026-10-01 최종 측정(운영 노드 측정 파드 · 운영 RDS eval_run run_id 1·2 · 커밋 19b8400 · 3회 최저)에서 같은 값
트리거 적절 발동률 (종료 후 0~1,500ms) ≥ 0.85  
트리거 조기 발동률 / 지연 발동률 각각 별도 집계  
트리거 발동 지연시간 분포 (p50/p95) 측정·기록 (허용 창은 합/불 판정선일 뿐, 개선 추이는 이 분포로 본다) — ⚠ 하네스로는 채점하지 않는다(골든셋에 도착 시각이 없어 재면 가짜 만점이다). 운영 경로 값으로만 본다  
생성 환각 수치 발생 150문항 중 5건 이하  
생성 출처 표시율 100%  
컴플라이언스 재현율 ≥ 0.90  
컴플라이언스 정밀도 ≥ 0.60  
C-5 P1~P7 패턴 마스킹 누락 0건 — 절대 규칙 0건 (n=28) → 0건 ✅ (n=40 패턴 인스턴스, run_id 8·9 둘 다 — ⚠ 오류 없는 전사 한정) → 2026-10-01 최종 측정(운영 노드 측정 파드 · 운영 RDS eval_run run_id 1·2 · 커밋 19b8400 · 3회 최저)에서 같은 값
C-5 과잉 마스킹률 참고 기록 (목표 아님)  
C-5 STT 오류율별 마스킹 재현율 곡선 기록  
성능 내부 처리 p95 ≤ 1,000ms  
성능 E2E 체감 지연 측정·기록 — 2026-09-23 현재 미측정(w7-latency-budget, 수동 QA 게이트 뒤). 합성 통화 관찰값(첫 추천 1,352~3,300ms)은 STT 를 거치지 않아 E2E 가 아니다  
성능 통화당 토큰 비용 측정·기록 — 생성 모델을 운영에 싣지 않아 해당 없음(decisions/124, 카드는 스니펫 폴백)  
F-2 종결 요건 판정 정확도 → 필요서류 체크리스트(decisions/201·305) 100% — 절대 규칙 (조건부 착수) 1.0 (n=99, run_id 8·9 둘 다 — ⚠ 규칙표 상한, 자동 판정은 미측정. decisions/118 되돌림은 팀 판단) → 2026-10-01 최종 측정(운영 노드 측정 파드 · 운영 RDS eval_run run_id 1·2 · 커밋 19b8400 · 3회 최저)에서 같은 값
F-2 근거 규정 검색 정확도 (금융보험·쇼핑만 해당) — 2026-08-28 다산 단일 도메인으로 폐기(decisions/201) —  
F-3 반복 문의 연결 재현율 — rev.5 에서 보류(다산에 고객 ID 가 없다) · 확장 모듈 미착수 확정(decisions/132) —  
G-2 자원 매칭 정확도 ≥ 0.95 (여유 시 — 미구현 시 N/A)  
G-2 폐지·이전 기관 반환 0건 (여유 시 — 미구현 시 N/A)  
F-1 / G-1 탐지 성능 측정 불가 — 5.5절  

부록 B의 H·I 지표는 착수 확정 시 이 표에 편입한다.

첫 실측 (2026-08-27, 잠정)

측정일 2026-08-27 · 커밋 39cbe68 기준 작업분 · 표본 golden-set/v1-50.json (검색 B 케이스 14건 / 도메인 라벨 34건) · 재현:

# ES 기동 — 컴포즈는 2026-09-08 에 걷어냈다(decisions/107). 측정 당시 명령은
# `cd infra && docker compose up -d elasticsearch` 였고, 같은 이미지·같은 버전이다.
docker run -d --name callguard-elasticsearch -p 127.0.0.1:9200:9200 \
  -e discovery.type=single-node -e xpack.security.enabled=false \
  -e ES_JAVA_OPTS="-Xms512m -Xmx512m" seongyuna/callguard-es:9.5.1
export ELASTICSEARCH_URL=http://localhost:9200
.venv/bin/python scripts/index_knowledge_base.py --to-es --recreate
.venv/bin/python scripts/run_eval.py --golden-set golden-set/v1-50.json --runs 3

3회 실행 최저치가 1회 값과 같다 — BM25 도 검색 기반 도메인 판정도 결정적이라 흔들리지 않는다 (절대 원칙 4의 “최저치 고정”이 여기서는 자명하게 성립한다). 임베딩이 들어가는 4주차부터는 다시 본다.

이 값은 잠정이다. 공식 기준선은 3주차 골든셋 150건 재측정이고, CI 게이트로 고정하지 않는다 (w2-baseline-gate).

도메인 4종 반영 (2026-08-26) — Recall@5·MRR 등 검색 지표는 4개 도메인 전체 평균과 함께 도메인별로도 따로 집계한다. 도메인마다 지식베이스 크기·카테고리 수가 달라 평균값 하나로는 특정 도메인의 부진을 가릴 수 있다.

실측 (2026-09-22) — run_id 8·9

⚠ 「운영 구성」이라는 말을 쓰지 않는다. 2026-09-22 12:10 이전에는 그 말이 BM25 를 가리켰고 그 뒤로는 dense 를 가리켜, 같은 표 안에서 서로 다른 것을 뜻했다. 아래 두 이름만 쓴다.

이름 무엇 지금 운영에?
BM25 기준선 규칙 마스킹 + BM25(nori), NER 끔 ❌ — 09-22 12:10 이전의 운영 구성. 지금은 dense 가 0건일 때의 대체 경로다
운영 실구성 규칙+NER(koelectra-ner) + KoE5 dense, 리랭커 없음, B-6 문턱 꺼짐 ✅ 09-22 12:10 부터(decisions/124)

모델 구성 값은 운영에 없는 구성이다(decisions/121). → 2026-09-24 정정: 사실이 아니다. decisions/124 가 121(전용 GPU)을 대체해 NER·KoE5 임베딩을 운영 노드 CPU 에 실었고, 09-22 12:10 부터 운영 /health 의 spokes 에 pii_ner·retrieval_dense 가 있다. 운영에 없는 것은 리랭커뿐이다.

공통 조건 — 측정일 2026-09-22 17:08 KST · 커밋 5b2b4c4 · 골든셋 파일 golden-set/v1-150.json 내부판 v1-150.2(295건) = B 102 · B-6 23 · F-2 99 · C-5 항목 36(패턴 인스턴스 40) · C-6 15 · D-1 10통화(golden-set/postcall-v1.json) · ES 인덱스 101청크(여권 TERM-4.23 포함 · nori 품사 필터 decisions/214) · device cpu · 각 3회 최저치 · --record(⚠ 로컬 기록 DB, 운영 RDS 아님). 류준이 run_eval.py --runs 3 --retriever dense --record(run_id 8)와 --runs 3 --no-ner --retriever bm25 --record(run_id 9)로 쟀다. 값의 출처는 _project/STATE.md 「실측값」.

지표 목표 운영 실구성 (run_id 8) BM25 기준선 (run_id 9)
검색 Recall@5 (n 102) ≥ 0.70 0.971 ✅ (99/102) 0.853 ✅ (87/102)
검색 MRR (n 102) ≥ 0.55 0.875 0.686
C-5 누락 (n 40, 오류 0%) 0건 0 ✅ 0 ✅
C-5 오분류 · 과잉 (n 40) 참고 0 · 0.0 0 · 0.0
F-2 판정 정확도 (n 99) 100% 1.0 ⚠ 규칙표 상한 1.0
B-6 정답 없음 기권 (n 23) 측정·기록 0 (문턱 꺼짐) 1
B-6 문턱 측정·기록 dense 1순위 <0.67 기권을 채택했다가 같은 날 보류(대화체 60% 기권, decisions/215) — 기본값 꺼짐 해당 없음(눈금이 다르다)
컴플라이언스(tp 14) · 콜 가드(n 15) ≥0.90/0.60 1.0/1.0 ⚠ 자기충족 상한 같음
D-1 요약 핵심 항목 (10통화 · 60항목) 측정·기록 매크로 0.381 · 마이크로 0.35 (21/60) → 2026-10-01 최종 측정(run_id 1·2 · 커밋 19b8400): 매크로 0.877 · 마이크로 0.883 (53/60) 같음
D-2 문의 유형 정확도 측정·기록 측정 불가 — 유형이 null(이 커밋은 decisions/323 머지 전) → 2026-10-01 최종 측정(run_id 1·2 · 커밋 19b8400): 1.0 (n 10통화 · 유형 null 0 · 5종 중 3종 표본) 같음
트리거 · D-5 통화 온도 · 생성 · A-5 — 측정 불가(의도적 미배선 · 음성 골든셋 0건 · 생성 포트 미장착) — D-5 는 발표 전 배선하지 않기로 확정(decisions/317) 같음

STT 오류 내성 곡선 — ⚠ 한 세대 낡았다. 커밋 e966b62 · 골든셋 v1-150.1 · 검색 n 96 · C-5 판정 24 에서 잰 것이고, 5b2b4c4·v1-150.2 로는 아직 다시 재지 않았다. 위 표(n 102)와 같은 문장에서 섞어 쓰지 않는다. (scripts/measure_error_tolerance.py, 시드 3 — 검색은 최저, C-5 누락은 최대)

오류율 Recall@5 dense BM25 dense+리랭커 C-5 누락 규칙만 규칙+NER
0% 0.969 0.812 0.969 0 0
5% 0.969 0.812 0.969 1 0
10% 0.969 ✅(기준 ≥0.60) 0.792 0.969 2 0
15% 0.969 0.802 0.969 4 2
20% 0.969 0.792 0.969 4 2

읽을 때 붙이는 단서 —

그때의 값 — 2026-09-21 (골든셋 156건 · n 96 · 기록 DB 없음) | 지표 | 규칙+BM25 | NER+dense | +리랭커 | |---|---|---|---| | 검색 Recall@5 (n 96) | 0.833 | 0.979 | 0.979 | | 검색 MRR (n 96) | 0.666 | 0.885 | 0.919 | | C-5 누락 (n 28) | 0 | 0 | 0 | BM25 쪽은 정성윤이 커밋 `261bce4-dirty` 로, 모델 계열은 류준이 커밋 `97f7b25`(Apple M5 mps)로 쟀다. 그림 [2계열](/assets/error-tolerance-2026-09-21.png) · [5계열](/assets/error-tolerance-2026-09-21-models.png). **표본이 달라 위 표와 항목 단위로 비교할 수 없다** — 그 뒤 여권 조항이 들어오고(`decisions/217`) nori 품사 필터가 붙었다(`decisions/214`).

6.2 채점 원칙

  1. LLM을 채점자로 쓰지 않는다. 답을 만든 모델이 자기 답을 심판하면 순환이 된다. 모든 지표를 규칙으로 계산해 재현 가능하게 한다.
  2. 여러 번 실행한 값 중 최저치를 기준선으로 고정한다. 생성 모델은 같은 입력에도 답이 달라진다.
  3. 기준선 미달 시 CI 실패로 처리한다. 개선이 아니라 회귀 방지가 목적이다.
  4. C-5·F-2의 절대 규칙은 1건이라도 뚫리면 실패로 처리한다. 평균값으로 평가하지 않는다.
  5. 모든 지표는 정답 정의가 코드로 표현 가능해야 한다. 표현할 수 없는 지표는 지표가 아니다 (4.1절 트리거 허용 창이 그 예).

← 개발목차로 돌아가기