Best Prompt Engineering Techniques That Actually Work
The best prompt engineering techniques share three traits: they reduce ambiguity, they give the model room to reason before answering, and they're testable — you can run them against real inputs and measure whether output quality actually improved. This article walks through the techniques that consistently move the needle in production systems, not just in demos.
If you're evaluating prompt engineering advice, the fastest filter is: does this technique change model behavior in a way you can verify with a side-by-side comparison? If a technique only "sounds" better, skip it. Below are the ones that hold up.
Structure your prompt like a spec, not a sentence
Vague instructions produce vague output. The single highest-leverage change most people can make is separating a prompt into distinct sections instead of writing one paragraph of instructions.
A reliable structure:
ROLE: who the model is acting as
TASK: what it needs to do, in one sentence
CONTEXT: relevant background, data, or constraints
FORMAT: exact output shape (JSON schema, bullet list, word count)
EXAMPLES: 1-3 input/output pairs if the task is non-obvious
This works because LLMs are pattern-matchers on structure as much as on content. A clearly delimited prompt gives the model less room to guess what "good" looks like.
Few-shot examples beat instructions for edge cases
Telling a model "be concise" is weaker than showing it three examples of concise output. Few-shot prompting — including 2-5 example input/output pairs directly in the prompt — is still one of the most effective techniques, especially for:
- Consistent formatting (tables, JSON, specific tone)
- Domain-specific judgment calls (what counts as "urgent," what counts as "spam")
- Edge cases that are hard to describe in words but easy to demonstrate
Keep examples diverse — cover the boundary cases, not just the easy middle case. One example of the tricky scenario is worth more than three examples of the obvious one.
Chain-of-thought and "think before you answer"
For anything involving multi-step logic, math, or decisions with tradeoffs, letting the model reason before committing to an answer measurably improves accuracy. This doesn't require a special API — it's a prompting pattern:
Before answering, work through the problem step by step:
1. Identify the key constraints
2. List possible approaches
3. Evaluate tradeoffs
4. Give your final answer, clearly marked
Question: [your question]
For production systems, a common pattern is to request the reasoning and final answer in separate fields (e.g., reasoning and answer in a JSON object) so you can log the reasoning for debugging without showing it to end users.
Constrain the output format explicitly
Ambiguous format instructions are one of the biggest sources of parsing failures in production. Instead of "return the result as JSON," specify the exact schema:
Return only valid JSON matching this schema, no other text:
{
"summary": string,
"confidence": number (0-1),
"tags": string[]
}
Pair this with strict parsing on your end — reject and retry if the output doesn't validate. This is cheaper than trying to make the prompt perfect; a retry loop with format validation catches the tail of malformed outputs that no amount of prompt tuning fully eliminates.
Decompose complex tasks instead of cramming them into one prompt
A single prompt asking a model to "research, summarize, critique, and rewrite" a document will underperform four smaller prompts chained together, each with a narrow job. Decomposition:
- Makes each step easier to test and debug independently
- Lets you use cheaper/faster settings for simple steps and more careful prompting for hard steps
- Produces intermediate outputs you can inspect when something goes wrong
This is also where tool use becomes relevant — letting the model call functions for lookups, calculations, or structured actions instead of trying to simulate them in text. If you're building this on top of Claude, SubToAPI's tool use docs cover how to wire function calls into a standard chat completion request.
Negative constraints, used sparingly
Telling a model what not to do ("don't include disclaimers," "don't repeat the question") works, but it's a weaker technique than positive framing and should be a secondary tool. Overloading a prompt with a long list of prohibitions tends to produce inconsistent results — the model has to hold all the "don'ts" in mind while also doing the actual task. Where possible, rephrase constraints as positive instructions ("respond only with the JSON object" instead of "don't add extra text").
Test prompts the way you test code
The technique that separates production prompt engineering from casual prompting is evaluation discipline:
- Build a small set of representative test inputs (10-30 is enough to start)
- Run your prompt against all of them and manually grade output
- Change one variable at a time (wording, examples, format instructions)
- Re-run the full set and compare, not just eyeball a single example
Without this loop, you're optimizing for the one example in front of you, which is how prompts that look great in a chat window fail in production.
Streaming and iteration speed matter for prompt testing
The faster you can see output, the faster you can iterate on a prompt. If you're testing prompts through an API rather than a chat UI, streaming responses lets you see the first tokens immediately instead of waiting for a full generation — useful when you're running dozens of test variations. SubToAPI exposes Claude through a standard streaming endpoint (see the streaming docs) if you're building or testing prompts programmatically rather than one-off in a playground.
Putting it together
None of these techniques work in isolation as well as they do combined: a well-structured prompt, with 2-3 targeted examples, explicit output format, reasoning before the final answer, and a small test set you re-run on every change. Start there, and only add complexity (longer examples, more decomposition, negative constraints) when a specific failure mode shows up in your test set — not preemptively.
Questions
Does prompt engineering still matter with newer, more capable models? Yes. More capable models reduce how much scaffolding you need, but structure, examples, and explicit output formats still measurably improve consistency and reduce parsing failures, especially at scale where even a 1-2% error rate compounds.
How many few-shot examples should I use? Start with 2-3 covering distinct cases, including at least one edge case. More examples increase token cost and can hurt performance if they're redundant or contradictory in style.
Should I use chain-of-thought for every prompt? No — it adds latency and cost. Reserve it for tasks involving multi-step logic, calculations, or judgment calls; simple lookups or formatting tasks don't benefit and just get slower.