You've seen the Reddit posts. "ChatGPT is useless for coding." "The output is always generic." "It never does exactly what I want."
Then you see someone else get stunning results from the same model — nuanced analysis, working code on the first try, responses that feel like they came from a senior engineer who fully understood the problem.
Same model. Completely different outcomes.
The gap isn't the model. It's prompt craft — and more specifically, it's understanding why certain prompt structures work so that you're not just copying templates but actually engineering your inputs.
This post won't give you a list of "10 prompting tricks." It'll give you the mental model behind all of them — and then show you how to apply that to the techniques that actually matter in production.
Why Prompting Is Actually an Engineering Problem
Here's the framing that changes everything: a prompt is not a request. It's a context configuration.
When you send a prompt to a language model, you're not asking a question. You're constructing a context window — a slice of token space — that the model will use to predict what should come next. Everything about that context affects the prediction: the order of information, the format, the examples you include, the role you assign, the constraints you specify.
Bad prompts aren't "unclear" in the way a bad question to a human is unclear. They're under-specified context — they leave too much of the probability distribution open, so the model generates the statistically average response to that kind of input. And the statistically average response is almost never what you wanted.
Good prompts compress the distribution. They add enough constraints, examples, and structure that the space of likely outputs narrows dramatically — toward exactly what you need.
This is why prompting is an engineering discipline, not a communication skill. You're not "explaining better." You're configuring a probabilistic system.
The Three Axes of Any Prompt
Before covering specific techniques, here's the framework that unifies them. Every prompting decision lives on one of three axes:
1. Context richness — how much relevant information does the model have to work with? Techniques: few-shot examples, contextual prompting, RAG, conversation history
2. Reasoning structure — how is the model guided to think through the problem? Techniques: chain-of-thought, step-back prompting, self-consistency
3. Output constraints — how precisely is the desired output defined? Techniques: instruction prompting, persona-based, format specification, direct answer prompting
Most prompting failures come from neglecting one of these three axes. You gave it great context but no reasoning structure. You constrained the output perfectly but gave it no examples. You specified the format but forgot to give it the information it needs.
When a prompt isn't working, diagnose which axis is weak before reaching for a different technique.
The Techniques That Actually Matter
Zero-Shot Prompting — The Default You're Already Using
You ask, the model answers. No examples, no scaffolding.
Prompt: "Explain the difference between a mutex and a semaphore."Zero-shot works when the task is well within the model's training distribution — common concepts, standard formats, things that have been explained thousands of times in training data. It fails on edge cases, niche domains, and any task that requires a specific format or reasoning style the model can't infer from the question alone.
The failure mode to watch for: zero-shot prompts for complex tasks get the statistically average answer — correct at a surface level, but generic and often missing the specific nuance you needed. If you find yourself saying "it's not wrong, but it's not quite right either," you're experiencing zero-shot's ceiling.
When to use it: simple lookups, common explanations, tasks where any reasonable response will do. If you need precision, add structure.
Few-Shot Prompting — The Most Underused Technique
You provide examples of the input-output pattern you want, then give the real input.
Prompt:
Convert these descriptions to JSON objects:
Description: "A red 2019 Toyota Camry with 45,000 miles"
JSON: {"make": "Toyota", "model": "Camry", "year": 2019, "color": "red", "mileage": 45000}
Description: "A silver 2022 Honda Civic with 12,500 miles"
JSON: {"make": "Honda", "model": "Civic", "year": 2022, "color": "silver", "mileage": 12500}
Description: "A black 2017 Ford F-150 with 89,000 miles"
JSON:Few-shot works because you're showing the model the exact input-output mapping you want, rather than describing it in words. Demonstrations are more precise than instructions because they leave less room for interpretation.
The non-obvious insight: the quality of your examples matters more than the quantity. Two well-chosen examples that cover edge cases outperform five mediocre examples that all look similar. Your examples should show the model how to handle the hard cases, not just the easy ones.
When to use it: any task requiring a specific output format, classification with non-obvious categories, transformation tasks, any domain where "correct" has a precise definition your instructions might not fully capture.
Don't use it when: examples would make the prompt unnecessarily long for a simple task, or when the task genuinely has no fixed format and you want the model to have flexibility.
Chain-of-Thought (CoT) — Making Reasoning Visible
You ask the model to show its work. This sounds trivial. The effect is not.
Without CoT:
Prompt: "A store bought 200 items at $3 each and sold them all at $5 each.
If 10 items were returned and refunded at the purchase price,
what was the net profit?"
Response: "$370" ← possibly wrong, definitely unverifiableWith CoT:
Prompt: "A store bought 200 items at $3 each and sold them all at $5 each.
If 10 items were returned and refunded at the purchase price,
what was the net profit? Think through this step by step."
Response:
Step 1: Total cost = 200 × $3 = $600
Step 2: Total revenue from sales = 200 × $5 = $1,000
Step 3: Refunds for 10 returns = 10 × $3 = $30
Step 4: Net profit = $1,000 - $600 - $30 = $370Same answer in this case — but now you can verify the reasoning. And on harder problems, forcing step-by-step reasoning dramatically reduces errors, because the model's intermediate outputs become part of its context for subsequent steps.
Why this works mechanically: the model generates tokens sequentially. When you force it to write out reasoning steps, those intermediate tokens become context for the final answer. It's not that reasoning precedes generation — it's that earlier reasoning tokens are part of the generation context for later tokens. Writing out correct intermediate steps makes correct final steps more likely.
Zero-shot CoT: The infamous "Let's think step by step" suffix works because it pattern-matches to careful, methodical reasoning in training data. You don't always need to specify the steps yourself.
When to use it: any multi-step reasoning (math, logic, debugging, analysis), any task where you need to verify correctness, any complex decision that has intermediate steps. Almost always worth it for tasks that aren't trivially simple.
When to skip it: simple lookups, creative writing, tasks where reasoning steps would be noise. "What's the capital of Japan? Think step by step." adds nothing.
Self-Consistency — When One Answer Isn't Enough
Generate multiple responses to the same prompt (via multiple API calls or high temperature), then take the most common answer.
import anthropic
from collections import Counter
client = anthropic.Anthropic()
prompt = "What is 17% of 340? Show your calculation."
answers = []
for _ in range(5):
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=200,
messages=[{"role": "user", "content": prompt}]
)
answers.append(response.content[0].text.strip())
# Extract final numbers and find most common
# In practice, parse the final answer from each response
print(Counter(answers).most_common(1))Self-consistency is expensive (N× the API calls) but effective for high-stakes single questions where you want to reduce variance. The intuition: if five independent reasoning paths all arrive at the same answer, that answer is more likely to be correct than a single run.
When to use it: high-stakes calculations or decisions where you'd want a second opinion, tasks where you've seen the model inconsistently correct, expensive decisions where the cost of the wrong answer exceeds the cost of extra API calls. Not for production at scale — use it for validation or offline evaluation.
Instruction Prompting — Being Precisely Specific
Most developers under-specify their instructions. They write what they want without specifying format, length, constraints, or failure conditions.
Under-specified:
"Write a function to parse dates."Well-specified:
"Write a Python function that parses date strings in the formats
MM/DD/YYYY, DD-MM-YYYY, and YYYY-MM-DD, returning a datetime object.
Handle invalid inputs by raising a ValueError with a descriptive message.
Include type hints. Do not use external libraries beyond Python's standard
datetime module. Add a docstring with one example per format."The second prompt is longer. It also produces a usable function on the first try instead of requiring three rounds of back-and-forth corrections.
The checklist for good instruction prompts:
- What format should the output be in?
- What constraints apply (no external libraries, under X lines, specific language/style)?
- What should happen on edge cases or invalid inputs?
- What level of detail is expected (a function, a full module, a pseudocode sketch)?
- What should the output explicitly not include? The last one is particularly underused. "Do not include explanatory prose, just return the code" eliminates the most common annoyance in code generation.
Persona-Based Prompting — Activating the Right Knowledge Cluster
Assigning the model a role isn't roleplay — it's context compression. A well-defined persona activates a specific cluster of knowledge, tone, and reasoning style from the training distribution.
System: "You are a senior backend engineer at a high-growth startup.
You care deeply about operational simplicity, horizontal scalability,
and avoiding premature abstraction. When reviewing code, you prioritize
pragmatic solutions that a small team can maintain over elegant
architectures that require specialized knowledge."This is more effective than "be helpful and accurate" because it specifies which kind of helpful and accurate. A database administrator and a frontend developer might give equally correct but completely different answers to "how should I store user sessions?" The persona anchors the response to the perspective that's useful for your context.
The failure mode: vague personas. "You are an expert in X" is weak because "expert" is underspecified. What kind of expert? What do they prioritize? What's their background? The more concrete the persona, the more useful the activation.
When to use it: any task where perspective or domain expertise matters, building AI assistants or agents with consistent behavior, tasks where you want the model to make specific trade-offs (speed vs. accuracy, simplicity vs. completeness).
Contextual Prompting — Giving the Model What It Can't Know
The model's training data has a cutoff. It doesn't know your codebase, your specific requirements, your team's constraints, or the context of your current problem. Contextual prompting means supplying that missing information explicitly.
"Here's the relevant context:
- Stack: Node.js, PostgreSQL, Redis, deployed on AWS ECS
- Current issue: our /api/products endpoint takes 800ms on average
- Recent changes: we added full-text search last week using ILIKE queries
- Constraint: we can't change the database schema this sprint
Given this context, identify the likely cause of the slowdown and
suggest fixes we can implement without a schema change."Without this context, the model would give generic performance advice. With it, it can reason specifically about ILIKE queries on PostgreSQL at scale, point directly to missing trigram indexes, and suggest solutions that respect the schema constraint.
The rule: if you would need to explain the situation to a new team member before they could help you, you need to include that explanation in the prompt. The model has no memory of your previous conversations, no access to your codebase, no knowledge of your team's conventions.
Combining Techniques: What High-Quality Prompts Actually Look Like
The best prompts usually combine multiple techniques. Here's a real-world example for a code review task:
System (Persona):
"You are a principal engineer conducting a code review. You focus on
correctness, security, and maintainability — in that order. You write
concise, actionable feedback."
User (Instruction + Context + CoT):
"Review the following authentication middleware for a Node.js API.
The app handles financial data so security is the top priority.
Walk through each potential issue in order of severity. For each issue:
1. State what the problem is
2. Explain why it's a risk in this context
3. Provide a corrected code snippet
[code here]"This combines persona (principal engineer, defined priorities), instruction (specific format for feedback), context (financial data, security priority), and implicit CoT (the numbered structure forces ordered reasoning through each issue).
The result is a structured code review that matches the exact output format you need, with reasoning you can follow and verify, calibrated to the stakes of the application.
The Decision Framework
Choose Zero-Shot when:
- ✔ The task is common and well-defined
- ✔ Any reasonable response will do
- ✔ You're iterating quickly and precision isn't critical yet
Choose Few-Shot when:
- ✔ You need a specific output format or structure
- ✔ The task involves classification or transformation
- ✔ You've seen zero-shot produce the right idea but wrong format
Choose Chain-of-Thought when:
- ✔ The task involves multiple steps or calculations
- ✔ You need to verify the reasoning, not just the answer
- ✔ The model is inconsistently correct on similar tasks
Choose Persona when:
- ✔ Perspective, expertise, or domain focus matters
- ✔ You're building an assistant with consistent behavior
- ✔ You want specific trade-offs baked into every response
Choose Contextual when:
- ✔ The problem is specific to your codebase, system, or constraints
- ✔ Generic advice would be useless or misleading
- ✔ The model would need background knowledge you haven't provided
The meta-rule: When a prompt fails, diagnose which of the three axes is weak — context richness, reasoning structure, or output constraints — then add the corresponding technique. Don't just rephrase and retry.
Key Insights
Format specification is often worth more than better instructions. "Return a JSON object with keys: error, severity, suggestion" produces more usable output than a paragraph explaining what you want. The model is very good at following format constraints. Use them aggressively.
Negative constraints are underused. "Do not include introductory text," "Do not apologize or hedge," "Do not suggest solutions requiring schema changes" — these eliminate the most common failure modes more reliably than positive instructions that try to specify the same thing.
Examples beat descriptions every time. If you're spending more than two sentences describing the output format you want, you should probably just show an example instead. One well-chosen example is worth a paragraph of explanation.
System prompts are not just for chat. If you're using a chat-based API for a single-turn task, the system prompt is still valuable for establishing tone, constraints, and persona. Don't skip it just because you're not building a conversational app.
The model's failure is information. When a prompt produces a bad result, the specific way it failed tells you which axis needs work. Generic response → needs more context or examples. Wrong format → needs explicit format constraints. Missing reasoning → needs CoT. Wrong tone or expertise level → needs persona.
Common Mistakes
Asking multiple questions in one prompt. "Explain X, give an example, and tell me when not to use it" produces weaker answers to all three than three separate focused prompts. The model splits attention across multiple goals.
Treating "try different wording" as a debugging strategy. If your prompt fails, rephrasing without changing the underlying structure rarely helps. Diagnose the axis and add the right technique.
Over-specifying simple tasks. A heavily structured prompt for "what does Array.map do?" is overhead with no benefit. Match prompt complexity to task complexity.
Ignoring the system prompt. For any non-trivial application, the system prompt is where your persona, constraints, and behavioral guidelines live. Leaving it empty hands the model maximum freedom — which is rarely what you want.
TL;DR
- A prompt is context configuration, not a request — you're narrowing a probability distribution
- Three axes determine prompt quality: context richness, reasoning structure, output constraints
- Zero-shot → default for simple tasks; fails on precision and edge cases
- Few-shot → show examples when format or accuracy matters; examples beat descriptions
- Chain-of-thought → force visible reasoning for multi-step tasks; makes reasoning verifiable
- Self-consistency → sample multiple times, take consensus; expensive but reduces variance
- Instruction → specify format, constraints, edge cases, and what not to include
- Persona → activate specific knowledge and perspective; be concrete, not just "expert"
- Contextual → provide everything the model can't know; treat it like briefing a new hire
- When a prompt fails, diagnose the weak axis — don't just rephrase and retry
Conclusion
Prompting isn't a soft skill. It's an engineering discipline with a clear underlying mechanism: you're configuring the context that a probabilistic text model uses to generate its next tokens. Understanding that mechanism turns "try different wording" into "diagnose the weak axis and apply the right technique."
The developers getting the best results from LLMs aren't the ones with the most creative prompts. They're the ones who've internalized the three axes — context, reasoning structure, output constraints — and apply the right technique systematically when something isn't working.
The techniques in this post aren't exhaustive. New ones emerge as people push model capabilities. But the mental model behind them — prompt as context configuration, techniques as axis strengtheners — will generalize to anything new that emerges.
What's Your Most Reliable Technique?
Which prompting technique has saved you the most debugging time, or produced the biggest quality jump in a product you've built? And are there failure modes you've run into that none of these techniques fully address?
Drop it in the comments — the edge cases are where the interesting engineering problems live.



