AI AI-07.01
Prompting fundamentals
Write prompts that work: clear instructions, roles, context, examples and output format, then test them on real inputs and iterate like code.
The big idea
A promptThe text you send to a language model: instructions, context, examples and the input to work on. The model continues from it, so it shapes everything the model produces. is the whole briefing a model gets before it starts writing. The model knows a great deal in general and nothing about your situation: who the answer is for, what words your team uses, what a good result looks like, what to do when the input is odd. Whatever you leave out, it fills in with a plausible guess.
Most bad outputs are not the model being stupid. They are the model guessing sensibly at things the prompt never said. Good prompting is mostly removing the need to guess: state the task, give the context, show an example, fix the output format, and say what to do in edge cases. Then check on real inputs whether that worked, because a prompt that reads well can still fail.
Think of briefing a brilliant contractor who started this morning. "Write up the ticket" gets you something reasonable but wrong for your team. "Write three lines, area, severity on our S1 to S4 scale, and a one-sentence summary, for the on-call engineer; here is one done well" gets you what you need.
How it works
Clear instructions
Say what you want directly, as a task, not a hint. "Summarise this ticket for the on-call engineer in one sentence" beats "Can you look at this ticket?". Name the audience and the purpose, because they decide length, tone and what counts as important. If you would need to explain something to a new colleague, explain it to the model.
Roles
A role ("You are a support triage assistant for a software company") sets the general frame: vocabulary, tone, what to focus on. It helps most when the task depends on a particular perspective. It is not magic: a role without the specific instructions below it does little. Stable instructions and roles usually live in the system prompt ( System prompts and personas ).
Context
Context is everything the model cannot know: your product areas, your severity scale, who the user is, the document to work from. Missing context is the single most common cause of answers that are reasonable but wrong for you. Separate it clearly from the instructions, for example with headings or tags such as <ticket>...</ticket>, so the model never confuses data with orders.
Examples
One or two worked examples of input and ideal output show the standard far more precisely than adjectives like "concise" or "professional". They are the subject of Few-shot prompting and examples .
Output format
If a program reads the result, specify the exact shape: fields, order, allowed values, no greeting. If a person reads it, specify length and structure. For machine-readable output, use the provider's structured-output features as well ( Structured outputs ).
Edge cases
Say what to do when the input is empty, off-topic, in another language, or missing a field. Without a rule the model improvises, usually by inventing something plausible. "If the ticket reports no problem, reply only NO_ISSUE" is one line that removes a whole class of failures.
Iterate with test cases
Collect 10 to 30 real inputs, including awkward ones, and write down what a good output must contain. Run every prompt version on all of them. Change one thing at a time and keep a change only if the results improve. This turns prompting from guesswork into engineering, and the same test set later becomes your evaluation set ( Building an eval set ).
Try it
The sample outputs are hand-written illustrations of typical behaviour, not live model calls.
Try this:
- With every part off, all 12 checks fail. The output is friendly and roughly right, which is exactly why problems like this slip through when you only eyeball one answer.
- Turn on the output format only. The format check passes for three tickets but the area and severity are still the model's own words. Now add context and the example: 9 of 12 pass. Each part fixes a different check.
- Select the "no issue" ticket. Without the edge-case rule, the model invents an issue to summarise. Turn the rule on and all 12 checks pass.
Going deeper
Prompts as code, in code
The test loop is easy to automate. Here a stand-in model function replaces the API call so the example runs offline, but the harness is the real pattern: fixed cases, explicit checks, a score per prompt version.
# Treat prompts like code: run every prompt version over the same test cases and score it.
# `fake_model` stands in for a real API call so the example runs offline; swap in your client.
import re
CASES = [ # (ticket, expected area, expected severity); None means "no issue"
("Cannot log in with SSO since 9am.", "Auth", "S2"),
("Charged twice for March, fix it now!", "Billing", "S2"),
("Dashboard is slow sometimes.", "Performance", "S3"),
("Works again, thanks. Please close.", None, None),
]
def fake_model(prompt, ticket):
"""Mimics typical behaviour: it follows only what the prompt actually asks for."""
if "NO_ISSUE" in prompt and "close" in ticket.lower():
return "NO_ISSUE"
area = {"log in": "Auth", "charged": "Billing", "slow": "Performance"}
a = next((v for k, v in area.items() if k in ticket.lower()), "General")
sev = ("S3" if "slow" in ticket else "S2") if "S1" in prompt else "high"
if "three lines" in prompt:
return f"Area: {a if 'Product areas' in prompt else a.lower()}\nSeverity: {sev}\nSummary: ..."
return f"Looks like a {sev} priority problem with {a.lower()}. Worth a look!"
def check(out, area, sev):
if area is None:
return out.strip() == "NO_ISSUE"
return bool(re.fullmatch(rf"Area: {area}\nSeverity: {sev}\nSummary: .+", out))
V1 = "Summarise this support ticket for the on-call engineer."
V2 = V1 + " Reply with exactly three lines: Area, Severity, Summary."
V3 = V2 + " Product areas: Auth, Billing, Performance. Severity: S1 outage ... S4 question."
V4 = V3 + " If the ticket reports no problem, reply only NO_ISSUE."
for name, p in [("v1 task only", V1), ("v2 + format", V2), ("v3 + context", V3), ("v4 + edge case", V4)]:
results = [check(fake_model(p, t), a, s) for t, a, s in CASES]
print(f"{name:15} {sum(results)}/{len(CASES)} pass " + " ".join("." if r else "F" for r in results))Output
v1 task only 0/4 pass F F F F
v2 + format 0/4 pass F F F F
v3 + context 3/4 pass . . . F
v4 + edge case 4/4 pass . . . . Adding the format alone did not pass a single case, because the area and severity were still wrong. Context fixed three; the edge-case rule fixed the last. With a real model you would also run each version a few times, since sampling makes outputs vary.
Put long documents first, the question last
When a prompt includes a long document, placing the document before the instructions and question tends to work better than the reverse, and it also helps prompt caching ( Prompt caching and cost control ).
Tell it what to do, not only what not to do
"Do not use jargon" names the thing you want to avoid and leaves the alternative open. "Write for a customer with no technical background, in plain words" describes the target.
Trade-offs
| Option | Wins when | Loses when |
|---|---|---|
| Short, bare prompt | Quick to write; fine for one-off personal use | Model guesses audience, format and edge cases; inconsistent |
| Detailed prompt with context and format | Consistent, testable, fits your system | More tokens per call; needs maintenance as needs change |
| Adding examples | Pins down style and standard precisely | Costs tokens; model may copy examples too literally |
| Fine-tuning instead | Behaviour baked in; shorter prompts | Needs data and training; slower to change (see AI-06.07) |
Common mistakes
- Judging a prompt from one good-looking output instead of a set of test inputs.
- Leaving out context the model cannot know, such as your product names, scales or audience.
- Changing several things at once, so you cannot tell which change helped.
- Mixing instructions and data without clear separation, so text in the input is read as instructions.
- No rule for empty, off-topic or unusual inputs, so the model invents something.
In the wild
Anthropic
Prompt engineering overview (opens in a new tab)Before improving a prompt, the guide asks you to have a clear definition of success for your use case, some way to test against it empirically, and a first draft prompt. It notes that not every failing evaluation is best fixed by prompting; latency and cost, for example, are sometimes easier to improve by choosing a different model. It then covers techniques starting with being clear and direct, and moving on to examples, structuring prompts with XML tags, roles, letting the model think, and chaining prompts.
Check yourself
-
A model's ticket summaries are polite and roughly right, but use its own severity words instead of your S1 to S4 scale. What is missing from the prompt?
Show answer
B. Context: the severity scale and what each level means The model cannot know your scale unless you give it. Missing context produces reasonable but wrong-for-you answers.
-
Why test a prompt on a set of real inputs rather than one example?
Show answer
B. One good output hides failures on other inputs, especially edge cases Prompts fail on particular inputs. A fixed test set shows whether a change helps overall and catches regressions.
-
You changed the role, added two examples and rewrote the format rule at once, and results got slightly worse. What should you do?
Show answer
B. Revert and apply the changes one at a time, keeping only those that help Several simultaneous changes hide which one hurt. One change at a time makes the effect of each visible.
-
A program parses the model's reply. Which instruction helps most?
Show answer
B. Reply with exactly three lines: Area, Severity, Summary. No greeting. A precise output format is checkable and parseable; adjectives like concise leave the shape to the model.
Recap
- A prompt is a briefing: whatever you leave out, the model fills in with a plausible guess.
- State the task, give the context only you know, show an example, fix the output format and cover edge cases.
- A role sets the frame, but specific instructions do the work.
- Keep data clearly separated from instructions.
- Treat prompts like code: test every version on the same real inputs, change one thing at a time, and keep what measurably helps.