Eval Cycle — testset / metric SSOT / dual-call eval
개발자 / partner / 새 팀원이 SearchRight 검색 측정 cycle 을 빠르게 잡는 reference. 어떤 metric / 어떤 testset / 어떤 script / 어떤 cache flag 로 측정하는지 SSOT.
사용자 톤은 별 가이드 없음 — measurement 자체가 개발자 영역 (사용자는 검색 결과로 평가).
§1 testset SSOT — docs/data/g5-testset.json
| field | 의미 |
|---|---|
| 11 query (Q001~Q011) | 11 개 자연어 의뢰 — 도메인 / BM / 타겟 / 복합 4 차원 mix |
expected_ids[] | 각 query 의 정답 회사 ID (CSV 사용자 매핑 + manual mapping merge) |
expected_total | enriched pool ∩ 매칭 count (production parity) |
expected_unmatched[] | 일치 안 된 회사 (사용자 매핑 시간 존중) |
expected_unenriched[] | DB 에는 있지만 enriched pool 밖 (A6 cohort backlog) |
locked 2026-05-20 — paradigm = CSV 직접 ILIKE 폐기, normalize + exact match + 사용자 1:1 review + 사용자 notes 박제 exclusion (feedback_respect_user_curation_notes ★★★).
G18 augmented version (docs/data/g5-testset-g18-augmented.json) — judge-augment 로 expected 보강. precision metric 계산용.
§2 metric 정의 SSOT — docs/data/search-metrics-glossary.md
| metric | 정의 |
|---|---|
recall_at_n | 상위 N (default 200) 안 expected 회사 비율 = hit_count / expected_total |
recall_at_2n | 상위 2N (default 400) 안 expected 비율 (stability indicator) |
pool_completeness | 검색 pool 안 expected 비율 (filter 가 자른 회사 분리) |
negative_presence | 상위 N 안 expected_unmatched / 사용자 exclusion 회사 수 |
top_n_invalid_count | GATE-PRECISION judge 결과 (M19''-G1) |
current production (2026-05-22, M-PROD-G22 후):
- recall@200 default = 79.8%
- recall@200 opt-in
llm_rerank= 82.4% - dimension scoreboard (m-q-3b 후 동일): 도메인 85.8 / BM 78.7 (G20) / 타겟 81.1 / 복합 76.0
m-q-3b 결과 = recall 동일 (POST refactor 만, dual-call 88/88 byte-identical).
§3 측정 script
| script | 책임 |
|---|---|
packages/db/scripts/run-test-set.ts | 11 query × N runs 측정 → snapshot JSON 박제 |
packages/db/scripts/eval-compare.ts | 두 RUN_LABEL paired-t test → verdict (significant / trend / noise / identical) |
packages/db/scripts/dual-call-eval.ts | m-q-3b 신설 — V1 vs V2 byte-identity (88 호출 × 양 path) |
apps/web/src/lib/eval-cache.ts | EVAL_CACHE_MODE pin (parser / HyDE JSONL append-only) |
CLI 호환:
# 기본 11 query 1 run
pnpm tsx packages/db/scripts/run-test-set.ts --label baseline-2026-05-26
# 3-run paired (HyDE 변경 시 의무, feedback_hyde_change_multisample)
pnpm tsx packages/db/scripts/run-test-set.ts --label candidate --runs 3
# paired-t 비교
pnpm tsx packages/db/scripts/eval-compare.ts baseline candidate --metric recall_at_n
# dual-call byte-identity (m-q-3b 게이트)
EVAL_CACHE_MODE=true pnpm dev # 별 터미널
EVAL_CACHE_MODE=true pnpm --filter @searchright/db exec tsx scripts/dual-call-eval.ts
§4 EVAL_CACHE_MODE 격리
stochastic 분리 의무 — parser / HyDE 가 LLM 호출이라 run-to-run variance ±15~20pp 발생 가능 (feedback_parser_prompt_global_perturb FP-15).
apps/web/src/lib/eval-cache.ts:
EVAL_CACHE_MODE=trueenv → parser / HyDE 결과를packages/db/scripts/parser-cache.jsonl에 append-only pin- 다음 호출은 cache hit → 결정성 보장 (production 경로는 본 cache 안 만짐)
EVAL_CACHE_MODE 가 pin 안 하는 것:
- embedding (OpenAI text-embedding-3-small) — distributed inference FP non-determinism
- Cohere rerank — fresh API call 매 호출
- LLM listwise rerank — fresh
m-q-3b §5 B3 발견 — no-cache axis 에서 similarity ε-perturbation = embedding FP. EXCLUDE_FIELDS 에 similarity / bm25_score / final_score 등 추가로 dual-call 88/88 통과.
향후 mission 후보: EVAL_CACHE_MODE 에 embedding cache 추가 (m-q-3b §7 이월).
§5 새 mission 측정 의무 (체크리스트)
새 mission 진입 시 → mission file §4 측정 게이트 박제:
- 3-run paired (
feedback_hyde_change_multisample) — HyDE / parser 변경 시 - EVAL_CACHE_MODE=true 격리 (
feedback_filter_cut_counterfactual) — stochastic 분리 - per-company root cause (
feedback_expected_db_inspection) — aggregate 분포만 보지 말 것, expected 회사 id/name unique key 로 실제 DB 조회 - GATE-5 eval-compare artifact 첨부 (
docs/agent-rules/principles.md §Q2) —docs/data/eval-runs/*.jsonPR body link 의무 - dimension scoreboard 측정 (
feedback_dimension_scoreboard) — single hit_rate 금지, 도메인 / BM / 타겟 / 복합 분리
새 ontology / 6 dim 변경 추가 의무 (data-model.md §6):
- ontology source 갱신 + parser 동시 갱신 (FP-15)
- testset expected_ids 영향도 측정
- dual-call eval 게이트
§6 비용 cap + ledger
- 데이터 작업: 일 $20 cap (
feedback_harness_data_vs_agent_cost★★★) - 에이전트 실행: cap 없음 (별 ledger)
- mission close 시
COST_DASHBOARD.md §1 + §3 + §4 + .costs/usage.jsonl4 source 동시 갱신 (reference_cost_dashboard★★★)
current cumulative ~$368.58 (2026-05-26, m-q-3b $1.05 추가 후).
§7 박제 / 룰 reference
★★★ memory (검색 측정 anti-pattern 방지)
feedback_filter_cut_counterfactual— CUT 수 세지 말고 counterfactual 측정. EVAL_CACHE_MODE 격리 의무.feedback_hyde_change_multisample— HyDE 변경 = 3-run 다중샘플 의무.feedback_parser_prompt_global_perturb(FP-15) — parser SYSTEM_PROMPT 편집 = 전역 perturb.feedback_rerank_pool_sweet_spot— pool sweep (100/300/500) 으로 봉우리 채택. 단조 증가 가정 금지.feedback_tier_weight_zero_sum— 전역 tier / prior multiplier = zero-sum.feedback_expected_db_inspection— expected 회사 DB state 인지 + per-company root cause.feedback_data_quality_structural_detection— 데이터 품질 결함 검출 = 구조 기반 (length-only 금지).feedback_audit_check_vs_data_defect— audit FAIL = 데이터 결함 OR check 코드 결함, 먼저 분간.feedback_search_metrics_ssot— testset 확정 후 CSV 재참조 금지.feedback_recall_over_pool_metric— 고정 N 폐기, expected_hit_rate ≥ 7080% + negative_presence ≤ 12.feedback_measure_production_parity— 4 axis (hyde/rerank/profileSources/no_cache) + enriched_pool gate 자가 점검.
§8 더 깊은 reference
- pipeline 구조:
docs/dev/architecture.md §1 + §2 - 6 dim DB schema:
docs/dev/data-model.md - testset audit history:
docs/research/2{6,9,17,29,31,40,48}-*-testset-*.md - 검색 품질 트랙 history:
docs/archives/handoffs-2026-{04,05}.md(M-PROD-G2 ~ G22 + m-q-3b) - 사용자 톤 ("왜 이 결과인가"):
docs/user/how-it-works.md §5 한계