Applied Intelligence
Module 9: Working with Legacy Code

Building Mental Models Through Dialogue

From answers to understanding

Individual questions produce individual answers. Mental models require synthesis. Understanding an unfamiliar codebase means building a coherent picture of how components connect, why decisions were made, and where the real complexity lives.

Single-turn queries tell you facts. Multi-turn dialogue builds comprehension.

The difference mirrors human learning. A new team member's first day produces scattered information this file does X, that service talks to Y, don't touch Z because nobody knows why it works. Weeks of conversations, questions, and context-building produce actual understanding. AI agents compress this timeline, but only if the conversation builds systematically rather than jumping between disconnected topics.

The hierarchical understanding flow

Developer code comprehension research identifies three levels of understanding, and they matter here because jumping levels produces confusion:

Global level. High-level architecture, module boundaries, business domain mapping. What are the major components? How do they interact? What external systems does this codebase integrate with?

Local level. Specific modules and their internal structure. How does authentication actually work? What patterns does the data access layer follow? Where does the business logic for orders live?

Detailed level. Individual functions, data flows, edge case handling. What happens when this function receives null? How does error propagation work through this call chain?

Move through these levels deliberately. Start global, identify areas that matter, drill into specifics. Jumping directly to detailed questions about random functions produces answers without context technically correct but useless for understanding.

Ask architecture questions before implementation questions. Understanding that "authentication uses OAuth 2.0 with token refresh handled by middleware" makes subsequent questions about specific auth functions far more productive.

Iterative refinement in practice

The Explore-Plan-Code framework from Page 1 applies to understanding, not just implementation. Each exchange refines the mental model.

First pass: orientation.

What are the main directories in this project and what does each contain?

The response reveals project structure: src/api/ for endpoints, src/services/ for business logic, src/models/ for data structures, src/utils/ for shared utilities. A map emerges.

Second pass: component relationships.

How do the services in src/services/ interact with the API endpoints
in src/api/? Is there a consistent pattern?

The agent explains the pattern: endpoints validate input, call services, services contain business logic, services call repositories for data access. Architecture takes shape.

Third pass: specific mechanisms.

Show me an example of this pattern. Walk through what happens when a
user submits an order, from the API endpoint through to database writes.

Concrete code traces replace abstract descriptions. Understanding gains substance.

Fourth pass: exceptions and edge cases.

Does any part of the codebase deviate from this pattern? Are there
places where endpoints contain business logic directly?

Deviations reveal technical debt, historical accidents, or deliberate exceptions. The model accommodates reality rather than idealized architecture.

Pattern recognition vs. pattern invention

Here's something that trips people up: agents recognize patterns well. They do not invent patterns.

When codebases follow common conventions MVC, repository patterns, dependency injection agents map them quickly. When codebases invent their own patterns, agents need explicit guidance.

If your codebase mixes patterns some services follow one style, others follow another the agent will reproduce whatever it sees first. This is not architectural judgment. This is pattern matching. The agent has no preference between good patterns and bad ones.

Multi-turn dialogue exposes this limitation. Ask the agent to identify all architectural patterns in use. Ask which components follow which patterns. Ask whether the patterns are consistent or contradictory.

The answers reveal whether you're looking at deliberate architecture or accumulated accident. Agents cannot make this judgment for you, but they can surface the evidence you need to make it yourself.

If agents copy inconsistent patterns from your codebase, expect inconsistent output. Mixed conventions in the repository produce mixed conventions in generated code. Understanding the existing patterns helps you guide agents toward the ones you want.

The feedback loop in dialogue

Module 2 established the feedback loop as core to ASD: request, response, evaluation, feedback, refined response. Boris Cherny's observation holds here: "Give Claude a way to verify its work. If Claude has that feedback loop, it will 2-3x the quality of the final result."

For codebase understanding, verification takes specific forms.

Confirm against code. When the agent explains a flow, trace it yourself. If the explanation doesn't match the code, say so. "Your explanation says the middleware calls validateToken(), but I see it calling checkAuth() instead. Look again."

Test assertions. When the agent claims something about the codebase, test it. "You said there are no direct database calls outside the repository layer. Search for db.query across the entire codebase and show me what you find."

Request evidence. Push beyond narrative explanations. "Show me the specific lines where this configuration loading happens." Agents that understood correctly can provide evidence. Agents that guessed produce vague responses or admit uncertainty.

Expose contradictions. If an earlier response contradicts a later one, flag it. "Earlier you said authentication happens in middleware. Now you're saying it happens in the controller. Which is correct?"

Managing context across turns

Multi-turn conversations face the 39% problem from Module 4: model performance degrades as conversations extend. Context accumulates, signal-to-noise ratio drops, earlier information fades.

For long codebase exploration sessions, several strategies help.

Summarize periodically. After building understanding of a major component, ask the agent to summarize. "Summarize what we've learned about the authentication system in three bullet points." Summaries compress context and reinforce key information.

Reference explicitly. Don't assume the agent remembers earlier findings. "Using your earlier analysis of the service layer patterns, how does OrderService fit?" Explicit references pull forward relevant context.

Reset strategically. When exploring a new part of the codebase, consider starting fresh. A clean context sometimes outperforms accumulated history, especially if the new area has no connection to previous exploration.

Partition by component. Use separate conversations for separate architectural areas. One conversation for authentication, another for data access, another for the API layer. This prevents unrelated context from interfering.

From individual understanding to documented knowledge

The mental model exists in your head, not the agent's. When the conversation ends, the agent retains nothing. The next session starts from zero.

Dialogue that builds understanding should produce artifacts.

Notes as you go. Capture key findings in a document. "The codebase uses three authentication strategies: session-based for web, JWT for mobile, and API keys for integrations. The strategy is selected in AuthFactory.create() based on request headers."

Architecture summaries. After exploring major components, document the architecture. "Services follow a standard interface: constructor injection, async methods returning Result types, logging via the injected logger."

Pattern catalogs. Record the patterns you discover. "API endpoints follow the pattern: validate input, call service, transform response, send. Exceptions: health checks and metrics endpoints skip validation."

These artifacts become context for future sessions. What you learned through dialogue becomes persistent project knowledge.

When dialogue reaches its limits

Multi-turn conversation works well for building understanding. It has limits.

Large codebases exceed any context window. No amount of dialogue helps an agent understand a million-line codebase in a single session. Break exploration into focused investigations of specific subsystems.

Historical context lives outside code. Agents can see the current code. They cannot see the discussions that led to decisions, the bugs that motivated refactors, or the constraints that shaped architecture. Git history helps somewhat. Human knowledge often remains necessary.

Judgment about quality requires human input. "Is this architecture good?" is not a question agents can answer. "Does this architecture follow established patterns?" is. Agents describe; humans judge.

Trust degrades with conversation length. The longer a conversation runs, the more likely accumulated errors compound. If an early misunderstanding propagates through subsequent responses, later conclusions rest on faulty foundations. Verification becomes more important as conversations extend.

Building mental models efficiently

The pattern for effective codebase understanding through dialogue:

  1. Start with global architecture questions
  2. Identify components that matter for your task
  3. Drill into those components specifically
  4. Verify explanations against actual code
  5. Summarize findings to compress context
  6. Document knowledge for future sessions

The goal is not to make the agent understand the codebase. Agents have no persistent understanding. The goal is to use dialogue as a tool for building your own understanding, faster than reading code alone.

The next page examines systematic approaches to mapping architectures and dependencies moving from conversational exploration to structured analysis of how components connect across an entire system.

On this page