atlaso
A memory store that flags its own conflicts before your agent does.
from atlaso import Memory
m = Memory()
m.add("Alice prefers dark mode in the UI", user_id="alice")
for hit in m.recall("dark mode", user_id="alice"):
print(hit.content, "confident:", hit.is_confident)
That is_confident flag — and its siblings has_disagreement, agreement_score, conflict_peers — are why this library exists. Every recall() result tells you whether to trust it.
Atlaso v0.1's retrieval is lexical (BM25 over your text), not semantic — so recall("dark mode") matches "dark mode in the UI" but not "theme preferences". v0.2 adds optional embedding-based recall.
What Atlaso is
Atlaso is a memory store for AI agents built around Field 3.0 — an append-only, dispersion-aware knowledge model where every saved fact carries:
- Polarity —
positive / negative / cautionary / open — the stance of the claim.
- Evidence grade —
anecdotal / observed / replicated / verified — gated by the breadth of the claim.
- Scope — six experimental facets (note, model, dataset, env, version, n, seed) telling you under what conditions the claim holds.
- Contradictions — first-class edges, not metadata. Revising a fact deposits a new finding with
contradicts=[old_id].
When an agent calls m.recall(...), the result set is grouped by scope, and every hit is annotated with whether it agrees with its neighbors, whether its scope-bag has internal disagreement, and whether the SDK considers it safe to act on. Your agent gets data back; it also gets a verdict on whether the data is settled.
That's the whole pitch.
Full docs: rendered at https://atlaso.ai/docs · plain Markdown in ./docs/ for offline / on-github reading.
Install
pip install atlaso
pip install atlaso[mcp]
Python 3.10+. No phone-home, no analytics, no signup. The library runs entirely in your process against on-disk SQLite.
Quickstart — single user
from atlaso import Memory
m = Memory()
m.add("I prefer oat milk in lattes", user_id="me")
hits = m.recall("oat milk", user_id="me")
print(hits[0].content)
SaaS — multi-tenant
from atlaso import AsyncMemory
from fastapi import FastAPI, Depends
memory = AsyncMemory()
app = FastAPI()
@app.post("/remember")
async def remember(text: str, user = Depends(current_user)):
handle = memory.for_user(user.id)
return await handle.add(text)
The for_user(user.id) pattern is the recommended path. The lower-level memory.add(text, user_id="alice") exists for admin tooling but is the wrong shape for request handlers — see Authorization.
Recall with conflict awareness
results = m.recall("what does Alice eat?", user_id="alice")
print(results.explain())
for r in results:
if r.has_disagreement:
print(f"⚠ {r.content} conflicts with {r.conflict_peers}")
elif r.is_confident:
print(f"✓ {r.content}")
else:
print(f"? unconfirmed: {r.content}")
results.explain() is action language, not internals. Empty / confident / disagreement / thin-evidence each get their own one-sentence verdict.
Memory health
print(m.health(user_id="alice").explain())
The Field Maturity Index is a 0–100 geometric mean of Coverage × Precision × Resolution × Density — a single readable number for "how settled is what I know about this user?"
Retract, don't delete
m.retract(deposit_id, user_id="alice", reason="this fact was wrong")
Soft tombstone by default — the row stays citable in contradicts=. hard_delete=True is the GDPR/PII escape. reason= is required because Atlaso keeps a retraction trail.
What we deliberately don't ship
- No
update(). Atlaso deposits are immutable evidence. To revise an earlier finding, deposit a new one with contradicts=[old_id]. The audit trail is the point.
- No telemetry. Atlaso never phones home.
- No required LLM.
add() and recall() work with pure SQL + lexical retrieval. Bring your own embedder/extractor only if you want them.
- No cross-tenant footguns on autocomplete. Cross-tenant operations live in
from atlaso.admin import ... behind a confirm="I_UNDERSTAND_THIS_CROSSES_TENANTS" literal. They never appear on m.<TAB>.
Framework integrations
atlaso[mcp] covers Claude Code, Cursor, Codex, Windsurf, Cline via MCP — zero per-framework code.
For Python agents, see the recipes in docs/recipes/:
pip install atlaso[langchain] and the four other framework extras are reserved namespaces — they install only atlaso core today and emit a one-line FrameworkExtraReservedWarning when the SDK detects the framework is installed alongside it. Real adapters land in v0.1.x.
Inspect what you have
m.peek("alice")
(The default polarity is open — undecided / observed-but-not-stance-claimed. Stronger polarities like positive or negative require corresponding evidence. See the Glossary below.)
m.peek(user_id) is the "show me what's stored without writing a query" primitive. It returns a PeekView that iterates like a list but renders as a compact table in your REPL or notebook.
Debug a recall
hits = m.recall("dark mode", user_id="alice")
print(hits[0].explain())
hit.explain() answers "why did I get this result and should I act on it?" in plain language — no Field 3.0 jargon leaks. Useful for production-debugging unexpected retrievals.
Use it from bash — atlaso CLI
Once pip install atlaso lands, the atlaso command is on PATH and every Memory verb has a CLI mirror. Same vocabulary as the Python API, same vocabulary as the MCP tools — one mental model:
atlaso add "Alice prefers oat milk" --user alice
atlaso recall "coffee" --user alice
atlaso peek alice
atlaso health alice
atlaso list-recent --user alice --limit 5
atlaso get <deposit_id> --user alice
atlaso contradict "Alice moved to Brooklyn" <old_id> --user alice --reason "user moved"
atlaso retract <deposit_id> --user alice --reason "wrong fact"
atlaso retract <deposit_id> --user alice --reason "GDPR" --hard
Add --json to add / recall / get / list-recent / peek / health / contradict / retract to get machine-parseable output for piping into jq or shell scripts:
atlaso list-recent --user alice --limit 100 --json | jq '.[] | select(.polarity == "negative")'
atlaso recall "milk preferences" --user alice --json | jq '.is_confident'
atlaso --help lists every subcommand. Each subcommand has -h for its own usage. Errors print as atlaso <cmd>: <ErrorType>: <message> (no stack traces) so they're shell-friendly.
Health-check the install
$ atlaso doctor
atlaso doctor
──────────────────────────────────────────────────
✓ atlaso 0.1.0a3 importable
✓ Field 3.0 engine vendored
✓ storage path: /Users/me/work/.atlaso (auto-resolved)
✓ engine round-trip (add → recall → retract)
✓ atlaso[mcp] installed (run: python -m atlaso mcp)
──────────────────────────────────────────────────
OK — atlaso is healthy.
End-to-end install + path + engine sanity check in five seconds. Returns 0 on healthy, 1 if anything's broken.
Glossary
If the words below feel unfamiliar, read this once. Five sentences each.
- Deposit — a single saved fact. Immutable; revise by depositing a new one with
contradicts=[old_id].
- Polarity — the stance of the deposit:
positive (supported), negative (refuted), cautionary (works under conditions), open (undecided / question / hypothesis — this is the default).
- Evidence grade — how strong the support is:
anecdotal (one source, no measurement), observed (one careful measurement), replicated (multiple independent measurements agree), verified (independently checked against ground truth).
- Scope — the experimental facets describing under what conditions the claim holds:
note, model, dataset, env, version, n, seed. All optional.
- Bag — deposits that share the same scope facets are in one "scope-bag." The dispersion signals (
is_confident, has_disagreement, agreement_score) are computed per-bag.
- Contradicts — a list of deposit ids this finding supersedes. The new deposit + the contradiction edges are committed atomically.
- FMI — Field Maturity Index, a 0–100 health score. Geometric mean of Coverage × Precision × Resolution × Density. Returned by
m.health(); the four components are interpretable separately.
License
Apache 2.0.
Status
v0.1.0a3 — research preview. The SDK surface is fresh; please file issues.