AI coding agents are becoming much more useful, but there is one problem I keep running into:
They forget project-specific lessons.
Not because the model is bad. Not because the prompt is missing one more paragraph. The problem is structural.
Most coding agents work inside a temporary conversation context. They can understand what you tell them during the session, but once that context is gone, the same mistakes can easily happen again.
For example:
- an agent edits generated files manually instead of updating the source schema
- it moves business logic into React components even though the project uses stores/services
- it runs the wrong test command
- it ignores a previous debugging conclusion
- it repeats a fix that already failed last week
- it forgets that a specific folder has special conventions
This creates a strange workflow where developers keep telling agents the same things again and again.
At some point, “please remember this” should become part of the project itself.
The obvious solution: a lessons file
A simple idea is to create something like this:
LESSONS.md
- Do not edit generated GraphQL types manually.
- Use MobX stores for business logic.
- Run pnpm test:unit before changing payment logic.
- Do not modify files in src/generated/.
This is already better than nothing.
It makes implicit project knowledge explicit. It can be versioned in Git. It can be read by different agents.
But after working with this idea, I started to feel that a plain file is not enough.
The problem is not storing lessons.
The problem is retrieving the right lesson at the right moment.
Why plain lesson files do not scale well
A flat markdown file works when there are five lessons.
It becomes much less useful when there are fifty, a hundred, or several hundred.
Some problems appear quickly:
1.The file becomes noisy
Agents may read too much irrelevant context.
A lesson about GraphQL code generation is not useful when the agent is editing CSS.
A lesson about payment validation is not useful when changing a README.
If every agent reads every lesson every time, memory becomes noise.
2.Lessons lose context
A lesson like this is technically correct:
Do not edit generated files manually.
But it is missing important context:
- Which files are generated?
- Which command regenerates them?
- What caused the original mistake?
- Which rule does this relate to?
- Is this always true or only true for one package?
- Is this still current?
The lesson exists, but it is disconnected from the codebase.
3.Lessons become stale
Projects evolve.
A command changes.
A folder is renamed.
An architectural rule is replaced.
A plain file rarely tells you whether a lesson is fresh, outdated, or only partially valid.
4.Agents cannot easily reason about relationships
In real projects, knowledge is connected.
A mistake may be connected to:
- a file path
- a command
- an architectural rule
- a tool
- a package
- a domain area
- a previous failed fix
- another lesson
A flat file does not represent those relationships well.
That is why I started thinking about lessons as a graph.
Graph-based lessons
A graph-based lessons system treats a lesson not as an isolated note, but as a connected piece of project knowledge.
Instead of this:
Do not edit generated GraphQL types manually.
You can model it more like this:
Lesson:
Do not edit generated GraphQL types manually.
Update the schema and run codegen instead.
Connected context:
affected files:
- src/generated/graphql/*
- packages/api/generated/*
command:
- pnpm codegen
related rule:
- generated files are read-only
mistake type:
- manual edit of generated output
domain:
- GraphQL
- API types
freshness:
- confirmed recently
Now the lesson is no longer just text.
It has relationships.
Before an agent edits src/generated/graphql/User.ts, it can retrieve lessons connected to that path.
Before it changes payment validation, it can retrieve lessons connected to the payment domain.
Before it runs tests, it can retrieve the correct command connected to the current package.
This is closer to how developers actually remember project knowledge.
We do not remember everything as one giant document. We remember connections:
“This file is generated.”
“This folder belongs to the payment domain.”
“That command failed before.”
“This convention exists because of that production bug.”
A useful agent memory system should work the same way.
What should a lesson contain?
A lesson should probably include more than just a sentence.
For example:
Lesson:
Business logic should stay in MobX stores, not React components.
Reason:
The project separates domain logic from UI rendering.
Moving logic into components makes testing and reuse harder.
Applies to:
- src/stores/*
- src/features/* Related concepts:
- MobX
- domain logic
- React components
- separation of concerns Mistake type:
- architectural violation Suggested behavior: If a change requires business logic, add it to the store/service layer first. Keep React components mostly declarative.
This gives the agent enough information to act correctly, not just read a rule.
Human memory vs agent memory
One important question is:
Should agents be allowed to create lessons automatically?
I think the answer is: yes, but carefully.
For example, after a failed change, an agent could propose:
Proposed lesson:
Do not use npm in this repository. The project uses pnpm.
Evidence:
npm install created a package-lock.json and broke dependency consistency.
Suggested scope:
whole repository
Related command:
pnpm install
But I would not want every agent to permanently write lessons without review.
A better workflow may be:
- Agent detects a reusable lesson.
- Agent proposes the lesson.
- Human approves, edits, or rejects it.
- Approved lesson becomes part of the repository.
- Future agents can retrieve it when relevant.
This keeps memory useful without letting it turn into uncontrolled noise.
Why this matters more with multiple coding agents
Many developers now use more than one AI coding tool.
For example:
- Claude Code
- Cursor
- Codex CLI
- GitHub Copilot
- Gemini CLI
- Aider
- Roo
- Cline
- Windsurf
Each tool has its own configuration style.
Some use markdown instruction files.
Some use rules.
Some use commands.
Some support MCP.
Some have their own project config structure.
This creates another problem: project knowledge becomes fragmented.
You may have one rule in CLAUDE.md, another in .cursor/rules, another in AGENTS.md, and another in some tool-specific config.
Eventually, your agents are not working from the same understanding of the project.
That is the broader problem I am trying to solve with AgentsMesh.
What is AgentsMesh?
AgentsMesh is an open-source CLI/library for managing AI coding assistant configuration from one canonical source.
The idea is simple:
Define project knowledge once in .agentsmesh/, then generate native config files for different AI coding tools.
AgentsMesh can manage things like:
- rules
- commands
- agents
- skills
- hooks
- permissions
- MCP servers
- ignore patterns
- graph-based lessons
The lessons system is the part I find most interesting.
It is designed as structured, connected memory rather than a plain file full of notes.
The goal is not just to store instructions.
The goal is to help agents retrieve the right project knowledge at the right time.
Example workflow
Imagine an agent makes a mistake.
It manually edits a generated GraphQL type.
The build passes locally, but later codegen overwrites the change.
Instead of just saying in chat:
Do not do that again.
The project can record a lesson:
Lesson:
Do not manually edit generated GraphQL types.
Update the schema and regenerate types instead.
Connected files:
- src/generated/graphql/*
- packages/api/generated/* Command: pnpm codegen Related rule: generated files are read-only Mistake type: editing generated output
Later, another agent wants to edit a file inside src/generated/graphql/.
Before making the change, it can retrieve the lesson connected to that path.
The agent does not need to read every project instruction.
It only needs the relevant memory.
The real challenge: avoiding bad memory
Long-term memory sounds useful, but bad memory can be worse than no memory.
A lessons system needs safeguards.
Some questions I am still thinking about:
Should lessons expire?
Some lessons should probably become stale automatically.
For example, a command may change from:
pnpm test
to:
pnpm test:unit
If old lessons remain forever, agents may follow outdated instructions.
Should every lesson need approval?
Fully automatic memory can become noisy.
But requiring manual approval for every lesson may create too much friction.
A good system may need different trust levels:
- proposed
- approved
- deprecated
- archived
How do you prevent overfitting?
One failed interaction does not always mean there is a general rule.
If an agent makes one bad change, the lesson should not necessarily become:
Never touch this file.
A useful lesson should capture the actual reusable principle, not just fear from one mistake.
How much context is enough?
Too little context makes lessons vague.
Too much context makes them expensive and noisy.
The ideal lesson should be small, specific, and connected to the right parts of the project.
Why I think graph-based memory is worth exploring
Prompt files are useful.
Rules are useful.
Documentation is useful.
But AI coding agents need something more precise than “read this giant instruction file before every task.”
They need contextual recall.
When editing generated files, recall codegen lessons.
When touching payment logic, recall payment-related lessons.
When changing architecture, recall architectural constraints.
When running commands, recall the correct package manager and test scripts.
That is why I think graph-based project memory is a promising direction.
Not because graphs are trendy.
But because software projects are already graphs:
- files depend on files
- commands affect packages
- rules apply to directories
- mistakes happen in domains
- conventions relate to architecture
- fixes relate to previous bugs
Agent memory should reflect that structure.
Final thoughts
I do not think the future of AI coding agents is just bigger context windows.
Bigger context helps, but it does not solve everything.
The real improvement may come from better project memory:
- structured
- versioned
- reviewable
- connected to the codebase
- retrievable by relevance
- shared across tools
That is what I am experimenting with in AgentsMesh.
The core idea is simple:
Agents should not repeat the same project-specific mistakes forever.
When a mistake teaches something useful, that lesson should become part of the project.
GitHub: https://github.com/sampleXbro/agentsmesh
I would love feedback from developers building with AI coding agents:
How would you design long-term project memory so it helps agents avoid repeated mistakes without becoming noisy, stale, or over-engineered?
Top comments (18)
Modeling lessons as a graph solves the storage side, but the piece I keep snagging on is the retrieval trigger. The agent only benefits if it actually queries the graph before it touches
src/generated/graphql/User.ts, which means something has to slip a lookup into the loop at the right moment. You can store the lesson beautifully and still never read it. How are you planning to fire that retrieval, a hook that runs before any edit and matches on the file path, or are you trusting the model to remember to ask?Good point. The current approach depends on target capabilities.
For tools that support hooks, AgentsMesh can use a PostToolUse hook to query related lessons after file/tool activity and keep the agent aware of relevant context.
For targets without hooks, it falls back to a blocking rule that tells the agent to check lessons before working on a new area. It works reasonably well, but it depends on context quality — if the chat is overloaded or compacted, reliability drops.
So my current recommendation is to start a fresh chat for each new feature/topic, so the blocking rule and retrieved lessons stay visible and effective.
I agree with the direction here, especially the part about project-specific lessons becoming part of the project instead of being re-explained in every session.
The only thing I would push on is the word “memory.” It may be too generic. Not all project memory has the same value.
A rule like “use MobX stores for business logic” is different from “the last attempt to move this logic into React components failed because it broke subscription updates.” The first is a convention. The second is an episode with a cost attached to it.
For coding agents, I think the valuable layer is not generic “how to code” memory. The model already has a lot of that compressed into the weights. The valuable layer is project-contingent memory: decisions, failed attempts, local conventions, generated-file boundaries, fragile paths, weird commands, and the reasoning behind past tradeoffs.
So the question is not only “how do we store project memory?” It is also: what kind of memory is worth storing, and when should it be retrieved?
A graph helps a lot with structure, but the hard part is the trigger. If the agent is about to edit a generated file, run a migration, touch payment logic, or repeat a failed fix, memory should act before the mistake, not after another postmortem.
That is where project memory becomes more than notes. It becomes a local warning system for facts the model cannot re-derive from general coding knowledge.
Thanks Marco, I think you’ve named it better than I did.
“Memory” is too broad. What I’m trying to build with AgentsMesh is closer to a project-local warning system: short lessons about things the model cannot reliably infer from general coding knowledge.
So not “remember everything,” but “remember the expensive/local stuff”: failed fixes, generated-file boundaries, fragile commands, architecture decisions, local conventions, and tradeoffs. In the library these lessons are tied to file, command, and keyword triggers, so they can be recalled before the agent edits the wrong thing or repeats a known mistake.
That trigger layer is definitely the hard part, and I agree it’s where the real value is.
Hm. I'm now thinking... What if as a LLM thinks, it flags important tokens in terms of priority. Then in the feedback loop, inject the graph entries for those flags. It's not very token efficient, but given that it's cache hits, it's negligible performance and cloud-cost... But result is if it says Apple is important, whatever contextual memory it has about apple will be injected during the next loop, which creates a waterfall effect where each iterative loop, it drills down deeper into the memory, as it does it's thinking, essentially skipping the whole grep search and file-view functions entirely, which in turn would actually save on total tokens and context size in the end?
A system instruction can work for it, else could use a markov chain to determine the most unique word in each sentence, which tends to be the most relevant... Normally used to predict next word, which means the one that's markov-link is the lowest, would most likely be the point of friction, where a generic statement becomes an exact instruction... In turn, inferring what's relevant and what's boilerplate.
Thats an awesome initiative!
I think that approach of documenting lessons learned are good for the agent.
My opinion and what I have did:
I've been doing this using Cline agentic tool and it could be able to generate a good result!
Tests are also code documentation because they are exercising impl and will improve design decisions and assert that code is working!
Thanks! Totally agree with you.
Tests are probably one of the best forms of documentation because they describe the expected behavior and verify it at the same time.
I also like your point about contracts over implementations. That’s exactly the kind of context I think agents should remember and reuse, not just keep inside one chat session.
My idea with graph-based lessons is to connect these things together: decisions, contracts, tests, code areas, and previous mistakes, so the agent can retrieve the right context before making changes.
Really interesting that you’re already doing something similar with Cline.
The "telling the agent the same thing every session" problem is genuinely annoying. A flat file works until it doesn't.
The staleness problem is the hard one though, a lesson about a command that changed 3 months ago is worse than no lesson. How are you handling that?
Yeah, I agree — staleness is probably the hardest part.
Right now I’m thinking about lessons having metadata like status, lastVerified, confidence, and links to related files/commands. So if a lesson references a command, it shouldn’t just be a text note — it should be connected to the actual command/config it depends on.
The ideal flow would be: if the related command/file changes, the lesson becomes “needs review” instead of staying silently trusted.
I don’t think old lessons should be deleted automatically, but they should lose confidence or require re-validation. Otherwise, as you said, stale memory can be worse than no memory.
BTW, one more thing I forgot to mention: an agent can also deprecate an existing lesson and propose/create a new one if it detects an inconsistency.
For example, if a lesson references an old command but the actual package scripts show a different command now, the agent can mark the old lesson as deprecated and create an updated lesson instead.
So lessons are not meant to be permanent static rules — they can evolve with the project.
The retrieval-trigger question Nazar raised is the one I keep coming back to, but I would push it one floor under: who authors a lesson, and how do you verify the right lesson fired at the right moment? An agent self-proposing a lesson after a failed change is single-party authorship of "what counts as the reusable principle here," which means the same loop state that produced the failure decides what to remember about it.
The forward I would ask is on planted faults: can you produce a known mistake and verify the system retrieves the right lesson at recurrence, separately from the proposed/approved/deprecated lifecycle? Without that, the lessons graph is a write-side artifact.
Yeah, I think this is exactly the right pressure test. The lessons system today has decent write-side mechanics, including capture guardrails, dead-trigger checks, dedupe/upsert, deprecate/supersede, recall telemetry, and strict graph validation. However, it still mostly proves that "the graph is well-formed and recallable," not that "the right lesson fires when the same mistake recurs."
The planted-fault framing is the missing evaluation layer. I'd like to have a separate retrieval QA suite in which we would seed a known lesson and decoys, recreate the recurrence context, and verify that the expected lesson appears before the action. Ideally, it would appear in the top N and with the expected trigger and reason. This should be independent of the proposed, approved, or deprecated lifecycle.
Regarding authorship: I agree that agent self-capture should be treated as a proposal, not a fact. The review boundary can be Git/PR for now, but in the long term, the graph will probably require explicit provenance and approval states. However, approval only answers, "May this lesson enter memory?" Planted-fault evaluations answer the more important operational question: "Will this memory actually protect us at recurrence?"
Therefore, I'd consider this the next significant milestone. It's not about further refining the write side, but rather, creating a recurrence harness with known faults, expected lesson IDs, decoys, top-N assertions, and telemetry-derived precision and recall.
The current-state disclosure (write-side mechanics through graph validation, but proving "graph is well-formed and recallable" rather than "right lesson fires at recurrence") is honest stage-marking that lets the rest of the conversation be about the missing piece rather than relitigating what's shipped.
The "approval answers may-this-enter-memory, planted-fault answers will-this-protect-us-at-recurrence" cut is the part I want to ratify forward. Two separate gates, not one gate with two phases. Conflating them is how lessons systems can quietly become well-formed write-side artifacts that never get verified at the operational layer. Authorship-gate vs operational-protection-gate as typed slots, both required, neither inferable from the other.
Two refinements on the harness spec. First, the planted faults have to be authored outside whatever distribution the graph validator has already inspected, otherwise the "decoy" is a lesson the validator has reasons to recognize and the harness measures graph hygiene rather than retrieval discriminability. Second, precision and recall both have to run in both directions: catch rate on planted-fault recurrence, and false-positive rate on adjacent contexts where the lesson should not fire. The false-positive direction is what your original post named as the core risk and the harness has to make it measurable.
The milestone framing (recurrence harness with known faults, expected lesson IDs, decoys, top-N assertions, telemetry-derived precision and recall) is the right thing to be locking in as next. When the first harness run lands, the precision/recall numbers in both directions will be a useful empirical data point for the lessons space.
Thanks, this is a very good point.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.