Module 2: Zero-Shot and Few-Shot Prompting

1. Introduction: The Two Fundamental Techniques

Capsule overview

Zero-shot and few-shot prompting are the foundation of all prompt engineering. Without understanding when to use each technique, you waste tokens (few-shot when zero-shot is enough) or you get inconsistent results (zero-shot when few-shot is necessary). Most real-world tasks are solved with one of these two techniques — mastering them lets you correctly judge whether you need something more complex like Chain-of-Thought or ReAct.

Zero-shot means giving the model an instruction with no examples. The model infers the task from the description alone, leaning on its pre-trained knowledge. Few-shot means including 2-10 input→output examples that show the desired pattern. The model learns by analogy, not by updating parameters (that would be fine-tuning). Both techniques are complementary: zero-shot is cheaper and faster; few-shot is more accurate for tasks with specific formats or niche domains.

Why it matters: This module gives you the decision framework and the concrete patterns for both techniques. The Few-Shot Classification System you build in capsule 08 is reusable: you can take it to your real projects with your own categories and example bank.


Zero-Shot: Definition, Use Cases and Limitations

What zero-shot is

The model receives only the instruction and the input. There are no prior examples. The model uses its pre-trained knowledge to infer what to do with that instruction.

from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()
client = OpenAI()

# Pure zero-shot: instruction + input, not a single example
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {
            "role": "system",
            "content": "Classify the sentiment as POSITIVE, NEGATIVE or NEUTRAL. Answer with the category only."
        },
        {
            "role": "user",
            "content": "The product arrived on time and exceeded my expectations."
        }
    ],
    temperature=0,
    max_tokens=10
)
print(response.choices[0].message.content)
# Output: POSITIVE

Why zero-shot works

LLMs were trained on massive corpora where sentiment classification, translation, summarization and entity extraction appear thousands of times. When you say "classify the sentiment", the model has already internalized the concept. Zero-shot taps that pre-trained knowledge directly, with no need for examples.

Analogy: It's like asking a senior programmer "Write a function that reverses a list in Python." You don't need to give them examples of how to reverse lists — they already know. Zero-shot works the same way for tasks the model already knows well.

When zero-shot is enough

  • Common tasks: Translation, summarization, sentiment classification, entity extraction — the model knows them well from pre-training
  • Standard formats: You don't need examples for "return JSON" or "give me a bulleted list"
  • General domains: News, product reviews, generic business text
  • Cost and latency critical: Every example adds tokens; zero-shot minimizes both
  • Fast prototyping: Validate the concept before investing in curating examples

When zero-shot fails

  • The output has a very specific format the model doesn't know (e.g. your company's internal JSON schema)
  • The categories are internal jargon or from a highly specialized domain
  • There's ambiguity in the task that only examples can resolve
  • You need extreme consistency across calls to parse programmatically
  • The task requires following a very particular output pattern

Few-Shot: Definition, Use Cases and Limitations

What few-shot is

You include 2-10 examples in the form input → desired output. The model infers the pattern and applies it to the new input. "Few" means few — and few is enough, because LLMs are excellent at pattern recognition.

Important difference vs fine-tuning: Few-shot provides examples in the prompt. Fine-tuning updates the model's weights. Few-shot is faster, more flexible and reversible. Fine-tuning is more expensive and permanent. For most production tasks, few-shot is enough.

from openai import OpenAI

client = OpenAI()

# Few-shot: 3 examples before the real task
FEW_SHOT_TEMPLATE = """
Classify the type of customer query.
Categories: BILLING, TECHNICAL, ACCOUNT, OTHER.

Example 1:
Query: "I haven't been able to log in since yesterday"
Type: TECHNICAL

Example 2:
Query: "Can I change my billing plan?"
Type: BILLING

Example 3:
Query: "I want to cancel my subscription"
Type: ACCOUNT

Now classify:
Query: {query}
Type:"""

def classify_few_shot(query: str) -> str:
    prompt = FEW_SHOT_TEMPLATE.format(query=query)
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        temperature=0,
        max_tokens=15
    )
    return response.choices[0].message.content.strip()

# Test
queries = [
    "My March invoice has an incorrect charge",
    "The app won't load images",
    "I want to update my password"
]

for c in queries:
    print(f"{c}: {classify_few_shot(c)}")

Output:

My March invoice has an incorrect charge: BILLING
The app won't load images: TECHNICAL
I want to update my password: ACCOUNT

Why examples work

LLMs are excellent at in-context pattern recognition. Seeing 3 input → output pairs, the model infers: "Given this pattern, the next output must follow the same structure." Examples:

  1. Anchor the format: If the examples return one word, the model returns one word
  2. Reduce ambiguity: "TECHNICAL vs ACCOUNT" becomes clear when you see examples of each
  3. Define the domain: Examples of internal categories teach the model your specific jargon

When few-shot is necessary

  • Custom formats: Your output has a specific structure the model doesn't know by default
  • Niche domains: Internal categories, business jargon, your company's edge cases
  • Critical consistency: Examples anchor the format and reduce variability across calls
  • Ambiguous tasks: "Classify" without examples can produce inconsistent formats ("POSITIVE", "Positive", "positive")
  • Required accuracy > 90%: In specialized domains, few-shot can add +10-20% accuracy over zero-shot

When few-shot can backfire

  • The examples don't cover edge cases → the model extrapolates badly
  • The examples have selection bias → the model only classifies into the categories it saw
  • Too many examples of one category → bias toward that category
  • The examples are inconsistent → the model learns the wrong pattern

Side-by-Side Comparison

from openai import OpenAI
import time

client = OpenAI()

# Task: classify tickets with 12 internal categories
CATEGORIES = [
    "ACCESS", "INVOICE", "PERFORMANCE", "ERROR", "INTEGRATION",
    "CONFIGURATION", "DATA", "MIGRATION", "SECURITY",
    "TRAINING", "ESCALATION", "OTHER"
]

# Zero-shot: describes the categories but gives no examples
def classify_zero_shot(ticket: str) -> str:
    cats = ", ".join(CATEGORIES)
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {
                "role": "system",
                "content": f"Classify into ONE category: {cats}. The category only, nothing else."
            },
            {"role": "user", "content": ticket}
        ],
        temperature=0,
        max_tokens=15
    )
    return response.choices[0].message.content.strip()

# Few-shot: 5 representative examples
EXAMPLES = [
    ("I can't get into the system since 9am", "ACCESS"),
    ("The platform takes 30 seconds to load", "PERFORMANCE"),
    ("I need to connect our CRM to the API", "INTEGRATION"),
    ("Error 500 when I save a record", "ERROR"),
    ("How do I export the data to Excel?", "DATA"),
]

def classify_few_shot_v2(ticket: str) -> str:
    cats = ", ".join(CATEGORIES)
    examples_text = "\n".join([
        f"Ticket: {t}\nCategory: {c}"
        for t, c in EXAMPLES
    ])
    prompt = f"""Classify support tickets into: {cats}.

Examples:
{examples_text}

Ticket: {ticket}
Category:"""
    
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        temperature=0,
        max_tokens=15
    )
    return response.choices[0].message.content.strip()

# Comparative benchmark
test_tickets = [
    ("My password expired and I can't reset it", "ACCESS"),
    ("Last month's invoice has a double charge", "INVOICE"),
    ("We need to migrate data from the old system", "MIGRATION"),
    ("Error generating compliance reports", "ERROR"),
    ("Do you have SOC 2 certification?", "SECURITY"),
]

print(f"{'Ticket':<45} {'Ground Truth':<14} {'Zero-shot':<14} {'Few-shot':<14} {'Match'}")
print("-" * 100)

zs_correct = 0
fs_correct = 0
for ticket, ground_truth in test_tickets:
    zs = classify_zero_shot(ticket)
    fs = classify_few_shot_v2(ticket)
    
    zs_ok = "✅" if zs == ground_truth else "❌"
    fs_ok = "✅" if fs == ground_truth else "❌"
    
    zs_correct += (zs == ground_truth)
    fs_correct += (fs == ground_truth)
    
    print(f"{ticket[:44]:<45} {ground_truth:<14} {zs:<14} {fs:<14} {zs_ok}/{fs_ok}")

print(f"\nAccuracy: Zero-shot={zs_correct/len(test_tickets):.0%}, Few-shot={fs_correct/len(test_tickets):.0%}")

Typical output:

Ticket                                         Ground Truth   Zero-shot      Few-shot       Match
----------------------------------------------------------------------------------------------------
My password expired and I can't reset it      ACCESS         ACCESS         ACCESS         ✅/✅
Last month's invoice has a double charge      INVOICE        INVOICE        INVOICE        ✅/✅
We need to migrate data from the old system   MIGRATION      DATA           MIGRATION      ❌/✅
Error generating compliance reports           ERROR          ERROR          ERROR          ✅/✅
Do you have SOC 2 certification?              SECURITY       CONFIGURATION  SECURITY       ❌/✅

Accuracy: Zero-shot=60%, Few-shot=100%

In this case, the specialized-domain categories (MIGRATION vs DATA, SECURITY vs CONFIGURATION) are ambiguous for zero-shot but get resolved with examples.


The Technique Continuum

Zero-shot and few-shot are part of a continuum of techniques with different trade-offs:

Zero-Shot           Few-Shot        Chain-of-Thought      ReAct
    │                   │                  │                │
No examples        2-10 examples      Step-by-step      Reasoning
No reasoning       No reasoning        reasoning         + Action
                                                          (tools)

Cost:     Low           Medium             High          Very high
Setup:    None          Examples          Moderate          High
Latency:  Low           Medium             High          Very high

Use when:
- Standard tasks    - Niche domain     - Math/logic      - Tool use
- Simple formats    - Custom format    - Reasoning       - External data
- Cost critical     - Consistency      - Step-by-step    - Verification

Escalation rule: Start with zero-shot. If it fails, move up to few-shot. If it still fails on reasoning, use CoT (Module 4). Save ReAct (Module 5) for when you need external tools.


Quantitative Trade-offs

DimensionZero-ShotFew-Shot (5 examples)
Input tokens50-200300-800
Relative cost1x3-6x more tokens
Latency~0.3s~0.5s
Accuracy (general domain)80-90%85-95%
Accuracy (niche domain)50-70%75-90%
Format consistencyMediumHigh
MaintenanceLowMedium (curating examples)

Cost implication: With gpt-4o-mini at $0.15/1M input tokens, a 100-token zero-shot prompt vs a 500-token few-shot prompt = $0.000015 vs $0.000075 per call. At 10,000 calls/day: $0.05 vs $0.25/day. The difference is real but small on gpt-4o-mini; with gpt-4o it multiplies ~20x.


Module 2 Roadmap

#CapsuleWhat you'll see
01Introduction (this one)Zero-shot vs few-shot: definitions, when to use each, the continuum
02Zero-shot patternsDirect instructions, role-playing, format specification, constraint-based
03Few-shot: choosing examplesHow many to use, diversity, order, positives/negatives
04Example engineeringSynthetic examples, dynamic few-shot, K-nearest similarity
05Output formatting and parsingJSON, XML, consistency, regex extraction, handling malformed output
06Boundary testingAdversarial inputs, null, context overflow, defensive prompting
07Decision frameworkZero-shot vs few-shot: comparison table with metrics and benchmarks
08Project: Few-Shot Classification SystemConfigurable system with example bank and quantitative evaluation

Estimated duration: 1.25-1.5 hrs for the full module.


Connection to the Project

In the Few-Shot Classification System (capsule 08) you'll build:

  • A configurable classification system with N categories defined by you
  • An example bank with dynamic selection by similarity to the input (dynamic few-shot)
  • A quantitative zero-shot vs few-shot comparison: accuracy, latency, cost per call
  • Support for multiple domains (support tickets, sentiment, purchase intent)

The concepts in this capsule — when each technique is enough — are the basis of the project's decision engine. When the system receives a new domain, it automatically evaluates which technique is more effective.


What This Module Does NOT Cover

  • Chain-of-Thought: Step-by-step reasoning for logic/math tasks (Module 4)
  • ReAct: Combining reasoning with the use of external tools like APIs or search engines (Module 5)
  • Fine-tuning: Updating the model's weights with your data (requires different infrastructure, far more expensive)
  • Retrieval-Augmented Generation: Searching a database to add context (Advanced RAG guide, #8)
  • Prompt chaining: Chaining multiple prompts into a pipeline (Module 6)

Evidence of Success

By the end of this module you should be able to:

  • Explain the difference between zero-shot and few-shot in 2 sentences
  • Given a use case, decide which technique to use and justify it with quantitative criteria
  • Implement the 4 zero-shot patterns (direct instructions, role-playing, format spec, constraint-based)
  • Select and order examples for effective few-shot
  • Build a Few-Shot Classification System with an example bank and comparative evaluation

First Experiment: Measure the Impact in 10 Lines

Before moving on, run this snippet to see the difference in action:

from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()
client = OpenAI()

# Task: classify whether a text is about personal finance or investing
text = "I opened a fixed-term deposit at 8% a year to cover the mortgage payment."

# Zero-shot
r_zs = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "system", "content": "Classify into: SAVINGS, INVESTMENT, DEBT, EXPENSE. The category only."},
        {"role": "user", "content": text}
    ],
    temperature=0, max_tokens=10
)

# Few-shot (with 2 examples to guide the pattern)
r_fs = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": f"""
Classify into: SAVINGS, INVESTMENT, DEBT, EXPENSE. The category only.

Examples:
"I bought S&P 500 ETFs" → INVESTMENT
"I paid the minimum on my credit card" → DEBT

Text: {text}
Category:"""}],
    temperature=0, max_tokens=10
)

print(f"Zero-shot: {r_zs.choices[0].message.content}")
print(f"Few-shot:  {r_fs.choices[0].message.content}")
print(f"Tokens ZS: {r_zs.usage.total_tokens} | Tokens FS: {r_fs.usage.total_tokens}")
# Notice: the correct classification is SAVINGS (fixed-term deposit) + DEBT (mortgage)
# Which technique handles it better?

This experiment immediately reveals the trade-off: few-shot uses more tokens but can be more accurate on custom categories. In the coming capsules you'll learn exactly when that difference matters.


Summary

In this capsule you learned:

  • Zero-shot: Instruction + input, no examples. Works for common tasks and standard formats. Cheaper in tokens
  • Few-shot: 2-10 input→output examples. Necessary for custom formats, niche domains, critical consistency
  • The central trade-off: Zero-shot = fewer tokens, faster. Few-shot = more accurate, more consistent, more expensive
  • The continuum: Zero-shot → Few-shot → Chain-of-Thought → ReAct. Start simple, move up as needed
  • Escalation rule: Every technique has an added cost; move up only when the benefit justifies it

Next capsule: The 4 zero-shot patterns with runnable code — direct instructions, role-playing, format specification and constraint-based prompting.


Additional resources

  1. Language Models are Few-Shot Learners (Brown et al., 2020) — The original GPT-3 paper that introduced few-shot prompting as a discipline; the theoretical basis of this module
  2. OpenAI Prompt Engineering Guide — OpenAI's official strategies for both techniques, with examples of concrete tactics
  3. Anthropic: Use Examples (Few-Shot) — Claude's guide on when and how to use few-shot effectively
  4. Prompt Engineering Guide (DAIR.AI) — Few-Shot — Technical comparison with accuracy benchmarks across different tasks
  5. Learn Prompting: Zero-Shot & Few-Shot — Introductory resources with examples across multiple domains