Skip to content

All lessons

Area 07 // DeploymentLesson 121 / 14014 min read

Prompt versioning, model versioning and registries

Prompts, model choices and fine-tuned weights change an AI app's behaviour as much as code does, so each needs an immutable version, a record of how it was evaluated, and a registry with labels like "production" that you can move forward to release or back to roll back.

Think of it like this

Analogy

A publisher prints editions of a book: the second edition is never edited after printing; corrections become the third edition. A shop's "current edition" sign can point at any edition, and if the new one has a misprint, the sign goes back to the previous edition. Every sale receipt records which edition was sold.

The problem it solves

Someone edits the system prompt in a dashboard on Tuesday; on Thursday users complain. Which prompt was live when? What else changed? Was it evaluated? Model providers also update models and aliases, and fine-tuned models get retrained. Without versions, labels and records, you can't explain an answer, reproduce a bug, or roll back with confidence.

How it works: prompt versioning

  1. Treat prompts as artifacts: the template, the model it's meant for, parameters (max_tokens, tools, output schema) and few-shot examples together form one version.
  2. Store them in git (reviewed in pull requests: Git and GitHub) or in a prompt management tool (e.g. Langfuse) that keeps every version.
  3. Make versions immutable: a version number or content hash; changes create new versions (see the code).
  4. Use labels (production, staging) that point at versions; the app fetches by label (with caching and a fallback), so releasing or rolling back is moving a label.
  5. Evaluate before promoting: an eval gate runs on the new version; record its scores with the version.
  6. Log the version on every trace (tracing).

How it works: model versioning

  1. Pin exact model IDs or dated snapshots in config; treat aliases that move (like "latest") as risky in production.
  2. Track deprecations: providers retire models; plan migrations with evals before deadlines.
  3. Version your own models (fine-tunes, embedding models, rerankers): weights, training data version, code commit, hyperparameters and eval results (LoRA).
  4. Embedding models are special: changing one means re-embedding the whole index; version the index together with the model.
  5. Release model changes like code: eval gate, canary, monitoring (release strategies).

How it works: model registries and MLOps

  1. A model registry stores model versions with metadata and lineage, plus stage labels or aliases (e.g. MLflow Model Registry, cloud ML platforms, or private Hugging Face Hub repos with revisions).
  2. MLOps is the practice around it: reproducible training pipelines, data and model versioning, automated evaluation, deployment, monitoring for drift, and retraining.
  3. The flow: train or fine-tune → register version with metrics → evaluate → promote label to staging → canary → production; keep previous versions for rollback.
  4. For API-model apps, the "registry" may simply be versioned config: prompt versions, model IDs and parameters in git, with releases tagged.
Versions never change; labels move. Rollback moves the label back.

See it in code

Needs
Nothing: plain Python 3. Prompt tools and model registries offer the same idea with a UI, history and access control.

A tiny registry: content-hashed versions, movable labels, and a rollback that just moves a label.

registry.py
import hashlib, json
 
# A tiny prompt + model registry: every version is immutable and identified by a content hash;
# "labels" (production, staging) are movable pointers, so rollback = move the label back.
REGISTRY = {"versions": {}, "labels": {}}
 
def register(name: str, template: str, model: str, params: dict) -> str:
    body = {"template": template, "model": model, "params": params}
    vid = hashlib.sha256(json.dumps(body, sort_keys=True).encode()).hexdigest()[:8]
    REGISTRY["versions"][f"{name}@{vid}"] = body
    return f"{name}@{vid}"
 
def promote(label: str, version: str):
    REGISTRY["labels"][label] = version
    print(f"{label:10} -> {version}")
 
def get(label: str) -> dict:
    return REGISTRY["versions"][REGISTRY["labels"][label]]
 
v1 = register("support-answer", "Answer using the sources. Cite like [1].\n{sources}\nQ: {question}",
              "claude-haiku-5-5", {"max_tokens": 500})
v2 = register("support-answer", "Answer ONLY from the sources, cite every sentence like [1]. "
              "If unsure, say so.\n{sources}\nQ: {question}", "claude-sonnet-5-5", {"max_tokens": 600})
promote("production", v1)
promote("staging", v2)
promote("production", v2)          # after the eval gate passed on staging
promote("production", v1)          # rollback: just move the label, nothing is redeployed
print("serving:", get("production")["model"], "| versions stored:", len(REGISTRY["versions"]))
Output
production -> support-answer@4cb6248e
staging    -> support-answer@a78a4bef
production -> support-answer@a78a4bef
production -> support-answer@4cb6248e
serving: claude-haiku-5-5 | versions stored: 2

The hash covers the template, model and parameters together, so changing any of them makes a new version. Model IDs are as of November 2026.

A real example

Example

Explaining one bad answer

A customer forwarded a wrong answer from a bank's assistant, dated three weeks earlier. Because every trace stored the prompt version, model snapshot, retrieval index version and the retrieved chunks, the team found it in minutes: prompt faq@b71c with an index built before a fee change. The prompt was fine; the index was stale. They added an index-freshness check to the release checklist, and could show the regulator exactly which configuration produced the answer.

The easy way

Start here

Keep prompts in files in your repo next to the code, with the model ID and parameters in the same config file, and log the git SHA (which identifies all of them) on every request. Move to a prompt management tool when non-engineers need to edit prompts.

When you grow: the production setup

Teams use a prompt management system with immutable versions, labels per environment, access control and eval scores attached; a model registry for fine-tuned and embedding models with lineage; index versions tied to embedding models; release automation that promotes labels after gates and canaries; and traces carrying every version ID.

Trade-offs

What you gain

  • Any answer can be traced to an exact configuration.
  • Instant, safe rollbacks.
  • Changes are reviewed and evaluated before release.

What it costs you

  • Another system or process to maintain.
  • Prompt tools fetched at runtime add a dependency (cache with fallback).
  • Discipline needed to stop "quick edits" in production.

When not to use it

  • Never skip versioning for production prompts; even a single prompt file in git is a version history.

Common mistakes

  • Editing production prompts in place with no history.
  • Using model aliases that silently change.
  • Changing the embedding model without re-indexing.
  • Not logging prompt and model versions on traces.
  • Promoting versions without running evals.

Interview questions

Try answering out loud first, then open the model answer.

How do you version prompts in production?

Model answer

Treat each prompt (template, model, parameters, examples, schema) as an immutable version with an ID or hash, stored in git or a prompt management tool; reference it by labels per environment; promote after eval gates and canaries; roll back by moving labels; cache prompts in the app with a fallback; and log the version on every trace.

What is a model registry and why use one?

Model answer

A system that stores model versions with metadata (training data, code, hyperparameters, metrics, lineage) and stage labels or aliases. It provides a single source of truth for which model runs where, supports reproducibility and audit, and enables controlled promotion and rollback.

How do you handle a provider deprecating the model you use?

Model answer

Track deprecation notices; evaluate candidate replacements on your golden set (quality, cost, latency, safety); adjust prompts; release the new model behind a flag or canary with monitoring; keep the old one available until the deadline for rollback; and update pinned IDs in versioned config.

Quiz

Pick an answer to see whether it’s right and why.

  1. 01Why should a prompt version be immutable?
  2. 02How does a rollback work with a registry?
  3. 03Why pin an exact model snapshot instead of an alias like 'latest'?
  4. 04What should each trace record?
  5. 05What is a model registry?

0 of 5 answered

Key terms

Prompt versioning
Storing every prompt change as a numbered version, so you can review, test, deploy and roll back prompts like code.
Model versioning
Pinning and recording exact model versions (provider snapshots or your own trained weights) so behaviour is reproducible and changes are deliberate.
Model registry
A store of model versions with their metadata, metrics and lineage, plus labels showing which version runs in which environment.
MLOps
The practices and tools for reliably training, versioning, evaluating, deploying and monitoring machine learning models.
Immutable version
A version that can never be edited after it is created; changes always produce a new version.

Before and after

Progress is saved in this browser only.