Back to blog
5 min read

How do you write your first good prompt?

Turn a vague coding request into a bounded task with context, a concrete output, and acceptance checks you can verify.

  • #Prompts
  • #Vibe Coding
  • #Beginners
A structured prompt separates its goal, context, output, and acceptance checks
Share

Short answer

A good prompt states the goal, relevant context, desired output, and criteria you can check. Begin with one bounded task, include the current behavior, and improve the result through specific feedback instead of combining the whole product into one request.

The four layers of a verifiable prompt

Open each layer to see what it contributes to the same to-do form task.

  1. Goal

    State the user-visible outcome: the form must reject a blank task instead of adding it.

  2. Context

    Name the current behavior, relevant component, existing validation style, and boundaries.

  3. Output

    Request the smallest code and test changes that produce the required behavior.

  4. Acceptance

    Define checks for empty input, valid input, error clearing, and unchanged task creation.

You open a small to-do app and find a precise problem: pressing Add task with a blank field creates an empty row. The app already accepts valid tasks, so a broad rewrite would create more risk than value. Your first prompt should turn this observation into one bounded, testable change.

This guide follows that form from bug report to verified fix. It applies the same discipline used in vibe coding, where the model writes code but you remain responsible for the goal and evidence.

Start with the behavior you can observe

A model cannot inspect the failure you have in mind unless you describe it or give access to the running project. Name the trigger, current result, and expected result in concrete terms. This creates a shared starting point before either side discusses implementation.

For the to-do form, write the observation like this:

When I press Add task with an empty or whitespace-only field,
the app adds a blank row. It should keep the list unchanged and
show the form's existing validation message.

The example identifies two inputs, an empty string and whitespace, plus two visible outcomes. It does not guess whether the cause sits in a component, schema, event handler, or store. That separation matters because a confident implementation guess can send the model toward the wrong file.

Separate goal, context, output, and acceptance

OpenAI and Google both recommend clear instructions and relevant context in their official prompting guidance. For coding work, four layers make that advice operational: goal, context, requested output, and acceptance checks. Each layer answers a different question, so keep their roles distinct.

  • Goal: What user-visible behavior must change?
  • Context: Which facts, files, conventions, and constraints affect the task?
  • Output: What should the model change or return?
  • Acceptance: Which checks prove that the result works?

The goal for our form is not to add validation in the abstract. It is to prevent blank tasks without changing valid task creation. Context might include the component path, the existing error component, and the command that runs focused tests.

Bound the first change before naming features

Large requests mix decisions that need different evidence. If you ask for validation, task priorities, drag-and-drop, and a new design together, a failure no longer points to one cause. A smaller task makes review and rollback more dependable.

State both the allowed surface and the non-goals. For this example, allow changes to the task form and its tests. Keep persistence, task rendering, styling tokens, and dependencies outside the request unless inspection proves they are part of the bug.

This boundary also helps when you later delegate work to an AI agent. An agent can inspect and act across several steps, but it still needs a defined action space and a stopping condition.

Write one prompt for the blank-task failure

The following prompt combines the four layers without dictating an unverified implementation. It asks the model to inspect existing patterns before editing and names the evidence required at the end.

Goal: Reject empty and whitespace-only task submissions.

Context: Valid task creation already works. Reuse the existing
form error style. Do not add a dependency or change persistence.

Task: Inspect the task form and its tests. Implement the smallest
change that keeps the list unchanged for blank input and clears
the error after the user enters valid text.

Acceptance checks:
- Blank and whitespace-only submissions show the validation error.
- No task is added for either invalid input.
- A valid task is still added once.
- Focused tests cover invalid input, recovery, and valid input.

The prompt gives the model room to find the correct code path while limiting the result. It also requests a smallest change, not a preferred hook or validation library. That reduces the chance that your wording forces a new abstraction into an established project.

Review the response as evidence, not performance

A polished explanation does not prove that the form works. Review the actual diff, test output, and browser behavior. Ask the model to name changed files, commands it ran, and any checks it could not complete.

For this task, submit an empty value, spaces, and a valid label such as “Buy oats.” Confirm that invalid submissions leave the list unchanged. Then type valid text after an error and confirm that the message clears without a page reload.

Check the surrounding behavior as well. Press Enter if the form supports keyboard submission, submit twice, and reload after a valid task. These checks distinguish the requested fix from accidental changes to input focus, duplicate handling, or persistence.

Turn each mismatch into specific feedback

Suppose the model prevents blank tasks, but the error remains after you type a valid label. Do not ask it to try again without context. Report the exact sequence and expected recovery behavior.

The blank submission is blocked, but the validation message stays
visible after I type "Buy oats". Reproduce that sequence, clear the
error when trimmed input becomes valid, and add a regression test.
Keep the current task creation and styling unchanged.

This feedback preserves what already works and isolates the remaining defect. The new regression test becomes durable evidence for the next edit. If the correction causes a different failure, repeat the same pattern with that observed difference.

Recognize limits and failure cases

A detailed prompt cannot guarantee correct code. The model may inspect the wrong component, copy an outdated project pattern, weaken accessibility, or make a test pass without fixing the user flow. Missing runtime access can also prevent it from reproducing the issue.

Do not include secrets, private customer data, or production credentials as context. If the form handles regulated data or affects a critical workflow, add domain review and security checks beyond the model's code suggestions. A prompt defines work; it does not replace access control or accountable approval.

Stop when the task depends on a product choice you have not made. For example, deciding whether blank submission should show an inline message, disable the button, or do both affects accessibility and product behavior. Resolve that choice before asking the model to encode it.

Check the prompt and the finished change

Use this list before sending the prompt and again before accepting the result:

  • The prompt names the blank-input trigger, current result, and expected result.
  • The task changes one bounded behavior and lists relevant non-goals.
  • Acceptance checks cover empty input, whitespace, valid input, and recovery.
  • The model reports changed files and the exact tests it ran.
  • You inspect the diff and test the real form with keyboard and pointer input.
  • Any failed check becomes a specific follow-up prompt with reproduction steps.

A good first prompt does not need to predict every implementation detail. It needs to make the next decision and its evidence clear. Once the to-do form passes each check, stop expanding the request and record the verified outcome.

Mini quiz

Check your prompt decisions

Choose the best next move for each stage of the to-do validation task.

1 / 3

Which request gives the model a result you can verify?
Show solutions
  1. 1. Which request gives the model a result you can verify?

    Correct answer: Reject trimmed blank input, show the existing error style, and add tests for blank and valid tasks.

    The third request names the trigger, visible result, preserved behavior, and required evidence.

  2. 2. What is the safest first scope for this bug?

    Correct answer: Change blank-input handling and its focused tests.

    A bounded change is easier to review and less likely to disturb unrelated task behavior.

  3. 3. The error stays visible after valid text is entered. What should you send next?

    Correct answer: Describe that stale error, give reproduction steps, and require a regression test.

    Specific feedback turns the observed mismatch into the next checkable task.

Sources

  1. Prompt engineeringOpenAI · accessed 2026-07-15
  2. Prompt design strategiesGoogle AI for Developers · accessed 2026-07-15

Frequently asked questions

How long should a coding prompt be?

Use enough detail to define the task and its boundaries. A short prompt can work when the model already has the relevant project context, while a new task may need an example, constraints, and acceptance checks.

Do I need to name a framework?

Name it when the existing project or the requested output depends on it. If you do not know the stack, ask the model to inspect the project and explain its recommendation before editing files.

What should I do when the first result is wrong?

Report the observed mismatch, the expected behavior, and one way to reproduce it. Keep the next request focused on that difference instead of restarting the entire task.

Should I ask the model to plan first?

Planning helps when a task spans several files or carries product risk. For a small change, a bounded request and explicit acceptance checks may provide enough structure.