The anatomy of an effective agent prompt
With autocomplete you describe the next line. With an agent you describe the destination — and the more precisely you describe it, the less Claude has to guess. Five components, used together, reliably lift the success rate of any non-trivial task.
Goal
What to accomplish — stated specifically, not vaguely.
Context
The relevant files, patterns, and existing utilities to build on.
Constraints
What NOT to do — equally important as the goal itself.
Verification
How Claude should check its own work before declaring done.
Output format
What the final state should look like — files, tests, docs.
Weak vs. strong: the same task, two outcomes
Both prompts below ask for pagination. Only one gives Claude what it needs to land the change in a 5M-user codebase without breaking consumers.
Weak prompt
No context, no constraints, no definition of done. Claude must guess the schema, the strategy, and what "done" means.
Add pagination to the user list
Strong prompt
Goal, context, constraints, verification, and output — all five components, all in one message.
Add cursor-based pagination to GET /api/users.
Context: existing endpoints in src/api/routes/users.ts,
our pagination utility in src/utils/pagination.ts.
Constraints: don't change the response schema for existing
consumers; use cursor-based not offset-based (we have 5M+ users).
Verification: run existing tests, add tests for edge cases
(empty results, invalid cursor, last page), manually test with curl.
Output: working endpoint + tests + updated API docs in docs/api.md
Verification-first patterns
Claude performs dramatically better when it has something concrete to verify against. Give it a target it can measure itself by, and the agentic loop self-corrects until the target is met. Three patterns cover most cases.
Test cases as spec
Give input → expected output pairs and tell Claude to run them after implementing.
Screenshot comparison
Attach a Figma export and ask Claude to compare its build against it and iterate until they match.
Definition of done
State the exact pass criteria: tests green, new coverage added, zero TS errors, zero ESLint warnings.
Implement sortByDate. Verify:
[tomorrow, today, yesterday] -> [yesterday, today, tomorrow]
[null, today, yesterday] -> [null, yesterday, today]
Run the cases after implementing.
You're done when: all existing tests pass, new tests cover the
added code, TypeScript has no errors, ESLint reports zero warnings.
Complex multi-constraint prompts
For risky, cross-cutting work — like an auth migration — spell out the constraints as a checklist and the approach as ordered steps. Note the explicit out-of-bounds line at the end: telling Claude what to leave alone is as valuable as telling it what to change.
Migrate the authentication system from JWT to session-based auth.
Constraints:
- Existing logged-in users must not be logged out (add a migration grace period)
- Mobile API endpoints must keep accepting JWT for 90 days (document which)
- All new auth must use httpOnly cookies
- Sessions stored in Redis (use the existing client in src/cache.ts)
- No bcrypt — use our argon2 wrapper in src/security/hash.ts
Approach:
1. Read src/auth/ completely to understand the current flow
2. Design the migration strategy and show it to me before implementing
3. Implement backend changes, keeping JWT support as fallback
4. Update the frontend auth flow
5. Write tests for both auth methods
6. Add deprecation logging for JWT usage
Do NOT touch the OAuth integration (src/auth/oauth/) — that's separate work.
Explore before you implement
When the blast radius is unknown, don't ask for code — ask for a map. Plan mode lets Claude investigate and propose without editing, so you choose the approach before a single line changes.
[Plan mode] Before writing any code:
1. Read src/checkout/ completely
2. Map all the state transitions in the checkout flow
3. Identify every place that touches payment processing
4. Tell me: what would break if we added a 3D Secure verification
step between payment intent and confirmation?
5. Propose 3 implementation approaches with tradeoffs
I'll choose an approach, then you implement.
Interview mode
Sometimes the cleanest way to give Claude context is to let it ask for it. Tell Claude to interview you first — it gathers the requirements it actually needs, then implements based on your answers instead of guessing.
I need to implement a distributed rate limiter. Before you start,
ask me the questions you need to make good design decisions.
Don't ask more than 5 questions.
Build a personal prompt library
Every prompt that produces consistently good results is reusable capital. Save it. Organize your library by task type, codebase area, and the skill level a task requires.
- Capture the exact wording that worked — including the context and constraints, not just the goal.
- Group prompts by area (auth, payments, migrations) so the right one is easy to find.
- Share with your team in a prompts repository, or promote the best ones into Claude Code skills so they're invokable by name.
These prompting patterns scale up when you delegate work to parallel sub-agents, and you can revisit any chapter from the full Claude Code tutorial series.
Notes
Constraints beat enthusiasm
"Be careful" and "best practices" are unmeasurable. Replace them with checklists: files not to touch, commands that must pass, and explicit stop conditions. Claude optimizes against what you can verify.
Over-long prompts dilute priority
Pasting entire files when paths suffice burns context and buries the goal. Point at files, summarize architecture in two sentences, and put the single most important constraint first.
Verification must be runnable
"Make sure it works" fails in CI. Give exact commands — npm test -- --grep auth, screenshot paths, or API response shapes — so the agentic loop can self-correct without guessing.
Promote winners to skills, not copy-paste
A prompt library in markdown helps humans; a Claude Code skill helps the agent invoke the same spec by name. Graduate stable prompts into .claude/skills/ once they've survived three real tasks.
Prompt Engineering FAQ
How do you write an effective prompt for Claude Code?
Treat the prompt as a spec, not a wish. Combine five components — goal, context, constraints, verification, and output format — in a single message so Claude has to guess as little as possible.
What are the five components of a strong agent prompt?
A strong prompt states the goal specifically, supplies context such as relevant files and existing utilities, lists constraints on what not to do, defines how Claude verifies its own work, and describes the output format. Used together they reliably lift the success rate of any non-trivial task.
What is verification-first prompting?
Verification-first prompting gives Claude a concrete target to measure itself against so the agentic loop self-corrects until the target is met. Common patterns are test cases as a spec, screenshot comparison against a Figma export, and an explicit definition of done.
What are common mistakes when prompting Claude Code?
The biggest mistake is a weak prompt with no context, no constraints, and no definition of done, which forces Claude to guess the schema, the strategy, and what done means. For risky work, also forgetting to state what to leave alone is as costly as omitting what to change.
How is prompting Claude Code different from prompting a chatbot?
With a chatbot you describe the next line, but with an agent you describe the destination — and the more precisely you describe it, the less Claude has to guess. You can also let Claude interview you for requirements or use plan mode to explore before any code changes.
Quick summary
- A strong prompt has five parts: goal, context, constraints, verification, output format
- Give Claude something to verify against — test cases, screenshots, or an explicit definition of done
- For risky work, list constraints as a checklist, the approach as ordered steps, and what to leave alone
- Use plan mode to explore first and interview mode to gather requirements; save what works as a prompt library or skill