Course navigation
Chat History & MemoryLesson 1 of 8

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

Prior turns go into the history slot; the new question follows as the human line.
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?
The second answer depends on 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.

chat_prompt_template_demo.py
"""chat_prompt_template_demo.py"""
MessagesPlaceholder(variable_name="history")
prompt.format_messages(history=history, input=question)
history.append(HumanMessage) · history.append(AIMessage)

Download the code

chat_prompt_template_demo.py

Two HTML questions — history grows each turn

Download .py
Save into your 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
PowerShell — (.venv) active
(.venv) PS C:\projects\langchain-course> python chat_prompt_template_demo.py
Human: What does the HTML <a> tag do?
AI: The <a> tag creates a hyperlink to another page or resource.
Human: What attribute opens the link in a new tab?
AI: Use target="_blank" on the <a> tag.
The second reply names target because the model still sees the first <a> question.

Quick reference

  • MessagesPlaceholder — where past turns go in the template.
  • history — a list of HumanMessage and AIMessage objects, in order.
  • format_messages(history=…, input=…) — builds the list you pass to model.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.