Introduction
Prompt engineering has emerged as a critical skill for building LLM-powered applications. The difference between a good prompt and a great one can mean the difference between a useful AI and a frustrating one. This comprehensive guide covers advanced prompt engineering techniques used by top practitioners.
Prompt engineering is the art and science of crafting inputs that get the best outputs from language models.
Prompt Anatomy
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Anatomy of a Prompt โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ SYSTEM PROMPT (invisible instructions) โ โ
โ โ "You are a helpful coding assistant specialized..." โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ CONTEXT (background information) โ โ
โ โ "The following is a conversation about Python..." โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ FEW-SHOT EXAMPLES (demonstrations) โ โ
โ โ Input: 2+2 โ โ
โ โ Output: 4 โ โ
โ โ โ โ
โ โ Input: 3+3 โ โ
โ โ Output: ___ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ USER QUERY (what you want) โ โ
โ โ "Explain what a closure is in JavaScript" โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Fundamental Techniques
1. Zero-Shot Prompting
# No examples - just ask
prompt = """Classify the sentiment of this review as positive, negative, or neutral:
Review: "The product works great, I'm very satisfied!" """
# Result: Positive
2. Few-Shot Prompting
# Provide examples
prompt = """Classify the sentiment:
Input: "Love this product!"
Output: positive
Input: "Terrible experience, would not recommend"
Output: negative
Input: "It was okay, nothing special"
Output: neutral
Input: "Absolutely love it!" """
3. Chain-of-Thought (CoT)
# Encourage step-by-step reasoning
prompt = """Solve this problem step by step:
Problem: If a train travels 120 miles in 2 hours, what is its average speed?
Let's think step by step:
1. Distance traveled = 120 miles
2. Time taken = 2 hours
3. Speed = Distance / Time
4. Speed = 120 / 2 = 60 miles per hour
Answer: 60 miles per hour
---
Now solve this:
Problem: A store sells 3 items for $30. How much would 10 items cost?"""
Advanced Techniques
Tree of Thoughts
prompt = """Explore multiple solution paths for this problem:
Problem: Find the most efficient route to visit all these cities once: New York, Los Angeles, Chicago, Houston
Let's explore several approaches:
Approach 1: Nearest Neighbor
1. Start in New York
2. Go to nearest unvisited (Chicago)
3. Continue to nearest (Houston)
4. End in Los Angeles
Total: NYโChiโHouโLA
Approach 2: Greedy by distance
1. Calculate all pairwise distances
2. Choose shortest leg repeatedly
Approach 3: Brute force enumeration
1. Try all permutations (n! = 24 for 4 cities)
2. Find minimum
Best approach: For small n, brute force. For large n, nearest neighbor with 2-opt improvement.
---
Now solve: Route optimization for Boston, Seattle, Miami, Denver"""
ReAct (Reasoning + Acting)
prompt = """Answer the question by interleaving reasoning and actions:
Question: What is the capital of France?
Thought 1: I need to find the capital of France. I know this is a factual question.
Action 1: Recall from knowledge
Observation 1: Paris is the capital of France.
Thought 2: I have the answer from my knowledge.
Final Answer: Paris
---
Question: What year was the iPhone first released?
Thought 1: This is about a specific product release date.
Action 1: Recall from knowledge
Observation 1: The first iPhone was released in 2007.
Thought 2: I found the information.
Final Answer: 2007
---
Question: {user_question}"""
Self-Consistency
prompt = """Solve the problem in multiple ways and check for consistency:
Problem: A store is having a 20% discount. After the discount, there's a 10% sales tax. If an item costs $100 before everything, what's the final price?
Method 1: Apply discount then tax
- Original: $100
- After 20% off: $100 ร 0.80 = $80
- After 10% tax: $80 ร 1.10 = $88
Method 2: Calculate combined multiplier
- Combined: 0.80 ร 1.10 = 0.88
- Final: $100 ร 0.88 = $88
Methods agree! Final answer: $88
---
Problem: If you invest $1000 at 5% annual interest compounded yearly, how much after 3 years?"""
Prompt Patterns
1. Persona Pattern
prompt = """You are an experienced senior software engineer with 20 years of experience.
Your communication style is clear, practical, and focuses on battle-tested solutions.
When explaining concepts, you use real-world analogies from production systems.
Question: Explain why we should use dependency injection."""
2. Template Pattern
prompt = """Fill in the template for {language}:
Template:
1. Define [concept] as [brief description]
2. Show typical usage in {language}
3. Explain common pitfalls
4. Give best practice recommendation
Fill for: Error handling in {language}"""
3. Refusal Breaker
prompt = """The user is asking: "{question}"
If this is something you cannot help with, say:
"I understand you're asking about [topic], but I'm not able to help with that specific request."
If you can help, provide a helpful response.
Now respond to: {actual_question}"""
4. Context Manager
prompt = """You are helping a user with {context}.
Important context:
- The user is a {experience_level} developer
- They are working on {project_type}
- Their main concern is {main_concern}
Provide an answer that's appropriate for {experience_level} level, focusing on {main_concern}."""
5. Chain of Verification
prompt = """Answer the question, then verify your answer:
Question: {question}
Follow these steps:
1. Provide your initial answer
2. List the assumptions you made
3. Check each assumption against known facts
4. Revise if needed
5. Give final answer
Begin:"""
Handling Common Challenges
1. Output Formatting
# Control output structure
prompt = """Generate a user profile as JSON with exactly these fields:
{
"name": "<string>",
"email": "<string>",
"roles": ["<array of strings>"],
"metadata": {
"created": "<ISO date string>",
"verified": <boolean>
}
}
Generate a sample user:"""
2. Length Control
# Limit response length
prompt = """Explain quantum computing in exactly 3 sentences,
using simple language that a 10-year-old could understand."""
3. Handling Uncertainty
# Acknowledge limitations
prompt = """Answer the question. If you're not certain about something,
explicitly say "I'm not confident about X because..." rather than guessing.
Question: {question}"""
4. Bias Mitigation
# Reduce bias
prompt = """When answering, consider multiple perspectives and avoid
assumptions about gender, race, age, or background unless explicitly stated.
Question: {question}"""
Building Robust Prompts
The Prompt Engineering Framework
def build_prompt(
task: str,
context: str = None,
examples: list = None,
constraints: list = None,
format: str = None
) -> str:
parts = []
# 1. Context
if context:
parts.append(f"Context: {context}")
# 2. Constraints
if constraints:
parts.append(f"Constraints: {', '.join(constraints)}")
# 3. Few-shot examples
if examples:
for ex in examples:
parts.append(f"Example: {ex}")
# 4. Task
parts.append(f"Task: {task}")
# 5. Format
if format:
parts.append(f"Output format: {format}")
return "\n\n".join(parts)
# Usage
prompt = build_prompt(
task="Summarize this article",
context="Technical article about AI",
examples=[
"Input: AI is transforming... Output: AI is revolutionizing technology",
"Input: Machine learning is... Output: ML enables computers to learn"
],
constraints=["3 sentences max", "Begin with 'The article discusses'"],
format="Plain text"
)
A/B Testing Prompts
prompt_variations = {
"direct": "Explain what a closure is in JavaScript",
"detailed": """You are a JavaScript expert.
Explain closures to a developer who understands JS basics but wants to deepen their understanding.
Include:
- A clear definition
- A practical code example
- A common use case""",
"few_shot": """Explain JavaScript closures:
Example 1:
Code: const counter = () => { let n=0; return ()=>++n; }
Explanation: Creates a private counter that persists between calls
Example 2:
Code: function outer(x) { return function(y) { return x+y; } }
Explanation: x is captured from outer scope
Now explain:"""
}
# Test each
results = {}
for name, prompt in prompt_variations.items():
response = llm.complete(prompt)
results[name] = {
"response": response,
"length": len(response),
"quality_score": evaluate_quality(response)
}
Production Patterns
Prompt Versioning
from dataclasses import dataclass
from datetime import datetime
@dataclass
class PromptVersion:
version: str
prompt: str
created_at: datetime
metrics: dict
def __str__(self):
return f"v{self.version}: {self.created_at:%Y-%m-%d}"
# Store in version control
prompts = {
"summarizer": [
PromptVersion("1.0", "Summarize: {text}", datetime(2026, 1, 1), {"accuracy": 0.85}),
PromptVersion("1.1", "Provide a concise summary of: {text}", datetime(2026, 2, 15), {"accuracy": 0.92}),
]
}
Prompt Templates with Jinja
from jinja2 import Template
system_prompt = Template("""You are a {{ role }} for a {{ project_type }} project.
Your expertise includes: {{ expertise|join(', ') }}.
When answering:
- Be {{ tone }}
- Focus on {{ focus_area }}
- Consider the user's experience level: {{ user_level }}""")
# Render
prompt = system_prompt.render(
role="technical advisor",
project_type="e-commerce platform",
expertise=["backend", "scalability", "security"],
tone="practical and concise",
focus_area="production-ready solutions",
user_level="senior developer"
)
Prompt Evaluation
def evaluate_prompt(prompt: str, test_cases: list) -> dict:
results = []
for case in test_cases:
input = prompt.format(**case["inputs"])
output = llm.complete(input)
results.append({
"input": case["inputs"],
"expected": case["expected"],
"actual": output,
"correct": evaluate(output, case["expected"])
})
return {
"accuracy": sum(r["correct"] for r in results) / len(results),
"failed_cases": [r for r in results if not r["correct"]],
"avg_length": sum(len(r["actual"]) for r in results) / len(results)
}
Best Practices Summary
| Technique | When to Use |
|---|---|
| Zero-shot | Simple, common tasks |
| Few-shot | Task requires specific format or style |
| Chain-of-thought | Complex reasoning required |
| Tree-of-thought | Multiple solution paths |
| Self-consistency | Verification important |
| ReAct | Need external knowledge/actions |
Conclusion
Prompt engineering is both art and science. The key principles:
- Be specific - Clear instructions yield better results
- Show, don’t just tell - Few-shot examples help
- Break down complex tasks - Chain thoughts together
- Test and iterate - Prompt optimization is empirical
- Consider the user - Match output to audience
Master these techniques, and you’ll build LLM applications that are more reliable, accurate, and useful.
Comments