FAQ
Short answers to the questions that come up most — what rlat is, how it differs from a plain embedding store, when to reach for each command, and where the API key is and is not needed.
The basics
What is rlat?
A retrieval and answer-improvement layer for AI assistants. You point it
at a corpus — docs, code, notes, anything text — it builds a
.rlat knowledge model, and you query that model. A
query can return ranked passages with full source citations and drift
status, or — through rlat deep-search and the insight layer —
a faithfully-grounded answer where every claim traces back to the corpus.
Three layers do the work. The field is the encoder plus dense cosine retrieval. The store is the on-disk knowledge-model archive plus the verified-retrieval contract. On top of those, rlat composes grounded synthesis: it improves answers by grounding them in the corpus, never by asserting what is true in the world. It represents what the corpus says.
rlat owns grounding, not truth. A grounded answer is faithful to the corpus — it does not claim the corpus itself is correct.
How is it different from a vanilla embedding store?
Lossless verified retrieval. Every passage in every
.rlat carries (source_file, char_offset,
char_length, content_hash, drift_status). Most retrievers store
opaque embeddings and lose source attribution. rlat does not. Citations
are free; drift detection is free; fact-checking workflows compose on top
with no extra bookkeeping. And because rlat can see the shape of the whole
corpus, a knowledge model also audits itself — flagging
gaps, contradictions, and stale facts, and growing from verified sources
(see Self-improvement).
Does rlat learn about my world?
Yes. Alongside your documents, a knowledge model can carry three kinds of learned knowledge about the world they describe: stable facts (the tenant's capacity, the garden's water restrictions), standing constraints (no preview features, organic-only), and what was tried and failed. All three are proven to change answers — receipts on the Benchmarks page.
Capture is opt-in. Passive capture reads what you said in a
session and extracts world facts through four gates; the fourth is a
privacy gate — facts about a person (your role, your machine, your
habits) are dropped. The gate is prompt-level, validated rather than
architecturally guaranteed: zero person facts landed across every trap
in the pre-registered bench
(E2c). No API key
needed: the rlat-learn skill runs the same capture on
your Claude subscription, with you approving every fact — the
background hook (key required) is for unattended capture. You can also
record a fact deliberately with rlat capture-attribute my.rlat
"..." --kind attribute|constraint|falsified (or auto-probe with
rlat capture-env), and review or remove what has landed
with rlat lens / rlat profile
(rlat audit and rlat trace show the full
trail).
What encoder do you use?
Alibaba-NLP/gte-modernbert-base at 768d, CLS-pooled,
L2-normalised, with a maximum sequence length of 8192 tokens. It is pinned
to a specific Hugging Face commit so a fresh machine reproduces the same
embedding distribution that produced the locked BEIR-5 floor.
Validated against BGE-large-v1.5 (rlat wins by +0.026 nDCG@10) and E5-large-v2 (+0.081 nDCG@10) — apples-to-apples, same chunker, ANN, and scoring — plus Qwen3-Embedding-8B at +0.014 nDCG@10 mean on its own stack. See the Benchmarks page for the comparison table.
Why no rerankers, lexical sidecar, or auto-router?
Measured. Cross-encoder rerankers regressed gte-modernbert-base on 4 of 5 BEIR corpora — a training-distribution mismatch with strong dense top-k. A lexical V1 band failed parity on 4 of 5 corpora. Auto-mode routers add latency without a quality gain. A single recipe wins on quality, simplicity, and reproducibility.
The same discipline applies to learned facts. Automatic suppression of disproven facts was tested three ways and falsified — in the live run it suppressed a fact that was still right, failing the pre-registered safety bar. So corrections stay explicit: a disproven fact is corrected on the record, never silently dropped. The published record is at R4.
Storage modes
Bundled vs. local vs. remote storage mode?
| Mode | Where source lives | Use when |
|---|---|---|
local (default) | On disk; the .rlat carries embeddings + coordinates | You are indexing a working repo you will edit |
bundled | zstd-compressed inside the .rlat | Shipping a self-contained artefact — Hugging Face Hub, archive, offline distribution |
remote | Resolved over HTTP(S) against a SHA-pinned manifest baked in at build time | Source belongs at canonical URLs, e.g. a tagged GitHub release |
Remote mode is set with --store-mode remote --remote-url-base
<prefix>. The first query downloads cited source to a
per-knowledge-model cache, with SHA-pin verification on every read. See
the Storage modes page.
How do I switch storage modes without rebuilding?
rlat convert <km.rlat> --to {bundled|local|remote}.
It reshapes the storage mode in place without re-running the encoder —
the band, registry, and ANN index are
storage-mode-independent and flow through unchanged.
# hand off a working knowledge model as self-contained
rlat convert my.rlat --to bundled
# open a downloaded handout for editing
rlat convert handout.rlat --to local --source-root ./extracted/
# publish a private corpus to HTTP
rlat convert internal.rlat --to remote --remote-url-base https://docs.example.com/v1/
Conversion validates every passage's content_hash against
live bytes before writing. If any have drifted, conversion aborts with the
drift report; run rlat refresh or rlat sync
first, then retry.
Grounding and search
How do I tell the LLM how to use the retrieved passages?
rlat skill-context and rlat search --format
context both take a --mode flag that stamps a
directive at the top of the markdown output. The directive header always
ships, even when a weak-retrieval gate suppresses the dynamic body — the
LLM always sees the instruction.
| Mode | Posture | Single-shot bench (Microsoft Fabric) |
|---|---|---|
augment (default) | Passages are primary context, blended with the LLM's training. Body suppressed on weak retrieval so the LLM falls back to training rather than grounding on noise. | 76.5% accuracy / 3.9% hallucination (vs 56.9% / 19.6% for the LLM alone) |
constrain | Passages are the only source of truth; the LLM is told to refuse when evidence is thin. Pair with --strict on skill-context so drifted source aborts the load. | 66.7% accuracy / 2.0% hallucination / 91.7% distractor refusal |
knowledge | Passages supplement training. Lighter gate, because the directive already tells the LLM to lean on training. | 70.6% accuracy / 5.9% hallucination |
Full table + receipts: the hallucination bench.
rlat skill-context fabric.rlat --query "$user_query" --mode constrain --strict
rlat search compliance.rlat "what's our SOX retention policy?" --format context --mode constrain
Pick constrain for fact extraction, compliance, and audit
work where wrong-but-confident is worse than no answer. Pick
augment for broad documentation corpora where the LLM has
solid prior knowledge.
When should I use deep-search vs rlat search?
rlat deep-search needs an Anthropic API key. In a Claude
Code session, the deep-research skill runs the same loop
natively in your conversation — same prompts, same hop budget, same
name-verification check — with no extra cost. Use the skill in nearly
every interactive scenario; reach for the CLI verb when you need a
programmatic, batch, or non-Claude-Code surface.
rlat search is single-shot — one query, top-k passages,
return. No LLM at all (just the deterministic encoder, cosine, and ANN),
fully local, instant, and fine for one-hop fact lookups.
rlat deep-search (or the deep-research skill)
runs an internal multi-hop loop — plan, retrieve, refine, retrieve again,
synthesize — and returns a final answer plus the evidence union. It is
pricier and slower, but more thorough:
| Surface | Accuracy | Hallucination | Cost / q |
|---|---|---|---|
rlat search --format context (single-shot, augment) | 76.5% | 3.9% | $0.004 |
rlat deep-search | 92.2% | 2.0% | $0.009 |
Full table + receipts: the hallucination bench.
Pick deep-search when the question spans multiple files, when correctness matters more than latency or spend, or when you want a synthesised answer with citations rather than a list of passages. Stick with search for single-hop lookups, when you drive synthesis yourself downstream, or when latency and cost dominate.
What is --strict-names?
A safety check, independent of grounding mode, on rlat
skill-context, rlat search --format context, and
rlat deep-search. It extracts distinctive proper nouns,
acronyms, and alphanumeric IDs from the question, then verifies each
appears verbatim in at least one retrieved passage. When a distinctive
token is missing from every passage:
- Default — prepend a refusal directive to the body, so the LLM sees a "the corpus may describe a different entity" warning.
--strict-names— exit non-zero (rc=3). Skill loaders and scripts gate on this.
This catches the name-aliasing failure that score-based gating cannot —
e.g. a question about MaterializedViewExpress (MVE) when the
corpus only describes the adjacent MaterializedLakeView
(MLV). On paraphrase-rich documentation corpora, score and gap
distributions overlap completely between answerable and distractor
questions, so any score-floor gate is statistically falsified — the
name-check is the right mitigation.
How do I cite a search result?
Citations are built into every result.
rlat search my.rlat "query" --format json | jq '.[] | {file:.source_file, offset:.char_offset, drift:.drift_status, score:.score}'
From Python, the evidence op carries the same coordinates:
from resonance_lattice.rql import evidence
report = evidence(contents, store, query_emb)
for hit in report.hits:
c = hit.citation
print(f"{c.source_file}:{c.char_offset}-{c.char_offset + c.char_length} ({hit.score:.3f})")
evidence also returns calibration data — top1 score, source
diversity, drift fraction — that the caller can act on, for instance to
abstain when separation is thin.
Keeping a knowledge model fresh
What if my source files change?
Three ways to recover, all landing on the same incremental delta-apply:
- Live —
rlat watchruns the same incremental delta-apply asrefreshon a debounced timer triggered by filesystem events. Silent by default; zero-arg invocation auto-discovers*.rlatin the current directory. Local mode only. Needspip install rlat[watch]. - Manual —
rlat refresh my.rlatapplies an incremental delta: unchanged passages keep their band rows untouched, modified or added passages are re-encoded, removed passages are dropped. Atomic in-place write. - CI / pre-commit —
rlat watch --onceis a synchronous one-shot reconciliation: it walks every archive, reconciles against current disk state, and exits.
rlat refresh --dry-run reports the delta counts without
writing. rlat profile reports drift status without
rebuilding.
What if my source repo (remote) changes?
Run rlat sync my.rlat — the same incremental delta-apply as
refresh, but the upstream-state oracle is your remote source
instead of the local filesystem. Catalog mode
(--upstream-manifest <url>) diffs an authoritative
upstream JSON manifest and detects added, modified, and removed paths.
Poll mode (the default) re-fetches every URL in the
pinned manifest and detects modifications only — it cannot enumerate new
files. Catalog mode is the safe mode for removals, because only an
authoritative catalog can tell a deleted file apart from an unreachable
one.
rlat freshness my.rlat is the read-only check — it walks the
manifest, hashes each entry, and reports per-entry status
(verified / drifted / missing) with
no mutation. Useful as a CI gate before running sync.
What happens to earned insights when source drifts?
Insights — the cited summaries that live in the insight layer — are tied
to the source passages they cite. When a source file changes, the insights
built on it are marked stale and drop out of retrieval until re-verified.
rlat reverify my.rlat walks those stale insights so you can
keep or retire each one. See the claim system page for how
the source and insight layers relate.
Scale and building
How big can a knowledge model get?
Tested comfortably up to ~50K passages. Plain rlat search
scales further on FAISS HNSW, but the cross-knowledge-model dedupe
operations build an (N, N) cosine matrix — at 50K rows that
is roughly 10 GB of float32, the practical ceiling for those operations;
above it, pre-shard. Single .rlat files in the wild range
from ~10 MB (a small docset) to ~2 GB (a large code repo with bundled
source).
I don't have a GPU. Can I still build a big corpus?
Yes. In a Claude Code session, the rlat-build-on-kaggle skill
walks you through using Kaggle's free T4 GPU, which encodes
gte-modernbert-base roughly 10–20× faster than ONNX on CPU.
Anything over ~10K passages is meaningfully faster on Kaggle. The free tier
gives 30 GPU-hours per week. Skip Kaggle if your corpus is small (under
~2K passages, where the round-trip overhead exceeds the encode time) or if
you already have a CUDA GPU locally.
Is the API key required?
No — a key is not a prerequisite for anything rlat can
do. Most of the surface — build, search, profile, compare,
summary, skill-context, refresh, watch, sync, freshness, convert,
init-project, lens, audit (including
--shape/--external), trace, expertise,
workspace, capture-env, capture-attribute, consolidate-insights —
is offline and LLM-free. The loops that do need an LLM all run free
on your Claude subscription as in-session skills: deep research is
the deep-research skill, capture is
rlat-learn, curation is the four curation skills.
An Anthropic API key matters only when you want those same loops unattended — automation, CI, scheduled runs — via the CLI verbs:
rlat deep-search— the multi-hop research loop.rlat grow— the opt-in self-improvement pass that authors gap fills (--dry-runis free).rlat reverify— re-checks insights whose source drifted.rlat probe— the idle-cycle self-probe of weak-zone queries.rlat memory verify— the one LLM-driven memory subcommand. The other sixteen — includingconsolidate(fully mechanical),add,recall,capture,corroborate,feedback,gc,install-hooks— need no key.rlat intent decompose— the one LLM-driven intent subcommand (it refuses cleanly without a key). The other ten need no key;intent what-nextuses an LLM to phrase its recommendation when a key is present and falls back to a plain readout without one.- The opt-in background capture hooks
(
rlat memory install-hooks --mine/RLAT_ATOMIC_CAPTURE=1) — they fail open and stay silent without a key.
The skill paths keep you in the loop — rlat-learn has
you approve every fact before it lands. The full loop-by-loop mapping
(rlat-gap-scan, rlat-contradictions,
rlat-refresh-facts, rlat-curate are the
no-key grow) is on the
API keys page.
API key discovery order: RLAT_LLM_API_KEY_ENV (an indirection
pointing at another variable) → CLAUDE_API_2 →
CLAUDE_API → ANTHROPIC_API_KEY → the Kaggle
Secrets vault.
Does it ship to PyPI?
Yes — pip install rlat. The base install is ~250 MB; the full
encoder and build dependencies (pip install rlat[build]) add
torch and transformers, around 2 GB. For most consumers:
pip install rlat[build] then
rlat install-encoder once.
Memory and intent
What is memory?
Memory is how an assistant remembers what worked. It is a flat store of
short lessons — not a tiered log. Each lesson is tagged
with a polarity (prefer, avoid, or factual), counts how often it recurs,
and carries a confidence on a four-step ladder:
low → medium → high → verified. A lesson earns its rung from
how tasks actually turn out, not from a verdict you give it.
Two hooks make it hands-free: recall injects relevant lessons at the
prompt, capture lands what happened at session end. The housekeeping
pass — confidence raise, then forget — is one mechanical command,
rlat memory consolidate; lessons that keep proving
useful climb the ladder, ones that stay weak are dropped, so memory
stays small and sharp. The only command you usually reach for is
rlat memory add, to write a lesson by hand.
Where it lives: these per-user lessons are yours — stored on
your disk at ~/.rlat/memory/<user>/, scoped per
workspace, never inside a knowledge model. Shareable knowledge —
world facts, constraints, falsified findings — lands in the
.rlat file instead, because that file is built to be
handed to a teammate. The split is deliberate. Full operational
detail: Memory & sessions; the
conceptual model: the claim system.
Can I declare what I am working on?
Yes — rlat intent ships now. rlat intent add
records a live intent, list shows the active ones,
path shows how an intent decomposes, activate
switches the live one, and accept / reject
record a verdict on whether an intent was satisfied. These verdicts are
about intent only — they are not a gate on what memory or the insight
layer keeps. One subcommand, decompose, calls an LLM and
needs an API key; the rest are key-free.
Reporting and roadmap
Where do I report bugs or feature requests?
On GitHub: tenfingerseddy/resonance-lattice. Issues and discussions are enabled.
What's coming?
Roadmap-stable but undated: an HTTP server and SDK surface (rlat is CLI-only today), intent operators that boost or suppress retrieval, per-passage origin tracking in merge output, and an ANN attach point for high-QPS federated search. The retrieval substrate is the foundation; the missing pieces compose on top of it.