Search Tech Journey

Find topics, journeys and posts

6-month learning plan116 / 130
back to blog
llmadvanced 50m read

S116 · Prompting — Zero-Shot, Few-Shot, Chain-of-Thought, ReAct

The four prompting patterns that actually move the needle — with the failure modes, decision rules, and Anthropic/OpenAI-recommended templates for each.

LLMsM14 · LLMs & Applications· Session 116 of 130 90 min

🎯 Pick the right prompting pattern (zero-shot / few-shot / CoT / ReAct) for a new task in under 30 seconds and template it correctly.

Why this session exists

"Prompt engineering" got laughed at in 2024 and quietly became mandatory in 2026. The gap between a bad prompt and a good prompt is often bigger than the gap between GPT-3.5 and GPT-4. This session teaches you the four canonical patterns that actually earn their weight in production (zero-shot, few-shot, chain-of-thought, ReAct), the empirical evidence for each, and the templates the frontier labs actually recommend.

You will be able to
  • Explain the difference between zero-shot, few-shot, CoT, and ReAct in one sentence each.
  • Pick the right pattern for a new problem — extraction / reasoning / tool use — in under 30 seconds.
  • Write a prompt with structured output, system prompt, and constraints that survives production drift.
  • Diagnose 'the model won't follow my format' bugs by category (missing role, temperature too high, ambiguous instructions).
  • Explain why CoT helps math + logic tasks but hurts extraction and can trigger safety issues.

Prerequisites

  • S112 · BERT/GPT/T5 — you need the decoder-only mental model to reason about in-context learning.
  • S113 · LLM Sampling — decoding parameters interact with every prompting pattern here.


(a) Intuition · 5 min

How you ask a very smart intern to do work
🌍 Real world

You hired an intern who is smart, has read the internet, but has no idea what your company does. You have four levers:

1. Just ask ("summarise this contract"). 2. Show 2–3 examples of the desired output. 3. Ask them to think out loud before answering. 4. Give them access to tools (a calculator, a search bar, a database) and tell them how to use each.

The trick is knowing which lever the task actually needs. Show-examples for a subjective classification. Think-out-loud for math. Give-tools for anything that requires external knowledge or precise computation.

💻 Code world

LLM prompting is exactly the same four levers with fancy names: zero-shot = just ask. Few-shot = show examples. Chain-of-thought = "let's think step by step". ReAct = tool use with an explicit Thought → Action → Observation loop.

Modern LLMs are trained to respond well to these patterns because their instruction-tuning datasets contain thousands of each. Reaching for the right one is a 30-second decision that often gets you an entire benchmark point.

The four patterns and their default use cases
  • Zero-shot — just ask. Works surprisingly well on frontier models for extraction, classification, summarisation. Try this FIRST always.
  • Few-shot (in-context learning) — 2–5 examples in the prompt. Best when the output format is unusual or the task is subjective (tone, style, taxonomy).
  • Chain-of-thought (CoT) — 'let's think step by step' or explicit reasoning trace. 20–40 point gains on multi-step math/logic. Zero help on extraction.
  • ReAct — Thought → Action → Observation loop with tools. The default pattern for LLM agents; every function-calling API is a variant of this.

The rise of the four patterns

  1. 2020
    GPT-3 + in-context learning
    Brown et al. show that a 175B decoder can 'learn' a new task from a few examples in the prompt. Kicks off prompt engineering as a discipline.
  2. 2022
    Chain-of-Thought · Wei et al.
    Adding 'let's think step by step' or example reasoning traces gives huge gains on GSM8K and BBH benchmarks.
  3. 2022
    ReAct · Yao et al.
    Combining Reasoning + Action traces enables LLMs to use tools coherently. Foundation for every 2024+ agent framework.
  4. 2023
    Self-consistency · Wang et al.
    Sample N CoT traces at T=0.7, majority-vote the final answers. Another 10-point gain on math tasks, at 5-20× cost.
  5. 2024
    Structured output APIs
    OpenAI JSON mode, Anthropic tool_use, Gemini function calling. Prompting becomes 'give a schema, get a schema-conforming answer'.
  6. 2025
    Reasoning models (o1, Claude thinking)
    CoT gets baked into the model. External CoT prompts become less necessary — but the mental model still applies.

(b) Visual walkthrough · 15 min

The decision tree

The four patterns side by side

Zero-shot

Just ask. Cheap. Try first.

  • 1 API call, no examples
  • Best for: extraction, classification, summarisation on well-known tasks
  • Fails on: unusual formats, niche domains, subjective judgments
  • Cost baseline
Few-shot

Show 2–5 examples in-context

  • 1 API call, longer prompt
  • Best for: unusual output formats, tone matching, custom taxonomies
  • Fails on: reasoning-heavy tasks (examples don't teach reasoning)
  • Cost 1.5–3× baseline
Chain-of-thought

Reason step by step first

  • 1 API call, longer generation
  • Best for: math, logic, planning, multi-hop reasoning
  • Fails on: extraction (overthinks), can be verbose
  • Cost 3–10× baseline
ReAct

Thought → Action → Observation loop

  • N API calls (one per step)
  • Best for: tool use, search, code exec, database queries
  • Fails on: purely-linguistic tasks (overkill)
  • Cost 5–50× baseline; latency multiplies

The anatomy of a well-structured prompt

What every good prompt has (Anthropic-style)

1. System prompt
Role, tone, top-level instructions. Persists across turns. 'You are a customer-support agent for Acme Inc. Answer only from the provided knowledge base.'
system
2. Task instruction
The concrete ask. Imperative mood, unambiguous. 'Classify each ticket into one of: BILLING, TECHNICAL, ACCOUNT.'
task
3. Input delimiter (XML tags recommended)
Wrap user input to make it visually and syntactically distinct. <ticket>...</ticket>. Anthropic recommends XML; OpenAI works fine with triple-backticks.
delim
4. Examples (if few-shot)
2–5 input/output pairs in the same format as the real request. Order matters — models weight recent examples slightly higher.
shots
5. Output format spec
Explicit schema. 'Respond with valid JSON matching {"category": string, "confidence": number}.' Combine with API JSON mode where available.
output
6. Reasoning cue (if CoT)
'First, think step by step inside <thinking> tags. Then give the final answer inside <answer> tags.' — makes the reasoning parseable/hideable.
reason

CoT visualised

For trivial arithmetic both get it right. Move to a 3-step word problem and CoT is often 30 points higher. Move to extraction ('what is the customer's name?') and CoT hurts because there's nothing to reason about.

The ReAct loop


Common misconception
✗ What most people think

"Chain-of-thought works because the model reasons step by step. So the reasoning text it produces is an explanation of how it got the answer."

✓ What is actually true

The generated reasoning is a computation substrate, not necessarily a faithful account. It helps because each emitted token is another forward pass conditioned on everything before — the model buys itself serial compute it otherwise could not have, and it puts intermediate results into the context where later steps can attend to them. But models demonstrably produce correct answers with unfaithful stated reasoning, and can be steered by cues they never mention.

Why the myth is so sticky

Because the output looks exactly like human reasoning, and we have no other prior for text of that shape. The stronger reason it sticks: it makes an accurate prediction — CoT does improve multi-step accuracy — so the mechanism story is never falsified in daily use. The falsification only shows up when you plant a biasing cue in the prompt and watch the model change its answer while its stated reasoning stays the same.

Prove it to yourself

A faithfulness probe you can run on any model:

# 1. Ask a multiple-choice question with CoT. Record answer + reasoning.
# 2. Re-ask identically, but add a biasing cue:
#      'I think the answer is (C), but check my work.'
# 3. Compare.
#
# If the answer moves toward (C) while the stated reasoning never
# mentions your suggestion, the reasoning is not the cause of the
# answer. Run over ~50 questions and report the flip rate.

The practical consequence: never treat a model's stated rationale as an audit trail. It is generated text subject to the same pressures as any other output.

From first principles
Start with the question

Why does "think step by step" improve accuracy at all? The model's weights do not change, and it already had the same information.

  1. 1
    A transformer applies a fixed number of layers per token. The compute available to produce one token is bounded and constant, regardless of how hard the question is.
    forced by · depth is fixed at architecture time; there is no loop
  2. 2
    So any problem requiring more sequential steps than the model has layers cannot be solved within a single token's forward pass.
    forced by · each layer can perform roughly one step of composition; you cannot fit k sequential steps into fewer than ~k layers
  3. 3
    But generation is autoregressive: every token emitted is appended to the context and the whole stack runs again. Emitting n tokens gives you n × depth sequential compute.
    forced by · the model re-reads its own output, so the context is a working memory that persists across passes
  4. 4
    Crucially, that working memory is written in tokens, so it must be explicit. An intermediate result the model does not write down is lost when the next forward pass begins — nothing else carries state between tokens except the KV cache of what was actually emitted.
    forced by · there is no hidden scratchpad; the context is the only state
  5. 5
    Therefore prompting for explicit intermediate steps converts a depth-bounded problem into a length-bounded one, and length is the cheap resource.
    forced by · you can always generate more tokens; you cannot add layers at inference
⇒ Therefore

Therefore CoT is a compute-allocation technique: it trades output tokens for serial depth. That reframing explains the whole family at once.

And note what this predicts: (1) CoT should help most on problems with genuine sequential structure — arithmetic, multi-hop lookup, constraint satisfaction — and help little or not at all on single-step recall or sentiment, which is exactly the observed pattern; (2) even meaningless filler tokens should provide some benefit if they buy passes, which has been observed; (3) the natural extension is to spend far more tokens deliberately at inference. That prediction is precisely what reasoning models do, and why they are priced per reasoning token.

Mental modelThe prompt is a program; tokens are the runtime

You are not persuading an agent. You are conditioning a distribution and allocating compute. The prompt sets the region of the distribution the model samples from; the tokens it generates are the only working memory it has, and each one buys another full pass through the network.

So a prompt has two independent jobs: constrain the space of acceptable outputs, and allocate enough tokens for the computation the task actually requires.

  • Show, do not describe. A single well-chosen example constrains format more precisely than a paragraph of instruction, because format is a pattern the model can copy.
  • Put the instruction where attention will reach it. Very long contexts show position sensitivity — the middle is the weakest place for a critical constraint.
  • Decompose rather than elaborate. Two calls with clear single jobs beat one call with a complicated prompt, because each call gets its own full compute budget and its own clean context.
  • A stated rationale is output, not explanation. Never use it as an audit trail or a safety control.
🔔 Fires when you see

Fire this model the moment you see: a prompt being made longer to fix a failure · a model getting arithmetic wrong · inconsistent output format · someone citing the model's explanation as evidence · a task that a human would need scratch paper for.

The tradeoff

Your zero-shot prompt is at 80% accuracy and you need 95%. Add few-shot examples, add chain-of-thought, or fine-tune?

Few-shot examples
+ you gain fastest reliable lever for format and style conformance; changeable in seconds; requires no training infrastructure and no labelled dataset beyond a handful of items
− you pay every example is paid for in input tokens on every single request forever, which at volume is a permanent tax; examples can bias the model toward their specific surface patterns; and it does little for tasks that fail on reasoning rather than format
pick when the failures are format, tone or convention errors, and request volume is low enough that the token overhead is acceptable
Chain-of-thought / decomposition
+ you gain the only lever that adds actual computation, so it is the one that fixes genuine multi-step reasoning failures; and the intermediate output is inspectable, which makes debugging far easier
− you pay output tokens are the expensive kind, and latency scales directly with them — a user-facing path may not have the budget; it also does not help, and can hurt, on tasks with no sequential structure
pick when errors are arithmetic, multi-hop, or constraint-violations, and you have the latency headroom
Fine-tuning
+ you gain moves behaviour into the weights, so the per-request prompt shrinks to almost nothing — lowest steady-state cost and latency at high volume, and it can teach genuinely new formats or domain conventions
− you pay needs hundreds to thousands of quality examples, a training and eval pipeline, and a versioning story; and it locks you to a base model, so upgrading means redoing the work
pick when volume is high and sustained, the task is stable, and prompt engineering has already plateaued — never as the first move
What a senior engineer actually does

Diagnose before you reach. Sample twenty failures and classify them: format errors want examples, reasoning errors want decomposition, knowledge gaps want retrieval, and only "the model understands but will not consistently comply" wants fine-tuning. Most teams fine-tune when they had a format problem, and most reach for a longer prompt when they had a compute problem.

The cost asymmetry also matters and is often ignored: few-shot tokens are paid on every request in perpetuity, while fine-tuning is paid once. At sustained volume the crossover arrives fast — but only after the prompt has stopped improving, because fine-tuning a task you have not yet specified precisely just bakes in your confusion.


(c) Hands-on · 25 min

Compare the four patterns on the same benchmark of math + extraction problems. This is the fastest way to build intuition for when each wins.

"""prompt_patterns.py — measure zero/few/CoT/ReAct on a small task set.
 
Requires: openai or anthropic sdk + API key. Change MODEL/CLIENT to match.
"""
from __future__ import annotations
import json
import os
import re
import time
from openai import OpenAI
 
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
MODEL = "gpt-4o-mini"     # cheap, fast, plenty smart enough for the demo
 
 
def ask(system: str, user: str, temperature: float = 0.0) -> str:
    r = client.chat.completions.create(
        model=MODEL,
        messages=[{"role": "system", "content": system},
                  {"role": "user",   "content": user}],
        temperature=temperature,
    )
    return r.choices[0].message.content.strip()
 
 
# ---------- The evaluation set: a math word problem + an extraction ----------
MATH_Q = (
    "Alice has 3 more apples than Bob. Bob has twice as many as Charlie. "
    "Together they have 33 apples. How many does Charlie have?"
)
MATH_A = "6"
 
EXTRACT_Q = (
    "Customer email: 'Hi, my name is Priya Sharma. My order #A-4821 arrived "
    "damaged. Please refund $89.99 to my card ending 4242. Thanks!'"
)
EXTRACT_SCHEMA = ("Extract as JSON: {name, order_id, amount, "
                  "issue_category (damage/late/wrong/other)}")
 
 
# ---------- 1. Zero-shot ----------
def zero_shot(q: str) -> str:
    return ask("You are a helpful assistant. Answer concisely.", q)
 
# ---------- 2. Few-shot ----------
FEW_SHOT_MATH = """Solve each problem. Give only the final integer answer.
 
Q: There are 5 pens. I buy 2 boxes of 4. How many pens total?
A: 13
 
Q: A train leaves at 3 and arrives at 7. How many hours?
A: 4
 
Q: {q}
A:"""
def few_shot(q: str) -> str:
    return ask("You are a helpful assistant.", FEW_SHOT_MATH.format(q=q))
 
# ---------- 3. Chain-of-thought ----------
COT = "Let's think step by step. Show your reasoning, then on the last line write 'ANSWER: <value>'."
def cot(q: str) -> str:
    out = ask("You are a helpful assistant.", f"{q}\n\n{COT}")
    m = re.search(r"ANSWER:\s*(.+)", out)
    return m.group(1).strip() if m else out.splitlines()[-1]
 
# ---------- 4. ReAct (tool-using) — mini implementation ----------
def get_apples(person: str) -> int:  # a fake 'database'
    return {"charlie": 6, "bob": 12, "alice": 15}.get(person.lower(), -1)
 
TOOLS_DESC = ("You have one tool: get_apples(person). "
              "Respond in the form:\n"
              "Thought: ...\nAction: get_apples('name')\n"
              "or\nThought: ...\nFinal Answer: <value>")
def react(q: str, max_steps: int = 5) -> str:
    convo = f"Question: {q}\n"
    for _ in range(max_steps):
        out = ask(TOOLS_DESC, convo)
        convo += out + "\n"
        if "Final Answer:" in out:
            return out.split("Final Answer:")[-1].strip()
        m = re.search(r"Action:\s*get_apples\(['\"]?(\w+)['\"]?\)", out)
        if m:
            obs = get_apples(m.group(1))
            convo += f"Observation: {obs}\n"
        else:
            break
    return "(no final answer)"
 
 
# ---------- Run all four on the MATH problem ----------
print(f"MATH problem: {MATH_Q}")
print(f"Correct answer: {MATH_A}\n")
for name, fn in [("zero_shot", zero_shot),
                 ("few_shot",  few_shot),
                 ("cot",       cot),
                 ("react",     react)]:
    t0 = time.time()
    ans = fn(MATH_Q)
    print(f"  {name:<10}{ans[:60]:<60}  ({time.time()-t0:.1f}s)")
 
# ---------- Run zero-shot vs few-shot on EXTRACTION ----------
print(f"\nEXTRACTION problem: {EXTRACT_Q}")
zs = ask("You are a data extractor. Respond with ONLY valid JSON.",
         f"{EXTRACT_Q}\n\n{EXTRACT_SCHEMA}")
print(f"  zero-shot JSON → {zs[:120]}")

What each block does

Anatomy of the four patterns

zero_shot
One API call with just the question. Baseline. Fastest and cheapest.
few_shot
Two solved examples in the prompt, then the real question. Model 'imitates' the format from the examples. Watch: temperature is 0 so imitation is deterministic.
cot
Adds 'let's think step by step' + a parseable ANSWER: marker. Generation is ~5× longer but math accuracy jumps.
3-10×
react
Manual loop: model emits Thought + Action; we execute the tool; feed Observation back; repeat. This is the pattern every agent framework (LangChain, LlamaIndex) wraps.
The parser (regex for 'ANSWER:' and 'Action:')
Fragile — production uses structured-output APIs or JSON mode. But the fragility teaches you why structured APIs exist.
parse
Try itDiscover self-consistency

Add:

from collections import Counter
def self_consistent(q: str, k: int = 5) -> str:
    answers = []
    for _ in range(k):
        out = ask("You are a helpful assistant.",
                  f"{q}\n\n{COT}", temperature=0.7)
        m = re.search(r"ANSWER:\s*(.+)", out)
        if m:
            answers.append(m.group(1).strip())
    return Counter(answers).most_common(1)[0][0]
 
print("self_consistent →", self_consistent(MATH_Q))

Run 5–10× and see how much more stable it is than single-shot CoT.

💡 Hint · Take the CoT function, set temperature=0.7, run it 5 times, and majority-vote the ANSWER lines. On tricky math problems this beats T=0 CoT by another ~5 points. This is 'self-consistency' from Wang et al. 2023.

(d) Production reality · 15 min

War story OpenAI · early GPT-3 users· 2022thousands of API customers
🔥 What broke

Early API users kept complaining that GPT-3 was 'bad at math'. Simple word problems it fluffed constantly. Papers on 'why LLMs can't reason' proliferated.

🧯 The fix

Wei et al. (Google) showed that adding 'Let's think step by step' or a few worked examples with reasoning steps produced 30+ point gains on GSM8K (grade-school math). The model could reason all along — it just needed permission to.

🎓 Lesson to steal
Never conclude an LLM 'can't do X' before trying CoT. Half the 'model is stupid' bug reports are missing-CoT bug reports.
Post-mortem
War story Anthropic · Claude support ticketsfrequent early-2024 pattern
🔥 What broke

Customers reported Claude 'refuses to follow the format' — asked for JSON, got prose. Asked for one word, got a paragraph.

🧯 The fix

Anthropic's official recommendation: use XML tags to delimit input/output sections, put the format spec at the end of the prompt (recency bias), and provide a partial 'assistant' turn that starts with the desired opening (e.g. pre-fill an opening brace for JSON output).

The pre-fill trick alone fixed 80% of format-compliance issues before official 'JSON mode' shipped.

🎓 Lesson to steal
Prompt structure matters more than prompt cleverness. XML tags + recency + assistant pre-fill = boring but bullet-proof.
Post-mortem
War story ReAct paper · Yao et al.· 2022baseline for every 2024 agent framework
🔥 What broke

Pre-ReAct, LLMs given tools would either hallucinate tool call arguments or forget to use tools at all. Naive prompting like 'you have a search tool, use it' failed.

🧯 The fix

ReAct: explicitly interleave Thought (reasoning about state) and Action (tool call) in the same generation, then feed the Observation back into the next generation. The Thoughts anchor the model in the plan, the Actions provide grounded facts, the Observations correct any drift.

Every agent framework since 2023 (LangChain, LlamaIndex, Autogen, CrewAI) is a ReAct variant. Function-calling APIs are ReAct with the parsing done by the platform.

🎓 Lesson to steal
Interleaving reasoning and action is the design pattern that makes agents work. Pure 'Action → Observation → Action' loops (no Thought) drift after ~5 steps.
Post-mortem

Where this shows up next

Prompting patterns underpin every LLM application
S117 · RAG Chunking
The retrieved chunks become part of a zero-shot prompt; format determines answer quality.
S118 · RAG Retrieval
Query rewriting is often a few-shot prompt over the raw user question.
S120 · LLM Agents
Every agent framework is a ReAct loop with function-calling APIs replacing regex parsing.
S121 · Multi-Agent Orchestration
Multi-agent = one ReAct loop coordinating multiple sub-loops. The patterns nest.
S122 · LLM Evaluation
LLM-as-judge is itself a prompting pattern: a zero-shot classification with a rubric.
S123 · Fine-tuning + LoRA
Fine-tuning is 'bake this prompting pattern into the weights so you can stop paying for it every call'.

(e) Recall + stretch · 10 min

Quick recall · click to reveal
★ = stretch question

Explain-out-loud test

  1. What is in-context learning and why doesn't BERT do it?
  2. When does CoT help, and when does it hurt?
  3. What is the ReAct loop and why does 'Thought' matter?

What comes next

Hub: The 6-Month Learning Plan


Part of a 130-session evergreen learning series. Session structure: intuition → visual → hands-on → production war stories → recall. Duration: 90 minutes.