Short answer: cache retrieval artifacts only behind a versioned key that includes the corpus snapshot, access scope, chunking policy, and retrieval configuration; then invalidate from document events and keep final answers short-lived. For legal contract review, a fast stale answer is worse than a deliberate cache miss.

Caching is useful here because reviewers repeat clause searches, reopen the same contract, and refine questions around the same evidence. It is dangerous for exactly the same reason: an old indemnity clause or a result copied across matters can look perfectly plausible. Retrieval-augmented generation joins a retriever with a generator, so a useful cost model keeps those stages separate rather than treating a response as one indivisible object [1].

Don't begin with a time-to-live value. Begin with the bill, the retention boundary, and the events that make an entry false.

What does caching really cost in a legal contract review workspace?

The bill has at least four terms: document parsing and embedding work when the corpus changes, retrieval work for each cache miss, generation work after retrieval, and storage plus operational work for cached artifacts. Let Q be query count, Hr the retrieval-cache hit rate, Hg the answer-cache hit rate, and S the retained bytes. The workload is roughly Q * (1 - Hr) retrieval executions, Q * (1 - Hg) generations, plus storage and invalidation traffic proportional to S. Actual currency depends on the chosen components, so pretending there is one universal break-even point would be misleading.

Use a worked workload in units before applying prices. Suppose a team runs 1,440 questions in a review day. If 360 normalized questions repeat against the same corpus version and permission scope, a retrieval cache can avoid 360 retrieval executions. If each retained retrieval artifact contains 20 excerpts averaging 3 KB, retaining all 1,440 artifacts consumes about 86.4 MB before indexes and metadata; retaining only the 360 reused artifacts consumes about 21.6 MB. These are assumptions for arithmetic, not a benchmark. Replace every number with a trace from the workspace.

The dominant term may still be generation, especially when reviewers ask unique questions over recurring evidence. That is why retrieval and answer hit rates need separate counters. A team that reports one combined cache-hit percentage can't tell whether it avoided evidence lookup, answer generation, or neither.

Start there.

How should 11 retrieval design practices handle caching for legal contract review?

  1. Normalize intent conservatively. Fold harmless whitespace and Unicode differences, but don't erase legally meaningful distinctions. may and must, a section number, a party name, and a date belong in the key. Semantic similarity can suggest a candidate entry; it should not silently declare two legal questions equivalent.

  2. Split the cache by pipeline stage. Keep parsed pages, chunks, embeddings, retrieval results, and generated answers as separate artifact classes. A chunk cache can remain valid while an answer becomes stale because the prompt policy changed. This separation also shows which stage actually moves cost and latency.

  3. Version every dependency in the key. Include the matter, corpus snapshot, document set, access scope, parser version, chunking policy, embedding configuration, retrieval configuration, and answer-policy version as applicable. A missing dependency creates accidental reuse. A long key is cheap; undisclosed cross-matter evidence isn't.

  4. Make freshness a document-class decision. An executed agreement, a live draft, and a newly uploaded amendment do not share one useful freshness window. Define an explicit maximum staleness for each class, then make that policy visible in the result metadata. I'm not sure a proposed interval is safe until update frequency and reviewer tolerance are measured; those two observations resolve the uncertainty.

  5. Invalidate from document events. Upload, replacement, deletion, reclassification, permission change, and matter closure should advance a corpus or authorization version. Expiration remains a backstop — it isn't the primary correctness mechanism. Versioned keys also avoid racing through a large cache to delete individual entries during an active review.

  6. Bind entries to authorization context. Cache keys and lookups must preserve tenant, matter, role, document-level grants, and any ethical-wall policy used during retrieval. Shared caches are acceptable only when the authorization context is part of the identity and is checked again before evidence is returned. Never rely on an opaque query hash as the permission boundary.

  7. Prefer evidence caching over prose caching. Retained chunk identifiers, source versions, scores, and citation locations can accelerate repeated retrieval while still allowing the answer layer to apply the current instructions. Final prose has a narrower reuse window because wording can conceal a changed source or policy. For a high-impact review, regenerate from verified evidence.

  8. Treat empty results as volatile. A cached no matching clause result can become false as soon as an amendment arrives or parsing completes. Give negative entries a shorter policy than positive evidence, and invalidate them on corpus change. Short means a value justified by ingestion latency and review risk, not an arbitrary five-minute habit.

  9. Use admission rules instead of caching everything. Admit an artifact after reuse, for an approved recurring workflow, or when measured recomputation cost warrants retention. One-off exploratory questions often have no second hit. They increase storage, enlarge the sensitive-data surface, and make eviction of useful entries more likely.

  10. Observe correctness beside hit rate. Record stage-specific hits, misses by reason, entry age, corpus version, authorization version, invalidation lag, citation resolution, and regeneration outcome. A rising hit rate paired with more stale-version rejections is not an improvement. Audit logs should identify cache decisions without copying full contract text into general-purpose telemetry.

  11. Design deletion and replay together. Store enough metadata to reproduce why an artifact was eligible: key fields, version identifiers, timestamps, retrieval configuration, and source references. Apply the matter's retention and legal-hold rules to the artifact itself. When retention expires, delete the excerpts and final prose; keep only the minimum audit metadata permitted by policy.

Caching does not improve a weak parser, repair bad chunk boundaries, or prove that the retrieved clauses answer the question. It only reuses prior computation under declared conditions.

A small versioned cache contract

The cache interface should make unsafe omissions difficult. This Python example produces a deterministic key from explicit dependencies and refuses reuse after expiry. It stores no contract text in the key, and it treats authorization and corpus versions as first-class inputs.

from dataclasses import asdict, dataclass from datetime import datetime, timezone import hashlib import json @dataclass(frozen=True) class RetrievalIdentity: matter_id: str normalized_question: str corpus_version: str authorization_version: str chunking_version: str embedding_version: str retrieval_version: str def cache_key(identity: RetrievalIdentity) -> str: payload = json.dumps( asdict(identity), sort_keys=True, separators=(',', ':'), ensure_ascii=True ).encode('utf-8') return hashlib.sha256(payload).hexdigest() def reusable(entry: dict, identity: RetrievalIdentity, now: datetime) -> bool: if now.tzinfo is None: raise ValueError('now must be timezone-aware') return ( entry['key'] == cache_key(identity) and entry['expires_at'] > now.astimezone(timezone.utc) and entry['corpus_version'] == identity.corpus_version and entry['authorization_version'] == identity.authorization_version ) 

A production implementation also reauthorizes each returned source and verifies that every citation resolves against the current snapshot. The cache should return a typed miss reason such as expired, corpus_changed, access_changed, or policy_changed. Those labels turn invalidation from guesswork into something the team can measure.

There is an edge case worth calling out. Two reviewers can type the same question while seeing different document subsets because one is walled off from an annex. The normalized text matches, but the authorization version does not, so the second lookup must miss. If the key omits that version, the cache has crossed a compliance boundary even though its hash and TTL look tidy.

No shortcut fixes that.

Failure drills, deployment, and the retention catch

Test the cache with state transitions, not just repeated reads. Create a fixture containing an agreement and amendment; retrieve a clause; replace the amendment; change one reviewer's grant; change the chunking version; then repeat the original question. Each transition should produce a miss or a newly verified result for a documented reason. Also test simultaneous ingestion and querying: pin each request to one corpus snapshot so its citations don't mix versions midway through retrieval.

Deploy version changes by writing the new namespace first, reading it only after the corresponding index is ready, and allowing the old namespace to age out under policy. This makes rollback a version selection rather than a mass rewrite. Alerts should focus on invalidation lag, authorization mismatches, missing citations, and unexpected growth by artifact class. Cache availability affects latency; source verification governs correctness.

The catch is retention. Keeping every excerpt and answer makes incident reconstruction easy, but it duplicates sensitive contract language and expands deletion work. Keeping only hashes makes privacy work easier, but a hash cannot show which passage a reviewer saw. A practical boundary is to retain source identifiers, versions, decision metadata, and approved audit events for the required period while expiring copied excerpts and generated prose earlier under the matter policy. When something goes wrong after those payloads have expired, the team can reconstruct the configuration and source snapshot if those still exist, but it may not reproduce the exact displayed wording. That loss is deliberate and should be accepted by legal, security, and operations before launch.

This approach is not suitable when the source set changes continuously and the system cannot emit trustworthy version or permission events. In that case, skip cross-request caching of retrieval results and keep only request-local computation until versioning exists. It is also a poor fit for a one-time review with almost no repeated questions; admission and invalidation machinery may cost more operational attention than it saves.

Enable a cache class only when its identity, freshness owner, invalidation event, permission check, retention rule, and miss fallback are all named. Otherwise, leave it off.

References

  1. Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks: https://arxiv.org/abs/2005.11401

Further reading