Prompt Engineering: The Core Moves
Master the four prompting patterns that most reliably change what an LLM produces: role prompting, few-shot examples, chain-of-thought, and output format control — explained through the next-token prediction lens.
- Estimated time
- ~14 min
- Difficulty
- intro
- Sources
- 4 sources
In the previous lesson we established that an LLM is a next-token predictor: at every step it looks at everything in the context window and assigns probabilities to what token could plausibly come next. A prompt is simply the context you load into that window before sampling begins. Everything in this lesson follows from that one fact.
Why low-signal prompts produce generic answers
Ask a model “explain why my Python code is slow” and you get a generic paragraph about interpreted languages. The context window contains almost no signal about format, audience, or level of detail — so the model samples from a broad swath of “Python performance” content in its training distribution. The most probable completion for a vague prompt is a vague answer.
Every technique in this lesson works by adding signal to the context window, narrowing the output distribution from “anything that could plausibly follow these tokens” toward exactly the shape of response you want.
The same question, two signal levels
Low signal: What is REST?
The model draws from a wide distribution — Wikipedia intro, blog post, textbook definition, all equally probable. You get a definition you didn’t need.
High signal: You are a senior engineer reviewing a junior developer's first PR. Explain REST in one plain-English sentence, then list the top two misconceptions you'd flag in a code review.
Genre, audience, length, and structure are all specified. The output distribution collapses around “senior-engineer code-review voice explaining something to a junior.”
The practice of deliberately constructing the context window — role, examples, instructions, and format constraints — to shift the distribution of model outputs toward the results you want.
Check your understanding
A vague prompt returns a generic answer. The most accurate explanation is:
Move 1 — Role prompting
The first high-leverage move: add a role prefix before any content. One sentence that tells the model what kind of person is speaking — or what kind of response this is — shifts the entire prior distribution for every token that follows.
The mechanism is the same token statistics you saw in the previous lesson: the training corpus contains millions of documents. Conversations that start with “You are a senior security engineer” are overwhelmingly written by or for security engineers. That vocabulary, those risk framings, that assumed knowledge — all of it becomes more probable as soon as the role tokens appear in context.
Role prefix in action
Without role: Summarize this legal contract clause.
Output: hedged, generic, likely recommends consulting a lawyer.
With role: You are a paralegal summarizing contract clauses for a non-lawyer client. Be direct: flag risk, explain jargon, skip the boilerplate. Clause: [...]
Output: risk-first, plain-language, actionable — because “paralegal writing for a non-lawyer” is a well-represented corpus genre.
The widget below shows how four different role framings shift the predicted output character for the same underlying question. Notice where two roles converge — that is where corpus coverage is thin and the role signal washes out.
Common misconception
More elaborate role descriptions produce better outputs.
What's actually true
A three-paragraph fictional persona with a name, backstory, and personality quirks usually performs worse than a two-sentence functional role. The model does not simulate a character — it pattern-matches to corpus genres. Functional roles (“senior security engineer,” “regulatory analyst”) have dense corpus representation; elaborate invented personas do not. Extra tokens can introduce contradictions the model must resolve, diluting the genre signal.
Check your understanding
Why is 'You are a distributed systems engineer who debugs Kafka consumer lag' more effective than 'You are an expert'?
Move 2 — Few-shot examples
If role prompting sets the prior, few-shot examples move the posterior directly. You place completed input → output pairs into the context window; the model reads the pattern and continues it.
The key insight from the GPT-3 paper [Language Models are Few-Shot Learners] : you do not need to fine-tune the weights. You can reshape model behavior at inference time by placing high-quality examples in the context. Each example is just more context tokens — and at every decoding step, the model attends to all of them.
Zero-shot vs. few-shot for classification
Zero-shot: Classify the sentiment of this tweet: "The queue took 45 minutes but the food made up for it." Label:
The model may output “Positive,” “Mixed,” “Neutral,” or even “Overall positive with a negative note” — any label it considers reasonable.
Few-shot:
Tweet: "Best meal I've had this year." Label: POS
Tweet: "Service was shockingly slow." Label: NEG
Tweet: "Arrived as expected." Label: NEU
Tweet: "The queue took 45 minutes but the food made up for it." Label:Now the label vocabulary is locked. The output distribution concentrates on POS, NEG, or NEU because those are the tokens that completed the pattern three times already in this exact context window.
The widget below lets you vary shot count from 0 to 4 and observe how format-lock behavior changes. Notice the cliff between 0 and 1 is almost always larger than between 2 and 4 — a single example carries enormous format signal.
What examples teach
Examples primarily teach format, not knowledge. The model already knows what sentiment is from pre-training. Your examples teach it what output shape you want. This is why even mislabeled examples can still improve format consistency — the label semantics matter less than the structural pattern.
Check your understanding
You add 4 few-shot examples to a classification prompt. What has primarily changed?
Move 3 — Chain-of-thought
For tasks requiring multi-step reasoning — math, logic, code debugging — asking the model to “think step by step” before the answer can dramatically improve accuracy. [Chain-of-Thought Prompting Elicits Reasoning in Large Language Models] This is chain-of-thought (CoT) prompting, and the mechanism connects directly to what you already know about next-token prediction.
When the model is forced to produce intermediate reasoning tokens before the answer token, those tokens become part of its context for the answer. It is literally reading its own scratch work.
Direct vs. chain-of-thought on a percent problem
Direct: A store marks up an item 30% from cost, then discounts it 20%. Is the final price above or below cost? Answer:
Common wrong output: “below cost” or “at cost.” The model jumps to a plausible-sounding conclusion.
Chain-of-thought: A store marks up an item 30% from cost, then discounts it 20%. Think step by step, then give the final answer.
Output: “Start at cost C. After 30% markup: 1.3C. After 20% discount: 1.3C × 0.8 = 1.04C. That is above cost.”
After generating 1.04C. That is, the token above is by far the most probable continuation — not because the model “checked its work” but because the intermediate tokens built context that made above the obvious next token.
The simplest CoT trigger is appending “Let’s think step by step.” to any prompt — this phrase alone was found to elicit reasoning steps without any examples. [Large Language Models as Zero-Shot Reasoners]
The widget below steps through a CoT trace token by token. You can see which tokens are “scratch work” and where a direct-answer completion would have diverged — that divergence point is the threshold concept.
When chain-of-thought fails
CoT fails in two situations:
-
Small models. Below roughly 100B parameters, adding CoT tokens can hurt accuracy — the model does not have the representations needed to produce useful intermediate steps, and wrong intermediate tokens mislead the final answer rather than constrain it.
-
When the reasoning chain contains an early error. A wrong step becomes high-confidence context for the next step, and the model reasons confidently to a wrong answer. Mitigation: self-consistency (sample multiple chains, majority-vote the final answer) or an explicit verification instruction (“Now check: is each step correct?”).
Common misconception
Chain-of-thought works because the model is thinking more carefully, like a person slowing down.
What's actually true
The model has no metacognition. CoT works because intermediate tokens are literal context. Generating “gap = 120 km” shifts the distribution over the next token from “anything after the problem statement” to “things that coherently follow a distance calculation.” It is mechanical, not reflective.
Check your understanding
Why does chain-of-thought prompting improve accuracy on multi-step problems?
Move 4 — Output format control
The final move requires no new mental model. You already know that context shapes the distribution. Format constraints are simply the most direct application: specify the exact shape of the output, and the set of valid completions collapses.
| Vague request | Format-controlled request | |
|---|---|---|
| Prompt | List the pros and cons of React vs. Vue. | Compare React and Vue on: bundle size, learning curve, ecosystem. Output as a markdown table. One row per dimension. Columns: React | Vue. |
| Output | Prose paragraphs — variable length, no schema. | Markdown table — scannable, parseable, predictable. |
| Downstream use | Requires human reading to extract structure. | Can be piped directly into a table renderer or diff tool. |
Three highest-leverage format instructions:
- Name the container. “JSON object,” “markdown table,” “numbered list,” “one sentence” — each maps to a distinct corpus genre with predictable structure.
- Name the fields explicitly.
Return JSON with keys: summary, risk_level, action_itemsis less ambiguous than “return a JSON summary.” The model pattern-matches to documents with those exact field names. - Set a length constraint. “In under 100 words” or “exactly 3 bullet points” tells the model which part of the completion-length distribution to sample from.
Requesting structured JSON output
Prompt:
Extract the entities from this sentence. Return JSON only — no prose, no markdown fences.
Schema: {"people": [...], "places": [...], "dates": [...]}
Sentence: "Alice and Bob met in Berlin on 14 March to finalize the treaty."Expected output:
{"people": ["Alice", "Bob"], "places": ["Berlin"], "dates": ["14 March"]}Without the explicit schema, the model might use different key names, wrap the JSON in a code block, or add an explanation paragraph. The schema locks the output structure.
Role and format instructions can conflict
If your role says “be conversational” and your format says “output only JSON,” the model faces a contradiction. Conversational registers do not produce bare JSON. Resolve the conflict explicitly: “Respond in JSON only — no conversational text, regardless of the conversational role above.”
Check your understanding
You ask the model to return JSON but it wraps the output in a markdown code block. The best fix is:
Composing the four moves
The four moves stack. A well-structured prompt has:
- Role — sets the genre and expertise register.
- Few-shot examples — demonstrates the transformation pattern.
- Chain-of-thought instruction (when multi-step reasoning is needed) — forces intermediate context.
- Format constraint — locks the output schema.
Not every prompt needs all four. A factual lookup needs none. A complex analytical pipeline benefits from all four.
A composed prompt combining all four moves
// Role (prior)
You are a senior security engineer reviewing Python code.
// Format constraint (output shape)
For each issue found, respond with exactly this JSON:
[{ "severity": "critical|high|medium", "line": number, "issue": string, "fix": string }]
No preamble. No explanation outside the JSON array.
// Few-shot example (pattern lock)
Example:
Input: password = request.get("pw")
Output: [{"severity": "critical", "line": 1,
"issue": "Unsanitised user input stored as password",
"fix": "Hash with bcrypt before storing"}]
// Chain-of-thought instruction (for complex code)
Before generating the JSON, think step by step about each line's security
implications. Then produce only the JSON array.
// Task
Review: [CODE_HERE] flowchart TD
A[Task] --> B{Multi-step reasoning?}
B -- Yes --> C[Add chain-of-thought]
B -- No --> D[Skip CoT]
C --> E{Consistent format needed?}
D --> E
E -- Yes --> F[Add format constraint]
E -- No --> G[Skip format constraint]
F --> H{Training data coverage thin?}
G --> H
H -- Yes --> I[Add role + few-shot examples]
H -- No --> J[Minimal prompt may suffice]
I --> K[Send prompt]
J --> KCheck your understandingQ 1 / 5
Which technique works by concentrating the probability distribution around vocabulary and reasoning patterns associated with a particular domain expertise?