Chat Prompts and Messages with LangChain
Intuition
Chat models take a list of messages, each with a role: the system message sets the rules, human messages are the user's turns, AI messages are the model's earlier replies. Writing those lists by hand gets repetitive; a prompt template fills in the variable parts and slots the conversation history in the right place. LangChain also lets you swap a real model for a fake one in tests.
Precise explanation
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate.from_messages([
("system", "You are a tutor for {subject}. Answer in at most {max_words} words."),
MessagesPlaceholder("history"),
("human", "{question}"),
])
value = prompt.invoke({"subject": "Python", "max_words": 50, "history": [...], "question": "..."})
value.to_messages() # [SystemMessage, ..., HumanMessage]
chain = prompt | model | StrOutputParser()
chain.invoke({...}) # the model's reply as a string
- Each message has
.type("system","human","ai") and.content. {name}in a template is a variable; literal braces are written{{and}}. Variable values are inserted as plain text — braces inside a question are not interpreted.prompt.input_variableslists the variables the template needs.|composes runnables: the prompt's output goes to the model, the model's message to the parser.FakeListChatModel(responses=[...])returns its responses in order — deterministic, offline tests. A real provider (OpenAI, Anthropic, a local Ollama model) drops in with the same interface.
Worked example
With subject "Python", 30 words and one earlier exchange, the prompt produces four messages: system,
human (earlier question), ai (earlier answer), human (new question). Piped into
FakeListChatModel(responses=["A list is mutable."]), the chain returns "A list is mutable."
What the library does inside
It builds the role/content list that you assembled with a chat template in LM-18 (the optional deep dive after this step); the model wrapper converts it to the provider's format.
Common mistakes
- Putting the history into the system message as one long string instead of real messages.
- Forgetting a variable, which raises a
KeyErrorwhen the prompt is invoked. - Testing with a real, paid model where a fake one would make the test deterministic.
Why this matters
Every LLM application — chatbots, RAG, agents — is built from prompts, messages and chains like these.
References
- Messages (LangChain docs) — LangChain (
S130) - langchain-core prompts reference — LangChain (
S132)