FLSoft Academy

MODULE 2 · PROMPTING & CONTEXT / 20 MIN Free NOVEMBER 2026 EDITION · CLAUDE CODE 2.1.318

Prompts that work the first time

Turn vague requests into specific, verifiable tasks: point at the right files, state the constraints, and define what done means.

Updated 5 November 2026 · Reviewed 5 November 2026

What you’ll be able to do

Write task prompts that get the right change on the first or second try, give Claude the context it needs without overloading it, and correct a wrong result efficiently instead of starting over.

Why this matters

Claude Code is capable, but it can’t read your mind. When a result disappoints, the cause is rarely the model “not being smart enough”. Far more often, the prompt left out something only you knew: which part of the code mattered, what must not change, or how to tell that the job was done. Claude then fills the gaps with reasonable guesses, and some of those guesses won’t be what you meant.

The fix isn’t longer prompts for their own sake. It’s including the few pieces of information that remove the guesswork. The extra 30 seconds you spend on a prompt routinely saves several rounds of back-and-forth.

The four parts of a good task prompt

A strong task prompt answers four questions. You don’t need all four every time, but when a result disappoints, one of them is usually missing.

1. Goal: what should be true afterwards? Describe the outcome, not the steps. “Users can reset their password by email” gives Claude room to find the right approach in your codebase. “Write a function called resetPassword” doesn’t say what the function is for.

2. Context: where should it look, and what’s relevant? Point Claude at the relevant files and patterns, for example “Auth lives in @src/auth; email is sent via @src/lib/mailer.ts”. Without this, Claude spends time searching, and might base its work on the wrong part of the code.

3. Constraints: what must it not do? Anything you’d object to in review belongs here: “No new dependencies”, “Keep the public API unchanged”, “Don’t touch the legacy folder”. Claude can’t respect a rule it was never told.

4. Done means: how do you both know it worked? Give Claude a way to check its own work: “Add tests and run npm test”, “The build must pass”, “Show me the diff”. As you saw in lesson 1.2, a way to verify is what turns plausible-looking code into working code.

PartQuestion it answersExample
GoalWhat should be true afterwards?“Users can reset their password by email.”
ContextWhere, and what’s relevant?“Auth lives in @src/auth. Email is sent via @src/lib/mailer.ts.”
ConstraintsWhat must it not do?“No new dependencies. Keep the existing API shape.”
Done meansHow do we know it worked?“Add tests, run npm test, and show me the diff.”

Before and after

Vague:

add caching

Specific:

The /products endpoint in @src/routes/products.ts hits the database on every
request. Add an in-memory cache with a 60-second TTL keyed by the query string.
No new dependencies. Add a test proving the second call within 60s doesn't hit
the DB (mock the repository). Run the tests.

Look at what each sentence of the specific version does:

  • “The /products endpoint in @src/routes/products.ts hits the database on every request” is the context and the reason. Claude knows exactly where to work and why.
  • “Add an in-memory cache with a 60-second TTL keyed by the query string” is the goal, precise enough to remove the obvious design questions. (TTL, “time to live”, is how long a cached entry stays valid.)
  • “No new dependencies” is a constraint. Without it, adding a caching library would be a perfectly reasonable choice.
  • “Add a test proving the second call within 60s doesn’t hit the DB… Run the tests” is done means. It tells Claude how to prove the cache actually works.

The vague version could reasonably produce a dozen different solutions. The specific one takes 30 seconds longer to write and leaves very little to guess.

Ways to give context

Context is the part people most often under-supply. You have several ways to give it:

  • Reference files and folders with @. Type @ and pick a file (@src/auth/login.ts) or a folder (@src/auth/). Claude reads exactly what you point at, instead of searching and possibly finding the wrong thing.
  • Paste errors exactly as they appear. Copy the full error message and stack trace. Don’t paraphrase it: file names, line numbers and exact wording are what Claude uses to find the cause.
  • Show it, don’t describe it. For a visual bug, paste a screenshot (Ctrl+V, or Alt+V on Windows) or drag the image file in. Lesson 2.4 covers this.
  • Point at an example to copy. “Follow the same pattern as @src/routes/orders.ts” is often more precise than paragraphs of description, and it keeps new code consistent with the old.
  • Pipe output in from your shell. cat error.log | claude -p "what's the root cause?" sends a file’s contents as part of the prompt.

Exercise: rewrite three prompts

In a project of your own (or loop-practice), take these three vague prompts and rewrite each one using the four parts:

  1. “write some tests”
  2. “the README is bad”
  3. “speed this up” (pick any slow-looking function)

For each one:

  1. First, try the vague version and note what Claude does.
  2. Rewind the changes (Esc Esc → Restore code and conversation), or /clear and undo with git.
  3. Now try your rewritten version and compare.

What you’ll see: with the vague prompts, Claude typically asks clarifying questions or makes broad, generic changes. With the rewritten ones, it goes straight to the right files and produces something much closer to what you’d accept in review.

When the result is wrong

Don’t start over. Starting a new conversation throws away everything Claude learned about the task. Instead, give specific feedback, the way you would to a colleague whose work is 80% right:

  • “That works, but use the existing logger instead of console.log.” Name the exact change you want.
  • “Revert the change to config.ts, which is out of scope.” Rein in changes you didn’t ask for.
  • “The test passes, but it doesn’t cover the case where the list is empty.” Point at the gap, not just the symptom.

Vague feedback (“that’s not right”, “try again”) leads to another round of guessing. Specific feedback usually fixes the result in one step.

Common mistakes

  • Describing steps instead of the outcome. Tell Claude what should be true afterwards and let it work out how.
  • Leaving out “done means”. Always say how the result will be checked: tests, a build, a command to run.
  • Paraphrasing errors. Paste the exact message and stack trace.
  • Over-stuffing context. Point at the relevant files rather than pasting everything.
  • Restarting instead of correcting. Specific feedback in the same conversation is faster than a fresh start.

Verify it worked

  • You rewrote all three vague prompts with a goal, context, constraints and a definition of done
  • You compared at least one vague prompt with its rewritten version
  • At least one prompt used @ to reference files
  • You corrected a result with specific feedback instead of starting over

Knowledge check

4 QUESTIONS · PASS MARK 80%
1. Which prompt is most likely to produce the change you want?
2. What does typing `@src/api/users.ts` in a prompt do?
3. Why include "run the tests and fix any failures" in a prompt?
4. Claude keeps adding a dependency you don't want. What's the best fix?

Tip: select the text that's wrong before clicking, and it's quoted in your report.

Report a problem

Lesson: Prompts that work the first time

What's wrong?