Prompts
Write, preview, version, and reuse model instructions without redeploying your application.
Prompts
Prompts are the instructions that shape an LLM response — the system and user templates. In PromptRails, prompts are first-class resources: you can edit and preview them in Studio, share them across agents, and keep an immutable content history without redeploying your application. In API v2 a prompt is content-only: the model, sampling, output schema, and caching that surround the prompt live on the agent version. Publishing that agent version pins the exact prompt version used in production.
Prompt Management Overview
A prompt version contains:
- System prompt — The standing instructions for role, tone, policy, and behavior.
- User prompt — A template that turns runtime input into the message sent to the model.
- Input schema — An optional JSON schema for validating the template’s input.
- Version notes — A changelog entry for why the version exists.
Model assignment, sampling parameters, the output schema, and response caching are configured on the agent version that links to the prompt, not on the prompt itself. Preview a prompt’s rendering while you iterate, then link it to one or more agents when it is ready.
Technical detailsTemplate and schema details
Jinja2 Templating
PromptRails uses Jinja2 templating so the prompt can include values from the execution input. Keep templates readable: most production prompts only need variables, a few conditionals, and simple loops.
Basic Variables
You are a customer support agent for {{ company_name }}.
The customer's name is {{ customer_name }}.
Please help them with their inquiry:
{{ message }}Conditionals
You are a {{ role }} assistant.
{% if language == "spanish" %}
Please respond in Spanish.
{% elif language == "french" %}
Please respond in French.
{% else %}
Please respond in English.
{% endif %}
User query: {{ message }}Loops
Here are the relevant documents for context:
{% for doc in documents %}
Document {{ loop.index }}: {{ doc.title }}
Content: {{ doc.content }}
---
{% endfor %}
Based on the above documents, answer: {{ question }}Filters
Customer name: {{ name | upper }}
Order date: {{ date | default("Unknown") }}
Summary: {{ long_text | truncate(200) }}Input Schema
Use an input schema when the caller or downstream tool expects a stable request shape. Input schemas catch bad requests before the model call. The prompt version owns the input schema; the output schema is configured on the agent version, alongside the model config.
Input Schema
{
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "The user's message"
},
"language": {
"type": "string",
"enum": ["en", "es", "fr", "de"],
"default": "en"
},
"context": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["message"]
}Model Assignment
Model selection lives on the agent version, in model_config:
- Primary model (
model_id) — The default model for execution - Fallback model (
fallback_model_id) — Used if the primary model fails or is unavailable
Models are configured from workspace credentials and then referenced by PromptRails. See Credentials for provider setup.
Temperature, Max Tokens, and Top P
These sampling parameters are set in the agent version’s model_config, not on the prompt:
| Parameter | Default | Range | Description |
|---|---|---|---|
temperature | Provider default | 0.0 - 1.0 | Controls randomness. Lower values produce more deterministic outputs. |
max_tokens | Provider default | Varies by model | Maximum number of tokens in the response. |
top_p | Provider default | 0.0 - 1.0 | Nucleus sampling. Controls diversity by limiting the token pool. |
Use lower temperature for extraction, classification, and policy work. Use higher temperature when the agent is meant to explore ideas or generate varied drafts. Keep max_tokens explicit when the caller or downstream system expects a bounded response. See Agent Versioning for the full model_config reference.
Model Capabilities
Some model controls only appear when the selected model supports them. PromptRails shows these capability-gated settings on the agent version’s model configuration instead of asking teams to memorize which provider supports which feature.
Reasoning
Models with extended reasoning support can expose a Reasoning effort control. Higher effort lets the model spend more on internal reasoning before answering. It is useful for harder analysis tasks, but it can add latency and token usage. Reasoning token counts are reported in traces when the provider returns them.
Web Search
When a model supports provider-native web search, enabling Web search lets the model search during a run and return citations with the response. Citations are captured with the output so the run can be reviewed later.
Structured Output
Structured output constrains the model response to JSON, optionally against a schema you define. Use it when the caller, evaluator, or downstream tool expects a stable shape instead of free-form text.
Structured output and tool calls interact: when a schema is set, the requested response shape takes precedence over free-form tool selection.
Model Deprecation
Models can be marked deprecated when a newer model supersedes them. A deprecated model that is not in use is hidden from new selection; a deprecated model already attached to an agent version stays visible with a warning so existing workflows keep running while the team migrates.
Technical detailsProvider feature and prompt API details
Provider Prompt Caching
Enabling provider-side Prompt caching lets the provider reuse compute for a repeated prompt prefix, such as a long system prompt, document, or few-shot example. This can reduce cost and latency on follow-up calls.
This is distinct from PromptRails-side response caching, which short-circuits the LLM call entirely for identical rendered inputs.
- Some providers use explicit cache breakpoints.
- Some providers cache repeated prefixes implicitly.
- Cached token counts are reported in traces when the provider returns them.
Response Caching
PromptRails supports response caching on the agent version. When cache_timeout is greater than 0, identical rendered prompts can return a cached response without another LLM call.
This is PromptRails-side response caching, distinct from provider prompt-prefix caching. Provider caching reduces the cost of repeated prompt prefixes; PromptRails response caching skips the model call for identical rendered inputs.
from promptrails import PromptAgentConfig
version = client.agents.create_version(
agent_id="your-agent-id",
version="1.1.0",
config=PromptAgentConfig(prompt_id="your-prompt-id"),
cache_timeout=3600, # Cache responses for 1 hour
message="Added caching for translation agent"
)Caching is keyed on the rendered prompt content (after template variables are substituted), so different inputs produce different cache entries.
Creating Prompts
Python SDK
# Create a prompt
prompt = client.prompts.create(
name="Product Description Generator",
description="Generates product descriptions from features"
)
# Create the first version (content-only)
version = client.prompts.create_version(
prompt_id=prompt.id,
system_prompt="You are an expert copywriter who writes compelling product descriptions.",
user_prompt="""Write a product description for:
Product: {{ product_name }}
Category: {{ category }}
Features:
{% for feature in features %}
- {{ feature }}
{% endfor %}
The description should be {{ tone }} and approximately {{ word_count }} words.""",
input_schema={
"type": "object",
"properties": {
"product_name": {"type": "string"},
"category": {"type": "string"},
"features": {"type": "array", "items": {"type": "string"}},
"tone": {"type": "string", "default": "professional"},
"word_count": {"type": "integer", "default": 150}
},
"required": ["product_name", "features"]
},
message="Initial version"
)The model and sampling for this prompt are chosen on the agent version that links to it — see Agent Versioning.
JavaScript SDK
const prompt = await client.prompts.create({
name: 'Product Description Generator',
description: 'Generates product descriptions from features',
})
const version = await client.prompts.createVersion(prompt.id, {
systemPrompt: 'You are an expert copywriter who writes compelling product descriptions.',
userPrompt: `Write a product description for:
Product: {{ product_name }}
Category: {{ category }}
Features:
{% for feature in features %}
- {{ feature }}
{% endfor %}`,
message: 'Initial version',
})Previewing Prompts
Preview a prompt’s rendering to check the template output without running a model:
preview = client.prompts.preview(
prompt_id="your-prompt-id",
input={
"product_name": "Wireless Earbuds Pro",
"category": "Electronics",
"features": [
"Active noise cancellation",
"30-hour battery life",
"IPX5 water resistance"
],
"tone": "enthusiastic"
}
)
print(preview)To run the prompt against a model, execute an agent that links to it — see Agents.
Prompt Status
| Status | Description |
|---|---|
active | The prompt is available for previewing and linking to agents |
archived | The prompt is hidden from normal listings and new setup work |
Related Topics
- Prompt Versioning — Version management and promotion
- Agents — How agents use prompts
- Tracing — Prompt rendering appears as
promptspans in traces