Part 2 of 5 · 2 min read
Prompts as files
One new numbered file per version, a fingerprint that catches hand edits, and a readable diff for reviewers.
prompts/
triage/
v1.json
v2.json
v3.json
PromptStore.save() always writes a new numbered file and records a note and a fingerprint, a short hash of the prompt content.
Fingerprint (hash)
A short code computed from the content so that any change to the content changes the code. Here, 12 characters of a SHA-256 hash of the prompt fields. If the stored fingerprint no longer matches the stored prompt, the file was altered.
store = PromptStore("prompts")
v = store.save("triage", spec, note="add 'other', add word limit") # -> 2
spec = store.load("triage") # latest; or store.load("triage", 1)
Why this shape:
- Git does the history. Each version is a small text file, and
git diffandgit blamejust work. - Old versions stay, so a rollback is "load version 2".
- The fingerprint catches accidental hand edits. If someone edits the prompt text in
v1.jsondirectly,loadraises a clear error instead of silently running a different prompt than the one that was tested. Someone who edits both the text and the fingerprint is stopped only by code review, which is what Git is for. difffor reviewers prints changes field by field:
~ context: 'Labels: billing, bug, account, other' -> 'Labels: billing, bug, other'
- Names are checked. A prompt called
../escapeused to write outside the prompts folder. Names now allow only letters, digits,-and_.
Also store with each result which model and which settings (temperature, for example) were used. The fingerprint covers the prompt text, but the same text on another model is a different system.
Check yourself
Someone fixes a typo directly in v2.json without changing the fingerprint. What happens on the next load? (It raises "edited by hand: fingerprint mismatch". The right way is save, which creates v4.json with a new fingerprint and a note.)