feat(search): add optional temporal relevance boost#451
Open
feat(search): add optional temporal relevance boost#451
Conversation
Add opt-in recency parameter that applies exponential time-decay to
search scores. Documents from today score unchanged; at the configured
half-life, scores drop by weight/2 (~7.5% with default weight 0.15);
very old documents asymptote to score * (1 - weight), never zeroed out.
Formula: score * (1 - weight + weight * 2^(-ageDays / halfLife))
Available via:
- CLI: qmd query "test" --recency-days 30
- SDK: store.search({ query: "test", recency: { halfLife: 30, weight: 0.15 } })
- MCP: query tool recencyDays parameter
Applied after RRF + reranker blend (step 7 in the pipeline), so it
does not interfere with retrieval or reranking. Uses existing
modified_at timestamps from the documents table - no schema changes.
Closes tobi#367
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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
Adds an opt-in
recencyparameter to search scoring that applies exponential time-decay to final scores. Documents from today score unchanged; at the configured half-life, scores drop gently; very old documents asymptote toscore * (1 - weight)and are never zeroed out.Why this matters
For temporal corpora like meeting notes, journals, and chat transcripts, document age is a meaningful relevance signal. "What did we discuss about the API?" should favor last week's meeting over January's.
--explainoutput (BM25 normalization and dedup already handled)Changes
applyRecencyDecay()instore.ts- exponential decay:score * (1 - weight + weight * 2^(-ageDays / halfLife))recencyoption added toHybridQueryOptions,StructuredSearchOptions, and SDKSearchOptions--recency-days <n>CLI flag onquerycommand (default weight 0.15)recencyDaysparameter on MCPquerytoolrecencyDecayfield in--explainoutput when recency is activemodified_atfrom documents table (existing column, no schema changes)Demo
With
--recency-days 7, the March 12 document drops from 0.2000 to 0.1800 (10% reduction at ~9 days age with 7-day half-life), while today's document stays at 1.0000. TherecencyDecaymultiplier is visible in--explainoutput.Testing
6 unit tests covering:
modifiedAtreturns score unchangedAll 35 tests pass (
npx vitest run test/store.helpers.unit.test.ts).This contribution was developed with AI assistance (Claude Code).
Closes #367