You end up with a support agent that still knows what a tenant told it last week, so you stop re-stuffing the same policy documents into every prompt and stop paying for those tokens on every turn. Two extra headers on a normal chat completion do it. Ringside recalls the relevant memory before the model call and learns durable facts from the turn afterwards. One Brain per product, with a scope per tenant inside it.
What you need
- An FC API key with scopes
api:writeandapi:chat, exported asFC_API_KEY pip install httpx
Full code
python# memory_agent.py import os, httpx API = "https://api.fightclub.pro/v1" H = {"Authorization": f"Bearer {os.environ['FC_API_KEY']}"} http = httpx.Client(base_url=API, headers=H, timeout=120) # 1. Create a Brain (standard seals document text at rest). brain = http.post("/brains", json={"name": "support", "encryption": "standard"}).json()["id"] # 2. Load a tenant's knowledge. Scope it so /acme only ever sees its own. # Reference docs are chunked + embedded server-side; no pre-splitting. http.put(f"/brains/{brain}/entries", json={ "scope": "/acme", "class": "reference", "title": "Refund policy", "body": "Refunds are issued within 14 days for unused credit. " "Enterprise plans are billed annually and are non-refundable mid-term.", }) def ask(question: str, scope="/acme", customer="cus_acme"): """Ambient memory: recall-inject-before, learn-after, billed to the customer.""" r = http.post("/chat/completions", headers={"Brain": brain, "Brain-Scope": scope, "FC-Customer": customer}, json={"model": "match:anthropic/sonnet", "messages": [{"role": "user", "content": question}]}) return r.json()["choices"][0]["message"]["content"] # 3. Ask. The refund policy is recalled and injected automatically. print(ask("can I get a refund on an enterprise plan mid-term?")) # -> cites the non-refundable enterprise rule from memory # 4. Teach it a durable fact in passing. Next turn it remembers. print(ask("by the way our account manager is Dana Lee, please remember that")) print(ask("who is our account manager?")) # -> "Dana Lee" (learned from the earlier turn, no explicit write)
How it works
Brain-Scopeis the isolation boundary. A recall at/acme/q3-auditsees/,/acmeand/acme/q3-audit, never a sibling like/globex. Addsubtree: trueon a directrecallcall to let an operator search a whole branch at once.- Learning is automatic and fail-closed. After each turn Ringside reconciles the smallest change into memory. Greetings and off-task chatter are dropped by a cheap gate; most turns change nothing, which is correct. Nothing is written if the model returns nothing usable.
- Forgetting is on a curve. Facts decay by type: infrastructure and decisions stay until superseded, preferences fade over months, "right now" status rots in days. Set
decay_anchor: "last_used"in thememory_policyfor spaced-repetition behaviour.
Going further
- Right to be forgotten:
POST /v1/brains/{id}/forgetwith{"scope": "/acme"}or{"entity": "Dana Lee"}erases a tenant's branch or a single entity, cascading to chunks and graph edges. - Regulated writes: set
memory_policy.learn_mode: "review"so load-bearing changes wait in a queue you approve via/proposals. - See the Brains concept page for the full model and the reference for every endpoint.