Cookbook

Version-Control Prompts

Prompts are code. Version them, track which version each trace used, and compare performance across versions. 2Signal's prompt template system gives you immutable, auto-incrementing versions with variable extraction built in.

Step 1: Create a Prompt Template

Use the REST API to create a new prompt template. Variables wrapped in {{double_braces}} are automatically extracted and stored as metadata.

curl -X POST https://your-instance.2signal.dev/api/v1/prompt-templates \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "support-agent",
    "content": "You are a helpful customer support agent for {{company_name}}. Answer questions about {{topic}} concisely and accurately.",
    "description": "Main support agent system prompt",
    "commitMessage": "Initial version"
  }'

This creates the support-agent template at version 1. The variables company_name and topic are extracted automatically from the content.

Step 2: Push a New Version

To iterate on a prompt, push a new version by posting to the same endpoint with the same name. The previous version remains immutable and available.

curl -X POST https://your-instance.2signal.dev/api/v1/prompt-templates \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "support-agent",
    "content": "You are a helpful customer support agent for {{company_name}}. Answer questions about {{topic}} concisely. If unsure, say so rather than guessing. Always include a follow-up question.",
    "commitMessage": "Add uncertainty handling and follow-up prompting"
  }'

Version 2 is created. Version 1 is still available and any traces that used it retain the reference.

Step 3: Resolve a Template in Your Agent

Fetch the latest version by name, or pin to a specific version:

# Latest version
curl "https://your-instance.2signal.dev/api/v1/prompt-templates?name=support-agent" \
  -H "Authorization: Bearer your-api-key"

# Specific version
curl "https://your-instance.2signal.dev/api/v1/prompt-templates?name=support-agent&version=1" \
  -H "Authorization: Bearer your-api-key"

Step 4: Use in Python

Fetch the template at runtime and substitute variables before passing it to your LLM:

import httpx

def get_prompt(name: str, version: int | None = None) -> dict:
    params = {"name": name}
    if version:
        params["version"] = version
    resp = httpx.get(
        "https://your-instance.2signal.dev/api/v1/prompt-templates",
        headers={"Authorization": "Bearer your-api-key"},
        params=params,
    )
    return resp.json()["data"]

template = get_prompt("support-agent")
prompt = (
    template["content"]
    .replace("{{company_name}}", "Acme")
    .replace("{{topic}}", "billing")
)

Step 5: Compare Versions

Every LLM span records the promptTemplateVersionId it used. This means you can filter traces by prompt version in the dashboard and compare evaluator scores across versions. For example, after rolling out version 2 of your support agent prompt, you can check whether the LLM_JUDGE pass rate improved compared to version 1 — all without changing your evaluation setup.

What's Next

Have questions? Join our community!

Connect with other developers and the 2Signal team.

Join Discord