Prompt engineering patterns that actually work

Role framing, few-shot, chain-of-thought, ReAct, and the anti-patterns that quietly wreck reliability.

πŸ’¬ Module 1 8 min read Not started

Why this matters

Prompt engineering in 2026 is not "be a helpful assistant." It is a small set of structured patterns β€” Chain-of-Thought, ReAct, Reflexion, Few-shot, Self-consistency β€” that lift accuracy by 20-60% on hard tasks for free. Every senior agent you build composes these patterns inside framework code.

Learning objectives

  1. Use the 7 high-leverage prompt patterns and know when each one wins.
  2. Write a system prompt that is robust against off-topic and adversarial inputs.
  3. Measure the lift each pattern gives on your own task with a small eval set.

1. Anatomy of a great system prompt

A production system prompt has 6 sections. Memorise the order:

1. Role / persona       (who is the model?)
2. Goal                 (what is success?)
3. Capabilities & tools (what can it do?)
4. Constraints          (what must it never do?)
5. Output format        (how must it respond?)
6. Examples             (1-3 few-shot demos)

Worked example:

text
You are an SQL analyst at a fintech company.

GOAL
Translate user questions into safe, performant SQL for our Postgres warehouse and explain results in plain English.

CAPABILITIES
You can call the tool `run_sql(query: str)` and `lookup_schema(table: str)`.

CONSTRAINTS
- NEVER write UPDATE, DELETE, INSERT, DROP, ALTER, GRANT, or REVOKE.
- If a query would scan more than 1 million rows, ask the user to narrow it.
- Refuse politely if the question is unrelated to our data.

OUTPUT FORMAT
First a 1-line plan, then the SQL fenced in ```sql ... ```, then the result, then a 2-line summary.

EXAMPLES
User: top 5 cities by revenue last quarter
Plan: aggregate revenue per city for Q-1, top 5
```sql
SELECT city, SUM(amount) AS revenue
FROM orders
WHERE created_at >= date_trunc('quarter', now()) - INTERVAL '1 quarter'
  AND created_at <  date_trunc('quarter', now())
GROUP BY city ORDER BY revenue DESC LIMIT 5;

Summary: Mumbai led at β‚Ή4.1Cr, followed by Bengaluru and Delhi.


Why this works: every section gives the model an explicit handle the LLM can grip, instead of guessing.

---

## 2. The 7 high-leverage prompt patterns

### Pattern A β€” Zero-shot
Just ask. Works on easy tasks. Default starting point.

```text
Classify the sentiment of: "The flight was cancelled, again."

Pattern B β€” Few-shot (criminally underused)

Add 2-5 examples in the prompt. Lifts accuracy 20-40% almost everywhere.

text
Classify sentiment as positive, negative, or neutral.

Text: "Loved the food."
Sentiment: positive

Text: "Service was slow but ok."
Sentiment: neutral

Text: "Never coming back."
Sentiment: negative

Text: "{user_input}"
Sentiment:

Tip: include hard / borderline examples, not easy ones, so the model learns the boundary.

Pattern C β€” Chain-of-Thought (CoT)

Ask the model to think step-by-step before answering. Massively reduces errors on math, logic, multi-step questions.

text
Question: A train leaves Mumbai at 6:00 going 80 km/h. Another leaves Pune at 6:30 going 100 km/h on the same track. Mumbai-Pune is 150 km. When do they meet?

Think step by step before giving the final answer.

For modern reasoning models (o1, o3-mini, claude-opus-4.7-thinking, gpt-5.5-thinking) the chain-of-thought happens internally and you do not need the trigger phrase β€” the API exposes a reasoning block.

Pattern D β€” Tree-of-Thought (ToT)

Explore multiple reasoning branches, then pick the best. Used for hard planning. Programmatically: ask the model to generate 3 candidate plans, score each, pick the highest.

text
You are solving: "Plan a 3-day Tokyo trip under $1500."

Step 1: generate 3 different *strategies* (budget, mid-range, luxury-on-points).
Step 2: for each strategy, write a full day-by-day plan.
Step 3: score each plan 1-10 on: cost, fun, feasibility.
Step 4: return the winning plan.

Pattern E β€” ReAct (Reason + Act)

The pattern that powers every agent. Interleave Thought, Action, Observation:

Thought: I need today's date to plan ...
Action: get_date()
Observation: 2026-06-07
Thought: Now I need exchange rates ...
Action: get_rate(from="USD", to="JPY")
Observation: 154.20
Thought: Final answer ...

You will not write this raw β€” frameworks (LangGraph, CrewAI, OpenAI Agents SDK) implement it. But the prompts under the hood look exactly like this. Read the react paper once.

Pattern F β€” Self-consistency

Sample N answers (e.g. N=5 with temperature=0.7), take the majority answer. Cheap accuracy boost on math/logic. Used in production by Anthropic for some workloads.

python
import collections, asyncio
async def majority_answer(question, n=5):
    answers = await asyncio.gather(*(ask(question, temp=0.7) for _ in range(n)))
    return collections.Counter(answers).most_common(1)[0][0]

Pattern G β€” Reflexion / self-critique

Generate a draft β†’ ask the model (or a critic model) to find flaws β†’ ask for a revision. The cheapest 10-30% quality boost on writing/coding tasks.

text
[Step 1: generate]
Write a 200-word LinkedIn post about agentic AI.

[Step 2: critique]
Review the above post against these rubrics: clarity (1-10), original insight (1-10), CTA strength (1-10). For each below 8, give 1 concrete fix.

[Step 3: revise]
Rewrite incorporating the fixes.

In LangGraph you build this as a 3-node graph: generate -> critique -> revise -> END if score>=8 else loop.


3. Prompt hygiene rules (production must-haves)

  1. Use Markdown headers (##) and clear sections. LLMs respect structure.
  2. Put fixed text first, variable text last. Helps prompt caching and "lost in the middle."
  3. Use XML or JSON tags for important content blocks in long prompts:
    <document>{...}</document>
    <user_question>{...}</user_question>
    Anthropic models are particularly trained on XML-like tags.
  4. Be explicit about refusals. "If the question is outside the documents, say: 'I do not know based on the provided context.'"
  5. Banlists for outputs. "Do not mention competitors X, Y, Z. Do not provide medical, legal, or financial advice."
  6. End with what to do, not what not to do. Models follow positive instructions better.
  7. Anchor the output schema in the prompt and enforce it programmatically. Belt + suspenders.

4. Common prompt failure modes (and the fix)

FailureCauseFix
Model adds prose around JSON"Just JSON" pleaUse response_format={"type":"json_object"} or structured outputs
Model lies / hallucinates citationsNo groundingRAG + "If unsure, say 'I do not know.'"
Model is verboseNo length cap"Answer in ≀50 words." + max_tokens
Model refuses normal requestOver-alignedRe-frame: "As a helpful assistant for our internal team..."
Few-shot biases outputExample imbalanceBalance + shuffle examples
Multi-turn driftHistory growsSummarise older turns into a "context block"
Lost in the middleLong contextPut critical info first or last; use RAG

5. Measuring lift (do not skip this)

Whenever you change a prompt, measure. Build a tiny eval set (20-50 inputs with expected outputs) and compare.

python
from collections import Counter

def grade(predicted: str, expected: str) -> bool:
    return expected.lower() in predicted.lower()

def run_eval(prompt_fn, dataset):
    results = [grade(prompt_fn(x["input"]), x["expected"]) for x in dataset]
    return sum(results) / len(results)

base_acc = run_eval(zero_shot_prompt, dataset)
fewshot_acc = run_eval(few_shot_prompt, dataset)
print(f"zero-shot: {base_acc:.2f}, few-shot: {fewshot_acc:.2f}")

When you can say in an interview "I shipped few-shot, accuracy went from 0.62 to 0.81 on a 200-pair eval set," you are no longer a junior.


Hands-on lab (2 hours)

Pick a real task: classify customer-support tickets into billing, technical, account, other.

  1. Build a 50-ticket dataset (write tickets manually or use synthetic ones from an LLM).
  2. Implement five prompts: zero-shot, few-shot (5 examples), CoT, few-shot+CoT, reflexion.
  3. Run each on the dataset; record accuracy and per-call cost.
  4. Print a markdown table comparing accuracy vs cost.
  5. Pick a winner and explain the trade-off in your README.

This single project, done well, is a portfolio piece.


Common pitfalls

  1. Adding "you are an expert" five times. Once is enough; the rest is noise.
  2. Shoving every rule in. Long system prompts hurt. Test removing rules.
  3. Few-shots that look the same. Diversify topic + difficulty.
  4. Reflexion for everything. It doubles cost; only use where needed.
  5. CoT in production output. Hide reasoning from end-users (hide_reasoning=true).

Self-check

  1. Why does putting critical info at the start AND end help in long contexts?
  2. When should you NOT use chain-of-thought?
  3. What is the difference between ReAct and Reflexion?
  4. Why is self-consistency expensive but accurate?
  5. Show a 2-shot prompt for extracting {date, amount, vendor} from invoices.

References

Sign in to save your progress and earn badges.