fix(rag): treat required and needed as question wording in relevance terms

Merged
BI
1mo ago
+85-1

Summary

  • Before: "What assessment documentation is required?" lists Assessment Documentation (AKG) 4th, behind Admissions, Radiotherapy and Pressure Injury pages. The paid diagnostic run 38912586460 (PR #3579 recording) shows AKG is ranked 1st to 3rd by retrieval selection and has the highest answer-stage score, so the reorder happens at context selection, which sorts by the per-source relevance verdict first. required was a core evidence term. AKG never says "required", so it scored only partial. The Admissions page says "required", so it scored direct and jumped ahead.
  • After: requirement wording is removed from the question text before tokenising, the same way should is already ignored. Core terms for the question become assessment, documentation, so AKG is direct and keeps its retrieval-led place. Removed words: need, needed, require, required, requires, and needs in "needs to". Kept as subject terms: the noun needs ("support needs"), requirement(s), need after a determiner or modifier ("the clinical need for", "an ongoing need for"), and all requirement words when the question contrasts required with optional.
  • How: one regex step in queryCoreTerms in src/lib/evidence-relevance.ts, plus tests in tests/evidence-relevance.test.ts. A Qodo bot commit (03259b71f) proposed a noun allowlist regex for the same review point. It was superseded by the whole-word approach, and its carers test is kept.

Areas touched: Answer engine
RAG impact: behaviour change — canary pair 38992332213 -> 38996641073

Canary pair

  • Before: run 38992332213 on main 27ef74141. After: run 38996641073 on main 99507ebca (this PR merged).
  • Golden retrieval is identical: document recall@5 1 to 1, content recall@5 1 to 1, mrr@10 0.9106 to 0.9106, failed cases 0 to 0. Per-case reciprocal rank shows zero regressions and zero changes across all cases.
  • Answer quality: assessment-documentation went from failed to passed. The two remaining failures, clozapine-missed-dose-table and admission-discharge-coverage-paraphrase, were failing before this PR too.
  • The after run is red on one latency gate: unsupported-route p95 9452 ms against a 4000 ms budget. It comes from one case, "What is the best coffee machine for my kitchen?", which spent 9450 ms in retrieval. That question has no requirement wording, so this change cannot alter it. The term step also runs after retrieval. The repo already treats this case as a known slow refusal (tests/eval-quality-retry.test.ts). This is a timing blip, not a behaviour regression, so no revert.

Verification

  • Checks run:
    • npx vitest run tests/evidence-relevance.test.ts: the new tests failed before the change (expected 'partial' to be 'direct'), and now Tests 11 passed (11).
    • Offline probe against the run 38912586460 dump previews: before the change, AKG was partial and Admissions direct.
    • npm run typecheck: recorded a pass for "typecheck:internal"
    • npm run test:focused for the changed files: Tests 2480 passed (2480)
    • npm run test on the first commit: Tests 31561 passed | 9 skipped (31570)

Risk and rollout

  • Risk: medium. Relevance verdicts can only become more generous for questions that use these verbs. That moves ordering within the existing relevance bands and the match chips. The live canary pair above measured no retrieval change and one answer fixed.
  • Rollback: revert the squash commit.
  • Provider or production effects: none from the code. The owner approved the paid before and after canary pair for this fix.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VkKjYakMrMXofU8foQCgbq