## 배경
1차 Phase 2.2 eval에서 발견: 23개 쿼리가 순차 호출되지만 각 request의
background analyzer task는 모두 동시에 MLX에 요청 날림 → MLX single-inference
서버 queue 폭발 → 22개가 15초 timeout. cache 채워지지 않음.
## 수정
### query_analyzer.py
- LLM_CONCURRENCY = 1 상수 추가
- _LLM_SEMAPHORE: lazy init asyncio.Semaphore (event loop 바인딩)
- analyze() 내부: semaphore → timeout(실제 LLM 호출만) 이중 래핑
semaphore 대기 시간이 timeout에 포함되지 않도록 주의
### run_eval.py
- --analyze true|false 파라미터 추가 (Phase 2.1+ 측정용)
- call_search / evaluate 시그니처에 analyze 전달
## 기대 효과
- prewarm/background/동기 호출 모두 1개씩 순차 MLX 호출
- 23개 대기 시 최악 230초 소요, 단 모두 성공해서 cache 채움
- MLX 서버 부하 안정
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
22개 쿼리(6개 카테고리)와 Recall/MRR/NDCG@10 + latency p50/p95
측정 스크립트 추가. wiggly-weaving-puppy 플랜 Phase 0.2 산출물.
- queries.yaml: 정확키워드/한국어자연어/crosslingual/뉴스/실패 케이스
실제 코퍼스(2026-04-07, 753 docs) 기반 정답 doc_id 매핑
- run_eval.py: 단일 평가 + A/B 비교 모드, CSV 저장
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>