Few-Shot Prompting: Learning from Examples
Master few-shot prompting to teach LLMs new tasks through carefully selected examples, formatting patterns, and example ordering strategies.
What you'll learn
- ✓How few-shot learning works and why examples matter
- ✓How to select and order examples for best results
- ✓Formatting patterns that improve consistency
- ✓The difference between few-shot and zero-shot prompting
- ✓When to use few-shot vs fine-tuning
Prerequisites
- •Basic familiarity with LLM APIs
What Is Few-Shot Prompting
Few-shot prompting means including a handful of input-output examples in your prompt before the actual task. The model learns the pattern from these examples and applies it to the new input. No training, no fine-tuning, no gradient updates. Just examples in the prompt.
Extract the product name and price from the text.
Text: "The new AirPods Pro 2 are available for $249"
Product: AirPods Pro 2
Price: $249
Text: "Get the Samsung Galaxy S24 Ultra starting at $1,299.99"
Product: Samsung Galaxy S24 Ultra
Price: $1,299.99
Text: "Apple's M4 MacBook Air costs $1,099 for the base model"
Product:
Price:
The model sees two completed examples and understands exactly what to extract and how to format it. Without examples, it might return a full sentence, use different labels, or miss edge cases like the “$1,299.99” format.
Zero-Shot vs Few-Shot
Zero-shot: Instruction ──────────────────> New Input ──> Output
(model interprets what you want)
Few-shot: Instruction ──> Example 1 ──> Example 2 ──> New Input ──> Output
(model sees exactly what you want) Zero-shot prompting gives instructions but no examples. It works well for tasks the model already understands clearly: “Translate this to French,” “Summarize this article,” “Is this email spam?”
Few-shot prompting is better when:
- The output format is specific or unusual
- The task is ambiguous and examples remove ambiguity
- You need consistent formatting across many calls
- The model tends to deviate from your instructions
How Many Examples
Research consistently shows diminishing returns after 3-5 examples for most tasks. Here is a practical guide:
| Examples | When to use |
|---|---|
| 0 (zero-shot) | Simple, well-known tasks |
| 1-2 | Format demonstration |
| 3-5 | Complex extraction, classification with nuance |
| 5-10 | Highly specific output format, edge cases |
| 10+ | Rarely worth it; consider fine-tuning instead |
More examples mean more tokens, higher cost, and more latency. Each example should earn its place by teaching something new.
Selecting Good Examples
The quality of your examples matters far more than the quantity. Here are the principles.
Cover the variety of inputs. If your task handles different formats, include examples of each.
SENTIMENT_EXAMPLES = """Classify the sentiment as positive, negative, or neutral.
"This product changed my life! Best purchase ever!" -> positive
"Arrived broken. Returning immediately." -> negative
"It's a phone. It makes calls." -> neutral
"The camera is great but the battery is terrible." -> mixed-negative
"Just received it, haven't opened yet." -> neutral
"{new_text}" ->"""
Notice the examples cover enthusiastic positive, angry negative, flat neutral, mixed sentiment, and a non-opinion. Each example teaches the model something different about where the boundaries are.
Include edge cases. The model will encounter ambiguous inputs. Show it how to handle them.
DATE_EXTRACTION = """Extract the date from the text. If no specific date is mentioned, output "NONE".
"Meeting scheduled for March 15, 2025" -> 2025-03-15
"Let's meet next Tuesday" -> NONE
"The report from 12/31/2024 needs review" -> 2024-12-31
"We launched sometime in Q3 last year" -> NONE
"Due by Jan 1" -> NONE
"{text}" ->"""
The “next Tuesday” and “Q3 last year” examples explicitly teach the model that relative dates should be NONE, not guessed. Without these, the model would try to resolve them.
Match the difficulty of your actual inputs. If your production inputs are messy (typos, abbreviations, mixed languages), your examples should be messy too. Clean examples teach the model to expect clean input.
Example Ordering
The order of examples affects model output. Two rules of thumb:
- Put the most similar example last. Models pay more attention to examples closer to the actual input (recency bias).
- Vary the classes. If you are doing classification, do not put all positives first and all negatives last. Interleave them.
# Bad ordering: model may default to "negative"
examples = [
("Great product!", "positive"),
("Love it!", "positive"),
("Amazing quality", "positive"),
("Terrible service", "negative"),
("Broken on arrival", "negative"),
("Worst purchase ever", "negative"), # Last examples are all negative
]
# Good ordering: balanced, interleaved
examples = [
("Great product!", "positive"),
("Terrible service", "negative"),
("It works fine", "neutral"),
("Love the design!", "positive"),
("Broke after a week", "negative"),
("Average quality, fair price", "neutral"),
]
Formatting Patterns
How you format examples matters. The model replicates the exact format it sees.
Key-value format (good for extraction):
Input: "John Smith, age 34, lives in Boston"
Name: John Smith
Age: 34
City: Boston
Arrow format (good for classification):
"Great product!" -> positive
"Terrible quality" -> negative
JSON format (good for structured output):
Input: "The 2024 Tesla Model 3 starts at $38,990"
Output: {"product": "Tesla Model 3", "year": 2024, "price": 38990}
Markdown table (good for multi-field extraction):
| Text | Category | Priority |
|------|----------|----------|
| "Server is down" | incident | high |
| "Add dark mode" | feature | low |
Pick one format and use it consistently across all examples. Mixing formats confuses the model.
Few-Shot in Code
Here is a reusable pattern for few-shot prompting with the OpenAI API.
import openai
client = openai.OpenAI()
def few_shot_classify(
text: str,
examples: list[tuple[str, str]],
categories: list[str],
model: str = "gpt-4o-mini"
) -> str:
"""Classify text using few-shot examples."""
# Build the examples section
example_text = "\n".join(
f'"{inp}" -> {out}' for inp, out in examples
)
prompt = f"""Classify the text into one of these categories: {', '.join(categories)}
Respond with only the category name.
{example_text}
"{text}" ->"""
response = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
temperature=0,
max_tokens=20
)
return response.choices[0].message.content.strip()
# Usage
result = few_shot_classify(
text="The checkout page keeps crashing on mobile",
examples=[
("My payment was charged twice", "billing"),
("App crashes when I open settings", "bug"),
("Can you add Apple Pay support?", "feature_request"),
("Login page shows a 500 error", "bug"),
("I was charged the wrong amount", "billing"),
],
categories=["billing", "bug", "feature_request", "general"]
)
# result: "bug"
Dynamic Example Selection
In production, you often have a large pool of examples and want to select the most relevant ones for each input. This is called dynamic few-shot or retrieval-augmented few-shot.
from sentence_transformers import SentenceTransformer
import numpy as np
model = SentenceTransformer('all-MiniLM-L6-v2')
# Your example bank
example_bank = [
{"input": "Server returns 503 errors", "output": "infrastructure"},
{"input": "Button color should be blue", "output": "design"},
{"input": "Add export to PDF feature", "output": "feature_request"},
{"input": "Database connection timeout", "output": "infrastructure"},
{"input": "Fonts are too small on mobile", "output": "design"},
# ... hundreds more
]
# Pre-compute embeddings
bank_texts = [e["input"] for e in example_bank]
bank_embeddings = model.encode(bank_texts)
def select_examples(query: str, k: int = 3) -> list[dict]:
"""Select the k most similar examples to the query."""
query_embedding = model.encode([query])
similarities = np.dot(bank_embeddings, query_embedding.T).flatten()
top_k = np.argsort(similarities)[-k:][::-1]
return [example_bank[i] for i in top_k]
# For a new input, select relevant examples dynamically
new_input = "The API rate limiter is blocking valid requests"
relevant_examples = select_examples(new_input, k=3)
# Returns infrastructure-related examples, not design ones
This approach scales better than cramming all examples into every prompt and gives the model more relevant context.
Few-Shot vs Fine-Tuning
| Aspect | Few-shot | Fine-tuning |
|---|---|---|
| Setup time | Minutes | Hours to days |
| Cost per call | Higher (more tokens) | Lower (no examples in prompt) |
| Flexibility | Change examples anytime | Requires retraining |
| Data needed | 3-10 examples | 50-1,000+ examples |
| Best for | Prototyping, varied tasks | High-volume, single task |
Start with few-shot. If you are making thousands of identical calls per day and the few-shot prompt is expensive, switch to fine-tuning. Few-shot is your prototyping tool; fine-tuning is your optimization tool.
Key Takeaways
Few-shot prompting is the most reliable way to teach an LLM a new task without training. Select examples that cover the variety of your inputs, include edge cases, and match the messiness of real data. Order matters: interleave classes and put the most relevant example last. Use a consistent format. And when your example bank grows large, use embedding-based retrieval to select the best examples dynamically for each input.
Related articles
- Prompt Engineering Prompt Engineering: Few-shot vs Zero-shot
Decide between zero-shot and few-shot prompting by weighing example quality, cost, and how strictly you need to control output format.
- Prompt Engineering Prompt Evaluation: Measuring and Improving Quality
Learn how to measure prompt quality with evaluation datasets, scoring rubrics, A/B testing, and automated grading to iterate on prompts with evidence.
- Prompt Engineering Prompt Engineering for Code Generation
Learn prompt patterns for writing, reviewing, debugging, and refactoring code with LLMs, including practical templates and real examples.
- Prompt Engineering Multi-Turn Conversations: Context and Memory Patterns
Learn how to design multi-turn LLM conversations with effective context management, memory patterns, conversation state tracking, and production architectures.