Memory-driven System 1 for AI agents

Decisions over large option sets, where the prompt stops scaling.

Which intent, product, entity or tool, out of thousands or millions? Does this ticket match a known issue? Does the policy say yes? With a handful of options, prompt an LLM. With too many to list, MahaBodi keeps them in memory, retrieves a shortlist, and decides in one forward pass with Laya's typed decision models, grounded in your documents and labelled past decisions, in one Rust engine (tested at 5.9M pages — a tie with Laya + dense — and at a 1M constructed pool — a win; a simple remembered prior beats both; see When to use it).

choices · yes/no · routingRust corePython · Node · Java · C# · GoMIT licensedno text generation
The MahaBodi tree: glowing graph roots, a green trunk and branches, and heart-shaped Bodhi leaves carrying neural nodes

Why MahaBodi

Accuracy numbers compare both systems on the same machine and items with an exact McNemar test; the later comparisons (learning, fine-tuning, entity linking) were pre-registered. The full tables, losses included, are below.

0
tokens generated per decision
A typed answer with a probability per final candidate, and no text to parse. One model pass for a few options (a tournament runs a few for many). 125 ms p50 for 4 options on a CPU; 1.9× slower than Laya on 77.
+16.8 pts
vs Laya on 77-intent Banking77
0.660 vs 0.492 for Laya as shipped; ties Laya with a shortlist (0.642). Multilingual too: 51 languages, 0.405 vs 0.366, against laya-multilingual without its Router.
seconds
to learn, no retraining
2,000 labelled cases in 1.5–16 s on a CPU. Never below Laya on 5 fresh suites (a plain kNN is a strong alternative). Near-ties: 26 % → 91 % correct.
0.78
answers from your documents
BoolQ grounded in memory, up from 0.42 with the question alone (always-yes: 0.626). Confidently wrong answers fall from 45 % to 17 %.
61 % vs 5 %
finds what users mistype
Misspelled keyword queries, right passage in the top 5, against BM25, at 300 paragraphs. At 2,000 it ties BM25 on clean queries and loses on keyword queries.
5.9M
pages: runs at catalogue scale
100K: retrieval beat a dense shortlist (0.177 vs 0.121). 5.9M (v1 store): ties Laya + dense at 8.3 s per decision. 1M constructed pool (v2 store): beats Laya + exact dense, 0.164 vs 0.129 (p = 0.023), 6.2 s p50. A remembered alias prior beats all of them, 0.75–0.80.
6
languages, one Rust core
Rust, Python, Node.js, Java (from source), C#/.NET and Go, on crates.io, PyPI, npm and NuGet. MIT licensed.
Open
results you can check
Same-item comparisons, the later ones pre-registered; losses next to wins, per-item predictions in the repo, and every number recomputed by a second reviewing agent.
Candidate pool searched, log scale: Laya alone reads up to 150 measured options and cannot run at 10,000; Laya with your own index and MahaBodi both search 5.9 million pages and decide among 20 retrieved candidates. Height is pool size, not accuracy.

When to use it

Where MahaBodi fits best, and where something else does.

Thousands to millions of options

MahaBodi's memory

Laya can't read 10,000 options at once. MahaBodi's retrieval beat a dense shortlist at 100K pages (0.177 vs 0.121), and it ran 5.9M pages through PostgreSQL on one Mac mini, tying Laya + dense there (numerically lower; 8.3 s per decision). The rebuilt v2 store (per-passage vectors) was then tested at a 1M-page constructed pool — golds, hard negatives mined against the baseline's own retriever, random fill — and beat Laya + an exact dense shortlist, 0.164 vs 0.129 (p = 0.023), consistent with retrieval (no decider-only arm at 1M). The alias prior still beats both (0.749). What the memory stores matters most: on AIDA, a simple remembered alias prior beat every system, MahaBodi included (0.78 vs 0.18 at 100K).

Many options, no training step

MahaBodi

It learns from labelled cases in seconds on a CPU and is never below Laya as shipped on 5 fresh suites (3 beats, 2 ties). A plain kNN is a strong alternative: at default settings it beats MahaBodi on Banking77 (0.892 vs 0.832; on another fresh sample, the opt-in calibrate=200 ties kNN at 0.882 vs 0.876).

Small fixed label sets (2–77 tested), GPU and labelled data

Fine-tune a classifier

A fully fine-tuned Laya beats MahaBodi on 4 of 6 suites. MahaBodi's advantage there is no training step, and updates take seconds when labels change.

From agent to decision

Agents across the business send typed requests. MahaBodi remembers, shortlists and decides in one pass, then sends a typed answer back, and it learns from labelled outcomes without retraining. Illustrative uses; measured results are below.

AI agents scattered across eight business functions, all routed through MahaBodi
Animated end-to-end architecture: agents send typed requests through six engine stages (typed request, guard and cache, query cascade, shortlist, Laya decision, experience) backed by memory (fastmemory graph, dense vectors, experience memory) and a PostgreSQL scale path; the typed answer returns to the agent and labelled outcomes feed experience memory

One tree, four parts

Each part of the tree is a component you can test on its own, and every result below traces back to one of them.

Roots

fastmemory graph

Documents become a topology of actions, data and concepts. A density check keeps every record reachable, and hybrid keyword-plus-meaning search finds it again, even through typos.

Trunk

The MahaBodi engine

One Rust core: a query cascade with handoff flags, tournament shortlisting for many options, experience memory, and a script guard.

Branches

Six languages

The same engine and the same JSON API from Rust, Python, Node.js, Java, C#/.NET and Go, all tested against the real model.

Leaves

Laya decisions

Typed choice, score and yes/no answers with calibrated probabilities, in one forward pass. Nothing is generated, so nothing needs parsing.

Measured, not promised

Same machine, same Laya checkpoint on both sides, seeded test samples, and an exact McNemar test on the same items. A result counts as a win only at p < 0.05.

150
intents routed (CLINC150)
0.736 vs 0.708 for Laya with a MiniLM shortlist, the fair baseline (p = 0.027, one run); Laya alone 0.538. Re-tested on fresh items with an out-of-scope gate given to every system: 0.786 vs 0.756 (p = 0.014), out-of-scope recall 72 %. The pre-registered LLM arms of PREREG_ROUTER were not run (no API key): no claim against any LLM.
+16.8 pts
on 77-intent Banking77
0.660 vs 0.492 zero-shot, through tournament shortlisting. It ties Laya's MiniLM-shortlist mitigation.
0.78
BoolQ answered from memory
From 0.42 with the question only, and above always-yes (0.63). Confident errors fall from 45 % to 17 %. The oracle passage reaches 0.85.
ResultLaya / baselineMahaBodiVerdict
MASSIVE intent, 51 languages, zero-shot0.366 · 45/510.405 · 47/51beat
CLINC150 re-test on fresh items, same out-of-scope gate for every system0.756 (Laya + MiniLM shortlist + gate)0.786beat (p = 0.014; the gate lifts out-of-scope recall to 68–72 % for all systems)
Entity linking, 100K candidate Wikipedia pages (AIDA, 1,000 mentions; pre-registered)0.121 (Laya + dense shortlist) · Laya alone cannot run0.177beat (p = 0.0002; a retrieval gain: the deciders tie on the same shortlist)
Entity linking, natural 5.9M pages (v1 store: one vector per page, ts_rank)0.122 (Laya + dense shortlist)0.103tie (p = 0.14, numerically lower; 8.3 s per decision on a Mac mini)
Entity linking, 1M-page constructed pool (v2 store: per-passage vectors, cascade)0.129 (Laya + exact dense shortlist)0.164beat (p = 0.023; prior-dominated stage: the alias prior gets 0.749)
Entity linking, 10K candidate pages0.387 (Laya + dense shortlist)0.384tie (p = 0.92)
Entity linking vs a context-free alias prior (the entity a name usually means), 10K / 100K / 5.9M / 1Mprior: 0.800 / 0.784 / 0.772 / 0.7490.384 / 0.177 / 0.103 / 0.164 (v2 store at 1M)loss (the prior beats every context-reading system at every size)
Against Laya fully fine-tuned on the same 2,000 examples (encoder + head)Emotion 0.916 · SST-5 0.558 · prompt-inj. 0.974 · Banking77 0.8520.648 · 0.426 · 0.767 · 0.806loss on 4 of 6 · tie AG News, BoolQ · Banking77 ties with calibrate=200
Against Laya with its head fine-tuned on the same 2,000 examples (fresh items)Emotion 0.598 · Banking77 0.598 · SST-5 0.5300.648 · 0.806 · 0.426beat on Emotion, Banking77 · tie AG News · loss on SST-5
CLINC150, 150 intents + out-of-scope, zero-shot0.708 (Laya + MiniLM shortlist) · Laya alone 0.5380.736beat (p = 0.027, one run; in-scope only: out-of-scope recall 3 %)
Banking77, 77 intents, zero-shot0.4920.660beat (ties Laya + MiniLM shortlist)
Banking77 with 2,000 labelled examples (default settings, fresh items)0.462 (zero-shot)0.832beat (but a plain kNN on the same labels: 0.892, a loss)
Same, with opt-in calibrate=200 (third fresh sample)0.446 · plain kNN 0.8760.882beat Laya · ties kNN (p = 0.63); never below Laya or kNN on 5 suites
Latency, p50, CPU only (one Ubuntu i9-9900X, 8 threads, batch 1)Laya PyTorch: 165 ms (4 options) · 379 ms (77)125 ms · 730 msfaster on 4 (mostly ONNX Runtime) · 1.9× slower on 77 (tournament)
Calibration (ECE after the same temperature refit), 6 suitesBanking77 0.159Banking77 0.050beat on Banking77 only (tournament); tie on 5
Experience memory, default settings, 5 suites, fresh itemsLaya zero-shotno suite below Laya3 beats, 2 ties
Laya's near-ties (top-2 within 0.10), Banking7726 % correct91 % with labelled memorybeat
BoolQ answered from memory0.424 question only · 0.626 always-yes0.782beat (oracle passage: 0.846)
Misspelled keyword search (SQuAD, 300 paragraphs)BM25: 0.05 recall@50.61beat
Six other Laya suites (AG News, Emotion, SST-5, …)==tie: exact parity
Keyword search at 2,000 paragraphsBM25: 0.6840.660loss

Scorecard against Laya's 10 published benchmarks, zero-shot: 2 beats, 6 ties; all 10 are now measured. Calibration is scored per suite: better on Banking77 only, identical on the other 5. Latency is faster on 4 options (mostly from ONNX Runtime) and slower on 77 (the tournament). Neither counts as a beat. MahaBodi runs Laya's own models: the wins come from how it uses them, not from a new model. Full tables and per-item predictions →

Strengths and limits

Where MahaBodi stands today, with ties and losses reported next to wins.

Strong at

  • Memory that scales with your data: in process up to 100K documents, and on MahaBodi's PostgreSQL backend for large collections (pgvector for meaning search; Apache AGE for the graph, not yet used at 5.9M). 5.9M Wikipedia pages and 23M passages run on one Mac mini.
  • Retrieval that finds the right candidate: at 100K Wikipedia pages its memory puts the right page in the top 20 for 68 % of mentions, against 37 % for a dense-vector index, and it beats Laya + that index (0.177 vs 0.121)
  • Decisions with many options: 77 and 150 intents
  • Learning from labelled examples in seconds, with no retraining
  • Grounding decisions in your own documents, with citations
  • Typo-tolerant memory search
  • Zero generated tokens: a typed answer with probabilities, in one pass for a few options and a short tournament for many

Limits today

  • It is not a new model; on six suites it matches Laya exactly
  • Not yet compared with an LLM given every option in its context; the claim is cost and speed, not accuracy
  • Out-of-scope detection needs the opt-in similarity gate (off by default): about 72 % recall on fresh CLINC150 items in the benchmark, at some cost to in-scope accuracy. decide() reproduces the benchmark exactly (all 1,600 items on Ubuntu with the final build).
  • A fully fine-tuned Laya beats it on 4 of 6 small-label suites (e.g. Emotion 0.916 vs 0.648); with a fine-tuned head only, SST-5 is still a loss (0.530 vs 0.426)
  • On entity linking, a simple remembered alias prior (0.78) beats every context-reading system, MahaBodi included (0.18 at 100K pages)
  • With default settings, a plain kNN beats it on labelled Banking77 (0.892 vs 0.832). The opt-in calibrate step closes that gap to a tie by switching to kNN.
  • Retrieval can still be confidently wrong on hard, misspelled queries
  • The first 5.9M-page run used a simplified PostgreSQL configuration: one vector per page instead of one per passage, and PostgreSQL's text ranking instead of MahaBodi's own matching cascade. At 100K, those simplifications lowered the hit rate from 68 % to 48 %, and at 5.9M it took 8.3 s per decision and tied Laya + dense (0.103 vs 0.122). The full-configuration (v2) store has now been measured at a 1M constructed pool: it beats that baseline (0.164 vs 0.129, p = 0.023), and a pre-registered, descriptive 2×2 ablation shows that v2's improvement over the v1 store comes from the vector layout (granularity, embedded text and index change together and aren't separated). Its own 5.9M load stopped at 4.14M pages (disk), so v2 at the full natural pool remains unmeasured. The alias prior beats every context-reading arm at every size. TB–PB sizes are a blueprint (Enterprise).
  • Tool routing across thousands of tools is planned, not yet measured
  • Prebuilt packages (0.1.2) for Linux x86_64 and macOS x86_64 only, on crates.io, PyPI, npm and NuGet; Java is not on Maven Central

Scale it, or build with it

Deploy memory on PostgreSQL + Apache AGE with models on your own GPUs, or start coding in six languages today.