Skip to content

feat(rag): LRU/TTL rerank cache (key-tight + persistence) + MMR - #1329

Merged
github-actions[bot] merged 3 commits into
mainfrom
feat/rerank-cache-20260731
Aug 1, 2026
Merged

feat(rag): LRU/TTL rerank cache (key-tight + persistence) + MMR#1329
github-actions[bot] merged 3 commits into
mainfrom
feat/rerank-cache-20260731

Conversation

@IgorGanapolsky

@IgorGanapolsky IgorGanapolsky commented Aug 1, 2026

Copy link
Copy Markdown
Owner

rerun: LRU/TTL rerank cache (key-tightened + cross-process persistence) + MMR

Two rerank-layer lifts for the retrieval/eval stack:

  1. LRU + TTL rerank-result cache (tools/retrieval-rerank.js) — skips the
    expensive CE/ColBERT/LLM scoring stage on repeat queries (in-process, and
    across CLI/eval invocations when HERMES_RERANK_CACHE_PATH is set).
  2. MMR diversity re-rank (opt-in, --rerank-diversity <0-1>; lambda=0 is a no-op)
    — de-duplicates near-duplicate candidates so a single snippet stops crowding the
    top of the ranked list.

Review Comment #1 (cache key collision) - FIXED

canonicalCandidates now hashes the full snippet (0,2000 — covers CE's 1200 and
ColBERT's 2000 char consumption) plus start_line/end_line. Snippets matching for
the first 800 chars but diverging after (or shifted source coords forwarded by
dualPathRetrieve) are now natural misses, never stale hits. Regression test added.

Review Comment #2 (cache never hits) - FIXED

rerank is reached via spawnSync per query for CLI/eval, so a plain module Map
is process-local. Added opt-in cross-process persistence: RerankCache accepts
persistPath, loads on construction, and write-throughs (atomic temp+rename,
fail-open) on each set. The module singleton enables it via HERMES_RERANK_CACHE_PATH
(default null => in-memory, hermetic for tests). In-process repeated reranks (same
query + strategy + candidate-set) hit automatically; CLI/eval repeats hit when the env
is set. Doc corrected to drop the false "always-on LaunchAgent hits it" claim.

Verification

  • node --check tools/retrieval-rerank.js tests/test-retrieval-rerank.js - OK
  • node tools/retrieval-rerank.js --self-test - OK
  • node --test tests/test-retrieval-rerank.js - 22/22 hermetic pass (env scrubbed)
  • Analysis: Analyze (javascript-typescript) PASS; Analyze (swift) is non-required
    and pre-existing (this PR touches no Swift code).

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@greptile-apps

greptile-apps Bot commented Aug 1, 2026

Copy link
Copy Markdown

No reviewable files after applying ignore patterns.

@github-actions
github-actions Bot enabled auto-merge (squash) August 1, 2026 15:38
@gitar-bot

gitar-bot Bot commented Aug 1, 2026

Copy link
Copy Markdown

Gitar is working

Gitar

@IgorGanapolsky
IgorGanapolsky force-pushed the feat/rerank-cache-20260731 branch from 7c01dae to eb2882b Compare August 1, 2026 15:41

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7c01dae765

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tools/retrieval-rerank.js
Comment thread tools/retrieval-rerank.js Outdated
@IgorGanapolsky
IgorGanapolsky force-pushed the feat/rerank-cache-20260731 branch from b457fad to 39cb4cb Compare August 1, 2026 16:18
@IgorGanapolsky IgorGanapolsky changed the title feat(rag): LRU cache for second-stage rerank result (latency/cost A+ lift) feat(rag): rerank LRU cache + MMR diversity (latency + ranking A+) Aug 1, 2026
@IgorGanapolsky
IgorGanapolsky force-pushed the feat/rerank-cache-20260731 branch from 39cb4cb to e0ed7c0 Compare August 1, 2026 16:35
Igor Ganapolsky added 3 commits August 1, 2026 13:55
…lift)

Adds an LRU+TTL cache over the expensive CE/ColBERT/LLM rerank (scoreCandidates)
inside rerank(). Production-safe & hermetic:

- Keyed on query + strategy + limit + llm-flag + canonical (order-insensitive)
  candidate-set fingerprint; a changed upstream set / index refresh misses.
- Write-disabled when an embedder/chat is injected (test fakes) so fake vectors
  never poison the prod cache; production path caches by default, no flag needed.
- HERMES_RERANK_NO_CACHE=1 / --no-cache / options.disableCache force off
  (fail-open: cache faults never change matches, only latency).
- TTL default 5min, LRU cap 256; cacheHit/cacheKey surfaced on result; matches
  cloned on hit (no cross-call mutation).

Latency/cost lift: skips CE/ColBERT/LLM embeddings on repeated queries on the
always-running Hermes process. Does NOT touch retrieval-dual-path.js /
rag-stack-scorecard.js (owned by in-flight #1314/#1301). Single-file change to
post-#1317 retrieval-rerank.js.

Verified non-ownership: plan.md §2 grep + open-PR file-scan both NONE for
tools/retrieval-rerank.js + tests/test-retrieval-rerank.js. Base origin/main@cacfc79a9.
Maximal Marginal Relevance greedy re-rank: (1-λ)*rerankScore - λ*max_overlap.
λ = options.diversityLambda (default 0 => no-op, so A+ nDCG@K scores/rankings
unchanged). Lexical-overlap redundancy penalty => zero extra model calls;
opt-in (CLI --rerank-diversity, env HERMES_RERANK_DIVERSITY). Pure mmrReorder
+ 3 hermetic tests (determinism, no-op, redundancy-demotion).
Address both P1 review comments on #1329:
- Comment #1 (key collision): canonicalCandidates now hashes the full
  snippet (slice 0,2000 - covers CE 1200 / ColBERT 2000 windows) and
  start/end line, so snippets differing beyond char 800 or shifted
  source coords are natural misses, never stale hits.
- Comment #2 (dead cache): implement the suggested cross-process
  persistence -- RerankCache(persistPath) loads on construction and
  write-throughs (atomic temp+rename, fail-open). The module singleton
  opts in via HERMES_RERANK_CACHE_PATH env (default null => in-memory,
  hermetic for tests). Doc corrected: rerank is spawnSync-per-query;
  cache hits in-process same-(query,strategy) reranks and, with the
  env set, across CLI/eval invocations.
@IgorGanapolsky
IgorGanapolsky force-pushed the feat/rerank-cache-20260731 branch from e0ed7c0 to 891c06f Compare August 1, 2026 17:55
@IgorGanapolsky IgorGanapolsky changed the title feat(rag): rerank LRU cache + MMR diversity (latency + ranking A+) feat(rag): LRU/TTL rerank cache (key-tight + persistence) + MMR Aug 1, 2026
@github-actions
github-actions Bot merged commit 0d2498b into main Aug 1, 2026
20 of 21 checks passed
@IgorGanapolsky
IgorGanapolsky deleted the feat/rerank-cache-20260731 branch August 1, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant