Prompt templating and versioning

GuideLast reviewed Oct 16, 2026By Himanshu Ramchandani
Short answer

A prompt is part of your application's logic, so manage it like code. Keep each prompt in its own file as a template with named variables, store it in Git, give it a version, log that version with every model call, review changes in pull requests, and run your test set before a new version goes live. When something goes wrong in production, you should be able to say exactly which prompt version produced the answer and roll back to the previous one in minutes.

Why prompts need versions

In many projects, the prompt starts as a string in the middle of a Python file. Someone edits it to fix one complaint, someone else adds a rule a week later, and after a few months nobody knows why each line is there, which version produced last Tuesday's bad answer, or whether the latest change made things better or worse.

A small change in a prompt can change behaviour across thousands of requests. That makes prompts as important as code, and they need the same discipline: history, review, tests and the ability to roll back.

Templates

A template is a prompt with placeholders for the parts that change per request.

You summarise customer support emails for {company_name}.

Write a summary in {language} of at most {max_words} words.

Email:
<email>
{email_text}
</email>

Fill it with a simple, strict templating approach. Python's str.format or string.Template is enough for many projects, and Jinja2 is useful when you need loops or conditions, like including a list of retrieved chunks.

from pathlib import Path
from string import Template

template = Template(Path("prompts/summarise_email/v3.txt").read_text())

prompt = template.substitute(
    company_name="Acme Electronics",
    language="English",
    max_words=25,
    email_text="My order ORD-123456 hasn't arrived and it's been 10 days.",
)

substitute raises an error if a variable is missing, which is what you want: a prompt sent with a missing value is a silent bug.

Escape or clearly delimit user-provided values, so a user can't break the structure of your template with their input.

Store prompts as files

Keep prompts out of the code and in their own files, one folder per prompt.

prompts/
    summarise_email/
        v1.txt
        v2.txt
        v3.txt
        config.yaml
        CHANGELOG.md
    answer_question/
        v1.txt
        config.yaml

The config.yaml can hold the settings that belong with the prompt: the model, temperature, maximum tokens, the output schema and which version is live. A prompt version is only reproducible together with these settings, because the same text behaves differently on a different model or temperature.

The changelog says what changed in each version and why, with a link to the test results.

Log the version with every call

Every model call should log the prompt name and version, along with the model and settings. When a user reports a bad answer, you can find the exact prompt that produced it, reproduce it, and test the fix against it.

Review changes like code

Changes to prompts go through pull requests. The description says what changed, why, and how it was tested, with the evaluation results before and after. Reviewers look for contradictions with existing rules, unclear wording, and changes that could affect other cases.

Test every version

Before a new version goes live, run it on your prompt test set and compare it with the current version on the same inputs. Automate this in your CI pipeline, so a prompt change that lowers the pass rate can't be merged without someone deciding to accept it.

Rolling out a new version

For important prompts, don't switch everyone at once.

  • Shadow mode: run the new version alongside the current one on real traffic, without showing its answers, and compare.
  • Gradual rollout: send a small share of traffic to the new version, watch your metrics, then increase.
  • Quick rollback: switching the live version should be a configuration change, not a code deployment.

Prompt management tools

As the number of prompts and people editing them grows, dedicated tools help. LLM observability platforms like Langfuse, LangSmith and others include prompt registries that store versions, link them to traces, and let non-engineers propose changes. They are useful, but files in Git with good logging cover most teams' needs for a long time.

From the floor

I haven't taught prompt versioning as its own topic in a session yet, so this page is written from documentation and standard practice. The part I repeat in every build applies here too: when you change something, run your earlier test cases again to check that the other parts are still working, and a prompt change is a code change.

Next step

Read prompt caching.

Sources