Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lamar

An experience engine for AI agents.

Memory systems answer "what should the agent remember?" Lamar asks "how should the agent change because of what it remembers?"

Memory is becoming solved. Learning after deployment is not.


The problem

Every agent memory layer today (Mem0, Zep, Letta, LangMem, Cursor's rules, Claude Code's CLAUDE.md) does the same thing: extract facts, embed them, retrieve the top-k by similarity, inject them into the prompt.

That pipeline has no idea whether any of it helped.

Consider two lessons sitting in your agent's memory:

When the build fails, clear DerivedData.
When the build fails, delete the lockfile.

They are equally on-topic. A similarity search cannot tell them apart, because similarity is blind to outcome. One of them works. The other wastes your morning.

And when the world changes (the repo moves, the API is deprecated, the convention is quietly abandoned), a memory store has no mechanism for ceasing to believe something. It will surface the fossil forever, with total confidence.

The idea

Retrieval is not a search problem. It is a decision problem under uncertainty.

Which experiences should influence this turn, given limited context, imperfect knowledge of what actually works, and a reward signal that arrives after the fact?

That is a contextual bandit. It is the same shape as the problem Yahoo solved for news recommendation in 2010:

Yahoo (LinUCB, 2010) Lamar
context = user + page context = task, error class, project, language
arm = which article to show arm = which experience to inject
reward = did they click reward = did the human keep the work
policy = ranking policy = retrieval

Yahoo: every click improves recommendations. Lamar: every interaction reweights what the agent believes.

Once retrieval is a bandit, the rest of the system falls out of it rather than being bolted on:

  • Forgetting is not a module. It is an arm's value estimate falling until it stops being selected.
  • Testing your own beliefs is not a feature. It is the exploration bonus.
  • Promotion is not an approval workflow. A new claim is a cold arm; curiosity tries it, and the outcomes decide.

Three verbs

from lamar import Lamar, ExperienceStore, Signal

lam = Lamar(ExperienceStore("~/.lamar/experience.json"))

# 1. which experiences should influence this turn?
rec = lam.recall({"project": "trace", "language": "swift", "task": "build_fails"})
run_my_agent(system_prompt + rec.as_prompt())

# 2. what did the human actually do about it?
lam.report(rec.episode_id, Signal.REVERTED)

# 3. offline, at night: consolidate, decay, retire, surface contradictions
lam.sleep(traces=todays_sessions)

recall and report are cheap, synchronous, and call no model at all. All the expensive and dangerous work happens in sleep, away from the user, where it can be reviewed before it changes anything.

That split is the thesis, not an implementation detail:

Online, a system collects experience. Offline is where experience becomes intelligence.

What an experience is

Not a note. A claim that can be wrong, and that carries the evidence for and against itself.

Experience(
    precondition="the Xcode build fails after a dependency bump",
    action="clear DerivedData before rebuilding",
    rationale="stale module maps survive a clean build",
    scope=Scope(project="trace", language="swift"),
)

It plays two roles at once, and everything in Lamar exists to keep them in sync:

  1. a lesson a human can read: when X, do Y, because Z
  2. an arm a bandit can pull: a feature vector with a running reward estimate

Free-text notes cannot be scored, decayed, contradicted, or retired. That is why every other memory layer can only accumulate.

Where the reward comes from

Behavioral signals. Nothing else.

The outcome signal does not live in the model. It lives in your application. Only your app knows whether the developer reverted the patch, whether the deploy held, whether the quote won.

Signal.SHIPPED    # committed, merged, deployed
Signal.ACCEPTED
Signal.REASKED    # asked the same thing again
Signal.CORRECTED  # "no, that's wrong"
Signal.REVERTED   # undid the work

Lamar does not ask an LLM to grade its own trajectory. Models are cheerful about their own output, and the resulting reward is noise wearing a lab coat.

Model agnostic, by construction

Not by adapter count. The bandit is arithmetic; scope matching is string comparison; reward comes from what a human did. None of it needs a model.

Exactly one job does: reading a pile of raw traces and noticing that the same thing keeps going wrong. So the protocol is one method.

class MyModel:
    def complete(self, prompt: str, *, max_tokens: int = 2048) -> str: ...

Anything with that method works. Adapters for Anthropic, OpenAI and Ollama ship in the box as lazy imports. Lamar has zero dependencies. Not even numpy.

Does it work

examples/memory_gym is a falsifiable test, built to be fair rather than flattering. Per task the store holds six claims that are all equally relevant: one that helps, one that hurts, four that do nothing. Halfway through, the world silently flips and one true lesson becomes false.

policy        first 500   pre-flip  post-flip  recovered
--------------------------------------------------------
none              43.0%      39.4%      40.7%      38.4%
similarity        44.6%      39.8%      42.0%      35.2%
lamar             57.2%      59.4%      62.7%      55.8%

The success rate says Lamar wins. This says why:

share of injected slots, by what the lesson actually was:

                       TRUE   FALSE   INERT   FOSSIL
similarity   pre-flip    15.8%   15.2%   65.1%    4.0%
             post-flip   16.6%   15.6%   64.2%    3.6%   <- identical. it cannot learn.
lamar        pre-flip    35.1%    1.0%   51.0%   12.9%
             post-flip   49.5%    0.0%   50.2%    0.3%   <- fossil: 12.9% -> 0.3%

Nobody told it the world had changed.

Note the middle row. After the flip, similarity retrieval performs worse than having no memory at all (35.2% vs 38.4%), because it cannot stop injecting a lesson that has become false. It has no capacity to disbelieve.

python3 examples/memory_gym/gym.py
python3 -m unittest discover -s tests

The dangerous part, stated plainly

The moment experience is allowed to change behavior, you inherit reinforcement learning's stability problems without reinforcement learning's math. A memory store is immune to this only because it never learns.

The failure mode: the agent draws a wrong lesson from a lucky episode. The lesson starts influencing decisions. Those decisions generate more episodes that appear to confirm it. The system becomes stably, confidently, self-reinforcingly wrong.

Four defenses, each of which exists because a version of this code got it wrong first:

  1. A single episode can never mint a belief. Promotion requires evidence that clears a confidence bound.

  2. Every claim has its own control group. The episodes where it was eligible and did not fire. Without one, an experience is scored against a baseline it itself contaminated, its measured lift collapses toward zero, and noise retires it. (This executed two genuinely good lessons before it was fixed.)

  3. All evidence decays. Scored on its whole life, a lesson that was true for a year and false since last month still shows a glowing record. Lifetime averages keep fossils alive forever.

  4. Randomized holdout. Lamar sometimes deliberately withholds an experience the policy wanted to use, and watches what happens without it. This is the only estimator that survives "the agent would have succeeded anyway." It costs real performance, and that cost is explicit and tunable, because a system claiming to validate its own beliefs for free is lying.

And every decision is made on a confidence bound, never a point estimate, asymmetrically:

  • promote when the pessimistic bound is still positive: even read uncharitably, it helps
  • retire when the optimistic bound is still negative: even read charitably, it hurts
  • otherwise, do nothing

Being useless is not grounds for retirement. A useless claim simply stops being selected, which costs nothing and reverses itself the moment it starts working. Retirement is reserved for demonstrable harm.

Known limitations

Stated because a benchmark that hides its failures is marketing.

  • Lamar is better at proving a lesson harmful than proving one helpful. A good lesson gets selected on nearly every episode, so it is almost never absent, so its control group stays thin and the bound will not clear. In the gym, only 1 of 4 genuinely helpful lessons earns a helps verdict; the rest sit at unknown while still being used. It never gets one wrong (0/4 helpful lessons were judged harmful, 0/4 harmful and 0/16 inert were judged helpful), but "I cannot prove this works" is a real gap in an auditability story. Targeting the holdout at the thinnest control group helps and does not close it.

  • Reward attribution is approximate. Several experiences are injected, one outcome comes back, and each gets credited with the shared reward. This is correct in expectation only when arms appear in varied combinations. If your candidate pool is never larger than k, the same experiences co-occur every episode and no algorithm can separate them. Make sure you have more candidates than slots.

  • Low volume hurts. A solo developer's agent produces hundreds of episodes a week, not millions. Feature vectors are deliberately small and hand-built for this reason. Do not dump an embedding into Experience.features: it will look sophisticated and never converge.

  • Untested in production. Every number on this page comes from a synthetic environment. The next milestone is a real one.

Status

Early. The core loop works and is tested. The Claude Code adapter is next.

Why "Lamar"

Lamar Valley, in Yellowstone. People go there not to change the wolves, the bears or the bison, but to sit still and watch them.

Observation is the first layer.

License

MIT

About

An experience engine for AI agents. Retrieval as a contextual bandit, not a search.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages