Treating Prompts Like Code: Versioning, Review, and Rollback
A one-line edit in a web console changes behavior across every request, with no history and no way back. Prompts in the repo, rendered hashes in the logs, eval results in the PR — and a quarterly prune.
Prompts are the highest-leverage, least-governed artifact in most agent systems. A one-line edit changes behavior across every request, and in a lot of teams that edit is made in a web console, by one person, with no review, no history, and no way back except remembering what it said before.
The fix isn't a specialized platform. It's applying the practices you already use for code, with a few adjustments for what makes prompts different.
Put them in the repository
The default should be prompts as files in version control, next to the code that uses them. This buys diffs, blame, review, branching, and rollback for free.
The argument against — non-engineers need to edit them — is real but usually solvable: a small editing interface that opens a pull request, rather than one that writes to production. The people who need to edit prompts also benefit from review; they're rarely the ones asking to skip it.
prompts/
support_agent/
system.md
tools/refund.md
routes/billing.md
extractor/
system.md
Splitting by role and route rather than one large file makes diffs meaningful and lets route-specific changes be reviewed by the people who own that route.
Version the rendered string, not just the template
Prompts are usually assembled — a base plus route-specific sections plus injected values. What matters for reproducibility is what the model actually received.
Log a hash of the rendered prompt on every call, alongside the template version. When a run misbehaves, the hash tells you exactly which text was in play. Without it, you know which template version was deployed and not what it rendered to for that particular request.
Review prompts as behavior changes
A prompt diff needs a different reading than a code diff. What to ask:
- What behavior is this meant to change? Stated in the PR description, testable.
- What else might it change? Prompt instructions interact; a line added to encourage thoroughness affects every request, not the one that prompted it.
- Is this the right place for it? Tool-specific rules belong with the tool; deterministic rules belong in code. ⚠️ Review is the natural checkpoint for stopping system prompts from accumulating things that belong elsewhere.
- Does it duplicate or contradict an existing line? Long prompts commonly contain mutually inconsistent instructions added months apart.
✅ Require eval results in the PR. A prompt change without a before/after comparison is an untested behavior change, and the tooling to produce one is a script.
Rollback must be one action
Because a prompt change can degrade behavior in ways evals miss, reverting has to be trivial:
- Prompt version pinned in deploy config, not baked into an image.
- Previous versions retained and immediately selectable.
- Rollback independent of code deployment — you should not need to ship code to revert a sentence.
If a prompt lives in a database edited through an admin panel, keep every version and make restoring one a single click. The failure to avoid is a production prompt whose previous text exists nowhere.
What's genuinely different from code
Three things justify small deviations from normal code practice:
Effects are non-local and non-obvious. You can't read a prompt diff and reason reliably about its consequences. This is why eval results in the PR matter more here than for a typical code change.
They're multi-author by nature. Domain experts write better constraint language than engineers. The workflow should welcome that, with review as the safety net rather than access restriction.
They drift against the model. A prompt tuned to compensate for one model version's tendencies can be counterproductive on the next. Prompts need periodic pruning in a way code doesn't — a scheduled review that removes lines whose original reason has expired.
🔍 The audit worth running quarterly
For each line in a long prompt: remove it, run the eval suite, see if anything changes.
A meaningful share of accumulated lines have no measurable effect — added alongside a real fix and credited with it. Removing them shortens the prompt, improves adherence to what remains, and cuts cost on every call. It's the cheapest quality improvement available to a mature agent, and nothing else will prompt you to do it.
The takeaway
Prompts in the repository, split by role and route, with the rendered hash logged on every call. Review them as behavior changes with eval results attached, keep rollback to a single action independent of code deploys, and prune periodically — because the lines that accumulate are rarely the lines that work.