Zero-shot vs few-shot vs one-shot prompting represents the most fundamental design choice you make before sending a single token to an LLM. The distinction isn’t academic — it directly determines your token budget, latency profile, and whether the model actually follows your instructions. Most teams default to few-shot without measuring whether the examples pay for themselves. This post breaks down the trade-offs so you can choose deliberately.
What each approach means
Zero-shot sends the task instruction alone. No examples, no demonstrations. The model relies entirely on its pre-training and the clarity of your prompt.
# Zero-shot classification
prompt = """Classify the sentiment of this review as positive, negative, or neutral.
Review: "The battery life is incredible but the screen scratches too easily."
Sentiment:"""
One-shot provides exactly one labeled example before the target input. It’s the minimal demonstration — enough to show format and style, not enough to teach patterns.
# One-shot classification
prompt = """Classify the sentiment of this review as positive, negative, or neutral.
Review: "Shipping was fast and the packaging was secure."
Sentiment: positive
Review: "The battery life is incredible but the screen scratches too easily."
Sentiment:"""
Few-shot includes multiple examples (typically 3–10, sometimes more). The goal is in-context learning: the model infers the task structure from the demonstration set.
# Few-shot classification
prompt = """Classify the sentiment of each review as positive, negative, or neutral.
Review: "Shipping was fast and the packaging was secure."
Sentiment: positive
Review: "App crashes every time I open settings."
Sentiment: negative
Review: "It works. Nothing special."
Sentiment: neutral
Review: "The battery life is incredible but the screen scratches too easily."
Sentiment:"""
Capabilities and task fit
Zero-shot works surprisingly well for tasks the model has seen extensively during pre-training: summarization, translation, code generation in popular languages, basic reasoning. It fails on idiosyncratic formats, domain-specific schemas, or tasks requiring style mimicry the model hasn’t internalized.
One-shot bridges a narrow gap. It excels when the task is familiar but the output format is non-standard — a specific JSON schema, a custom markup dialect, a particular citation style. The single example anchors the format without consuming significant context.
Few-shot shines on:
- Few-class classification with subtle boundaries (legal clause types, medical coding, support ticket routing)
- Structured extraction with nested schemas where the model needs to see how you handle optional fields, arrays, nulls
- Style transfer where “write like X” is too vague but three examples make it concrete
- Multi-step reasoning where the demonstration shows the decomposition pattern
The capability curve isn’t linear. Going from zero to one shot often yields a disproportionate jump for format-sensitive tasks. Going from three to five shots rarely helps unless the task has genuine variance the model needs to cover.
Price and cost model
Token economics are straightforward but frequently ignored. Every example you add costs input tokens on every request. At scale, this compounds.
| Approach | Typical input overhead | Cost per 1M requests (est.) |
|---|---|---|
| Zero-shot | 0–50 tokens | Baseline |
| One-shot | 50–200 tokens | +10–40% |
| Few-shot (5 ex) | 300–800 tokens | +60–160% |
These percentages assume a 500-token average request. If your requests are short (classification, extraction), the overhead dominates. If you’re sending 10k-token contexts (RAG, code review), the few-shot premium becomes negligible.
Output tokens don’t change across approaches — the model generates the same answer length regardless of how many examples you showed it. The cost delta is purely input-side.
If you’re routing through a gateway that meters per-token usage (n4n.ai surfaces this in response headers), you can measure the exact penalty per approach in production rather than estimating.
Latency and throughput
Input tokens increase prefill time linearly. On most providers, prefill scales with context length — more examples means longer time-to-first-token (TTFT). Decode time (generation) is unaffected.
Typical prefill latency on current hardware:
- 500 tokens: ~50–100ms
- 1,500 tokens: ~150–300ms
- 3,000 tokens: ~300–600ms
For latency-sensitive paths (chat, autocomplete, real-time classification), few-shot can push you past acceptable TTFT thresholds. One-shot is usually safe. Zero-shot is optimal.
Throughput (requests/second) drops proportionally because each request occupies the model longer during prefill. If you’re running your own inference, this translates directly to GPU hours. If you’re on a provider API, you hit rate limits faster.
Ergonomics and maintenance
Zero-shot prompts are trivial to version-control, diff, and review. Change the instruction, commit, deploy. No example curation needed.
One-shot requires maintaining one representative example. The risk: that example becomes a crutch. If it contains a subtle bias or edge case, the model overfits to it. Rotate the example periodically or parameterize it.
Few-shot introduces real maintenance burden:
- Example drift: As the model updates, examples that worked may become counterproductive
- Coverage gaps: You need examples spanning the input distribution — rare classes, adversarial inputs, format variations
- Order sensitivity: Example order affects output. Randomize or fix deterministically, but don’t ignore it
- Context pressure: Examples compete with RAG context, conversation history, or system prompts
A practical pattern: store few-shot examples in a separate JSON/CSV file, load at runtime, and version them independently from the prompt template. This lets you A/B example sets without redeploying code.
// examples/sentiment.json
{
"task": "sentiment_classification",
"examples": [
{"input": "Shipping was fast and the packaging was secure.", "output": "positive"},
{"input": "App crashes every time I open settings.", "output": "negative"},
{"input": "It works. Nothing special.", "output": "neutral"},
{"input": "Great features but terrible documentation.", "output": "mixed"}
]
}
Ecosystem and tooling support
Most prompt engineering frameworks (LangChain, LlamaIndex, DSPy, Mirascope) treat few-shot as a first-class primitive. They provide:
- Example selectors (similarity-based, diversity-based, MMR)
- Dynamic example assembly per request
- Optimization loops that tune example sets
Zero-shot and one-shot are just special cases of the same APIs with k=0 or k=1.
Evaluation tooling matters more for few-shot. You need to measure whether each example improves or degrades performance on a held-out set. DSPy’s BootstrapFewShot and MIPRO optimizers automate this, but they require a metric and a dev set — infrastructure many teams don’t have yet.
Provider-specific features: some models (Claude, GPT-4) handle long few-shot contexts gracefully. Others degrade noticeably past 2–3 examples. Test on your target model, not a proxy.
Limits and failure modes
Zero-shot fails when:
- The task requires a format the model hasn’t memorized (custom DSL, proprietary schema)
- Instructions are ambiguous and examples would disambiguate
- The domain uses terminology the model interprets differently (legal, medical, financial)
One-shot fails when:
- The single example misrepresents the distribution (e.g., only shows simple cases)
- The task has high variance that one example can’t cover
- The example introduces a spurious pattern the model latches onto
Few-shot fails when:
- Examples exceed the model’s effective in-context learning capacity (varies by model, typically 10–50 for current SOTA)
- Examples contain contradictions or noise
- The demonstration set leaks label information the model shouldn’t use (e.g., examples that inadvertently encode the answer key)
- Context window pressure forces truncation of actual input (RAG chunks, conversation history)
A subtle failure mode: few-shot can hurt performance on tasks the model already knows well. The examples may constrain the model’s natural reasoning or introduce interference. Always benchmark zero-shot as a baseline.
Comparison table
| Dimension | Zero-shot | One-shot | Few-shot (3–10) |
|---|---|---|---|
| Best for | Familiar tasks, standard formats, latency-critical paths | Format anchoring, style hints, minimal overhead | Subtle classifications, complex schemas, style transfer |
| Input token overhead | None | Low (50–200) | Medium-high (300–1,500+) |
| TTFT impact | Baseline | +10–50ms | +50–300ms |
| Maintenance burden | Near zero | Low (1 example) | High (curate, version, evaluate) |
| Format control | Weak | Strong | Strongest |
| Domain adaptation | Poor | Moderate | Good |
| Risk of overfitting | None | Low | Moderate (example bias) |
| Context pressure | None | Minimal | Significant |
| Evaluation complexity | Trivial | Simple | Requires dev set + metric |
| Typical quality ceiling | Model’s pre-training | Model + format | Model + task pattern |
Which to choose — verdict by use case
Start with zero-shot. Always.
It’s the baseline. Measure quality on a representative eval set. If it meets your threshold, stop. You’ve saved tokens, latency, and maintenance.
Switch to one-shot when:
- Zero-shot produces valid content but wrong format (JSON schema, XML tags, specific delimiters)
- The task is familiar but the model consistently misses a style cue (tone, verbosity, citation style)
- You need a single formatting anchor and can’t afford few-shot latency
Pick the most representative example — not the cleanest, not the shortest. The example should look like your median production input.
Invest in few-shot when:
- Zero-shot and one-shot both fail on a held-out eval set
- The task has genuine ambiguity that examples resolve (boundary cases, multi-label, hierarchical categories)
- You have (or can build) an evaluation pipeline to maintain example quality over time
- The token/latency budget absorbs the overhead — typically batch workloads, async pipelines, or high-value predictions where accuracy justifies cost
Hybrid patterns that work in production
Dynamic few-shot: Retrieve k nearest neighbors from a labeled dataset at request time. This keeps examples relevant to the specific input and avoids static example rot. Requires a vector index over your labeled data and a selector (cosine similarity, MMR, or a learned ranker).
# Pseudocode for dynamic few-shot
def build_prompt(query, k=3):
examples = vector_store.search(query, k=k)
prompt = template.render(examples=examples, query=query)
return prompt
Progressive disclosure: Start zero-shot. If the model’s confidence (logprobs) or a lightweight classifier flags low confidence, retry with one-shot, then few-shot. This keeps the happy path fast and only pays the example tax on hard cases.
Schema-as-example: For structured output, use a JSON Schema as the one-shot example rather than a concrete instance. Some models (GPT-4, Claude 3.5) follow schemas reliably without concrete demonstrations.
# One-shot with schema instead of instance
prompt = """Extract entities as JSON matching this schema:
{
"type": "object",
"properties": {
"entities": {"type": "array", "items": {"type": "string"}},
"relations": {"type": "array", "items": {"type": "object", "properties": {"head": {"type": "string"}, "relation": {"type": "string"}, "tail": {"type": "string"}}}}
}
}
Text: "Acme Corp acquired Beta Inc for $2M."
JSON:"""
Decision checklist
- Run zero-shot on your eval set. Record accuracy, format compliance, latency, cost.
- If format fails → one-shot. Test one representative example. Re-measure.
- If accuracy fails on ambiguous cases → few-shot. Build a dev set. Curate 5–8 diverse examples. Evaluate.
- If few-shot helps but context is tight → dynamic few-shot. Index your labeled data, retrieve per request.
- If few-shot helps but maintenance is painful → distill. Fine-tune a smaller model on the few-shot outputs, or use the examples to generate synthetic training data for a classifier head.
The zero-shot vs few-shot vs one-shot decision isn’t a one-time choice. It’s a knob you turn per task, per model, per latency budget. Treat it like any other hyperparameter: measure, iterate, and automate the evaluation so you know when the model updates shift the optimum.