Every session I watched my AI agent burn tokens rediscovering the same codebase it already knew yesterday. That's not intelligence, that's amnesia with extra steps. Here's how I fixed it.
I watched Cursor spend almost two minutes just figuring out how our resume parsing pipeline connects to the skills matching service last month. Two minutes, on a codebase it had already "seen" a dozen times that week. That moment is what got me thinking seriously about how we structure context for AI agents working on ITJobOpportunities. Not prompts, not model choice — just: how does the agent know what it already knows? The amnesia problem is real, and it's expensive Here's the thing nobody tells you when you start wiring AI coding agents into a real workflow: every session starts from zero. The agent doesn't remember that it spent three minutes last week understanding how our JobFitController talks to the async scoring pipeline. It re-reads the service, re-reads the SSE handler, re-derives the relationship between the fit-check flow and candidate creation. Every single time. I used to think RAG solved this. Embed the codebase, retrieve relevant chunks, done. It doesn't — not for architecture understanding. RAG is good at "find me the function that does X." It's bad at "explain how these four services fit together and why." Those are different problems, and I learned that the hard way after wiring an embeddings-based retrieval layer into an internal tool and watching it confidently serve stale chunks from a service we'd refactored two weeks earlier. Nothing broke loudly. It just quietly gave wrong answers with total confidence. That's worse than a crash. This failure mode has a name now — some call it agent amnesia — and the fix people are calling the LLM Wiki pattern is simple in a way that made me feel a little slow for not doing it sooner: have the LLM write documentation for itself, in a format optimized for how LLMs actually read, and keep it fresh automatically. Not a README for humans. A wiki for machines. Why RAG breaks down for coding agents specifically RAG is a great tool for the right job — question answering over large document sets, semantic search across a knowledge base but coding agents need something different, and there are three specific reasons RAG falls short there. It re-derives relationships every time. Your agent wants to know how one service relates to another. RAG retrieves chunks from both files and the LLM figures out the relationship again — work it already did last session, now gone. Retrieval quality depends on vocabulary matching. If a class is commented as "skill extraction" but your agent queries for "resume parsing," the embeddings might not surface the right chunks. Architecture understanding shouldn't hinge on word choice. It goes stale silently , and this one bit me personally. A vector index has zero awareness that someone refactored a service last Tuesday. It serves the old chunks with total confidence. No warning, no flag, just wrong. None of this is RAG's fault exactly — it's the wrong tool for "help the agent hold a mental model of the system." That's a documentation problem, not a search problem. The three-layer structure, mapped onto our stack The pattern breaks into three layers, and once I saw it laid out this way it clicked because it maps almost exactly onto how I already think about docs at ITJobOpportunities — I'd just never automated the middle layer. Layer 3: The Schema AGENTS.md / CLAUDE.md — "the wiki exists here, check it first" Layer 2: The Wiki docs/agent-wiki/*.md — LLM-generated, agent-native docs Layer 1: Raw Sources Your actual codebase — the wiki never touches this Layer 1, raw sources , is just the code — untouched, immutable from the wiki's perspective. For us that's the jobs-posting backend (Java 25, Spring Boot 4.1) plus the two React frontends. The wiki reads it, never edits it. Layer 2, the wiki , is where the value shows up. Instead of a human writing prose that rots in three weeks — we've all got a README that lies to us — an LLM writes structured markdown shaped for how another LLM scans it later. Dense headings, explicit cross-references, no throat-clearing about "in this document we will explore." Just facts, laid out for scanning rather than reading. Layer 3, the schema , closes the loop, and it's the part people skip because it feels too simple to matter. This is your AGENTS.md or CLAUDE.md — the file Cursor, Claude Code, and Copilot all read at session start. You don't dump the whole wiki in there. You point to it. What "agent-native" documentation actually looks like I tried writing a wiki page for our Job Fit flow the human way first, out of curiosity. Three paragraphs of context before I got to anything an agent could actually use. Then I rewrote it agent-native, and the difference was almost embarrassing. Human version, roughly: The Job Fit feature allows candidates to check how well their resume matches a given job posting. This was built to provide value without requiring candidates to fully apply, and it uses an asynchronous scoring pipeline to avoid blocking the UI... Agent-native version: ## Job Fit Check Entry: JobFitController.checkFit() Flow: resume upload → async scoring job → SSE stream (fallback: polling) Score range: 0-100. Output: matched skills, missing skills, short summary. Persistence: candidate saved ONLY if email extracted from resume. See: candidate-summary.md#assessment-boundary for how this differs from the recruiter-facing AI assessment. That second version took me maybe four minutes once I stopped trying to be a good technical writer and just started dumping facts under headers. Honestly, it's more useful to me too when I'm jumping back into that code after two weeks on something else. Turns out agent-native docs are just... good docs. The cross-reference line matters more than it looks. See: candidate-summary.md#assessment-boundary isn't decoration — it's something the agent can follow programmatically instead of guessing whether it should look elsewhere. Closing the loop with AGENTS.md This is the step I originally underestimated. Generating good wiki pages does nothing if the agent doesn't know to check them first — it'll still default to grepping through source because that's its baseline behavior. Here's roughly what I added to our root AGENTS.md for the jobs-posting repo: ## Agent Context Before reading source files for architecture questions, check `docs/agent-wiki/` first: - docs/agent-wiki/architecture.md — service boundaries and data flow - docs/agent-wiki/ai-flows.md — Job Fit, resume improvement, candidate assessment: what's public, what's recruiter-only, what's async - docs/agent-wiki/auth.md — Keycloak realm setup, JWT flow Wiki is regenerated periodically. Prefer wiki context over re-deriving from source unless you suspect it's stale (check the file's last modified date). Short, deliberately. I made the mistake early on of pasting a whole architecture summary directly into AGENTS.md , and it blew up the context budget on every session, even ones that had nothing to do with architecture. The instruction file is a pointer, not a payload. Where this gets tricky in a real system I'm not going to pretend this is free. A few things the "just generate a wiki" pitch tends to skip over. The staleness problem doesn't disappear, it just moves. Instead of a RAG index quietly serving old chunks, your wiki markdown can quietly go stale, and unlike embeddings, nothing forces a refresh. You need a trigger — a scheduled job, a git hook, something. Ours runs periodically right now, and I already know that cadence isn't tight enough for anything touching the AI resume pipeline, which changes often. There's a scoping problem too, and it bit me on day one. Point your wiki generator at a repo root instead of a specific module, and it'll happily generate an entry for test fixtures, CI config, anything not excluded properly. Scope it tight. For us that meant generating separate wiki sets for jobs-posting , jobs-admin-console , and job-posting-ui rather than one giant wiki trying to cover three repos with three different concerns. And on...