Developer Prompt Patterns That Actually Work

header 9

# Developer Prompt Patterns That Actually Work

Most developers treat prompts like magic incantations—throw some words at an LLM and hope for the best. That approach wastes tokens and produces mediocre results.

After months of shipping AI-assisted features into production, I’ve found that specific prompt patterns consistently outperform “write me code” by a significant margin. These aren’t theoretical frameworks. They’re copy-pasteable patterns you can use today.

This article breaks down six prompt patterns that work in real development workflows, with code examples you can drop into your next session.

## The System Prompt Foundation

Every solid prompt starts with a well-crafted system prompt. This sets the model’s behavior before you even ask your actual question.

The key insight: tell the model *who it is* and *what constraints it operates under*, not just what to do.

“`python
# Instead of this:
# “Write a Python function to process data”

# Do this:
system_prompt = “””You are a senior Python backend engineer with 15 years of experience.
You write production-quality code with:
– Type hints on all functions
– Docstrings using Google style
– Proper error handling
– No placeholder comments

When asked to generate code, output only the code block with no explanation unless explicitly requested.”””
“`

This works because LLMs are highly context-sensitive. A vague system prompt produces vague code. A specific one gives you exactly what you need.

**What to include in system prompts:**
– Specific language/framework expertise
– Code style preferences (formatting, naming conventions)
– Output format requirements
– Things to avoid (no pseudocode, no TODO comments)

## Few-Shot Learning for Code Generation

Few-shot prompting shows the model examples of what you want. For code, this is incredibly powerful because you can demonstrate your exact style and conventions.

The trick: use real code from your codebase, not made-up examples.

“`python
# Example of few-shot prompting for generating API endpoints

prompt = “””Generate a FastAPI endpoint following our project conventions.

Example from our codebase:
“`python
@router.post(“/users//orders”)
async def create_order(
user_id: int,
order_data: OrderCreate,
db: AsyncSession = Depends(get_db)
) -> OrderResponse:
”’Create a new order for a user.”’
service = OrderService(db)
order = await service.create(user_id=user_id, data=order_data)
return OrderResponse.model_validate(order)
“`

Now generate a similar endpoint for:
– Resource: /products/{product_id}/reviews
– Create a review for a product
– Use ReviewCreate and ReviewResponse models”””
“`

The model learns from the exact pattern: decorator style, dependency injection, docstring format, return type. This produces consistent code that matches your existing codebase.

**When to use few-shot:**
– Generating code that must match existing patterns
– Creating components with specific structure (CRUD, tests, etc.)
– When one-shot prompts produce inconsistent results

## Chain-of-Thought for Complex Logic

For multi-step problems or code requiring careful reasoning, explicitly ask the model to think through the problem first.

This isn’t about being nice to the AI. It’s about getting better results by forcing it to work through the logic before writing code.

“`python
prompt = “””Generate a Python function that calculates options Greeks using Black-Scholes.

Before writing code, reason through:
1. What are the input parameters needed?
2. What are the edge cases (zero time to expiry, zero volatility)?
3. Which formula applies to each Greek (delta, gamma, theta, vega, rho)?
4. How should we handle invalid inputs?

Then implement the function with proper error handling.”””
“`

The reasoning appears in the model’s output before the code. You can verify the logic is sound before using the implementation.

**When to require chain-of-thought:**
– Implementing algorithms with specific formulas
– Code requiring business logic decisions
– Any scenario where bugs have high costs
– When you need to audit the reasoning

## Structured Output Patterns

LLMs are inconsistent with output formats. If you need JSON, XML, or a specific code structure, be explicit—and use the model’s structured output capabilities when available.

“`python
# Using OpenAI’s structured output (or similar with other providers)

from pydantic import BaseModel, Field

class CodeReview(BaseModel):
issues: list[str] = Field(description=”List of issues found”)
severity: list[str] = Field(description=”Severity for each issue: critical, major, minor”)
suggestions: list[str] = Field(description=”Suggested fixes for each issue”)
approval_status: str = Field(description=”One of: approved, changes_requested, needs_review”)

prompt = “””Review this function for security issues, performance problems, and code quality:

“`python
def get_user_data(user_id):
conn = sqlite3.connect(‘app.db’)
cursor = conn.cursor()
cursor.execute(f”SELECT * FROM users WHERE id = “)
return cursor.fetchone()
“`

Provide your review in the specified JSON format.”””

# The model will output valid JSON matching the schema
response = client.beta.chat.completions.parse(
model=”gpt-4o-2024-08-06″,
messages=[{“role”: “user”, “content”: prompt}],
response_format=CodeReview
)
“`

This pattern eliminates parsing headaches and ensures you get exactly the format you need. It’s essential for building AI into applications where you need reliable, parseable output.

**Structured output works well for:**
– Generating code review summaries
– Extracting data from natural language
– Building AI-powered tools and dashboards
– Any programmatic consumption of LLM output

## Code Review and Debugging Patterns

Here’s where AI genuinely shines: explaining code you didn’t write and finding bugs in code you did.

The key is providing enough context for the model to be useful.

“`python
# Debugging prompt pattern

prompt = “””You are debugging a Python application. Given the error, the failing code,
and the relevant context, identify the root cause and provide a fix.

ERROR:
Traceback (most recent call last):
File “app.py”, line 42, in get_user
return cache.get(user_id)
AttributeError: ‘NoneType’ object has no attribute ‘get’

FAILING CODE:
“`python
def get_user(user_id: int) -> User:
cache = None
if settings.CACHE_ENABLED:
cache = redis_client.get(f”user:”)
if cache:
return User.parse_raw(cache)
# … database lookup
“`

CONTEXT:
– redis_client is a Redis client instance
– settings.CACHE_ENABLED is True
– The error occurs on first request after startup

What is the root cause and how do you fix it?”””

# The model correctly identifies that redis_client.get() returns None
# when the key doesn’t exist, not a Redis get method call
“`

Without the error traceback and context, the model would guess. With specific details, it pinpoints the exact issue.

**For code reviews, include:**
– The actual code (not described, but in a code block)
– What the code should do
– Any specific concerns you have
– Your project’s tech stack and conventions

## Combining Patterns for Production

Real-world prompts combine multiple patterns. Here’s a production example that combines system prompt, few-shot, and structured output:

“`python
system_prompt = “””You are a code reviewer for a Python web application.
You provide concise, actionable feedback in JSON format.

Code style rules:
– Use type hints
– Prefer async/await for I/O operations
– No bare except clauses
– Use our custom exceptions from app.exceptions”””

few_shot_example = “””Input:
“`python
async def delete_user(user_id):
await db.delete(user_id)
return {“status”: “ok”}
“`

Output:
“`json
{
“issues”: [
“Missing type hints on function parameters and return”,
“No error handling for database failures”,
“Should verify user exists before deletion”
],
“severity”: [“major”, “critical”, “minor”],
“suggestions”: [
“Add type hints: async def delete_user(user_id: int) -> dict”,
“Wrap in try/except and handle IntegrityError”,
“Add SELECT before DELETE to verify existence”
],
“approval_status”: “changes_requested”
}
“`”””

actual_code = “””“`python
async def process_payment(order_id: int, amount: float):
if amount < 0: raise ValueError("Invalid amount") order = await orders.get(order_id) await payment_gateway.charge(order.user_id, amount) await orders.update(order_id, status="paid") ```""" prompt = f"""{system_prompt} {few_shot_example} Now review this code: {actual_code}""" ``` This single prompt produces consistent, actionable code reviews that integrate directly into your workflow. --- ## Key Takeaways - System prompts set the foundation—be specific about expertise, style, and constraints - Few-shot learning uses real examples from your codebase for consistent output - Chain-of-thought reasoning produces better results on complex logic problems - Structured output eliminates parsing issues and enables production AI integration - Debugging prompts need error traces, failing code, and context to be useful - Combine patterns in production for reliable, repeatable results --- ## Next Steps 1. **Pick one pattern** from this article and use it in your next coding session today 2. **Build a prompt library** — save your best-performing prompts in a file for reuse 3. **Test systematically** — compare results with and without these patterns, measure the difference 4. **Iterate on system prompts** — they're the highest-leverage change you can make These patterns aren't magic. They're engineering. Treat them like any other tool in your stack: apply them where they fit, discard what doesn't work, and keep refining.