Lesson 3 of 20

Lesson 02: Effective Prompting

The quality of Claude's output is directly proportional to the quality of your input. This lesson covers the mental models and practical techniques that separate expert users from beginners.


The Core Mental Model

Think of Claude as a brilliant new engineer on your team. They are:

  • Highly capable but unfamiliar with your specific codebase
  • Literal — they'll do exactly what you ask, not what you meant
  • Contextually limited — they can only see what's in the conversation
  • Eager — they'll attempt anything, even if they should ask first

Your job as the "senior" on this team is to give clear context, clear goals, and clear constraints.


The Anatomy of a Great Prompt

Bad Prompt

"Fix the login bug"

Good Prompt

"Users are getting a 401 error when their JWT expires mid-session instead of being redirected to login. The auth check is in middleware/auth.ts:34. The token refresh logic should already exist in services/auth.ts but isn't being called on 401 responses from the API client in lib/api-client.ts. Fix this so expired tokens trigger a refresh attempt before failing."

What makes it good:

  • Describes the symptom (401 error)
  • Describes the expected behavior (redirect to login)
  • Points to specific files and line numbers
  • Explains what should already exist
  • States the desired outcome clearly

Technique 1: Give Claude the Answer You Think Is Right

Even if you're not sure, share your hypothesis. It saves exploration time.

"I think the issue is in calculateTotal() in cart.ts — it's not accounting for discount codes applied after items are added. Can you check and fix it?"

Even if you're wrong, Claude will correct you. If you're right, it goes straight to the fix.


Technique 2: Specify Scope Explicitly

Claude will often do MORE than you asked if you don't constrain it. This isn't always good.

"Fix only the null pointer exception on line 47. Don't refactor anything else."

Or the inverse — tell Claude not to hold back:

"This function is a mess. Rewrite it completely. Don't feel constrained by the existing structure."


Technique 3: Ask for Multiple Options

When you're not sure which direction to go, ask Claude to lay out choices.

"I need to add real-time notifications. Give me 3 approaches (e.g., WebSockets, SSE, polling) with trade-offs for each, then recommend one for a system with ~10k concurrent users."


Technique 4: Chain Tasks

Claude handles complex multi-step workflows well when you describe them linearly.

"1. Read the existing UserService class. 2. Add a softDelete(userId) method that sets deletedAt instead of removing the record. 3. Update the getUser() and listUsers() methods to filter out soft-deleted records. 4. Run the tests and fix any failures."


Technique 5: Reference Code Precisely

Always use file:line references. Claude will navigate to the exact location.

"The type error is at src/types/user.ts:89 — the permissions field is typed as string[] but the API returns an object. Fix the type."


Technique 6: Constrain the Output Format

"Explain how the auth middleware works. Keep it under 5 bullet points. No code."

"Rewrite this function. Show me only the changed function, not the whole file."

"List every file that imports from utils/helpers.ts. Just the file paths, nothing else."


Technique 7: Use "Thinking Out Loud" for Hard Problems

For debugging or architectural decisions, ask Claude to reason through the problem before acting.

"Before making any changes: explain your understanding of why the race condition is happening and what your fix will do. Then make the fix."


What NOT to Do

Don't be vague about what "done" looks like. Bad: "Make the performance better." Good: "The dashboard query is taking 3s. Get it under 500ms. The query is in db/reports.ts:120."

Don't paste massive amounts of unrelated context. More context isn't always better. Irrelevant information dilutes the signal. Point to specific files instead of dumping entire codebases.

Don't ask Claude to guess at requirements. If you're not sure what you want, figure that out first. Claude excels at implementation, not at requirements discovery (unless you ask it to help you think through requirements explicitly).

Don't accept the first answer blindly. Push back. Ask "Why did you do it that way?" or "Is there a simpler approach?" Claude will often find a better solution when challenged.


Prompting for Different Task Types

Bug Fixing

Context: [what the code is supposed to do]
Symptom: [what's actually happening, with error messages/stack traces]
Location: [file:line where you think the issue is]
Hypothesis: [your guess at the cause, if any]
Constraint: [what you don't want changed]

Feature Development

Goal: [what user problem this solves]
Behavior: [how it should work, with examples]
Integration: [what existing code it touches]
Tests: [what test cases should pass]

Refactoring

Target: [what to refactor and why]
Outcome: [what the result should look like]
Preserve: [external behavior / API contracts that must not change]
Scope: [exact boundaries — don't touch X]

Code Review / Explanation

What I want to understand: [specific thing]
My current understanding: [your mental model]
Level of detail: [high-level / deep dive]

Practical Exercise

Take a task you'd normally describe in one sentence and rewrite it using the structured format for its type (bug/feature/refactor). Notice how much more precise your requirements become just from filling in the template.