In-Context Learning: Zero-Shot & Few-Shot
Introduction
Here is the superpower that makes prompting work at all: a foundation model can learn a new task from examples you put in the prompt — with no training, no fine-tuning, no data pipeline. Show it the pattern and it follows it, instantly, on the very next call.
This ability is called in-context learning (ICL), and zero-shot and few-shot prompting are its two everyday forms. They're the foundation everything else in this section builds on.
You'll learn:
- What in-context learning actually is (and why it works)
- Zero-shot prompting — and when it's enough
- Few-shot prompting — teaching by example
- A clear rule for choosing between them
- How to pick good examples (few-shot done right)
What Is In-Context Learning?
Recall from the foundations section: a model just predicts the next token given everything before it. In-context learning falls right out of that. When you place a task description — or a few worked examples — in the prompt, you bias those next-token predictions toward the pattern you've shown. The model adapts its behavior from the context, not from any change to its weights.
Three consequences matter:
- No training. The "learning" is temporary and per-request — it lives only in that one prompt's context window. Send a different prompt and it's gone.
- Instant. No data collection, no training run. Edit the prompt, get new behavior on the next call.
- It's why one model does thousands of tasks. The same model classifies, extracts, translates, and writes code — you just describe (or demonstrate) the task in context.
In-context learning is what made foundation models general-purpose tools instead of one-task-per-model systems. It was the headline result of the GPT-3 paper, "Language Models are Few-Shot Learners."
Zero-Shot — Just Ask
Zero-shot means you describe the task and provide zero examples — you just ask. Modern instruction-tuned models are remarkably good at this for common tasks.
from anthropic import Anthropic
client = Anthropic()
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=20,
messages=[{
"role": "user",
"content": "Classify the sentiment of this review as POSITIVE, NEGATIVE, or NEUTRAL.\n\n"
"Review: 'Shipping was slow, but the product is fantastic.'"
}],
)
print(resp.content[0].text)Zero-shot is your default: it's the cheapest, simplest thing that could work. Reach for it first for well-known tasks (summarize, classify into obvious buckets, translate, answer a question). You only escalate when zero-shot falls short.
Few-Shot — Teaching by Example
Few-shot means you include a handful of input → output examples (the "shots") before the real input. The model infers the pattern — the exact labels, the format, the tone — and applies it. This is the fix when zero-shot is almost right but won't behave precisely.
Suppose you need a custom label scheme and one-word, uppercase output, every time:
examples = (
"Review: 'Arrived broken and support ignored me.'\nLabel: ANGRY\n\n"
"Review: 'It works fine, nothing special.'\nLabel: MEH\n\n"
"Review: 'Absolutely obsessed, best purchase this year!'\nLabel: DELIGHTED\n\n"
)
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=10,
messages=[{
"role": "user",
"content": "Label each review using the same scheme as the examples. "
"Reply with only the label.\n\n"
+ examples
+ "Review: 'Shipping was slow, but the product is fantastic.'\nLabel:"
}],
)
print(resp.content[0].text) # -> DELIGHTEDNotice what the examples bought us: a custom taxonomy (ANGRY / MEH / DELIGHTED) the model had no way to guess zero-shot, plus a locked-in output format (one uppercase word). Few-shot is the everyday tool for shaping output, not just getting it.
Choosing: Zero-Shot vs Few-Shot
Start zero-shot; add shots only when you need to. A simple decision guide:
| Reach for… | When you need… |
|---|---|
| Zero-shot | A common task, a capable model, minimal prompt size & cost |
| Few-shot | A custom output format or schema; domain-specific labels the model can't guess; a specific tone/style; help with tricky edge cases; more consistency than zero-shot gives |
The tradeoff: few-shot improves reliability but adds input tokens (cost + latency) on every call, and bad examples can hurt. So use the fewest, best examples that get the job done — typically 2–5.
Few-Shot Done Right
Examples are instructions — treat them with care:
- Be representative & diverse. Cover the real range of inputs, including a tricky edge case, not three near-identical easy ones.
- Be perfectly consistent in format. The model copies your formatting exactly — stray punctuation or casing in your examples shows up in its output.
- Balance the labels. All-positive examples bias the model toward positive. Mix the classes.
- Keep it lean. 2–5 strong examples usually beat 15 mediocre ones — and cost far fewer tokens.
- Don't leak the answer. Make sure an example isn't accidentally identical to the real input.
And remember the bigger framing for any prompt: Role + Context + Task + Format — tell the model who it is, what it's working with, what to do, and exactly how to shape the output. Few-shot is the most reliable way to nail that last part.
Visualization

🧪 Try It Yourself
Zero-shot vs few-shot. Take a tricky classification (e.g. detecting sarcasm). Try it zero-shot, then add 2–3 examples including a sarcastic one. When did the examples actually help?
→ When the behavior was hard to describe but easy to show (format, tone, edge cases). If a clear instruction already nails it, the examples just waste tokens. Rule of thumb: show, don't tell — but only when telling isn't enough.

Common Pitfalls
- Inconsistent example formatting. The model mirrors your examples precisely — a typo or stray format in a shot becomes a bug in production.
- Biased examples. All-positive (or all-easy) examples skew predictions. Balance classes and include edge cases.
- Too many shots. Beyond ~5 you usually pay tokens for little gain — and risk "lost in the middle" on long prompts.
- Thinking few-shot = fine-tuning. It's per-request and temporary; it doesn't update the model. If you need the behavior baked in permanently and cheaply at scale, that's a fine-tuning question (later section).
- Skipping zero-shot. Don't add examples reflexively — try the cheap thing first and escalate only when it fails.
Key Takeaways
- In-context learning lets a model pick up a task from the prompt itself — no training, instant, temporary (it lives in the context window).
- Zero-shot = describe the task, no examples. It's your cheap, simple default.
- Few-shot = add 2–5 input→output examples to lock in custom labels, formats, tone, and edge-case handling.
- Choose zero-shot first; escalate to few-shot when you need precision or a custom scheme — at the cost of more input tokens.
- Good examples are representative, consistently formatted, balanced, and lean.
Next: we turn this into a repeatable craft with the anatomy of a great prompt.