ChatPromptTemplate
In Prompt Templates, each call sent one system line and one human message. Follow-up questions need earlier turns in the prompt too. MessagesPlaceholder reserves a slot for that list. You pass history into format_messages on every call.
The template
Three parts: a system line, a history slot, then the new question. Same ChatPromptTemplate style as before — with history in the middle.
Three parts in order:
system
Keep each reply to one short sentence.
history
HumanMessage, AIMessage, …
empty first turn · filled after that
human
{input} — this turn's question
prompt = ChatPromptTemplate.from_messages([
("system", "Keep each reply to one short sentence."),
MessagesPlaceholder(variable_name="history"),
("human", "{input}"),
])Turn 1 vs turn 2
On the first call, history is empty — the model sees system + human only. After you save the question and reply, the second call includes that full exchange.
Turn 1 — history = []
system: Keep each reply… human: What does <a> do?
Turn 2 — history has turn 1
system: Keep each reply… human: What does <a> do? ai: The <a> tag creates a hyperlink… human: What attribute opens in a new tab?
history holding the first exchange.Each turn
Build messages with format_messages, call the model, then append the question and reply to history. Same four steps for every question.
messages = prompt.format_messages(history=history, input=question) reply = model.invoke(messages) history.append(HumanMessage(content=question)) history.append(AIMessage(content=reply.content))
The demo script
chat_prompt_template_demo.py asks two questions about the HTML <a> tag. The second only makes sense if the first exchange is still in history.
Download the code
chat_prompt_template_demo.py
Two HTML questions — history grows each turn
langchain-course folder. Needs venv, .env, and packages from Project Setup.Run it
Activate the venv from Project Setup, then:
python chat_prompt_template_demo.py
target because the model still sees the first <a> question.Quick reference
MessagesPlaceholder— where past turns go in the template.history— a list ofHumanMessageandAIMessageobjects, in order.format_messages(history=…, input=…)— builds the list you pass tomodel.invoke.- Docs: Prompt templates · Messages.
What's Next
Next: InMemoryChatMessageHistory — same steps, with add_user_message and add_ai_message instead of a manual list.