Vocabulary for this course

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

callback
A function the library calls at fixed points in a run, such as when a step starts or ends.
chain
A series of steps where each one passes its result to the next, ending in the answer.
invoke
The method that runs a step once with one input and returns its result.
memory
Stored history from earlier turns, added back to a request so the model can refer to what was said.
message
One labelled turn in a chat request, marked as coming from the system, the user or the model.
model
The trained program that reads a message list and returns the next turn.
output parser
The step that turns a model's raw text into a value your program can use, or raises an error.
pipe
The operator that joins two steps into one new step, running the left side first.
prompt
The text a model receives for one request, built from fixed wording and the values filled into it.
prompt template
A reusable prompt with named blanks that are filled in for each request.
runnable
Any step with a standard way to run it, so steps can be joined without knowing each other's code.
streaming
Sending a reply in pieces as it is produced, rather than waiting for the whole text.
tool
A function exposed to a model, with a name, described inputs and a result.
tool call
A model's request to run a named tool with specific arguments, which your code may accept or refuse.

LangChain from the ground up

Prompts are templates

A prompt with blanks in it is a template: fixed instructions, variable slots, and a rule about what happens when a slot is empty.

Part 2 of 10

Beginner14 min readBack to Courses

The same instructions, different facts

Almost every prompt is the same paragraph with one or two things changed: the user’s question, a piece of context, a tone, a language. Writing that paragraph again for every call is how prompts drift — one copy says “answer briefly”, another forgot to, and now the same application behaves differently depending on which branch ran.

A template fixes the instruction once and leaves named slots for the parts that vary. {topic} and {audience} are not special syntax; they are placeholders that a formatting step replaces before the text is sent.

The drift is easy to miss because each copy looks reasonable on its own. One branch says “answer briefly”, another says “be concise”, a third has no limit at all; the application then appears inconsistent depending on which route the request took. A template makes that impossible: there is one instruction, and a change to it is a single diff that every caller inherits.

Roles are part of the template

Chat models do not take one blob of text. They take a list of messages, each with a role: system sets the behaviour, human is what the user said, ai is what the model said before. A template for a chat model therefore produces a list, not a string.

Keeping the system message separate is not cosmetic. It is the part you control most strongly, it is usually the part you cache, and it is the part that should never contain untrusted user text. A template that concatenates everything into one string throws that separation away.

It also means the template can be cached by role: the system block is identical across calls, while the human block changes. Providers price cached input differently, and keeping the stable text in its own message is what makes that possible. A template that merges the two gives up that option for no gain.

A chat prompt template

from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a {role}. Answer in at most two sentences."),
    ("human", "{question}"),
])

messages = prompt.format_messages(role="database tutor", question="What is an index?")
for message in messages:
    print(message.type, "→", message.content)

A template with named slots

Call `render` with a missing variable and read the error. Then call it with an empty string and see why that case needs its own guard.

Output
Click "Run" to execute your code

Validate at the edge

Missing and empty are different failures and deserve different messages. A missing key is a programming error: the caller forgot an argument, and the template should raise before a model call is paid for. An empty value is a data error: the caller supplied a slot with nothing in it, and the prompt builder cannot know whether that is legitimate.

A common mistake is handling both with the same guard deep inside the template. The symptom is an error message that says “missing audience” when the audience was supplied as an empty string, which sends the reader looking in the wrong place. Validate where the value enters, with a message that names the actual problem.

Missing values should fail loudly

"{topic}".format() raises KeyError when the caller forgets a value, and that is the behaviour you want: a prompt that silently reads “Explain in one sentence” because topic was never supplied is worse than a crash, because it still costs a model call and returns a plausible answer to the wrong question.

The subtle case is an empty string. Formatting succeeds, the prompt looks fine, and the model answers about nothing. Treat empty as missing at the boundary where the value enters, not deep inside the prompt builder where the context is gone.

Never interpolate raw user text into the system message. Keep instructions and data in separate messages, or a question can rewrite the rules it is supposed to be answered under.

Templates are testable data

Because a template is a string plus a substitution rule, it can be asserted like any other value: given these inputs, the rendered prompt is exactly this. That test catches the change nobody meant to make — a reworded instruction that quietly removed the length limit.

It also makes prompts reviewable. A diff on a template shows the instruction that changed, which is far easier to discuss than a diff on a chain that builds the string inline.

Messages, not one string

The builder produces a message list. Add a fourth role for a retrieved document and place it before the human question, so the instructions stay separate from the data.

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

What problem does a prompt template solve?