Your AI Coding Assistant Can't See Architecture


Ask your AI coding assistant to review a pull request and it will read every file, check for bugs, suggest improvements, and confidently say “looks good to me.” Ask it about the architecture and it will do the same thing — read the files it can see and guess.

The problem is that architecture isn’t in any file. It’s in the relationships between files — how modules depend on each other, where a change propagates, which structural contracts are missing. An LLM can read 50 files and still not know that a seemingly simple refactoring touches 70% of the system, or that a module it’s about to modify sits inside a dependency cycle involving 47 other modules.

This isn’t a limitation that will be solved by a larger context window. Architecture is a graph property. You can’t infer propagation cost by reading source code sequentially any more than you can infer traffic patterns by reading a list of street names.

What LLMs see vs. what architecture is

An LLM reading your codebase sees:

  • Files — individual source files with their imports, exports, functions, classes
  • Local patterns — code style, naming conventions, framework usage within a file
  • Direct dependencies — the imports at the top of the file it’s currently reading

What it doesn’t see:

  • Transitive dependencies — module A imports B, which imports C through F, which import twelve more. The LLM sees one hop. The graph has hundreds.
  • Propagation cost — if you change this module, what percentage of the system is affected? This requires computing reachability across the full dependency graph.
  • Cycles — a dependency cycle means modules can’t be reasoned about independently. Detecting cycles requires the complete graph, not a file-by-file scan.
  • Structural hotspots — which modules are simultaneously the most coupled, most central, and most changed? This requires combining static analysis with graph centrality measures.
  • Missing contracts — guardrails, sandboxes, validation boundaries, approval gates. An LLM can check if a function exists, but it can’t systematically verify that every tool invocation in an agent has a corresponding safety boundary.

When an LLM says “the architecture looks solid,” it’s offering an opinion based on local patterns. It has no mechanism to compute the global properties that actually determine architectural health.

The confidence gap

The gap between what an LLM confidently states and what is structurally true can be large — and it’s invisible in the output. LLM responses about architecture don’t come with uncertainty markers. “The refactoring looks safe” and “this change affects 71% of the system” sound equally authoritative. One is computed. The other is extrapolated from a limited local view.

This matters especially for decisions that are expensive to reverse: large refactorings, module extractions, architectural pivots, production deploys on Friday afternoon. These are exactly the moments when teams lean on their AI assistant for a second opinion — and exactly the moments when local pattern-matching is most likely to mislead.

The problem isn’t that LLMs are bad at architecture. It’s that architecture requires a kind of analysis — graph computation, reachability, structural enumeration — that is categorically different from reading and pattern-matching text. Asking an LLM to assess propagation cost from source files is like asking a doctor to assess blood pressure from a photograph. The information simply isn’t there in the representation.

Why this matters for AI agent codebases specifically

For traditional software, the consequences of invisible architecture are expensive but recoverable — a painful refactoring, a slow incident, a quarter of tech debt cleanup.

For AI agent codebases, the consequences can be immediate and severe. An agent loop without a termination guard doesn’t slowly accumulate debt — it runs until it exhausts its token budget or gets killed. A missing guardrail on a tool with shell access isn’t a code smell — it’s an open attack surface. A handoff cycle in a multi-agent graph doesn’t degrade performance gradually — it causes runaway delegation.

These are structural properties. An LLM building or reviewing an agent can check that a function exists, that a parameter is passed, that a library is imported. It can’t verify that every loop in the agent graph has an exit condition, that every tool invocation is inside a trust boundary, or that the delegation graph is acyclic. Those checks require building and analyzing the graph — not reading files.

What architectural ground truth looks like

The questions that LLMs currently can’t answer reliably, but that have precise deterministic answers:

  • What is the propagation cost of this module? (Fraction of the system reachable from it)
  • Does this change introduce a dependency cycle?
  • What is the blast radius of modifying these three files?
  • Which modules have the highest coupling and the most churn — where is refactoring most valuable?
  • Does this agent graph have cycles? Are all loops bounded?
  • Which tool invocations lack safety annotations?

None of these require judgment. They require computation. They’re properties of the graph, computable from the code, deterministic across runs.

An LLM that has access to computed architectural facts — rather than having to infer them from sequential file reads — can give answers that are grounded in the actual structure of the system. The quality of the output changes not because the model is smarter, but because the input is richer.

The right division of labor

LLMs are excellent at what they’re built for: reading code, understanding intent, generating idiomatic implementations, explaining concepts, suggesting refactors at the function level. These are fundamentally text tasks, and language models are the right tool.

Architecture analysis is not a text task. It’s a graph task. Coupling, reachability, centrality, cycle detection — these require algorithms that operate on the dependency graph as a whole, not pattern-matching on file contents.

The productive framing isn’t “can AI understand architecture?” It’s “what does each tool do well, and what is each tool blind to?” LLMs are blind to architecture the same way a grep command is blind to runtime behavior — not because of a limitation to be fixed, but because of a fundamental mismatch between the tool and the task.

When teams understand that gap, they stop asking their AI assistant to do something it structurally cannot do, and start giving it the architectural context it needs to do what it does well.