Skip to content

Few-Shot and Chain-of-Thought Prompting

Prerequisites

Before this lesson you should be comfortable with:

  • Prompt anatomy — role, context, task, format, constraints (Lesson 1)
  • Basic LLM API calls — sending messages and reading responses
  • Python string formatting — f-strings and multiline strings

You do not need machine learning background. Few-shot and chain-of-thought are prompting techniques, not training methods.


What You'll Learn

Objective Time Difficulty
Contrast zero-shot, few-shot, and many-shot prompting 10 min Intermediate
Select and curate examples that teach the model your pattern 10 min Intermediate
Apply chain-of-thought (CoT) to reasoning and math tasks 10 min Intermediate
Combine few-shot + CoT and run a classification pipeline in Python 15 min Intermediate

Intuition First: Show, Don't Just Tell

Imagine onboarding a new analyst to classify customer support tickets. You could hand them a rulebook (zero-shot). Or you could sit beside them and walk through five real tickets: "Here's how I'd classify this one, and here's why."

The second approach — learning from examples — is what few-shot prompting does. You embed input-output pairs directly in the prompt. The model pattern-matches against them at inference time.

Chain-of-thought adds one more layer: you don't just show the answer, you show the reasoning path. "This ticket mentions a double charge and billing — that's Finance, High priority, escalate." The model learns both the label and the decision logic.

Together, these two techniques are among the highest-ROI changes you can make to a production prompt.


Zero-Shot vs Few-Shot Prompting

Zero-Shot: No Examples

You give the model a task with no examples. Works well for simple, well-defined tasks where the model already understands the domain.

from openai import OpenAI

client = OpenAI()

def classify_zero_shot(review: str) -> str:
    prompt = f"""Classify this customer review as Positive, Negative, or Neutral.

Review: "{review}"
Classification:"""

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

# classify_zero_shot("The product arrived on time but the packaging was damaged.")
# → "Neutral"

Few-Shot: Learning from Examples

You provide input-output pairs. The model learns the pattern and applies it to new inputs.

FEW_SHOT_TEMPLATE = """Classify each customer review as Positive, Negative, or Neutral.

Review: "Absolutely love this product! Best purchase ever."
Classification: Positive

Review: "Terrible quality. Broke after one day. Want a refund."
Classification: Negative

Review: "It's okay. Does what it says, nothing special."
Classification: Neutral

Review: "{review}"
Classification:"""

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

Few-shot is more reliable because the model sees your exact label definitions in action — including how you handle ambiguous cases.

How Many Examples?

Examples Name Best For
0 Zero-shot Simple tasks, clear instructions
1–3 Few-shot Most tasks, establishing format
5–10 Many-shot Complex classification, nuanced output
10+ Many-shot Specialized domains, precise formatting

Rule of thumb: Start with 3 diverse examples that cover edge cases. Add more only when eval shows specific failure patterns.


Few-Shot Best Practices

1. Choose Diverse Examples

# BAD: All examples are similar — model only sees positive
bad_examples = [
    ("Great product!", "Positive"),
    ("Love it!", "Positive"),
    ("Amazing!", "Positive"),
]

# GOOD: Cover the full range
good_examples = [
    ("Great product! Exceeded expectations.", "Positive"),
    ("Broken on arrival. Worst purchase.", "Negative"),
    ("It works. Nothing remarkable.", "Neutral"),
]

2. Match Your Target Distribution

If 60% of real inputs are negative, your examples should roughly reflect that. Skewed examples teach skewed behavior.

3. Include Edge Cases

edge_case_examples = [
    ("Best thing I ever bought!", "Positive"),
    ("Total waste of money.", "Negative"),
    ("Good product but overpriced.", "Neutral"),       # Mixed → Neutral
    ("Not bad at all, surprisingly.", "Positive"),     # Double negative → Positive
    ("I guess it's fine...", "Neutral"),               # Lukewarm → Neutral
]

Edge-case examples are how you encode your business definitions, not the model's default assumptions.


Chain-of-Thought (CoT) Prompting

Chain-of-thought prompting asks the model to show its reasoning step by step. This dramatically improves performance on logic, math, and multi-step reasoning.

Without CoT

no_cot = """
Q: A store has 15 red shirts and 8 blue shirts. They sell
3/5 of the red shirts and 1/4 of the blue shirts. How many
shirts remain in total?

A:"""
# Model might jump to a wrong answer without intermediate steps

With CoT

with_cot = """
Q: A store has 15 red shirts and 8 blue shirts. They sell
3/5 of the red shirts and 1/4 of the blue shirts. How many
shirts remain in total?

A: Let me work through this step by step.

Step 1: Calculate red shirts sold
- Started with 15 red shirts
- Sold 3/5 of them: 15 × 3/5 = 9 red shirts sold
- Red shirts remaining: 15 - 9 = 6

Step 2: Calculate blue shirts sold
- Started with 8 blue shirts
- Sold 1/4 of them: 8 × 1/4 = 2 blue shirts sold
- Blue shirts remaining: 8 - 2 = 6

Step 3: Total remaining
- 6 red + 6 blue = 12 shirts remaining

The answer is 12 shirts."""

The Magic Phrase

Simply adding "Let's think step by step" can significantly improve reasoning:

zero_shot_cot = """
Q: If it takes 5 machines 5 minutes to make 5 widgets,
how long would it take 100 machines to make 100 widgets?

Let's think step by step.
"""
# Without CoT, many models answer "100 minutes" (wrong!)
# With CoT: 5 minutes — each machine makes 1 widget in 5 minutes

Combining Few-Shot + CoT

The most powerful technique: show examples with reasoning chains.

TICKET_CLASSIFIER = """You are a customer support classifier. Classify tickets
and explain your reasoning.

Ticket: "I can't log in. I've tried resetting my password 3 times."
Reasoning: The customer is experiencing a login issue and has already
attempted self-service (password reset) multiple times. This indicates
a possible account lockout or system bug, not just a forgotten password.
Category: Technical - Account Access
Priority: High
Escalate: Yes (multiple failed self-service attempts)

Ticket: "When is your Black Friday sale?"
Reasoning: The customer is asking about an upcoming promotion. This is
a straightforward information request with no urgency.
Category: Sales - Inquiry
Priority: Low
Escalate: No

Ticket: "I was charged twice for my subscription this month."
Reasoning:"""

The model will follow the same structured reasoning pattern for the new ticket.


Runnable Example: Building a Few-Shot Classifier

from openai import OpenAI

client = OpenAI()

EXAMPLES = [
    ("Great product! Exceeded expectations.", "Positive"),
    ("Broken on arrival. Worst purchase.", "Negative"),
    ("It works. Nothing remarkable.", "Neutral"),
    ("Good quality but overpriced.", "Neutral"),
]

def build_few_shot_prompt(text: str, examples: list[tuple[str, str]]) -> str:
    lines = ["Classify sentiment as Positive, Negative, or Neutral.\n"]
    for input_text, label in examples:
        lines.append(f'Text: "{input_text}"')
        lines.append(f"Sentiment: {label}\n")
    lines.append(f'Text: "{text}"')
    lines.append("Sentiment:")
    return "\n".join(lines)

def classify(text: str) -> str:
    prompt = build_few_shot_prompt(text, EXAMPLES)
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        temperature=0,
    )
    return response.choices[0].message.content.strip()

# Quick eval loop
test_cases = [
    ("Absolutely love it!", "Positive"),
    ("Total waste of money", "Negative"),
    ("It's fine I guess", "Neutral"),
]

for text, expected in test_cases:
    result = classify(text)
    status = "✓" if expected.lower() in result.lower() else "✗"
    print(f"{status} Expected: {expected}, Got: {result}")

When to Use Each Technique

Is the task simple and well-defined?
  ├── Yes → Zero-shot (just clear instructions)
  └── No
        ├── Does it need specific output format?
        │     └── Yes → Few-shot (show format examples)
        └── Does it require reasoning/logic?
              ├── Yes → Chain-of-thought
              └── Both format + reasoning?
                    └── Few-shot + CoT (most powerful)

Production Connection

Few-shot and CoT patterns appear everywhere in production AI:

  • Version your example sets — examples are part of the prompt artifact. When you change examples, bump the version and re-run eval.
  • A/B test example selection — swapping 3 examples for 5 different ones can move accuracy ±10%. Test before deploying.
  • Eval loops — maintain a golden set of 20–50 inputs with expected outputs. Run it after every prompt change.
  • Failure recovery — if CoT output is correct but format is wrong, add a final instruction: "After reasoning, output ONLY the classification label on the last line."
  • Token budget — each example costs tokens. In high-volume APIs, 5 examples × 10K requests/day adds up. Measure accuracy vs. cost.

Example contamination

Never put production user data directly into few-shot examples without review. Use curated, anonymized examples stored in your prompt registry.


Edge Cases & Common Misconceptions

Misconception 1: More examples always help. Beyond 5–10 examples, returns diminish and token costs rise. Quality and diversity matter more than quantity.

Misconception 2: CoT is only for math. CoT improves any task requiring multi-step reasoning: legal analysis, code debugging, medical triage, financial calculations.

Misconception 3: You must show reasoning in production output. You can ask the model to reason internally and output only the final answer: "Think step by step, then respond with only the classification label."

Misconception 4: Few-shot examples must match input length. Short examples work fine for long inputs. What matters is that the pattern (format, labels, edge-case handling) is clear.


Key Takeaways

  • Zero-shot works for simple tasks; few-shot teaches the model your exact pattern and label definitions.
  • Choose 3 diverse examples covering all categories and at least one edge case.
  • Chain-of-thought dramatically improves reasoning — "Let's think step by step" is surprisingly effective.
  • Few-shot + CoT combined is the strongest pattern for complex classification and routing tasks.
  • Version example sets, A/B test changes, and run eval loops before deploying to production.
  • Control token cost by limiting example count and stripping reasoning from final output when not needed.
  • Match example distribution to real-world class distribution to avoid biased predictions.
  • Diagnose failures by checking whether the model misunderstood the task (zero-shot issue) or your definitions (few-shot issue).

Next Lesson

Lesson 3: System Prompts and Role Design — Learn how to design system prompts that control LLM behavior, personality, and output format across an entire conversation.