Deep Dives11 min read24 May 2026

The 10 Prompting Patterns Every Developer Should Know

Beyond copy-pasting error messages — these are the reusable mental models that make AI genuinely useful for software engineering. Learn the pattern once, apply it to every problem.

Most developers treat AI prompting as a skill you either have or you don't. It's not. It's a set of learnable patterns — reusable structures you can apply to almost any problem. Learn the pattern once and you can adapt it to every new situation.

This article covers 10 patterns that experienced AI users reach for constantly. Some you probably know. Some will change how you work.

These patterns work with any capable AI model — Claude, GPT-4, Gemini. The principles are model-agnostic, though some models respond better to certain patterns than others.

1. Role Assignment

You tell the AI who to be before you give it the task. The role sets the vocabulary, the level of depth, and the assumptions the AI makes about what you need.

Without a role: you get a general answer. With a role: you get an answer calibrated to a specific perspective, seniority level, and domain.

Without role vs with role
-- Without role:
"Review this code."

-- With role:
"You are a senior backend engineer who has been burned by production incidents caused
by poor error handling. Review this code with that lens — what would keep you up at
night if this shipped? [paste code]"

Useful roles for developers: senior engineer (critical review), junior developer (explains what the code does simply), security researcher (looks for vulnerabilities), technical writer (makes documentation clear), developer who's never seen this codebase (tests whether the code is self-explanatory).

The role doesn't have to be a job title. "You are a developer who has never used this library before" produces a useful review of whether your API design is intuitive. "You are the developer who will have to maintain this in 6 months" produces a different and equally valuable review.

2. Rubber Duck Prompting

Rubber duck debugging is the practice of explaining a bug out loud to an inanimate object — the act of explaining forces you to think through the problem systematically. AI makes this dramatically more useful because the rubber duck talks back.

Instead of asking the AI to solve your problem, ask it to ask you questions. This keeps you thinking rather than just accepting an answer.

Rubber duck prompt
"I have a bug I can't solve and I want to work through it. Instead of giving me a solution,
ask me one diagnostic question at a time — like a doctor narrowing down a diagnosis.
I'll answer each one and you ask the next question based on my answer.

Bug: my API endpoint returns 200 but the data is empty when called from the frontend.
It works fine when I test it directly with Postman."

The AI will ask about authentication headers, CORS preflight, request parameters, environment differences — and your answers will often surface the issue before you even reach a fix.

Use this pattern when you suspect you don't fully understand the problem yet. If you understand the problem well, just ask for the solution. If you're unsure, the questioning process teaches you more than a direct answer.

3. Explain Then Fix

Instead of asking for a fix directly, ask the AI to explain what's wrong before it fixes it. This serves two purposes: you learn from the explanation, and it forces the AI to reason through the problem before committing to a solution — which produces more accurate fixes.

Explain then fix prompt
"Here is my code and the error I'm getting:

[paste code + error]

Before you give me a fix:
1. Explain what is causing this error in plain English
2. Explain why the current code produces this behaviour
3. Then give me the fix with an explanation of what changed and why

I want to understand the bug, not just copy a fix."

This pattern works especially well for bugs in logic you don't fully understand — new language features, unfamiliar frameworks, or code written by someone else.

Research shows that asking AI to "think step by step" before answering produces more accurate responses on complex problems. Asking for an explanation first is the same principle: it forces reasoning before commitment.

4. Test-First Prompting

Ask the AI to write tests before writing the implementation. This mirrors TDD and forces the AI to reason about what the code should do before thinking about how to implement it.

Test-first prompt
"I need to write a function that [describe what it should do].

Before you write the implementation:
1. Write comprehensive tests for this function — happy paths, edge cases, error cases
2. The tests should document the expected behaviour clearly
3. Then write the implementation that makes all the tests pass

Requirements:
- [list specific requirements]
- Language: [language]
- Testing framework: [framework]"

This also works well when you have existing untested code. Ask for the tests first, then ask the AI to review whether the tests match the actual behaviour — discrepancies reveal either bugs in the code or bugs in your assumptions.

Variation: ask the AI to write tests for behaviour you want but haven't implemented yet. The tests become a specification. Then ask it to write the implementation that passes them.

5. The Constraints Frame

Add explicit constraints to every task where the output could go in many directions. Without constraints, the AI picks defaults that may not match your situation. With constraints, you get an answer shaped for your specific context.

Unconstrained vs constrained
-- Unconstrained:
"Refactor this function to be cleaner."

-- Constrained:
"Refactor this function. Constraints:
- Do not change the function signature (other code depends on it)
- Do not introduce any new dependencies
- Keep it in plain JavaScript — no TypeScript
- Optimise for readability over cleverness — this will be maintained by junior devs
- The function must run in Node.js 14+ (no optional chaining ?. please)
[paste function]"

Useful constraint categories: don't change X, keep Y, optimise for Z, avoid W, must work with N. The more specific your constraints, the more usable the output.

Tell the AI what you've already tried. "I already tried [approach] and it didn't work because [reason]" saves a round trip where the AI suggests exactly what you already ruled out.

6. Comparative Analysis

When you're deciding between two approaches, don't ask the AI which is better in the abstract. Give it both options and ask it to compare them against your specific priorities.

Comparative analysis prompt
"I'm deciding between two approaches for [describe the problem].

Option A: [describe or paste code]
Option B: [describe or paste code]

My priorities in order:
1. [most important — e.g. correctness]
2. [second — e.g. performance at scale]
3. [third — e.g. ease of maintenance]
4. [fourth — e.g. developer experience]

Compare the two options against each priority. Then give me a recommendation and explain
any tradeoffs I should be aware of."

This pattern works for: implementation approaches, library choices, architecture decisions, database schema options, API design alternatives.

7. Before / After Refactoring

When asking for a refactor, ask the AI to show you the before and after side by side with an explanation of every change. This makes the refactor reviewable — you can see exactly what changed and why, rather than having to diff two versions yourself.

Before/after prompt
"Refactor this function to improve readability.

Show me:
1. The original code (labelled BEFORE)
2. The refactored code (labelled AFTER)
3. A numbered list of every change you made with a one-line explanation of why

Do not change the external behaviour. Do not change the function signature.

[paste code]"

This pattern also works for documentation: ask for the before (original) and after (improved) version of a README, docstring, or comment with a list of what was changed.

Add "explain each change" to any refactoring prompt. Refactors you don't understand are refactors you can't debug when something goes wrong.

8. The Socratic Prompt

Instead of asking for an answer, ask the AI to teach you by asking questions. This is especially useful when you're learning a new concept and want to test your understanding rather than just read an explanation.

Socratic prompt examples
"Quiz me on [concept] in [language]. Ask me one question at a time. After I answer each one:
- Tell me if I'm right or wrong
- Explain the correct answer if I got it wrong
- Then ask the next question
Start easy and get progressively harder. Begin."

-- Variant for architecture decisions:
"I'm going to describe my architecture plan. Instead of telling me if it's right or wrong,
ask me questions about my assumptions and edge cases — like a technical interviewer would.
I want to find the gaps in my thinking myself.

My plan: [describe]"

This pattern builds real understanding rather than just transferring information. If you can answer the AI's questions correctly, you understand the material. If you can't, you know exactly where the gaps are.

9. The Exhaustive List

When you're doing something where missing an item has consequences — security review, edge case analysis, test coverage, migration planning — ask the AI to be exhaustive rather than comprehensive. The word choice matters.

Exhaustive list prompts
"List EVERY possible cause of this error. I don't want the 3 most likely causes —
I want all of them, including edge cases. I'll filter by likelihood myself: [paste error]"

"List EVERY edge case this function doesn't currently handle. Be exhaustive.
Include cases that are unlikely but would cause silent failures: [paste code]"

"List EVERY thing that could go wrong when I run this database migration.
Include things that are unlikely. I need to know what to roll back from: [describe migration]"

The AI will naturally tend to give you the 3-5 most likely things. Asking for an exhaustive list pushes it to think through the long tail — which is often where the real problems hide.

Follow up with "What did you not include that you should have?" — this often surfaces one more thing the AI held back because it seemed unlikely. For security and migration work, that unlikely thing matters.

10. Iterative Refinement

The best prompt isn't the first prompt — it's the third. Each iteration narrows the output toward what you actually need. Most developers get a first response that's 60% right and give up. The 60% is the starting point, not the result.

Here's how an iterative refinement session looks:

Iteration pattern
-- Round 1: get the rough shape
"Write a function that [describe requirement]"

-- Round 2: fix what's wrong
"Good start. A few issues:
1. The function doesn't handle [edge case] — it should [describe expected behaviour]
2. The variable names are too vague — rename [x] to [something descriptive]
3. The error message on line [N] isn't helpful — make it say exactly what went wrong
Update the function with these fixes."

-- Round 3: add what's missing
"Almost there. Two more things:
1. Add input validation at the top — throw a specific error if [condition]
2. Add a JSDoc comment documenting the parameters and return value
Final version please."

The key is being specific about what's wrong. "Make it better" produces generic improvements. "The error handling swallows the original error — re-throw it with the original message attached" produces exactly what you asked for.

Keep iterating in the same conversation thread. The AI has full context of everything above, so you don't need to re-explain the task each round. Just describe the delta — what needs to change from the current version.

Combining Patterns

The real power comes from combining these patterns in a single prompt. A code review prompt might combine Role Assignment (senior engineer), Exhaustive List (every possible issue), and Constraints Frame (focus on production readiness). A debugging session might combine Rubber Duck Prompting (ask me questions) with Explain Then Fix (explain the root cause before suggesting a solution).

  • Role + Constraints: "As a security researcher reviewing production code, identify every input that could be maliciously crafted. Don't stop at the obvious ones."
  • Test-First + Explain Then Fix: "Write tests that expose this bug, then explain the root cause, then fix it."
  • Comparative + Exhaustive: "Compare these two approaches. For each, list every way it could fail in production."
  • Rubber Duck + Iterative: "Ask me questions about this bug. After each answer, tell me what new information it gives you about the probable cause."
Save your best prompts. The ones that produce consistently good results are worth keeping in a notes file or a prompt library you can revisit. The prompt is the skill — once you've written a great debugging prompt template, you can reuse it for every bug.
promptingpatternsdeveloper toolsAI
🎓Interactive Courses

Ready to go further?

Take the interactive course — daily lessons, real exercises, XP and streaks. Turn reading into lasting skills.

Daily streaksXP & levels
Start a course