Appearance
Prompt Templates & Variables
A prompt hardcoded with data is a script. A prompt with variables is a function. Templates separate the prompt logic from the data, making prompts reusable, testable, and version-controlled. This lesson covers Jinja2-style templating, variable management, and treating prompts as code.

What you'll learn
- Templates separate prompt structure from data, same prompt, different inputs, consistent output format
- Jinja2 or Python's
string.Templateare the standard tools, avoid string concatenation - Version control the template, not the rendered output. The template is the source of truth
Build it
Step 1: Python string.Template
Python's string templates allow you to define a static prompt structure and inject variables at runtime.
python
from string import Template
SUPPORT_TEMPLATE = Template("""You are a customer support agent for $company.
## User Info
Name: $customer_name
Plan: $plan_type
## Recent Orders
$recent_orders
## Message
$user_message
Respond in 2-3 sentences. Be helpful and concise.""")
prompt = SUPPORT_TEMPLATE.substitute(
company="Acme Corp",
customer_name="Alice",
plan_type="Premium",
recent_orders="Order #12345: Shipped\nOrder #12346: Processing",
user_message="Where is my order?",
)Step 2: Jinja2 for complex logic
Jinja2 provides advanced templating features like loops and conditionals for building complex, dynamic prompts.
python
from jinja2 import Template
template = Template("""You are a code reviewer. Focus on: {% for area in focus_areas %}{{ area }}{% if not loop.last %}, {% endif %}{% endfor %}.
Review:
```python
{{ code }}{% if include_tests %} Also check that tests cover the new code. {% endif %}""")
prompt = template.render( focus_areas=["security", "performance", "style"], code="def foo(): pass", include_tests=True, )
### Step 3: Store templates as files
Storing templates as YAML files separates prompt configuration from your application code, enabling version control and schema validation.
```yaml
# prompts/support/response.yaml
name: customer-support-response
version: 2.0.0
template: |
You are a customer support agent for {{ company }}.
## User Info
Name: {{ customer_name }}
Plan: {{ plan_type }}
## Message
{{ user_message }}
Respond in 2-3 sentences.
variables:
company:
type: string
required: true
customer_name:
type: string
required: true
plan_type:
type: string
default: "Basic"
user_message:
type: string
required: trueWhat goes wrong
| Mistake | How you notice it | The fix |
|---|---|---|
| Variable not escaped | Special characters in user input break the prompt format | Use template engines that auto-escape. Never use str.replace() for variable substitution |
| Missing variable | Template.render() raises KeyError | Validate all required variables before rendering. Provide defaults for optional ones |
| Template too complex | Conditionals and loops make the template hard to read | If the template has more than 3 conditionals, split it into multiple templates |
| Template and data drift apart | Template expects customer_name but code passes name | Use a schema to validate variables. Pydantic models or JSON Schema catch mismatches |
Confirm it worked
Ensure your templates render correctly by validating variable substitution before sending the prompt to the model.
python
from string import Template
t = Template("Hello, $name. Your order $order_id is $status.")
result = t.substitute(name="Alice", order_id="12345", status="shipped")
assert "Alice" in result and "12345" in result and "shipped" in result