Design prompts as testable interfaces, not magic wording.
The same model can give a useless answer or a great one to the same question — the difference is the prompt. This module shows why, and what a model is really reacting to.
A prompt is the only lever you control: instructions plus context shape every token the model writes.
Why this matters: It matters because most 'bad model' results are really bad prompts you can fix yourself.
An does one thing: given some text, it predicts the next , over and over, until it stops. It has no goals of its own and no memory of you. The only thing steering it is the text you put in front of it — the .
That is why prompt engineering exists. The model is fixed, but the prompt is the one lever you fully control. A vague prompt makes the model guess at audience, length, format, and tone — and it will guess differently every time. A specific prompt removes that guessing.
So most "the model is bad at this" problems are really "my prompt is underspecified" problems. The skill is learning to say exactly what you want before blaming the model. Three habits do most of the work:
Suppose you want help replying to an unhappy customer email.
Vague prompt: "Reply to this email." The model guesses the tone (maybe too casual), the length (maybe a wall of text), and may promise a refund you never authorized.
Specific prompt: "You are a support agent. Write a calm, 4-sentence reply apologizing for the delay. Do not promise a refund. End by offering to escalate." Now the tone, length, and a hard constraint are all set — and you can check each one in the output.
Same model, same email. The only thing that changed was how much guessing you left to the model.
Slide from a vague prompt to a fully specified one and watch how much the model has to guess.
Say the task in one sentence, including the audience: "Explain recursion to a 12-year-old" beats "explain recursion."
The model has no access to your data. Paste the document, the code, or the constraints it must use into the — that is the text it can actually read.
Name the output shape — "three bullet points," "a single sentence," "valid JSON" — so you can tell at a glance whether the model complied.
Your prompt is not understood as ideas — it is split into (word fragments) and processed left to right. Everything the model 'knows' for this request is the text inside the : your instructions, any pasted material, and the conversation so far.
A reliable prompt isn't one blob of text — it's five parts: role, task, context, constraints, and output format. Seeing the parts is what lets you debug a prompt instead of rewriting it from scratch.
Every strong prompt names a role, a task, the context to use, constraints, and an output format.
Why this matters: It matters because once you can see the parts, you can debug a prompt instead of guessing.
Quick recall from module 1: before reading on, name the one thing you control that most changes a model's output. (It's the — the model is fixed, so removing the model's guessing is your job. This module gives you the parts to specify.)
Most strong prompts are built from the same five parts. Naming them turns prompting from guesswork into editing — when an answer is wrong, you fix the part that caused it.
Not every prompt needs all five, but when an answer disappoints, it is almost always because one of these was missing or vague.
Here is a working prompt with each part labeled:
If the result is too long, you know exactly where to look: the constraints. If it sounds wrong, check the role. That is the payoff of seeing the parts.
"Summarize this article." Works, but the summary's length and reading level are unpredictable.
"You are an editor. Summarize this article for a busy executive in 3 bullet points." Now tone and length are pinned.
Paste the article text, then add: "Return only the bullets, no preamble." Every part is now specified and checkable.
Where you put each part affects how strongly the model follows it. Two practical rules: put the most important constraints near the end of the prompt (models weight recent instructions heavily), and clearly separate your instructions from pasted context — using delimiters like triple quotes or XML-style tags so the model doesn't mistake the data for a command.
Once you can build a clear prompt, the next choice is technique: just ask (zero-shot), show examples (few-shot), or ask the model to reason step by step (chain-of-thought). Each trades tokens and effort for reliability — and bigger is not always better.
Zero-shot, few-shot, and chain-of-thought trade tokens and effort for reliability on harder tasks.
Why this matters: It matters because reaching for the heaviest technique first wastes tokens and can hurt accuracy.
Decision this forces: Choose the lightest prompting technique that meets the task: zero-shot, few-shot, or chain-of-thought.
When a plain prompt isn't reliable enough, you have three escalating techniques.
Each step up costs more and fills more of the . The discipline is to start at zero-shot and only escalate when a real failure shows you need to.
Ask plainly and run it on a few real inputs. If it's reliably right, stop here — you've spent the fewest tokens.
When output shape or style is inconsistent, show two or three correct examples (few-shot). The model imitates them.
When answers are confidently wrong on multi-step problems, add "think step by step" (chain-of-thought) so the model works through the logic.
| Option | Best for | Token cost | Reliability gain | When to choose | Cost | Complexity |
|---|---|---|---|---|---|---|
| Zero-shot | Common, well-defined tasks the model already knows. | Lowest — just the instruction. | Baseline; no extra help. | Use first, always. Escalate only if it actually fails on real inputs. | Low | Low |
| Few-shot | Specific formats or styles hard to describe in words. | Medium — examples take up context. | Strong for format and consistency. | Use when output shape or style drifts and you can show good examples. | Medium | Medium |
| Chain-of-thought | Multi-step reasoning: math, logic, planning. | Highest — model writes its reasoning. | Strong on problems that need stepwise logic. | Use when answers are confidently wrong on problems that need several steps. | High | Medium |
Few-shot works because the model copies your examples — including their flaws. If all your examples are short, it will keep answers short even when a longer one is needed. If they all cover the easy case, it won't generalize to the hard one. Pick examples that span the range of inputs you actually expect, and make sure each one is exactly the output you'd want.
The payoff of all the parts is a prompt that returns structured output your program can trust. This module builds one and pins its output to a JSON schema — and shows how to check the AI-generated version before you ship it.
A production prompt pins the output to a schema so downstream code can trust and parse it.
Why this matters: It matters because free-form text breaks your code; a schema turns the model into a reliable component.
When a prompt feeds a program — not just a human reader — the output format becomes the most important part. Free-form prose is unpredictable to parse. Instead, tell the model to return data that matches a fixed , usually JSON with named fields.
A schema does two jobs: it tells the exactly which fields to produce, and it gives your code a contract to validate against. If a required field is missing, you can catch it and retry instead of crashing on a surprise.
Putting every part together for a support-ticket classifier:
The schema that this prompt promises to fill is shown next — read it before you peek at the prediction.
{"type":"object","properties":{"category":{"type":"string","enum":["billing","bug","feature","other"]},"urgency":{"type":"integer","minimum":1,"maximum":3}},"required":["category","urgency"],"additionalProperties":false}enumrequiredadditionalPropertiesThis is the contract. The prompt tells the model to return JSON in this shape; your code validates the reply against it and retries if it doesn't match. The enum stops the model from inventing a category, and additionalProperties:false rejects any surprise fields.
{"category":"billing","urgency":3} — a billing complaint about a double charge is high urgency. The schema guarantees exactly these two fields, so your code can read result.category directly.
Role + task + constraints: "You are a support classifier. Read the message and label it. Only use the categories listed."
Add: "Return JSON with fields category (string) and urgency (1-3). Return only the JSON." Now the shape is fixed.
Append the actual customer message, clearly delimited, so the model classifies that text and not your instructions.
It's common to ask an AI assistant to write a prompt for you. A drafted prompt can read beautifully and still be broken. Check these before shipping it:
A prompt that works on your one example will quietly fail on real users' inputs. This module covers the common failure modes — ambiguity, edge cases, and prompt injection — and a checklist for testing a prompt before you rely on it.
Prompts fail on edge cases, ambiguity, and injection — you find these by testing, not by re-reading.
Why this matters: It matters because a prompt that works on your one example will quietly fail on real users' inputs.
Decision this forces: Decide whether a prompt is reliable enough to ship: tested on one example, tested on a small input set, or tested and monitored in production.
Recall from module 2: before reading on, try to name the five parts of a prompt from memory. (Role, task, context, constraints, output format.) Keep them in mind — most failures below trace back to one of these being vague or missing.
A prompt that looks perfect on your example almost always has gaps that only real inputs expose. The three most common failure modes:
An instruction you read one way the model reads another. "Summarize briefly" — how brief? The model picks, and it varies. Fix by replacing judgment words with numbers and concrete rules.
Empty input, a very long input that overflows the , an input in another language, or one with no clear answer. The prompt that handles your sample may return garbage — or nothing — on these.
Because the model reads your instructions and the pasted user input as one stream of , a malicious input can contain its own instructions — "ignore the above and do X." The model may obey them. This is prompt injection, and it is why you must clearly mark which text is data and never give a model more authority than the least-trusted input deserves.
Collect 5-10 real inputs that span easy, hard, and weird (empty, huge, hostile). Note the output you'd want for each.
Run the prompt on every input. Where the output misses, trace it to a specific part of the prompt and tighten that part.
Add an input that tries to override your instructions. If the model obeys it, separate data from instructions more firmly before shipping.
| Option | Edge cases | Output reliability | Injection safety | When to choose | Cost | Complexity |
|---|---|---|---|---|---|---|
| Tested on one example | Untested — empty/huge/hostile inputs unknown. | Looked right once; variance unknown. | Never probed. | Fine for a throwaway one-off you'll read yourself. Never for production. | Low | Low |
| Tested on a small input set | Easy + hard + weird inputs all checked. | Consistent across the set; format validated in code. | Probed with an override input; data separated from instructions. | The right bar for anything users or code depend on. | Medium | Low |
| Tested + monitored in production | New failures logged and folded back into the test set. | Schema-validated with retries and alerting. | Least-privilege plus ongoing review of suspicious inputs. | Use when the prompt is on a critical path and inputs are untrusted at scale. | High | Medium |
When a prompt fails a test, the instinct is to swap in a bigger model. Usually the cheaper fix is in the prompt: tighten the vague constraint, add one representative example, or move the critical rule to the end. Change one thing at a time and re-run your test set, so you know which edit actually helped.
Close the book for a moment and reconstruct the path from memory: (1) why does the prompt — not the model — drive output quality? (2) what are the five parts of a prompt? (3) when do you escalate from zero-shot to few-shot to chain-of-thought? (4) why pin output to a schema? (5) what are the three ways a prompt breaks on real inputs?
If any rung is fuzzy, that's the module to revisit. The through-line: a prompt is something you specify deliberately and test, not a lucky phrase.
Solo build: pick one real task you'd hand a model (classify an email, extract fields from a doc, draft a reply). Write the full prompt with all five parts, pin its output to a small JSON schema, then run it on five inputs including one empty and one hostile. Note every failure and the prompt edit that fixed it. NEXT RUNG: once this is solid, learn how a prompt becomes a tool-calling step in an agent loop — your schema discipline is exactly what tool definitions need.
Two people ask an AI the same question — one gets a vague, unhelpful answer and the other gets a precise, useful one. What is the most likely reason for the difference?
The model reads exactly what you give it — richer, clearer prompts consistently produce better outputs because the model has more signal to work with.
You send a prompt and the AI returns a wall of text with no structure, even though your app needs to parse the result as JSON. Which prompt component did you most likely leave out?
The Format component tells the model exactly how to structure its response; without it, the model defaults to free-form prose that downstream code can't reliably parse.
A developer needs an AI to classify customer emails into three categories. The task is straightforward and the model is capable. Which prompting technique should they try FIRST?
The guiding principle is to choose the lightest technique that meets the reliability bar — zero-shot costs nothing extra and should be validated before adding examples or reasoning chains.
List the five components of a well-structured prompt.
A complete prompt includes a Role (who the model acts as), a Task (what to do), Context (relevant background), Constraints (limits or rules), and Format (how the output should look).
You've built a prompt and tested it on one example — it worked perfectly. Is it ready to ship to production?
A single passing test doesn't reveal edge cases or adversarial failures; a prompt is ready to ship only after it holds up across a realistic and varied input set, with monitoring continuing in production.