Your agent keeps making the same mistakes.
errlore makes that stop.
Stop the second mistake, not just the first.
Your coding agent reintroduces the same bug and forgets the same convention, session after session. errlore captures each fix as a lesson and injects it into the next similar prompt — so the second mistake doesn't happen. Then it tracks whether the lesson actually helped, and reinforces the ones that do.
error → your fix → lesson → injected into next similar prompt → outcome feedback → reinforce / decay
Three loops, all closed
01Lessons
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.
02Known issues
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.
03Trust experimental
Bayesian per-model, per-domain trust weights built from observed outcomes, for
routing via mem.best_model("code"). Needs a spread of real outcomes
to separate models — shipped, but not yet proven in the wild.
Fifteen seconds of the whole idea
Sixty seconds to a learning agent
from errlore import AgentMemory mem = AgentMemory("./agent_memory") # 1. agent failed — record it err = mem.log_error("gpt-5.6", "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.6", 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)
Measured, not promised
Paired A/B: the same model runs the task grid with and without errlore injection. Deterministic validators, no LLM judges; raw outputs committed to the repo. Reproduced across 5 independent runs (66.7–69.8% repeat-error reduction, exact McNemar p ≤ 1.8e-09 every run) and on a second model family — gemma-4-31b lands at 70.0% reduction (p = 2.6e-13).
| error class | plain | with errlore |
|---|---|---|
| knowledge-gap, claude-haiku-4-5 | 46/48 | 0/48 |
| knowledge-gap, gemma-4-31b | 70/72 | 12/72 |
| capability-gap (model skill limits), both models | ~17/48 | ~19/48 |
The knowledge-gap rows use conventions the model can't guess, so plain fails almost by construction — the result shows errlore captures the fix once and re-supplies it on the next task (the loop works), not that memory teaches skills. Two fresh realistic-convention families (an internal status enum, a non-standard git branch format) went 100% → 0% on both models. The honest row stays honest: errlore did not help on things the model can't do (letter counting, string reversal) — and even slightly hurt, on both model families. Reproduce it: python benchmarks/bench_error_reduction.py --backend anthropic.
Finds lessons by meaning, not keywords
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.
Drops into what you already run
Claude Code
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/.
Open WebUI
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.
Python SDKs
Working examples for the OpenAI SDK, Anthropic SDK, and LangChain in examples/ — each runnable offline, each showing the full learn-inject-reinforce cycle.
Why not just logs or vector memory?
| 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 warnings |
| 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.
Where it earns its keep
›Coding agents
that keep re-introducing the same class of bug across sessions.
›Extraction pipelines
that hallucinate dates, numbers and schema fields the same way every week.
›Multi-model routing experimental
pick the model per task from observed outcomes — mem.best_model("code"). The trust layer is shipped but still earning its evidence.
Built for the privacy-first crowd
fsync'd, file-locked, atomic
embeddings download once, then local
writers, corrupted lines
outcomes only from real feedback
Async API, log compaction and multi-agent memory are next — watch releases on GitHub to follow.