# Rewrite Weak Prompts with Zero-Shot, Few-Shot, and Chain-of-Thought

> Source: <https://sourcefeed.dev/a/rewrite-weak-prompts-with-zero-shot-few-shot-and-chain-of-thought>
> Published: 2026-09-09 11:38:54+00:00

# Rewrite Weak Prompts with Zero-Shot, Few-Shot, and Chain-of-Thought

Turn one vague prompt into a stable, parseable classifier using three prompting patterns, in runnable Python.

[Priya Nair](https://sourcefeed.dev/u/priya_nair)

## What you'll build

A single Python script that takes one vague, unreliable prompt and rewrites it three ways: zero-shot with explicit instructions, few-shot with examples, and chain-of-thought with visible reasoning. You'll run all four against the same ambiguous support ticket and watch the output go from chatty prose to a stable, parseable label.

## Prerequisites

- [Python](https://www.python.org/) 3.10 or newer (`python3 --version` ). The Anthropic SDK requires 3.10+.
- An Anthropic API key from the [Claude Console](https://platform.claude.com/settings/keys) , with a few cents of credit on the account.
- Verified against the [`anthropic`](https://pypi.org/project/anthropic/) Python SDK 1.4.0 and model`claude-opus-5` on macOS; Linux is identical, and on Windows use`.venv\Scripts\activate` instead of`source` .

## 1. Set up the project

```
mkdir prompt-patterns && cd prompt-patterns
python3 -m venv .venv && source .venv/bin/activate
pip install anthropic
export ANTHROPIC_API_KEY="your-api-key-here"
```

The SDK reads `ANTHROPIC_API_KEY` from the environment, so the code never touches the key directly.

## 2. Start with the weak prompt

Create `prompts.py`. The task: route support tickets into one of four categories. The test ticket is deliberately ambiguous, since it's half billing complaint and half how-to question.

``` python
import anthropic

client = anthropic.Anthropic()

TICKET = "I got charged twice this month. Also, how do I export my invoices to CSV?"

def ask(prompt: str) -> str:
    response = client.messages.create(
        model="claude-opus-5",
        max_tokens=1024,
        messages=[{"role": "user", "content": prompt}],
    )
    return "".join(b.text for b in response.content if b.type == "text").strip()

weak = f"Categorize this support ticket: {TICKET}"
```

The weak prompt names no categories, no output format, and no tie-breaking rule, so the model invents all three, differently on every run. That's the failure you're about to fix.

## 3. Zero-shot: state the task completely

Zero-shot means no examples, only instructions. It works when the instructions leave nothing to guess: allowed labels, a tie-breaking rule for the ambiguous case, and the exact output shape. The `<ticket>` tags separate untrusted input from your instructions, which Anthropic's docs recommend for any prompt that mixes the two. Append to `prompts.py`:

```
RULES = """You route support tickets. Classify the ticket into exactly one
category: BILLING, BUG, HOW_TO, or FEATURE_REQUEST.
If a ticket fits two categories, pick the one where the customer loses
money or data if it's ignored."""

zero_shot = f"""{RULES}
Reply with the category name only.

<ticket>{TICKET}</ticket>"""
```

## 4. Few-shot: teach edge cases with examples

Few-shot adds worked examples on top of the instructions. Use it when the format or the judgment calls are easier to show than to describe. Anthropic's guidance: 3 to 5 examples, relevant and diverse, wrapped in `<example>` tags so the model can tell examples from instructions. One example per category also covers the label set. Append:

```
few_shot = f"""{RULES}
Reply with the category name only.

<examples>
<example>The dashboard shows last week's numbers no matter what date range I pick. -> BUG</example>
<example>Can you add a dark mode? My eyes hurt at night. -> FEATURE_REQUEST</example>
<example>Where do I change my notification settings? -> HOW_TO</example>
<example>My card was declined but you still downgraded my plan. -> BILLING</example>
</examples>

<ticket>{TICKET}</ticket>"""
```

## 5. Chain-of-thought: make the reasoning visible

Chain-of-thought asks the model to reason before answering, with tags separating the reasoning from the answer so your code can parse each. Two caveats. Current Claude models already reason internally by default, so this pattern won't raise accuracy much on `claude-opus-5`; its value here is an audit trail you can log when a classification gets disputed. And on models where internal thinking is off, Anthropic's docs recommend exactly this tag structure as the fallback. Append:

```
cot = f"""{RULES}
Reason through the classification inside <thinking> tags, then put the
final category (nothing else) inside <answer> tags.

<ticket>{TICKET}</ticket>"""

for name, prompt in [("weak", weak), ("zero-shot", zero_shot),
                     ("few-shot", few_shot), ("chain-of-thought", cot)]:
    print(f"--- {name} ---\n{ask(prompt)}\n")
```

## Verify it works

```
python prompts.py
```

Expected output (the weak answer varies between runs; the wording of the thinking varies too, but the three rewrites should land on BILLING every time):

```
--- weak ---
This ticket covers two issues: a billing problem (duplicate charge) and a
question about exporting invoices. I'd categorize it as: Billing / Account...

--- zero-shot ---
BILLING

--- few-shot ---
BILLING

--- chain-of-thought ---
<thinking>The ticket has two parts: a duplicate charge and a CSV export
question. The duplicate charge means the customer is losing money, so the
tie-breaking rule says BILLING wins over HOW_TO.</thinking>
<answer>BILLING</answer>
```

Run it two or three times. The rewrites stay stable; that repeatability is the actual deliverable, since a router that returns prose one run and a label the next can't be parsed downstream.

## Troubleshooting

- **`anthropic.AuthenticationError: Error code: 401 ... 'invalid x-api-key'`** — the key is unset, mistyped, or exported in a different shell. Run`echo $ANTHROPIC_API_KEY` to check, and re-export in the terminal you're running the script from.
- **`ModuleNotFoundError: No module named 'anthropic'`** — the venv isn't active. Run` source .venv/bin/activate` and confirm`which python` points inside`.venv` .
- **`anthropic.NotFoundError: Error code: 404 ... 'model: ...'`** — a typo in the model ID. The exact string is` claude-opus-5` , with no date suffix.
- **`Error code: 400 ... 'Your credit balance is too low to access the Anthropic API'`** — add credits under Plans & billing in the Console; a new account with no balance hits this on the first call.

## Next steps

Anthropic's [prompting best practices](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices) covers the full technique set, including role prompting via the `system` parameter and prompt chaining. From there, the natural upgrades to this router are structured outputs (schema-enforced JSON instead of tag parsing) and a small eval set, because once you have 20 labeled tickets you can measure whether a prompt change helped instead of eyeballing it. The [interactive prompting tutorial](https://github.com/anthropics/prompt-eng-interactive-tutorial) drills each pattern with exercises.

## Sources & further reading

1. 
                                    [Prompting best practices](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices)
                                — platform.claude.com
2. 
                                    [Get started with Claude](https://platform.claude.com/docs/en/get-started)
                                — platform.claude.com
3. 
                                    [Prompt engineering overview](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/overview)
                                — platform.claude.com
4. 
                                    [anthropic - PyPI](https://pypi.org/project/anthropic/)
                                — pypi.org

[Priya Nair](https://sourcefeed.dev/u/priya_nair)· AI & Developer Experience Writer

Priya covers AI frameworks, developer productivity tooling, and the startup ecosystem across South and Southeast Asia, bringing a researcher's rigour and a practitioner's empathy to every story. She is deeply sceptical of benchmarks and asks hard questions so her readers don't have to.

## Discussion 1

okay but this is testing against one support ticket. how does this actually scale when you've got hundreds of different domain-specific categories and edge cases start piling up? i'd want to see the failure rate and consistency metrics across a realistic dataset before assuming any of these patterns will hold up as a classifier in production.
