Quality eval harness for chat + RAG answers (JOB-3)#60
Open
Pragadeesh122 wants to merge 3 commits into
Open
Conversation
The eval runner was written against a stale schema and never executed:
- table names were plural (projects/documents) but the live schema is
singular (project/document)
- it inserted a string user_id ('eval-system') into project.user_id, a
non-nullable UUID FK to user.id
- retrieval relevance metrics (recall@k, mrr, ndcg) were always 0 because
they compared expected dataset filenames against the vector store's
'source' (the {document_id}.ext storage object name)
Fixes:
- create an ephemeral user + project with correct singular table names and
a real UUID FK; tear both down (plus the user) in cleanup
- map each retrieved chunk's document_id back to its original dataset
filename before computing filename-based metrics
- add offline unit tests for judge response parsing + fallback
Co-Authored-By: Paperclip <[email protected]>
- add Makefile targets (make eval / eval-retrieval / eval-unit) - wire eval changes into PR CI: add evals/ and tests/ to the api paths filter so the offline eval unit tests run on every relevant PR - add advisory full-eval workflow (.github/workflows/eval.yml): manual + weekly, spins up the stack via compose, runs the end-to-end eval against hosted Pinecone + an LLM key, uploads reports as an artifact, writes the aggregate table to the job summary; continue-on-error and gated on secrets - commit a reference baseline (evals/baselines/smoke.md) with current scores - fix .gitignore: evals/reports/ was mis-merged into a nested path and never actually ignored - rewrite evals/README with how to add cases, read results, baselines, and CI Co-Authored-By: Paperclip <[email protected]>
Pragadeesh122
force-pushed
the
job-3-eval-harness
branch
from
July 17, 2026 02:17
0295f21 to
92da08a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes answer quality measurable so we can ship RAG/agent changes with confidence. Builds on the existing
evals/harness, which was written against a stale schema and had never successfully run — this PR makes it actually execute end-to-end, fixes a silently-broken retrieval metric, wires it into CI, and records a baseline.What changed
Harness fixes (it now runs)
projects/documents) but the live schema is singular (project/document), and inserted a stringuser_idinto a non-nullable UUID FK. Now creates an ephemeral user + project correctly and tears both down.source(a{document_id}.extstorage name). Now maps each retrieved chunk'sdocument_idback to its original filename.Repeatable + one command
make eval/make eval-retrieval/make eval-unit.CI (advisory at first)
pr.yml(addedevals/**+tests/**to the api paths filter). Addedtests/test_eval_judge.py(judge parsing + fallback); metrics were already covered.eval.yml: manual + weekly, spins up the stack via compose, runs the full eval against hosted Pinecone + an LLM key, uploads reports as an artifact and writes the aggregate table to the job summary.continue-on-error, gated on secrets (no-ops without them).Docs + baseline
evals/README.md(how to add cases, read results, baselines, CI).evals/baselines/smoke.mdwith current scores..gitignore:evals/reports/was mis-merged into a nested path and never actually ignored.Baseline (smoke: 4 docs, 10 queries; gen
gpt-5.4, judgegpt-4o-mini)Expected docs always retrieved (recall@5=1.0); ordering has headroom (MRR/NDCG). Answers fully grounded and complete.
Verification
make eval-unit→ 34 passed (offline).uv run python evals/run_eval.py --dataset smokeexecuted against the local stack + hosted Pinecone + OpenAI; ephemeral resources cleaned up.Notes / follow-ups
PINECONE_API_KEYandOPENAI_API_KEYto enable the advisoryeval.ymlruns; until then it no-ops.hallucinationdimension occasionally inverts its scale (scored 1 while reasoning "no hallucinations present"). Documented as a caveat; candidate follow-up is to reword it togroundedness.🤖 Generated with Claude Code