You give the agent a task in a part of the codebase it doesn’t know. It gets it wrong. So you do the natural thing: you write a longer prompt. You describe the architecture, name the important modules, explain that the payment logic lives here and the retry logic lives there, and you paste in a couple of key files for good measure. The agent gets it slightly less wrong, breaks something else, and you write an even longer prompt tomorrow.
I did this for weeks before I noticed the shape of it. The prompt kept growing and the failures kept moving. I was treating a structural problem as a wording problem, and no amount of better wording closes a structural gap.
The agent does not need more words about the codebase. It needs a map of it. Those are not the same thing, and the difference is the whole point of this piece.
A prompt is prose. A map is structure.
Here is what a long architectural prompt actually is from the model’s side: a wall of text it has to read, hold in the context window, and re-derive structure from every single time. You wrote “the OrderService calls into InventoryService before it writes.” That is a sentence. For the agent to use it, it has to parse the sentence into a relation, remember the relation, and hope you mentioned all the other relations that matter. You almost never do, because you are writing from your own mental map and you skip the parts that feel obvious.
A map is that structure handed over directly. OrderService calls InventoryService. That edge is a fact the agent can query, not a sentence it has to interpret. It does not compete for space in the context window with the actual task. It does not depend on you remembering to mention it. It is either in the map or it isn’t, and if the map is built from the code, it is.
This is why longer prompts hit a ceiling fast. Prose does not compose. Every sentence you add is more to read and more to potentially contradict. Structure composes: a thousand edges in a map cost the agent almost nothing until it queries the ten it needs.
prompt
- wall of text
- re-parsed each run
- competes for context
- you forget edges
map
- queryable edges
- built from code
- composes cheaply
- never forgets
Context engineering for coding agents is largely this realization applied end to end: the win is not stuffing the window fuller, it is putting the right structure where the agent can reach for it.
What a codebase map actually contains
“Map” is not a metaphor for “good documentation.” It is a specific thing. A useful codebase map carries, at minimum:
- The call structure. What calls what. This is the backbone. Most of an agent’s dangerous mistakes are edits that ignore a caller, and the call structure is exactly the set of edges that would have warned it.
- The dependency structure. What imports what, what depends on which service or table. This is how the agent knows a change is contained versus how it knows a change reaches across half the system.
- The type and data flow. Which types flow through which paths. Rename a field and this is what tells the agent every place that field is unpacked, not just where it is defined.
- The boundaries. Where one module ends and another begins, and which few functions bridge them. Agents that respect boundaries write changes that fit the existing shape instead of tunneling through it.
- The entry points. Endpoints, jobs, CLI commands, event handlers. The places execution actually starts, so a path can be traced from a real trigger to its effect.
- Reachability. What is live and what is dead. A map that knows nothing is calling a function is a map that lets the agent stop worrying about it.
None of that is prose you write. All of it is structure you read off the code. The map is a projection of the system, which is also why it does not go stale the way a hand-written architecture doc does. When the code changes, the map is regenerated from the new code, and it is true again without anyone remembering to update it.
Why “just use a bigger model” misses too
The other reflex, next to the longer prompt, is to wait for the bigger model. Surely a smarter agent with a longer context would just figure out the structure.
It figures out more of it, and it still starts every session from zero. A bigger context window is more room to paste files into; it is not a map, because the model still has to reconstruct the relations from the pasted text on every run. You are paying, in tokens and in time, to rebuild the same structure the code already contains, over and over, and hoping the reconstruction is complete this time. It usually isn’t, because the relations that break you are the non-obvious ones, and those are exactly the ones a from-scratch read is most likely to miss.
Hand the model the map instead and the smart model gets smarter, because it spends its capability on the task rather than on re-deriving the terrain. That is the sense in which the phrase is literal: codebase maps, not bigger prompts. The leverage moved from the size of the input to the shape of it.
The rename that a map would have caught
Make it concrete. You ask an agent to rename a field on a core struct, userId to accountId, a change that looks trivial. Without a map, the agent greps for userId, finds the definition and the obvious usages in the same module, updates those, and reports done. It missed the serializer in another package that reads the field by string key, the SQL migration that names the column, and a test fixture three directories away that hardcodes the old name. The build even passes, because the serializer failure only shows up at runtime against real data. You find it in production, or a reviewer finds it after an hour of reading.
With the map, the rename starts differently. The agent queries the graph for everything connected to that field: every function that reads or writes it, every type it flows into, every test that touches those functions, the config and migration nodes that reference it. It gets the full set before it changes a line, updates all of it or tells you which parts it can’t safely touch, and the change lands whole. The difference was never the model’s intelligence on the rename. It was whether the model could see the field’s neighborhood. A longer prompt would have described the module you already knew about and still missed the serializer, because you would have forgotten to mention it too. The map does not forget, because it is not remembering. It is reading.
Where PaellaDoc fits
This is one of the reasons PaellaDoc reads your repo into a graph on your machine before an agent touches it. The map, the call structure, the dependencies, the boundaries, the links from code back to the decisions that asked for it, gets built from the actual source and kept current as the source moves. Agents query it instead of re-reading the world from a prompt. The same structure is what lets a product knowledge graph answer questions one level up, about shape and validation rather than calls and types. Same technique, two altitudes.
The next time an agent gets it wrong in unfamiliar code, resist the longer prompt. Ask what relation it was missing, and whether that relation lives anywhere it can query. If it doesn’t, no sentence you add will put it there. A map will.
What’s the longest prompt you’ve written trying to explain a codebase to an agent? Tell me on the forum.
Frequently asked questions
Why does my agent keep getting things wrong in an unfamiliar codebase?
Usually because it lacks a map of the code’s structure, not because your prompt is too short. It greps, reads a few files, and infers the relations that matter, and it misses the non-obvious ones, like a caller in another package. The failure is structural, and no amount of better wording closes a structural gap.
What is a codebase map?
Not good documentation. It’s the structure read off the code: the call graph (what calls what), the dependency graph, type and data flow, module boundaries, entry points, and reachability. Because it’s a projection of the source, it regenerates when the code changes instead of going stale like a hand-written architecture doc.
Why doesn’t a longer prompt fix a coding agent’s mistakes?
Prose doesn’t compose. Every sentence is more to read, more to potentially contradict, and structure the model has to re-derive on every run, and you inevitably skip the edges that feel obvious. A map hands the structure over as queryable facts, so a thousand edges cost almost nothing until the agent queries the ten it needs.
Will a bigger model handle an unfamiliar codebase?
It handles more of it and still starts every session from zero, rebuilding the relations from pasted text each run. The relations that break you are the non-obvious ones a from-scratch read is most likely to miss. Hand the model the map and it spends its capability on the task instead of re-deriving the terrain.