Vocabulary for this course

The terms the chapters assume, in plain words. You can open this from any chapter.

constraint
A limit on the answer that a program can check, such as a length, an allowed label or a required citation.
context
The background material the model needs to answer well, kept separate from the thing it must act on.
continuation
The text a model writes next, given everything that came before it.
delimited block
Text wrapped by matching markers, such as triple backticks, so its edges are unmistakable.
distribution
The pattern of how often each possible value appears, or how likely each one is.
few-shot example
A worked input and answer pair placed in the prompt so the model can copy the pattern.
instruction
The sentence that names the task, usually starting with a verb.
JSON
A text format for structured data built from names, values, lists and nested braces.
model
The trained program that reads text and predicts what comes next.
output contract
The part of a prompt that states the shape of a valid answer, in words a checker can enforce.
parser
The code that turns the model's text into a value your program can use.
prompt
Everything sent to the model in one request: instructions, background, the input and the answer's required shape.
prompt injection
Text that tries to give the model orders, either typed by a user or hidden inside a document it reads.
register
The level of formality and the kind of wording suited to a particular audience or setting.
schema
A named set of fields with their types and allowed values, used to check an answer's shape.
system message
The opening instruction the model treats as standing policy for the whole exchange.
temperature
A setting that controls how much randomness the model adds when choosing each token.
token
A chunk of text — often part of a word — that the model reads and bills for.
user message
A turn written by the person using the app, treated as data rather than standing policy.

Prompt engineering from the ground up

Versioning and review

A prompt is a decision the product makes on every request, so it needs a history, a reviewer and a way back. Versions stay fixed; labels move.

Part 8 of 10

Intermediate14 min readBack to Courses

A prompt is source code

The prompt decides what the product does, so it changes for the same reasons code does: a bug report, a new policy, a model upgrade. When it lives as a string in a dashboard, that change has no diff, no reviewer and no way back. The next person to open it cannot tell whether a phrase was deliberate or left over from an experiment that ended months ago. The interface encourages the edit and records none of the reasoning behind it.

Versioning is the smallest fix. Every edit becomes a new numbered version with an author, a date and one sentence about why it exists. The old version stays readable, so an incident can be reproduced against the exact text that caused it rather than a reconstruction from memory. A rollback then becomes a single action instead of an emergency rewrite under pressure, which is when most second incidents happen. A version number is also the only handle a bug report can quote.

Immutable versions, movable labels

The useful split is between a version and a label. A version is immutable: once published, its text never changes, and its number only ever refers to that text. A label is a pointer — production, staging, canary — and moving a pointer is what a release means. The prompt a request used is then two facts, not one. Both live in the same store, and a version is never rewritten.

This is the same idea as a container tag that resolves to a digest. If editing version three in place were allowed, two requests a minute apart could run different prompts under the same name, and no log would show it. Immutability is what makes the version number in a log line trustworthy, and trust is the only reason to write it down. A request that cannot name its version is a request you cannot debug later.

Resolving a label with Langfuse

from langfuse import Langfuse

langfuse = Langfuse()

# The label resolves to an immutable version. Moving the label is the release.
prompt = langfuse.get_prompt("support-reply", label="production")
messages = prompt.compile(question=question, plan=plan)

reply = client.chat.completions.create(model="gpt-4o-mini", messages=messages)
print(prompt.version)  # log this beside the request id

A registry with versions and labels

Run the registry, then promote version three to production and print both labels again. Notice that the version numbers never change, only the pointers.

Output
Click "Run" to execute your code

What a review actually needs

Reviewing a prompt is not proofreading. The reviewer needs the diff, the reason, and the evidence: a fixed set of cases run against the old and the new version, with the outputs side by side. Without that table, approval is only an opinion about wording, and opinions do not catch a model that started refusing a category of question. The diff shows what the reader will see; the table shows what the model will do.

Keep the set small enough to read — twenty cases is usually enough to catch a regression in tone, format or refusal — and include the cases that failed before. A prompt change that fixes one case and silently breaks two is the normal failure, and only a comparison shows it. The reviewer should be able to say which cases changed and whether each change was intended. Attach the table to the change, not to a chat thread that will be lost.

Log the prompt id and version with every request. A label that moves without a record turns an incident into a guess about which text was live at 14:02.

Promote gradually, keep the receipt

A release should move a label, not edit text. Send a small share of traffic to the new version, compare the metrics that matter, then promote or roll back. The comparison is only honest if both versions run on the same inputs at the same time, so route by request id rather than by day, or the two samples will differ for reasons that have nothing to do with the prompt. A canary that shares no inputs with the control group measures the day, not the prompt.

Record every promotion in an append-only log: who moved which label, from which version to which, and why. That log answers the only question that matters during an incident — what changed, and when — without asking five people to check their memory. It also makes a canary reviewable after the fact, which is what turns a habit into a process. The log is short, boring, and the first thing you open when something breaks.

Promote, log, roll back

Run a promotion and a rollback, then read the audit log. Every line names the label, the old version and the new one, so the history is reconstructable.

Output
Click "Run" to execute your code

Check what you learned

One question at a time. A wrong answer explains itself — take another go.

Part 1 of 5

Why should a prompt be versioned like code?