Stop the second mistake, not just the first.
A memory layer for AI agents that learns from failures: every resolved error becomes a lesson, lessons are injected into future prompts, and Bayesian trust weights track which model to believe for which job.
error → your fix → lesson → injected into next similar prompt → outcome feedback → trust update
An error you resolve becomes a lesson. The next similar task gets it injected
into the prompt. report_outcome() reinforces lessons that helped and
decays ones that never do — errlore knows whether its own memory works.
Per-model weakness tracking. When gpt-x has failed date extraction four times,
the fifth prompt says so: KNOWN ISSUES: TimeoutError (x4). Models get
warned about their own history.
Bayesian per-model, per-domain trust weights built from observed outcomes.
mem.best_model("code") answers the routing question with data,
not vibes.
from errlore import AgentMemory mem = AgentMemory("./agent_memory") # 1. agent failed — record it err = mem.log_error("gpt-5.5", "extraction", error="hallucinated dates") # 2. you fixed it — extract the lesson mem.resolve(err, "added validation", lesson="For date extraction, demand ISO-8601 and verify against source") # 3. next similar task — memory speaks up task = "extract dates from contract" inj = mem.inject_for(task, model="gpt-5.5", task_type="extraction") prompt = task + "\n\n" + inj.text # [LESSONS FROM PAST FAILURES] # - UnclassifiedError: hallucinated dates -> For date extraction, # demand ISO-8601 and verify against source # # KNOWN ISSUES: # - Past error on similar task: hallucinated dates # 4. close the loop — did it help? mem.report_outcome(inj, success=True)
Paired A/B: the same model (claude-haiku-4-5) runs 96 tasks with and without errlore injection. Deterministic validators, no LLM judges; raw outputs committed to the repo. Exact McNemar over all 96 pairs: p = 1.8e-09.
| error class | plain | with errlore |
|---|---|---|
| knowledge-gap (workspace conventions) | 46/48 | 0/48 |
| capability-gap (model skill limits) | 17/48 | 20/48 |
The honest half is the second row: errlore did not help on things the model can't do (letter counting, string reversal) — and even slightly hurt. Memory fixes what the model doesn't know, not what it can't do. Reproduce it yourself: python benchmarks/bench_error_reduction.py.
Optional local embeddings (pip install errlore[embeddings], ~120 MB ONNX model, RU/EN and 50+ languages, no API keys). On a deliberately adversarial gold set — every query paraphrased so it shares zero words with its lesson:
| metric | keyword overlap | errlore embeddings |
|---|---|---|
| recall@1 | 0.000 | 0.375 |
| recall@5 | 0.000 | 0.675 |
| MRR | 0.000 | 0.488 |
The gold set is deliberately adversarial — every query is paraphrased to share zero words with its lesson. On natural queries with shared vocabulary, plain word-overlap does fine; embeddings earn their keep on paraphrased ones. Reproduce it yourself: python benchmarks/bench_retrieval.py — the gold set ships in the repo.
Hooks wire errlore into your coding agent: failed commands become lessons, and each session starts with a briefing of past pitfalls. See examples/claude-code/.
Two functions — a Filter that injects lessons into every chat and a feedback Action that closes the loop from a button under each message. Paste, enable, done.
Working examples for the OpenAI SDK, Anthropic SDK, and LangChain in examples/ — each runnable offline, each showing the full learn-inject-reinforce cycle.
| plain logs | vector memory | errlore | |
|---|---|---|---|
| stores failures | yes | sometimes | yes |
| turns them into lessons | no | no | yes |
| injects into future prompts | no | retrieval only | yes, with feedback loop |
| knows if a lesson helped | no | no | reinforce / decay |
| tracks per-model weaknesses | no | no | KNOWN ISSUES + trust |
| works offline, no server | yes | depends | yes |
Not a vector DB, not chat-history RAG, not observability. One job: failures become lessons that reach the next prompt.
that keep re-introducing the same class of bug across sessions.
that hallucinate dates, numbers and schema fields the same way every week.
pick the model per task from observed outcomes — mem.best_model("code") — not vibes.
Async API, log compaction and multi-agent memory are next — watch releases on GitHub to follow.