Prompt Engineering in Practice: Structured Patterns for Controllable LLM Output
Prompt Engineering in Practice: Structured Patterns for Controllable Output
Prompt engineering is not "try a different phrasing" — it is a set of reusable patterns. This guide covers four core techniques: role definition, few-shot examples, chain-of-thought reasoning, and output format constraints. Each includes a copy-ready prompt skeleton, plus a combination table for common scenarios.
The short version
Role definition gives the model a stance; few-shot gives it examples to learn your output pattern; CoT makes it think before answering; output format constraints make results directly parseable. Combine all four for the best results, but each addition increases token consumption.
Technique one: role definition
Role definition influences the model's knowledge focus, tone, and answer boundaries. It does not change the model's capability, but it changes how the model "positions itself" when answering.
# Basic
You are a technical documentation writer.
# Enhanced (with constraints)
You are a technical documentation writer.
- Your target audience is developers with 3 years of experience
- Avoid undefined abbreviations
- Explain each concept in one sentence on first mention
- Use TypeScript for code examples
Role definition principles
The enhanced version gives the model 4 executable constraints (who the reader is, what to avoid, how to explain, which language to use) — much more specific than "you are an assistant." More specific role definitions produce more predictable output, but do not pack rules that are not used every call; that wastes tokens.
Technique two: few-shot examples
Few-shot gives the model 2-3 input-output pairs in the prompt, so it learns your output pattern.
Rewrite the following product descriptions as image generation prompts.
Example:
Input: A wireless earbud
Output: A sleek wireless earbud floating against a gradient background, studio lighting, product photography
Input: A ceramic coffee cup
Output: A ceramic coffee cup with steam rising, warm morning light, kitchen counter
Now rewrite:
Input: A mechanical keyboard
Output:
Two principles for few-shot
(1) The format of your examples must exactly match the expected output (including punctuation and capitalization). (2) 2-3 examples are sufficient; more examples increase tokens without necessarily improving results. Examples should cover different types of input, not repeat the same pattern.
Technique three: chain-of-thought (CoT)
CoT makes the model show its reasoning before giving an answer. This significantly improves accuracy on math, logic, code review, and other complex tasks.
Reason through the following problem step by step, then give the final answer.
Question: A team of 5 people needs to complete 3 tasks each. Each task takes 2 hours.
If the team works 8 hours per day, how many days will it take to complete all tasks?
CoT applicability boundaries
CoT works well for math, logic, and multi-step reasoning; it adds little to fact retrieval, creative writing, or simple classification — it may even cause the model to output unnecessary reasoning. Decide by task type.
Technique four: output format constraints
Make the model output parseable formats directly (JSON, tables, templates), eliminating the cost of parsing free-form text.
Analyze the following code and return the result in this JSON format:
{
"issues": [{"line": <line_number>, "description": "<description>", "severity": "<low|medium|high>"}],
"summary": "<one-sentence summary>"
}
Output only the JSON, no other text.
Code:
<paste code here>
Two tips for JSON output
(1) Add "Output only JSON, no other text" at the end of the prompt to reduce the chance of the model adding explanations. (2) If the model still outputs non-JSON content, add a preprocessing step in your code to extract the JSON portion (using regex or a JSON.parse try-catch).
A practical checklist before shipping
- Test with a fixed eval set: 30-50 items covering typical, edge, and boundary cases. Record pass rate per category.
- Check output format: for JSON tasks, parse every output and count parse failures. For free-text tasks, check length and tone consistency.
- Measure token consumption: average and p95 across the eval set. A prompt that doubles token count may not be worth a small quality gain.
- Test with temperature 0 and 0.7: some prompts only produce reliable output at low temperature.
- Review edge cases: empty input, very long input, mixed languages, ambiguous instructions. These are where prompts break.
- Document the prompt version: date, changes, eval scores. This prevents "what changed?" confusion three weeks later.
- Check for prompt injection vulnerability: if the prompt includes user-provided content, test whether malicious input can override the system instructions.
A prompt that passes all seven checks is production-ready.
Common mistakes and how to fix them
These are the most common prompt engineering mistakes, with practical fixes:
1. Vague instructions. "Summarize this document" is vague — how long, what format, what tone? Fix: add specific constraints ("Summarize in 3 bullet points, max 20 words each, focusing on action items").
2. Contradictory instructions. "Be creative but follow this exact template" is contradictory — creativity means deviating from templates. Fix: remove the contradiction by deciding which constraint matters more.
3. Missing output examples. Without examples, the model guesses your expected format. Fix: add 1-2 few-shot examples showing exactly what good output looks like.
4. Too many constraints at once. Ten rules in one system prompt dilutes attention. Fix: separate into a system prompt (3-5 stable rules) plus task-specific instructions in the user message.
5. Not testing edge cases. A prompt that works on 90% of inputs but fails on 10% is not production-ready. Fix: add edge case items to the eval set and test explicitly.
6. Ignoring token count. A 2000-token prompt with 20-token output is 99% overhead. Fix: trim the system prompt, remove redundant examples, or compress history.
7. Assuming one prompt fits all models. A prompt optimized for GPT may underperform on Qwen or DeepSeek. Fix: test the same prompt across models and adjust per model.
Measuring improvement
To know whether a prompt change actually helped, measure these three numbers before and after:
- Pass rate on eval set — the percentage of items that meet all checkpoints
- Average output length — catches prompts that suddenly produce much shorter or longer outputs
- Token consumption per call — catches prompts that grew without adding value
Record all three in a spreadsheet with columns for prompt version, date, and notes. After 3-4 iterations you will see patterns: which constraints help, which hurt, and which have no effect. This is the evidence that turns prompt engineering from trial-and-error into engineering.
When to rewrite from scratch
Sometimes a prompt has accumulated so many patches that a rewrite is faster than another iteration. Signs it is time:
- The system prompt exceeds 500 tokens and every new rule seems to conflict with an existing one
- The few-shot examples cover the same pattern three times because no single example covers the edge case
- You cannot explain why the prompt includes a specific instruction
When this happens, start with a blank file, write the three most important constraints from memory, test on the eval set, and only add what the eval says is missing. This usually produces a shorter, clearer prompt that performs as well as or better than the accumulated version.
Prompt versioning
Treat prompts like code — version them, test them, and document changes:
- Store prompts in files (JSON/YAML/text), not hardcoded in application logic. This makes it easy to swap, test, and diff.
- Name each version (e.g.,
v1.0-baseline,v1.1-added-fewshot) and record what changed. - Run the eval set before and after every change; keep the results alongside the prompt version.
- Rollback is a file revert, not a code change — if v1.1 underperforms v1.0, switch back by pointing to the old file.
# prompts/classification.yaml
version: "1.2"
system_prompt: |
You are a document classification assistant.
Categories: technical, business, creative, other
Output only the category name.
few_shot:
- input: "Quarterly earnings report"
output: "business"
- input: "How to center a div in CSS"
output: "technical"
- input: "A poem about autumn"
output: "creative"
parameters:
temperature: 0
max_tokens: 16
This structure makes the prompt auditable, testable, and shareable across a team.
Handling edge cases
Prompts that work on typical inputs often fail on edge cases. Test with:
- Empty or very short input: does the model handle it gracefully or hallucinate content?
- Mixed languages: if the input contains unexpected language switches, does the model maintain coherence?
- Ambiguous instructions: if the input could be interpreted multiple ways, does the model ask for clarification or guess?
- Very long inputs near the context limit: does the model stay coherent or degrade?
These are the cases where prompt quality matters most. A prompt that only works on ideal inputs is not production-ready.
Combining the four techniques
| Scenario | Role | Few-shot | CoT | Format |
|---|---|---|---|---|
| Document classification | ✅ Brief | ✅ 2-3 examples | ❌ | ✅ JSON |
| Code review | ✅ Detailed | ❌ | ✅ Per-file reasoning | ✅ JSON |
| Creative writing | ✅ Detailed | ✅ 1-2 examples | ❌ | ❌ Free |
| Math / logic | ❌ Not needed | ❌ | ✅ Required | ✅ Final answer |
| Product description rewriting | ✅ Brief | ✅ 2-3 examples | ❌ | ❌ Free text |
FAQ
Can few-shot and CoT be used together?
How long should the system prompt be?
How much does temperature affect output?
How do I know if my prompt needs optimization?
Do these techniques work the same on open models and GPT?
Where is pricing?
Related reading
- JSON Structured Output Guide — deeper dive on format constraints
- LLM Evaluation Methodology — measuring prompt effectiveness
- Context Engineering Guide — managing the window budget
- Agent Framework Guide — prompt design in agent systems
- Pricing — live cloud pricing