---
title: "06 — Prompting Best Practices — How You Ask Is What You Get"
uid: prompting-best-practices
tags: ["prompt-engineering", "workflow", "vibe-coding", "roadmap:vibe-coding", "ai", "prompting"]
excerpt: "The prompt is the spec the model implements — one thing at a time, be specific, show examples, say what to avoid, and keep a context doc so you don't repeat yourself every session."
date: 2026-08-13T03:27:25+0000
source: https://www.aveshina.my.id/en/blog/prompting-best-practices
---

Treating the prompt as a wish and hoping was my prompting method, and the hopes came back half-met. Writing it down straightened out one idea: **how you talk to the AI determines the quality of what comes back** [1]. That isn't a platitude. It's a literal input-output relationship. The prompt is the spec the model implements, and a vague spec produces vague code the same way a vague ticket produces vague work from a human. The roadmap compresses the whole discipline into five rules, and they all trace back to that one idea.

The framing that clicked: **the prompt is a specification, not a wish.** When I write a ticket for a junior, I'm careful — scope, constraints, examples, what not to do. The AI deserves the same care, because it answers the spec literally.

## One thing at a time

The first habit, and the one I keep relearning: ask for one thing per prompt. A prompt like "add auth, set up the database, build the dashboard, and style it" comes back as four half-done things, none of them right. The model allocates its attention across everything I asked for, and each piece gets a quarter of the effort.

The discipline: break the work into the smallest unit that produces a verifiable result, prompt for that, verify, then move on. "Add a login form that posts to /api/login and shows the error on failure" is one thing. "Build the whole auth flow" is four. The four single-thing prompts produce better total output than the one four-thing prompt, and each step is checkable before the next begins.

```figure
<svg viewBox="0 0 700 260" xmlns="http://www.w3.org/2000/svg" class="my-6 w-full max-w-2xl" role="img" aria-label="Two prompting strategies. Left: one big prompt asking for four things at once produces four half-done pieces of code. Right: four sequential single-thing prompts each produce one clean, verified piece, stacked into a complete result.">
  <g font-family="ui-sans-serif, system-ui, sans-serif" text-rendering="geometricPrecision">

    <text x="175" y="24" font-size="11" font-weight="700" fill="#7f1d1d" text-anchor="middle">One big prompt — 4 things at once</text>
    <rect x="40" y="38" width="270" height="40" rx="8" fill="#fee2e2" stroke="#dc2626" stroke-width="1.5"/>
    <text x="175" y="62" font-size="10" font-family="ui-monospace, monospace" fill="#7f1d1d" text-anchor="middle">"auth + db + dashboard + styles"</text>

    <g font-size="9.5" fill="#7f1d1d" text-anchor="middle">
      <rect x="40" y="96" width="60" height="40" rx="6" fill="#fecaca" stroke="#dc2626"/>
      <text x="70" y="120">auth ¼</text>
      <rect x="110" y="96" width="60" height="40" rx="6" fill="#fecaca" stroke="#dc2626"/>
      <text x="140" y="120">db ¼</text>
      <rect x="180" y="96" width="60" height="40" rx="6" fill="#fecaca" stroke="#dc2626"/>
      <text x="210" y="120">dash ¼</text>
      <rect x="250" y="96" width="60" height="40" rx="6" fill="#fecaca" stroke="#dc2626"/>
      <text x="280" y="120">style ¼</text>
    </g>
    <text x="175" y="160" font-size="10" font-style="italic" fill="#7f1d1d" text-anchor="middle">four half-done things</text>

    <text x="525" y="24" font-size="11" font-weight="700" fill="#052e16" text-anchor="middle">Four sequential prompts — one each</text>

    <rect x="390" y="38" width="270" height="28" rx="6" fill="#dcfce7" stroke="#16a34a" stroke-width="1.5"/>
    <text x="525" y="56" font-size="10" font-family="ui-monospace, monospace" fill="#052e16" text-anchor="middle">"login form → /api/login" ✓</text>

    <rect x="390" y="74" width="270" height="28" rx="6" fill="#dcfce7" stroke="#16a34a" stroke-width="1.5"/>
    <text x="525" y="92" font-size="10" font-family="ui-monospace, monospace" fill="#052e16" text-anchor="middle">"session middleware" ✓</text>

    <rect x="390" y="110" width="270" height="28" rx="6" fill="#dcfce7" stroke="#16a34a" stroke-width="1.5"/>
    <text x="525" y="128" font-size="10" font-family="ui-monospace, monospace" fill="#052e16" text-anchor="middle">"dashboard route" ✓</text>

    <rect x="390" y="146" width="270" height="28" rx="6" fill="#dcfce7" stroke="#16a34a" stroke-width="1.5"/>
    <text x="525" y="164" font-size="10" font-family="ui-monospace, monospace" fill="#052e16" text-anchor="middle">"match existing styles" ✓</text>
    <text x="525" y="200" font-size="10" font-style="italic" fill="#052e16" text-anchor="middle">each verified before the next begins</text>

    <text x="350" y="240" font-size="10" fill="#64748b" text-anchor="middle">same total work; the sequential path produces better output</text>
  </g>
</svg>
```

## Be specific, and show examples

The second and third habits reinforce each other: be specific, and show examples [1]. Specificity means naming the exact behavior, the exact shape, the exact edge cases. "Handle errors" is not specific. "Return a 422 with { field, message } for validation errors and a 500 with { requestId } for server errors" is specific. The model fills unspecified gaps with its prior — and its prior is "the most common thing," which is rarely mine.

Examples are specificity's multiplier. The roadmap names them directly: _show examples_ [1]. A prompt with a sample input, a sample output, and a sample error is dramatically more likely to land than the same prompt in prose. This is the same reason mockups and screenshots matter in planning — concrete anchors tighten the model's output to my intent. When I have a reference, I paste it. When I don't, I sketch one.

## Say what to avoid

The fourth habit is the one I most often forgot: tell the model what to avoid [1]. "Don't add new dependencies." "Don't touch files outside src/auth/." "Don't use any." Without these constraints, the model reaches for the path of least resistance, which often introduces churn — a new library, an edit somewhere unrelated, a loosened type. Negative constraints are cheap to state and prevent a class of rework that's annoying to unwind.

A useful pattern I keep: every build prompt ends with a short "avoid" list — three or four bullets specific to the task. It takes ten seconds and saves the most common form of drift.

## The context document: don't repeat yourself

The fifth habit is the highest-leverage of all, and it took me longest to adopt: _use a context document so you don't repeat yourself every session_ [1]. Every fresh session starts with the model knowing nothing about my project. Without a context doc, I spend the first ten minutes re-explaining the stack, the conventions, the structure, the decisions — and the model still misses things I forgot to mention. With one, I paste a single file and the model is caught up.

A context doc is short. Mine is a few paragraphs:

```
PROJECT: habit-tracker
STACK: Next.js App Router, TypeScript strict, Tailwind, Supabase
STRUCTURE: app/[locale]/ for pages, lib/ for logic, store/ for Zustand slices
CONVENTIONS:
- Server Components by default; 'use client' only for interactivity
- Fetch from Supabase in Server Components; mutations via Server Actions
- No `any`; use unknown + type guards
CURRENT FOCUS: shipping the streaks feature (Phase 2)
```

This is the project's stable context — the stuff that doesn't change between sessions. The current focus line gets edited as I move; everything else stays. With it, each new session starts at "caught up" instead of "blank slate," and the model's first answer is already shaped by my project's actual decisions.

The roadmap points to a dedicated Prompt Engineering roadmap for going deeper [1][2], and the three approaches to shaping model output — retrieval, fine-tuning, and prompt engineering — are worth understanding as a spectrum [2]. For most app-level vibe coding, prompt engineering (with a context doc) is the right tier; the other two are heavier lifts for narrower gains.

## How I use this

A short checklist before every build prompt: one thing only, specifics over wishes, a concrete example if I can make one, an "avoid" list of three or four constraints, and the context doc pasted at the top of any fresh session. The discipline is small; the payoff is that the first answer is usable far more often, and the loop converges in fewer turns. The thing I stopped doing: wishing at the model and being surprised when it answered the wish literally.

## References

[1] roadmap.sh, "Prompting Best Practices," 2026. [Online]. Available: [https://roadmap.sh/vibe-coding/prompting-best-practices](https://roadmap.sh/vibe-coding/prompting-best-practices)

[2] roadmap.sh, "Prompt Engineering Roadmap," 2026. [Online]. Available: [https://roadmap.sh/prompt-engineering](https://roadmap.sh/prompt-engineering)

```quiz
Q: The roadmap's core claim about prompting is…
- prompting doesn't matter; model quality determines everything
- how you talk to the AI determines the quality of what comes back
correct: 1
explain: The prompt is the spec the model implements. A vague spec produces vague code. Five habits — one thing at a time, specific, examples, what to avoid, context doc — measurably improve output.

Q: Why does a multi-thing prompt ("auth + db + dashboard + styles") produce worse output than four single prompts?
- it doesn't; the model parallelizes well
- attention is split across all requests, so each piece gets partial effort
correct: 1
explain: The model allocates attention across everything asked. One-thing-at-a-time prompts each get full effort, are verifiable, and converge faster than one big prompt.

Q: What does "show examples" add to a prompt?
- nothing the model can't infer from prose
- concrete input/output anchors that tighten the model's output to your intent
correct: 1
explain: The model fills unspecified gaps with its prior (the statistically common thing). Examples override that prior with your specific intent, the same way mockups do in planning.

Q: A context document's main purpose is to…
- replace all other prompts
- carry the project's stable context into every fresh session so you don't re-explain it
correct: 1
explain: Each fresh session starts with the model knowing nothing about your project. A short context doc — stack, structure, conventions, current focus — starts the session at "caught up" instead of "blank slate."

Q: Why include an "avoid" list in a build prompt?
- to be polite to the model
- to prevent drift like unwanted new dependencies, unrelated edits, or loosened types
correct: 1
explain: Without negative constraints, the model takes the path of least resistance — often adding a library, editing unrelated files, or relaxing types. A short avoid list prevents that class of rework.
```
