Benchmarking
Benchmarking
이 저장소의 평가(evaluation) 경계는 공개 fixture smoke와 private/internal eval을 분리한다. 목적은 리뷰어가 평가 프레임워크와 산출물 구조를 재현할 수 있게 하되, 공개 fixture를 성능 benchmark처럼 오해하지 않게 하는 것이다.
이 레포지토리는 공개 가능한 작은 fixture를 smoke test 용도로만 사용합니다. 실제 성능 평가는 레포지토리에 커밋하지 않는 private/internal eval set을 기준으로 수행하는 것을 전제로 합니다.
Source Of Truth
eval/fixtures/smoke_rfp/raw/: CI 재현성 확인용 공개 RFP fixtureeval/config.yaml: fixture smoke eval config. 검색(retrieval), 답변 품질(answer quality), 인용 정확도(citation accuracy), 근거 검증(evidence verification), latency logging이 모두 실행되는지 확인한다.harness/smoke.yaml: harness 레벨 smoke profilebenchmarks/examples/private100_aggregate_manifest.example.json: private aggregate-only summary flow 검증용 fixturebenchmarks/ablations/rag_quality_axes.yaml:naive_baselinecontrol, primary run, ablation flag 정의benchmarks/registry.schema.json: registry와 run manifest의 최소 schemabenchmarks/registry.json: 커밋 가능한 aggregate registry. 공개 fixture smoke 결과를 성능 순위로 누적하지 않는다.
benchmarks/에는 실행 정의와 aggregate 지표만 둔다. 원문 RFP, raw logs, per-example dump, private case text는 커밋하지 않는다. 기본 baseline은 fixed-size chunking과 dense top-k retrieval만 사용하는 naive_baseline이며, full은 metadata-first/rerank/verifier retry를 켠 비교 대상이다.
Public Fixture Smoke
공개 fixture smoke는 다음을 확인한다.
eval/run_eval.py가 private data 없이 deterministic하게 실행된다.reports/eval_summary.json에 retrieval metrics, answer metrics, citation/evidence metrics, latency metrics가 남는다.scripts/check_latency_slo.py가eval/config.yaml의 latency budget을 검증한다.- PR CI가 네트워크 호출 없이 작은 corpus로 빠르게 회귀를 잡는다.
python3 scripts/build_index.py \
--input_dir eval/fixtures/smoke_rfp/raw \
--output_dir data/index \
--embedding_backend hashing
python3 eval/run_eval.py \
--config eval/config.yaml \
--index_dir data/index \
--output_dir reports
python3 scripts/check_latency_slo.py \
--config eval/config.yaml \
--summary reports/eval_summary.json
이 결과는 benchmark, aggregate report, portfolio headline metric의 source of truth가 아니다. 작은 fixture는 scoring/harness wiring과 재현성을 확인하는 smoke surface다.
Private/Internal Eval
실제 성능 평가는 private/internal eval set에서 수행한다. 원문 문서, per-case prediction, trace는 local-only로 유지하고, 공개 가능한 범위에서는 aggregate-only artifact와 reviewer-friendly evidence 문서만 커밋한다.
private aggregate manifest는 같은 summary tooling을 사용하되, suite.dataset에는 privacy, corpus_size, anonymized, comparison_group 같은 commit-safe metadata만 둔다.
python3 scripts/summarize_benchmark.py \
--manifest benchmarks/examples/private100_aggregate_manifest.example.json \
--registry /private/tmp/private100-registry.json \
--docs /private/tmp/private100-summary.md
이 예시는 흐름 검증용 fixture이며 실측 private 성과가 아니다. private 운영 원칙은 ADR 0005의 commit boundary 규칙을 따른다.
Metrics
평가 지표는 하나의 종합 점수로 합치지 않고 다음 축으로 분리한다.
| Axis | Metrics | Primary Use |
|---|---|---|
| Retrieval quality | chunk_recall@k, MRR, nDCG, rerank delta |
검색(retrieval) 품질과 reranking 효과 |
| Answer quality | accuracy, groundedness, answer format compliance, abstention outcomes | 답변 품질(answer quality)과 보류(abstention) 정책 |
| Citation / evidence | citation precision, claim-citation alignment, evidence coverage | 인용 정확도(citation accuracy)와 근거(evidence) 검증 |
| Latency | p50/p95, stage latency, retry cost, cold-start samples | 운영 latency와 retry cost trade-off |
eval_summary.json에는 같은 metric block이 by_query_type, by_hardcase_category, by_metadata_field, by_format로 전파된다. 공개 fixture smoke는 이 schema가 유지되는지 확인하고, private/internal eval은 실제 delta와 aggregate evidence를 제공한다.
Local Artifacts
scripts/run_benchmark.py는 실행별 산출물을 artifacts/benchmarks/<run_id>/에 저장한다.
run_manifest.json: run id, git commit, suite id, ablation flags, model/retriever/reranker/verifier config, metrics, latency, artifact patheval_summary.json: run의 aggregate eval summarypredictions.jsonl: per-example prediction dumplatency_samples.jsonl: per-example latency/retry sampleerror_examples.jsonl: metric이 실패하거나 partial로 판정된 비교용 error exampletraces/: per-example plan/diagnostics/evidence referencelogs/: index build 등 command log
artifacts/benchmarks/는 .gitignore 대상이다. 공개 fixture smoke 실행이라도 raw prediction과 trace는 noisy하고 커밋 diff를 크게 만들기 때문에 로컬 검증용으로만 둔다.
병행 Codex/Claude worktree에서 만든 benchmark artifact를 PR 근거로 첨부하려면
overlap-preflight 결과를 함께
남긴다. 같은 artifact root나 변경 파일을 공유한 run은 독립 benchmark evidence로
취급하지 않는다.
Stage Latency & Retry Cost
이슈 #32 이후 eval은 단일 latency_ms 외에 stage 단위 latency를 함께 기록한다. 목표는 reviewer가 “응답 시간이 어느 단계에서 쌓이는지”와 “verifier retry가 품질 개선만큼 latency 비용을 정당화하는지”를 동시에 판단할 수 있게 하는 것이다.
run_rag_query의 diagnostics 필드:
stage_latency: top-level stage별 ms —query_analysis_ms,context_resolution_ms,answer_generation_msfilter_stage_attempts[i].retrieve_ms/verify_ms: strict -> reduced -> relaxed 각 retry 시도의 retrieval+rerank, verifier 비용cold_start: 프로세스 첫 호출 여부. warm percentile에는 포함하지 않는다.
Reviewer가 latency trade-off를 읽을 때의 가이드:
latency.p95가 늘어났다면 먼저stage_latency.retrieve_ms/verify_ms를 보고 어느 단계가 원인인지 식별한다.latency_by_retry_count["1+"]의 p95와retry_cost.cases_with_retry를 함께 보고, 같은 retry로 얻은 groundedness/citation/abstention gain이 latency 증가를 정당화하는지 판단한다.cold_start_samples는 별도로 기록되므로 warm steady-state 비교를 흐리지 않는다.