get() is the one method you'll use. It embeds the query and serves fresh cached understanding — on the default pool path, the budget-packed, attributed claim payload (ctx.context["pool"]); on the legacy unit path, a semantically-matched unit — retrieving + synthesizing only what's missing, with the raw evidence always retained on the units.
Signature
ctx = cache.get(
query,
*,
namespace=None, # optional tenant/filter scope
related=3, # fold in up to N related units (0 to disable)
strategy=None, # override the ContextStrategy for this call
subs=None, # v0.7, pool path: planner-owned decomposition (list of
# sub-question strings or {"q", "hyde"} dicts)
constraints=None, # v0.7, pool path: intent metadata — {"dates": [...],
# "sources": [...], "entities": [...]} — feeder only
)
Just pass the question — the cache is keyed by the query's meaning, so similar phrasings reuse the same understanding.
New in v0.7 subs= feeds the probe union (an explicit subs= wins over the decompose= callable; subs=[] sanctions no decomposition; malformed entries fail open to the raw query). constraints= is a feeder only — matched units' best evidence sentences join the read's repair-candidate ledger, and serving never changes (pinned). Both default to None (inert), and both are pool-path parameters — the default path in keyed deployments; a loud ValueError on the legacy unit path, never silent inertness. Full reference: The failure chain.
Result
ctx.context # minimum decision-relevant payload: {"understanding": {...}, "raw": [...]}
ctx.understanding# the full structured understanding (dict)
ctx.evidence # all retained raw chunks — always reachable for specifics
ctx.raw_text # those chunks as one string
ctx.cache_hit # True if served from cache, False if just built
ctx.coverage # 0–1: how well the unit covers the query
ctx.escalated # True if it pulled fresh raw to cover the query
ctx.needs_retrieval # True when coverage fell below the floor — a hint to widen (v0.5)
ctx.recalled # list[RecalledClaim] — cross-unit claims surfaced for multi-hop (v0.4)
ctx.pool # pool path: served claims in served order — empty on the unit path (v0.6)
ctx.read_id # deterministic per-read id — the handle every failure-chain verb takes (v0.6)
ctx.confidence # semantic match strength of the hit
ctx.related # list[Related] — cross-unit reuse (see below)
ctx.unit_id # the cached unit's id
ctx.namespace # the namespace this read used
# v0.7 — the read's own provenance and doubt:
ctx.sources # artifact ids actually behind the served payload (both paths)
ctx.max_source_age_s # freshness age of this serve — MAX served-owner age, seconds
ctx.probes # probe texts this read scored (raw query first)
ctx.probe_coverage # per probe: {probe, best_claim, best_span, margin, fired}
ctx.gaps # actionable doubt: {probe, span, unit_id, source, kind}
ctx.parent_read_id # set on reprobe()/serve_unserved() results; "" otherwise
New in v0.6 On the pool path — New in v0.7 the default whenever a semantic embedder is available — the payload is the token-budgeted, globally-ranked fresh-claim pool: hand ctx.context["pool"] to your answerer, and ctx.pool lists the served claims in served order (owner + score per claim). The result contract shifts on the pool path: understanding is {"claims": [...]} with no summary key, unit_id is the owner of the top-ranked served claim, evidence is [] on a non-escalated serve (cite via drill(unit_id)), and cache_hit means zero synthesis calls ran this read. The v0.5 serve="pool" preview (ctx.context["pool"], fall back to the standard context if the key is absent) still works but is deprecated — its removal clock now counts from whichever release flips the pool default (the flip was not taken in v0.7.0). See Context intelligence for the full pool reference.
New in v0.6 Every read carries a deterministic ctx.read_id — the handle for the behavioral fallback loop (residual_spans=True): when your answerer refuses over the served payload, cache.report_refusal(ctx.read_id) returns an attributed retry payload (or None), and cache.report_success(ctx.read_id) confirms a successful retry (earning a durable query key under query_keys=True). Ids live in a 64-read ring buffer; stale ids return None, never raise.
recalled is New in v0.4. When the matched unit under-covers the query, cross-unit recall pools per-claim memory across all fresh units and surfaces the bridge facts a single unit can't — answering multi-hop questions at zero extra LLM calls. It's empty when recall didn't fire (single-hop hits, or a non-semantic embedder). When it does fire, those claims are also injected into the payload as ctx.context["understanding"]["recalled_claims"], so the LLM sees them without any extra plumbing.
coverage and escalated are New in v0.3 — they expose the semantic coverage gate, so you can tell when a cached hit fell back to fresh raw to cover the query.
Field reference
| Field | Type | Meaning |
|---|---|---|
context | dict | What to hand the LLM: projected understanding + raw (per strategy). |
understanding | dict | Full summary / claims / entities / facts. |
evidence | list[Chunk] | All retained raw — always reachable for specifics. |
cache_hit | bool | Served from cache vs. freshly built. |
coverage | float | 0–1 semantic coverage — max per-claim cosine of the matched unit (pool path: final post-build value); drives escalation. |
escalated | bool | Fresh raw was pulled because the hit under-covered. |
needs_retrieval | bool | New in v0.5 Coverage fell below the floor — a hint that this read would benefit from wider retrieval. |
recalled | list[RecalledClaim] | New in v0.4 Cross-unit claims surfaced for multi-hop: claim, score, unit_id. Empty when recall didn't fire — and always [] on the pool path, where the scan is cross-unit by construction (recall is a unit-path mechanism). |
pool | list[RecalledClaim] | New in v0.6 Pool path only: the served claims in served order (claim, score = query cosine, unit_id = owner). Empty on the unit path. |
read_id | str | New in v0.6 Deterministic per-read id — the handle for report_refusal / report_success and every v0.7 failure-chain verb (repair, reprobe, serve_unserved). |
related | list[Related] | Related units: unit_id, relation, understanding, score. |
sources | list[str] | New in v0.7 The artifact ids actually behind the served payload — served order first, de-duplicated. Both read paths. |
max_source_age_s | float | New in v0.7 The serve's freshness age: MAX served-owner age in seconds (0.0 when nothing served) — the per-read form of the stats() aggregate. |
probes | list[str] | New in v0.7 The probe texts this read scored — raw query first, then the subs=/decompose= probes. |
probe_coverage | list[dict] | New in v0.7 With gap_detector=True: per-probe {probe, best_claim, best_span, margin, fired}. Empty when the detector is off — inert by construction. |
gaps | list[dict] | New in v0.7 The actionable doubt: {probe, span, unit_id, source, kind} with kind "extraction_hole" (repair terrain) or "corpus_hole" (route to your tool). Advisory, never an error. |
parent_read_id | str | New in v0.7 Set on a reprobe() / serve_unserved() result — the read the second pass worked from; "" on ordinary reads. |
Examples
# the common case
ctx = cache.get("what is our leave policy?")
# multi-tenant isolation
ctx = cache.get("vacation rules", namespace="acme-corp")
# always include raw, and skip related expansion
from coalent import ContextStrategy
ctx = cache.get("leave policy", related=0, strategy=ContextStrategy.CONTEXT_RAW)
Next
- The failure chain — what to do with
read_idandgapswhen a read fails:repair,reprobe,serve_unserved. - Context intelligence — coverage, escalation, strategies, related.
- Data model — every field on the supporting types.