Module 4: The agentic workflow: Explore → Plan → Code
Explore, Plan, and Code: Claude Code's three modes
Explore, Plan, and Code: Claude Code's three modes
Overview
Claude Code has three operating modes: Explore (read-only analysis), Plan (design without execution), and Agent/Code (full execution). Each mode exists for a specific reason, and knowing when to use which one transforms your productivity.
This capsule covers the three modes in depth: how to activate them, what each one does internally, when to pick one over another, and how to combine them in the Explore → Plan → Code cycle. It also covers Opus's effort level, which controls how much reasoning capacity Claude spends on each answer.
The difference between a casual Claude Code user and a professional comes down to this: the professional picks the right mode for each situation. The casual user always sits in Agent mode and hopes Claude guesses what they need.
Explore Mode
Explore is the read-only analysis mode. Claude reads files, analyzes dependencies, looks for patterns, and builds a mental map of your codebase — but it doesn't run commands and doesn't write code.
When to use Explore
- Opening a project for the first time
- Before implementing a complex feature
- To understand code you didn't write
- To find bugs with no risk of breaking anything
- To analyze dependencies and architecture
How to activate Explore
There is no /explore command. You activate Explore through how you phrase your prompt. Claude picks up that you want analysis when you use verbs like "analyze", "explain", "find", "understand":
> Analyze the structure of this project. What framework is used?
How are the files organized? Where does the main logic
live?
Claude Code also has a built-in Explore subagent that automatically operates in read-only mode when Claude needs to investigate your codebase during a task. That subagent reads files and gathers information without modifying anything.
Basic example
> I'm starting to work on this project. Explain the overall
structure: what technologies it uses, how the files are
organized, and what the main entry points are.
Claude will:
- Read
package.json,requirements.txt, or the equivalent - Scan the directory structure
- Identify the framework and the main dependencies
- Find the entry points (
main.py,index.ts,app.py) - Give you a structured summary
Typical output:
The project uses FastAPI (Python 3.11) with this structure:
src/
├── main.py → Entry point, configures the FastAPI app
├── routers/ → 4 routers: users, products, orders, auth
├── models/ → SQLAlchemy models (5 tables)
├── schemas/ → Pydantic schemas for validation
├── services/ → Business logic, separated from routers
└── tests/ → Pytest, 23 tests (18 passing, 5 skipped)
Main dependencies: FastAPI 0.109, SQLAlchemy 2.0, Pydantic v2
Database: PostgreSQL (via asyncpg)
Auth: JWT with python-jose
Intermediate example
> Analyze the current authentication system. I want to understand:
1. How are the JWT tokens generated?
2. Where are they validated?
3. Are there refresh tokens?
4. What middleware protects the routes?
Don't make changes, just analyze.
Claude will read the relevant files and give you a full analysis of the auth flow, including any potential problems it spots.
Advanced example
> Analyze this project's dependencies. Identify:
- Outdated dependencies (more than 6 months old)
- Dependencies with known vulnerabilities
- Dependencies that get imported but never used
- Duplicate or redundant dependencies
Report only, change nothing.
What Explore does NOT do
- ❌ It doesn't run terminal commands
- ❌ It doesn't modify files
- ❌ It doesn't create new files
- ❌ It doesn't install dependencies
- ❌ It doesn't commit
That restriction is intentional. Explore is safe by design — you can use it on any codebase without risk.
Plan Mode
Plan is the design-without-execution mode. Claude analyzes your request, weighs the options, and produces an implementation plan you can review and approve before a single line of code runs.
When to use Plan
- Before implementing complex features
- Refactors that touch multiple files
- Database migrations
- Architecture changes
- When you want to weigh options before committing
How to activate Plan
Use the /plan command:
/plan I need to add a caching layer to the API. Redis or
in-memory. Give me a full plan.
You can also activate it with explicit language:
> Design a plan to migrate the database from SQLite to PostgreSQL.
Don't implement anything yet. I want to see the plan first.
Basic example
/plan Add pagination to every endpoint that returns a list.
Typical Plan output:
## Plan: Add pagination
### Files to modify:
1. src/schemas/pagination.py (CREATE) — Reusable pagination schema
2. src/routers/users.py (MODIFY) — Add offset/limit query params
3. src/routers/products.py (MODIFY) — Same
4. src/routers/orders.py (MODIFY) — Same
5. src/services/base.py (MODIFY) — Generic pagination method
6. tests/test_pagination.py (CREATE) — Tests for pagination
### Design:
- Generic `PaginatedResponse[T]` schema with items, total, offset, limit
- Query params: offset (default 0), limit (default 20, max 100)
- The service layer handles the SQL query with OFFSET/LIMIT
- Response includes metadata: total_count, has_more, next_offset
### Implementation order:
1. Pagination schema
2. Generic method in the service layer
3. Update the routers one by one
4. Tests
### Risks:
- Existing endpoints will change their response format (breaking change)
- You need a migration strategy for current clients
Shall I proceed with the implementation?
Intermediate example
/plan I want to refactor error handling. Right now every
router has its own try/catch. I want to centralize it. Give me the
options and your recommendation.
Claude will give you several options with pros and cons:
## Options for centralizing errors
### Option A: FastAPI exception handlers
- Register handlers for each exception type
- Pros: Native to FastAPI, well documented
- Cons: Less granular control per endpoint
### Option B: Custom middleware
- Middleware that catches every exception
- Pros: Total control, one single place
- Cons: Can hide errors during development
### Option C: Custom decorator (RECOMMENDED)
- An @handle_errors decorator wrapping each endpoint
- Pros: Explicit, easy to test, opt-in per endpoint
- Cons: Requires adding the decorator to every endpoint
### Recommendation: Option C
[Technical justification...]
Which one should I go with?
Advanced example
/plan I need to redesign the permissions system. Right now it's
role-based (admin/user). I need to migrate to granular RBAC with
per-resource permissions. The system has 4 models, 12 endpoints,
and 3 current roles. Full plan with a migration strategy.
What Plan does NOT do
- ❌ It doesn't run the plan automatically
- ❌ It doesn't modify files
- ❌ It doesn't run commands
- ❌ It doesn't make irreversible changes
Plan produces a document you review. Only when you say "go ahead" or "implement" does Claude switch to Agent mode.
Agent/Code Mode (default)
Agent is the full-execution mode. It's Claude Code's default — when you hand it a task without specifying a mode, it operates in Agent.
What Agent mode can do
- ✅ Read project files
- ✅ Write and modify files
- ✅ Create new files
- ✅ Run terminal commands (npm, pip, git, etc.)
- ✅ Run tests
- ✅ Install dependencies
- ✅ Make commits
The permission system
Claude Code asks for confirmation before potentially destructive actions:
Claude wants to run: rm -rf node_modules && npm install
Allow? [y/n/always]
You can configure permissions in your CLAUDE.md or in settings to pre-approve certain actions (for instance, always allow npm test).
Basic example
> Create a GET /api/health endpoint that returns
{ "status": "ok", "timestamp": "..." }
Claude will:
- Identify the framework (FastAPI/Express/etc.)
- Find where the routers live
- Create the endpoint in the right format
- Run tests if there are any
Intermediate example
> The test test_create_user is failing with "IntegrityError:
UNIQUE constraint failed: users.email". Fix it.
Claude will:
- Read the test
- Read the User model
- Spot that the test doesn't clean the database between runs
- Add a cleanup fixture or use a unique email per test
- Run the test to verify
Advanced example
> Implement the pagination plan we designed. Start with the
generic schema and then update the users router. Run
the tests after each change.
When to use Agent directly (without Explore/Plan)
You don't always need the full cycle. Going straight to Agent is right for:
- Simple bug fixes ("the button doesn't work, fix it")
- Mechanical tasks ("rename X to Y across every file")
- Boilerplate generation ("create a User model with these fields")
- Running commands ("run the tests and show me the results")
The Explore → Plan → Code cycle
The full flow
┌──────────┐ ┌──────────┐ ┌──────────┐
│ EXPLORE │────▶│ PLAN │────▶│ CODE │
│ (read) │ │ (design) │ │ (build) │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
│ │ │
└────────────────┴────────────────┘
ITERATE
The cycle isn't strictly linear. After Code, you can go back to Explore to verify. After Plan, you can go back to Explore to dig deeper. It's iterative.
Complete example: a new feature
Say you need to add email notifications to your API.
Step 1 — Explore:
> Analyze how emails are currently handled in this project.
Is there an integration with an email service? Is there a
message queue? Are there email templates?
Step 2 — Plan:
/plan Based on what you found, design an email notification
system. I need: a welcome email on signup, a password
reset email, and a purchase confirmation email. Give me the
plan with service options (SendGrid, SES,
Resend).
Step 3 — Code (incremental):
> Implement step 1 of the plan: the Resend integration
and the base email-sending service.
> Now implement the welcome template and the signup
trigger.
> Add tests for the email service.
Step 4 — Verify (back to Explore):
> Review everything we implemented. Are there edge cases we
didn't cover? Do the tests cover the main scenarios?
Is there any security problem?
Comparisons and decisions
Without a workflow vs with one
| Aspect | Without a workflow | With a workflow (E→P→C) |
|---|---|---|
| First prompt | "Add auth to my app" | "Analyze how routes are currently handled" |
| Result | A generic implementation that may not fit | An implementation that respects the existing architecture |
| Errors | You find problems after implementing | You find problems before writing code |
| Refactoring | Frequent — the first attempt is rarely right | Minimal — the plan already weighed the options |
| Total time | More (because you redo work) | Less (it's done right the first time) |
| Context window | Fills up with failed attempts | Gets used efficiently |
Which variation of the cycle to use
| Situation | Workflow |
|---|---|
| Complex new feature | Explore → Plan → Code (full cycle) |
| Simple bug fix | Code directly |
| Complex bug fix | Explore → Code |
| Refactoring | Explore → Plan → Code |
| New code in a familiar project | Plan → Code |
| Understanding somebody else's codebase | Explore (only) |
| Quick prototype | Code directly |
| Migration | Explore → Plan → Code → Explore (verify) |
Effort Level
The effort level controls how much reasoning capacity the model spends on each answer. It shifts the balance between speed and depth.
Important: The available levels depend on the model. You set it with
/effort, inside/modelwith the ← → arrows, in settings (effortLevel), or via an env var (CLAUDE_CODE_EFFORT_LEVEL).
Available levels per model
| Model | Levels | Default |
|---|---|---|
| Opus 5, Sonnet 5, Fable 5 | low, medium, high, xhigh, max | high (xhigh recommended for coding) |
| Haiku 4.5 | Not configurable | — |
Haiku 4.5 doesn't expose a configurable effort: if you set a level while on it, Claude Code simply ignores it.
Effort low → Light reasoning, fast answers
Effort medium → Speed/depth balance (cost-sensitive)
Effort high → Deep reasoning
Effort xhigh → Very deep (Opus 5 default)
Effort max → Maximum depth, no thinking-token cap (applies to the current session only)
When to use each level
| Level | Use case | Example |
|---|---|---|
low | Direct questions, mechanical edits | "Rename getData to fetchData in this file" |
medium | Cost-sensitive work that can trade off some intelligence | "Create a CRUD endpoint for products" |
high | The minimum for intelligence-sensitive work | "Refactor the auth middleware" |
xhigh | Recommended for coding/agentic (Opus 5 default) | "Design the permissions system for the API" |
max | Exhaustive reasoning — use with care (it can overthink) | "Analyze every race condition in this system" |
How it affects each mode
- In Explore: More effort = deeper analysis, catches more patterns
- In Plan: More effort = more options considered, better trade-offs
- In Code: More effort = more robust code, better edge-case handling
A practical example
/plan Redesign the caching system. Right now it uses an in-memory
dictionary that doesn't survive restarts. I need to consider:
Redis, Memcached, and a file-based cache. Give me pros/cons for each
one for our case (API with 10K req/min, 3 instances).
With Opus at effort high (the default), Claude weighs several dimensions before answering.
At effort high (default), Claude will:
- Analyze the current access patterns
- Consider each option in detail
- Evaluate the pros/cons specific to your case
- Consider edge cases (cache stampede, invalidation, replication)
- Give a recommendation with technical justification
At effort low, it would just give you a basic comparison table.
Fast Mode
On top of the effort level, Opus 5 supports fast mode — an optimization that generates output faster without switching models.
> /fast ← Toggle on/off
Important: Fast mode uses the same Opus 5. It does NOT switch to Sonnet or any other model. It's Opus with output-speed optimization.
Fast mode is especially useful during the Code phase of the Explore - Plan - Code cycle, where you generate code iteratively and want faster feedback loops. For the Plan phase with deep analysis, consider turning fast mode off so Opus reasons at full depth.
| Cycle phase | Fast mode recommended |
|---|---|
| Explore | OFF (deep analysis) |
| Plan | OFF (exhaustive reasoning) |
| Code (fast iteration) | ON (implementation speed) |
| Code (complex task) | OFF (maximum quality) |
Common patterns
Pattern 1: "Explore first, always"
Before any significant task, run Explore. Even if you think you know the codebase. Claude can spot things you don't see:
> Before we start, analyze the current state of the payments module.
Is there technical debt? Missing tests? Dead code?
Pattern 2: "Plan with options"
Don't ask for one plan. Ask for options:
/plan Give me 2-3 options for implementing the notification
system. Include pros, cons, and your recommendation.
Pattern 3: "Incremental code"
Don't ask for everything at once. Implement in steps:
> Implement only the model and the migrations. Nothing else for now.
> Now add the service with the business logic.
> Now the endpoints. Run tests afterward.
Pattern 4: "Verify loop"
After implementing, go back to Explore to verify:
> Review what we just implemented. Does it follow the pattern
used in the rest of the project? Are there inconsistencies?
Pattern 5: "Tiered effort"
Start at low effort for simple tasks, raise it for complex ones:
# Simple task → Sonnet
/model sonnet
> Rename the file config.py to settings.py and update the imports.
# Complex task → Opus
/model opus
> Now refactor the configuration system to use Pydantic
Settings with environment variable validation.
Pitfalls and edge cases
Pitfall 1: Using Agent mode for everything
The mistake: Giving implementation instructions without exploring first.
❌ "Add WebSockets to the app"
The problem: Claude doesn't know what infrastructure exists, what patterns are used, or what constraints there are. It'll implement something generic that probably won't fit.
The fix: Explore first.
✅ "Analyze the current API architecture. Is there any
real-time system? Are there WebSockets, SSE, or long-polling?"
Pitfall 2: Plans that are too ambitious
The mistake: Asking for a plan that covers far too much scope.
❌ /plan Redesign the whole API to use microservices.
The problem: The plan will be shallow because the scope is enormous.
The fix: Scoped plans.
✅ /plan Design how to extract the payments module as an
independent service. Just that module, not the whole API.
Pitfall 3: Not verifying after Code
The mistake: Assuming what Claude implemented is correct without reviewing it.
The fix: Always verify:
> Run all the tests.
> Check whether what you implemented follows the conventions in CLAUDE.md.
> Is there any edge case we didn't cover?
Pitfall 4: Ignoring the Plan output
The mistake: Saying "yes, implement it" without reading the plan.
The fix: Read the whole plan. Question decisions. Ask for alternatives. The plan is your chance to shape the solution before any code gets written.
Pitfall 5: Opus for everything
The mistake: Using Opus for trivial tasks.
The problem: Slower and more expensive answers with no benefit on simple tasks. It also burns more quota.
The fix: Use Sonnet for routine tasks and Opus for tasks that need deep reasoning. If you do use Opus, drop effort to low for the easier tasks.
Complete worked example
A real scenario: you add structured logging to an existing FastAPI project.
Phase 1: Explore
> Analyze how logging is currently handled in this project.
Is any logger in use? Are there logs in the routers? In the
services? Are errors logged? Give me a full report.
You discover the project uses print() statements scattered around, with no structured logging.
Phase 2: Plan
/plan I need to replace every print() with structured
logging. Requirements:
- JSON format for production
- Human-readable for development
- Request ID for traceability
- Log levels: DEBUG, INFO, WARNING, ERROR
- Integration with FastAPI middleware
Give me the plan with the files to create/modify.
Claude produces a detailed plan. You review it and ask for a tweak:
> In the plan, you add structlog. What if we use loguru
instead? It's simpler. Update the plan.
Phase 3: Code (incremental)
> Implement step 1: install loguru and create the logging
configuration module in src/core/logging.py
> Implement step 2: create the request ID middleware
and the request/response logging.
> Implement step 3: replace every print() in
src/routers/ with logger calls.
> Run the tests. If something fails, fix it.
Phase 4: Verify
> Review the full logging implementation. Is there any
print() left unreplaced? Do the tests cover the middleware?
Does the JSON format work correctly?
Practice exercises
Exercise 1: Basic — Explore your project
Open Claude Code in your project and run a full exploration:
> Analyze this project. Give me a report that includes:
1. Tech stack
2. File structure
3. Main dependencies
4. Entry points
5. Test status (if there are any)
Goal: Get familiar with the output of Explore mode.
What to expect
Claude should produce a structured report with all the information you asked for. If your project is small, the report will be short. If it's large, Claude will prioritize the most important files.
Check that the information is correct. If Claude gets something wrong, correct it — that improves its later answers in the same session.
Exercise 2: Basic — Plan an improvement
Find something you could improve in your project and use Plan mode:
/plan [describe the improvement you want to make]
Goal: Receive a structured plan and evaluate it critically.
What to expect
The plan should include:
- Files to create/modify
- Implementation order
- Identified risks
If the plan is too vague, ask for more detail:
> Step 3 of the plan is very generic. Give me more detail
on exactly what changes you'd make in that file.
If the plan has an error, point it out:
> In step 2 you mention modifying auth.py, but that file
doesn't exist. It's called authentication.py. Update the plan.
Exercise 3: Intermediate — The full E→P→C cycle
Run the full cycle on a real task:
- Explore: Analyze a specific module of your project
- Plan: Design an improvement for that module
- Code: Implement the first step of the plan
- Verify: Ask Claude to review what got implemented
Goal: Experience the full cycle from start to finish.
Tips for this exercise
Pick a scoped task:
- ✅ "Add input validation to an endpoint" (scoped)
- ✅ "Add a missing test" (scoped)
- ❌ "Redesign the architecture" (way too big)
During Code, implement only the first step of the plan. Don't try to do it all at once. The goal is to practice the cycle, not to finish a whole feature.
Exercise 4: Intermediate — Compare with and without the workflow
Do the same task two ways:
Without the workflow:
> [Describe the task directly and let Claude implement it]
With the workflow:
> [Explore → Plan → Code for the same task]
Compare the results. Which produced better code? Which consumed less context?
What you should notice
In most cases, the workflow approach produces:
- Code that respects the existing conventions better
- Fewer errors on the first implementation
- Better edge-case coverage (the Plan identifies them)
- Less back-and-forth to fix problems
The no-workflow approach can be faster for trivial tasks, but it produces worse results on complex ones.
Exercise 5: Advanced — Tiered model and effort
Practice switching model and effort within a session:
# Simple task → Sonnet
/model sonnet
> What version of Python does this project use?
# Standard implementation → Sonnet
> Create a test for the login endpoint.
# Refactoring → Opus (effort high by default)
/model opus
> Refactor the users service to separate the validation
logic from the persistence logic.
# Architecture → Opus + Plan
/plan Design a rate limiting system for the API.
Consider: per IP, per user, per endpoint. I want a
full plan with options.
Goal: Feel the difference between models and learn to pick the right combination.
What you should notice
- Sonnet for simple questions: Immediate, direct answer
- Sonnet for implementation: Correct and fast
- Opus (effort high): Robust implementation, considers more edge cases, better structure
- Opus + Plan: Exhaustive analysis, multiple options, detailed trade-offs
The difference between models is most visible on design and architecture tasks (where Opus shines) rather than mechanical ones (where Sonnet is plenty).
Exercise 6: Challenge — Multi-mode in a real session
Simulate a real 30-minute working session using all three modes:
- Start with Explore to understand your project's current state
- Identify 2-3 possible improvements
- Use Plan to design the most important one
- Implement with Code (incrementally, step by step)
- Verify with Explore
- Commit the result
Goal: Fold everything into a natural working flow.
Execution guide
Minutes 0-5: Explore
> Give me an analysis of the project's current state. What areas
need improvement? Is there technical debt? Missing tests?
Minutes 5-10: Plan
/plan [Pick the highest-impact improvement Claude identified
and ask for a plan]
Minutes 10-25: Code (incremental)
Implement the plan step by step. After each step, verify that the tests pass.
Minutes 25-30: Verify + Commit
> Review everything we implemented. Is it all correct?
> Commit with a descriptive message.
Summary
What you learned in this capsule:
- Explore mode is read-only analysis. Use it to understand before you act. It activates through analysis prompts or via the built-in Explore subagent.
- Plan mode is design without execution. It activates with
/planor by explicitly asking for a plan. It produces a plan you review before anything runs. - Agent/Code mode is full execution (the default). It reads, writes, runs commands. It asks for confirmation on destructive actions.
- The Explore → Plan → Code cycle is iterative, not linear. Adapt the variation to the task.
- Effort level (Opus 5, Sonnet 5, and Fable 5) controls reasoning depth. The current models have 5 levels (
low,medium,high,xhigh,max) withhighas the default;xhighis the one recommended for coding. You set it with/effort, inside/modelwith the arrows, or in settings. - Without a workflow, you get generic results. With a workflow, you get results that respect your existing architecture.
Next capsule: 03 - Multi-turn conversations — how to iterate effectively with Claude Code across multi-message conversations.
Additional resources
Official documentation
- Claude Code Best Practices — Workflows and context management recommended by Anthropic
- Sub-agents — The Explore subagent and the other built-in subagents
- Interactive Mode — Shortcuts, permissions, and task management
- CLI Reference — Full reference for commands and flags
- Model Configuration — Models, aliases, and effort levels
Context and configuration
Complementary
- Claude Code Overview — General architecture and capabilities
- Hooks — Automating actions in each mode (next module)