Martin Fowler's June fragments digest highlighted a framework from Chelsea Troy for working with large language models (LLMs) on code: four distinct conversational registers — exploring, brainstorming, deciding, and implementing. The insight is not that you need four different tools. It is that each mode asks the model to do a different kind of work, and collapsing them into a single thread produces the muddled outputs everyone complains about.
This article walks each register, what it is for, and why keeping them separate makes agent-assisted development more predictable.
Exploring — mapping the territory
The exploring register is read-heavy. You are asking the model to help you understand a codebase, a protocol, or a failure you do not yet have a theory for. Prompts sound like: "Walk me through how authentication flows from the middleware to the database layer" or "What are the three most likely reasons this endpoint returns 502 under load?"
The model's job is synthesis and navigation, not action. You are not asking it to write code yet. You are building a mental map — or letting it build one you can verify.
Think of exploring like walking a new city without a destination. You notice street names, landmarks, and which neighborhoods connect. You are not shopping yet; you are orienting.
Exploring conversations tend to be long and meandering. That is fine. They belong in a separate thread from implementation so the context window is not polluted with half-formed hypotheses when you later ask for a precise diff.
Brainstorming — generating options without committing
Brainstorming shifts from "what is here?" to "what could we do?" Prompts invite multiple approaches: "Give me three ways to cache this query result, with trade-offs" or "What are alternative architectures if we cannot add a Redis cluster?"
The critical discipline is deferring judgment. Brainstorming registers fail when the prompt smuggles in a decision — "Give me three ways to cache this, but we are definitely using Redis." That is deciding dressed as brainstorming.
Good brainstorming output is a short list of options with explicit trade-offs, not a recommendation. The recommendation belongs in the next register.
Deciding — narrowing to one path
The deciding register converts options into a plan. You present the brainstorm output (or your own shortlist) and ask the model to help you choose: "Given our team size and existing Postgres expertise, which of these three caching approaches fits best? State assumptions."
This is where constraints enter explicitly: budget, latency targets, team skills, migration risk. The model's value is making trade-offs visible, not making the decision for you.
A decision prompt should name what you are optimizing for. Without that, the model defaults to generic best practices that may not match your situation.
Deciding threads should be short. Once you have a chosen approach, close the thread. Carrying rejected alternatives forward into implementation wastes context and confuses the model about which path is active.
Implementing — executing one plan
The implementing register is where code gets written. The prompt references a decided plan: "Implement option B from our caching discussion. Use the existing Postgres connection pool. Add a TTL of five minutes. Write tests for cache miss and invalidation."
Implementation prompts should be narrow. They assume exploration, brainstorming, and deciding already happened — or that you, the engineer, did those steps and are now handing the model a spec.
Mixing implementation with exploration in one message — "Fix this bug, and also explain why Redis might be better long-term" — splits the model's attention and produces both shallow analysis and risky code changes.
| Register | Goal | Typical output | Keep separate because |
|---|---|---|---|
| Exploring | Understand | Summary, diagram, file map | Long context, no action items |
| Brainstorming | Generate options | Numbered alternatives | Judgment deferred |
| Deciding | Choose one path | Recommendation with assumptions | Short, closes alternatives |
| Implementing | Write code | Diffs, tests, config | Needs a frozen spec |
Why registers matter for context windows
Every token from an exploring tangent competes with tokens for the implementation spec. Models do not automatically forget earlier registers — they weight recent text, but ambiguous threads where you explored three architectures and then said "just fix the bug" leave the model uncertain about which architecture is in scope.
Separate threads per register is the practical fix. Some teams use separate chat sessions; others use explicit mode declarations at the top of a message: "Mode: implementing. Plan: [link or summary]. Do not reconsider architecture."
Either approach beats a single monolithic conversation that tries to do everything at once.
What this means for builders
Name the register before you prompt. A one-line prefix — "Exploring:" or "Implementing:" — reduces mode confusion more than a longer prompt without one.
Close brainstorm threads before implementing. Copy the decided plan into a fresh implementation thread. Treat the old thread as read-only reference.
Do not skip deciding. Jumping from brainstorm to implement is how teams end up with the first option the model suggested, not the one that fit their constraints.
Match register to tool settings. Implementation may warrant a coding agent with repo access. Exploring may work fine in a read-only chat with pasted file snippets. Using the same tool configuration for all four registers is convenient but not optimal.
Conclusion
LLM-assisted coding fails less from model capability and more from conversation hygiene. Troy's four registers — explore, brainstorm, decide, implement — give a vocabulary for the hygiene. Each mode asks a different question. Keeping them separated preserves context for the question that actually matters at each step, and produces outputs that match the kind of work you intended to do.
