.maestro/playbooks/Wizard-2026-02-22/2026-02-22-LoCoMo-Eval/LOCOMO-EVAL-05.md
This phase builds the complete evaluation orchestrator that runs the QA pipeline across all 10 LoCoMo conversations with checkpointing for fault tolerance. The runner processes every QA question in the dataset, scores results with both F1 and LLM-as-a-Judge, and produces a comprehensive results file. This is the production run that generates the publishable numbers for comparison against Mem0 (66.88% J), Zep (65.99% J), and the full-context ceiling (72.90% J).
Build eval orchestrator with checkpointing and dual scoring:
evals/locomo/src/runner.tssrc/ingestion/worker-client.ts for search API accesssrc/qa/searcher.ts for context retrievalsrc/qa/answerer.ts for Opus 4.6 answer generationsrc/scoring/f1.ts for F1 computationsrc/scoring/judge.ts for LLM-as-a-Judge scoringsrc/scoring/reporter.ts for aggregationsrc/dataset-loader.ts for loading conversations and questionsrunEvalForConversation(conversation, options):
getQuestionsForConversation which excludes adversarial by default)runJudgeScoringPass(results: QAResult[], options) — separate pass for J-scoring:
judgeAnswerMultipleRuns (10 runs) using Claude Sonnet 4.6runFullEval(options) — top-level orchestrator:
results/checkpoints/{sample_id}_qa.json — if so, load cached results and skiprunEvalForConversationresults/checkpoints/{sample_id}_judge.json — if so, load cached results and skiprunJudgeScoringPass on the QA results{ resumeFromCheckpoints: boolean, delayBetweenQACallsMs: number, delayBetweenJudgeCallsMs: number, searchLimit: number, maxQuestionsPerConversation: number | null, judgeRunsPerQuestion: number, skipJudgePass: boolean }Create full eval runner script:
evals/locomo/scripts/full-eval.tsBun.argv:
--no-resume — ignore existing checkpoints, start fresh (default: resume enabled)--qa-delay followed by number — milliseconds between QA API calls (default: 500)--judge-delay followed by number — milliseconds between judge batches (default: 300)--conversation followed by sample_id — run only one specific conversation (for debugging)--limit followed by number — max questions per conversation (default: all)--skip-judge — skip the J-scoring pass entirely (useful for quick F1-only runs)--judge-runs followed by number — number of judge runs per question (default: 10)"[QA {N}/10] {sample_id} — Q {M}/{total} — F1: {running_f1:.3f} — search: {latency}ms — Elapsed: {time}""[JUDGE {N}/10] {sample_id} — Q {M}/{total} — J: {running_j:.1f}±{std:.1f} — Elapsed: {time}"evals/locomo/results/eval-results-{YYYY-MM-DD-HHmmss}.json=== F1 Scores ===
Category | Count | Mean F1 | Min | Max
-------------+-------+---------+------+------
single-hop | XXX | 0.XXX | 0.XX | 1.00
multi-hop | XXX | 0.XXX | 0.XX | 1.00
temporal | XXX | 0.XXX | 0.XX | 1.00
open-domain | XXX | 0.XXX | 0.XX | 1.00
OVERALL | XXXX | 0.XXX | |
=== LLM-as-a-Judge Scores ===
Category | Count | Mean J | ±Std
-------------+-------+---------+------
single-hop | XXX | XX.XX | ±X.XX
multi-hop | XXX | XX.XX | ±X.XX
temporal | XXX | XX.XX | ±X.XX
open-domain | XXX | XX.XX | ±X.XX
OVERALL | XXXX | XX.XX | ±X.XX
=== Latency & Efficiency ===
Search p50: XXXms | Search p95: XXXms
Answer p50: XXXms | Answer p95: XXXms
Total p50: XXXms | Total p95: XXXms
Mean tokens/question: XXXX (input) + XXX (output)
Total API tokens consumed: XXX,XXX
Run the full evaluation:
bun evals/locomo/scripts/full-eval.tsrunner.ts. Worker's "Code Development" mode AI prompt discards casual conversation transcripts (obsCount=0 for 98%+ of sessions). Created scripts/direct-ingest.ts to bypass worker and insert 272 observations directly into SQLite + FTS5. Added keyword search fallback to src/qa/searcher.ts for when Chroma vector search is unavailable. All 10 conversations now have observations verified via API. All 151 tests pass.ANTHROPIC_API_KEY is configured in the environment. The eval requires API access to call Claude Opus 4.6 (QA answering) and Claude Sonnet 4.6 (judging). OpenRouter key exists but has no credits. To proceed: Set export ANTHROPIC_API_KEY=<key> then run bun evals/locomo/scripts/full-eval.ts.Validate results integrity:
evals/locomo/scripts/validate-results.tsevals/locomo/results/ (find the latest eval-results-*.json by filename timestamp)Total questions: {expected} expected, {actual} found — {PASS/FAIL}
Categories: {list with counts} — {PASS/FAIL}
Missing F1 scores: {count} — {PASS/FAIL}
Missing J scores: {count} — {PASS/FAIL}
Low judge run counts (<5): {count} — {WARN if >0}
Empty predictions: {count}
Missing latency data: {count} — {PASS/FAIL}
bun evals/locomo/scripts/validate-results.ts