How LLMs Actually Understand Your Code (They Do Not, Not Really)
I want to start with the claim in the title, because I think it actually matters for how you use these tools day to day: an LLM does not understand your code the way a colleague reading it would. It does something else, a statistical pattern-completion process over tokenized text, that happens to produce outputs good enough to feel like understanding most of the time. Knowing the actual mechanics underneath does not make the tools less useful, but it does explain a lot of their specific, otherwise-baffling failure modes, and once you see the mechanics clearly, you start prompting differently, more effectively, almost without trying.
Tokenization: your code is not read as code
Before a model ever sees your source file, it gets broken into tokens, which are not characters and not exactly words either, but subword chunks determined by a tokenizer trained separately from the model itself. A variable name like getUserById might tokenize as a single unit if it appeared often enough in training data, or it might split into get, User, By, Id as four separate tokens if it is less common. This matters more than it sounds like it should, because it means the model's actual internal representation of your identifier names is sensitive to how those names decompose into these subword units, not to their semantic meaning as a human would parse them.
This is part of why unusual or highly domain-specific naming conventions sometimes trip up a model in ways that clean, conventional naming does not. A function named processTxn2ForLegacyFlow tokenizes into a messier, less common sequence than processTransactionForLegacyFlow, and messier tokenization generally correlates with the model having seen fewer similar patterns during training, which translates fairly directly into lower quality completions and suggestions for that specific piece of code.
Context windows are not memory, they are a sliding view
When people say a model has a large context window, it is easy to misread that as the model remembers your whole codebase, which is not what is happening. A context window is closer to how much text the model can look at in a single forward pass, more like the visible area of a document in an editor than like a persistent memory of things it has seen before. Every single request to the model reprocesses the entire visible context from scratch, there is no accumulating internal state carried between calls the way a human's understanding of a codebase builds up over weeks of working in it.
This explains a specific, recurring frustration people report with agentic coding tools: a model correctly following a convention for the first ten files it touches in a session and then drifting from that convention on the eleventh, particularly if the session has run long enough that earlier context gets truncated, summarized, or pushed out of the active window to make room for newer content. It is not the model forgetting in the human sense, it is that the specific tokens establishing the convention are no longer inside the window being processed for that particular request. This is exactly why well-designed agentic tools re-fetch relevant file contents fresh for each step rather than relying purely on conversation history, and why giving explicit, restated constraints for a long task, rather than assuming earlier context still holds, produces more consistent results.
Attention: how the model decides what in the context actually matters
The mechanism that lets a transformer model weigh different parts of its input differently is called attention, and at a rough, intuitive level, for every token the model is generating, it computes a weighted relevance score against every other token currently in its context, then uses those weights to decide what to draw on. This is fundamentally different from a database lookup or a literal search. It is closer to the model asking, given everything currently in view, what is most relevant to predicting the next token here, computed fresh, statistically, every single step.
A practical consequence: information positioned in certain places within a long context, particularly the very middle of a very long prompt, has been shown across multiple published evaluations to sometimes get weighted less reliably than information near the beginning or end, an effect informally called lost in the middle. This is a real, measurable phenomenon in many models, though the degree varies significantly by model and has been actively improved across model generations. Practically, it means that for a genuinely critical constraint in a long agentic task, restating it near the point where it needs to be applied, rather than trusting it to be weighted correctly from deep in an already-long context, tends to produce more reliable results, and this is exactly the kind of small habit that separates people who get consistently good output from coding agents from people who get frustrated by inconsistent results on long sessions.
Why this explains specific, otherwise-confusing failures
A model confidently generating a function call to an API that does not exist, sometimes called hallucination, makes much more sense once you know the underlying process is next-token prediction based on learned statistical patterns rather than a lookup against a verified, ground-truth API surface. The model is not checking whether calculateTaxWithRegion is a real method on your tax service, it is predicting that this token sequence is plausible given everything it has seen, both in training and in your current context, about how similarly named services tend to expose their methods. When your actual codebase's API differs from the statistically common pattern, the model can confidently generate the common pattern instead of your actual one, especially if your specific API was not clearly present in the immediate context window.
This is exactly why grounding a coding agent in tools that let it read your actual files, run your actual type checker, and see real compiler or test errors closes this gap so effectively. The moment a hallucinated method call meets an actual TypeScript compiler, it produces a real error the model can read, and correcting behavior based on ground-truth feedback is a fundamentally more reliable path to a correct answer than trying to get the initial statistical prediction perfectly right on the first attempt.
What actually changes once you internalize this
I stopped thinking of prompting a coding model as talking to a colleague and started thinking of it as configuring a very sophisticated but fundamentally mechanical pattern completion process, and my results got noticeably better. I restate constraints rather than assuming they persist. I keep context windows focused rather than dumping in every file that might conceivably be relevant, since irrelevant content dilutes what the attention mechanism has to work with rather than helping it. And I lean much more heavily on tools that give the model real verification, tests, type checkers, linters, because that verification loop is doing something the raw prediction mechanism fundamentally cannot do on its own: telling the model, unambiguously, when it is wrong.
It is worth being clear that none of this is a criticism of the technology so much as a description of what it fundamentally is, and being accurate about what it is turns out to be the more useful stance than either the breathless framing that treats these systems as having genuine understanding, or the dismissive framing that treats their usefulness as an illusion. A next-token predictor trained on an enormous amount of code and paired with real tool access, real compilers, and real test suites, is a genuinely powerful combination, precisely because the statistical prediction handles the enormous space of plausible next steps efficiently, while the tool access handles the part that prediction alone cannot, verified ground truth. Understanding that division of labor, rather than treating the whole system as one undifferentiated black box that either understands your code or does not, is what actually lets you use these tools well, and it is the single mental model I would want any developer working with them daily to internalize first.
Related Posts
Sponsor Our Newsletter
Reach thousands of developers who are actively evaluating AI tools, MCP servers, and dev infrastructure. Our weekly newsletter goes to engaged technical decision-makers.
All sponsored content is clearly labeled per our editorial policy.