Prompting Techniques
When you ask Claude Code for help, it reads three things: your prompt, your project context, and your memory settings. Better prompts let Claude infer your intent precisely without you over-specifying every detail. This matters because Claude's next action depends entirely on understanding what you actually need, not what you said you wanted.
Why Prompting Matters Here
In Claude Code, your prompt competes with context for the model's attention. A vague prompt makes Claude reason about five possible interpretations. A sharp prompt—one with clear boundaries and specific constraints—narrows the search space and lets Claude focus on depth instead of guessing. This is especially true for architecture work (where planning matters more than speed) and refinement loops (where each iteration builds on exact feedback).
The Core Technique: Clear and Specific
A strong prompt names three things: what you're asking for, what you already know about the situation, and how you'll recognize success.
Bad: "Improve the database code"
Good: "Optimize the user lookup query in getUserById to use indexed fields and reduce Postgres query time from 50ms to <5ms. Current implementation: sequential scan on users table. Constraint: keep the function signature unchanged so callers don't need updating."
The difference is not just length. The good version tells Claude exactly what problem to solve (performance, not maintainability), what the current state is (sequential scan), what the target is (sub-5ms), and what breaks the solution (signature change). Claude can now think only about query optimization, not about whether you also want cleaner code or better error handling.
Name files and functions whenever you refer to a bug or change. "Fix the race condition in session.js where concurrent writes to sessionStore corrupt data" is a better starting point than "fix the bug where things don't work." It tells Claude which code to examine and what kind of problem to look for (concurrency, not logic error).
State constraints upfront. Embed them in the request rather than as afterthoughts. "Refactor to async/await, keeping the same error responses and function signatures" is clearer than starting the refactor and then saying "wait, don't break the API."
Show examples when the format matters. If you want async/await instead of callbacks, paste a small example of the style. If the output should match a specific format, link to an instance. Showing beats describing.
Two Real Patterns
Planning-first for architecture work.
When you're facing a hard design decision—whether to add a new service, refactor a complex module, or change how something scales—ask Claude to plan first, then implement:
> Plan mode: How would you approach adding real-time notifications
> to the chat without using polling?
>
> Consider: database constraints (Postgres, 5M rows), client limits
> (browser memory), and fallback if WebSocket fails.Accept or refine the plan once you see it. Then ask for implementation. This works because Claude's reasoning step happens upfront, in writing, where you can steer it before code commits to a direction.
Refinement loops for iterative work.
When building something iteratively—a UI component, a workflow, an integration—each prompt builds on the last result:
> First: Write a basic user login form with email and password fields.
> Second: Add client-side validation so errors appear as the user types.
> Third: Add a "forgot password" flow that sends a reset link.
> Fourth: Style it to match the design in [link to screenshot or reference].Each turn refines the previous result. The advantage is that Claude sees your reaction to each version. If you say "make the error messages less verbose," that feedback is sharper than trying to describe the final form upfront.
What Breaks Prompts
Vagueness breaks them. "Make it faster" doesn't say what you're measuring (throughput? latency? cold start?), by how much, or for whom. Claude guesses and wastes tokens on the wrong guess.
Conflicting constraints break them. "Make this backward compatible AND remove the old API" means different things. Pick one or describe the migration path.
Context-switching breaks them. "Also, while you're at it, let's add caching" pulls Claude's focus away from the current task. One focused request works better than a grab-bag.
Assuming knowledge breaks them. "Obvious" context is often invisible to Claude. Stating it—even when you think it's trivial—typically fixes a confusing prompt.
Related
- Extended Thinking - Control reasoning depth for hard problems
- Output Styles - Customize response format and length
- Memory System - Set persistent context and preferences