> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Demo Adding Short Term Memory

> Explains adding short term memory to chat models by using a MessagesPlaceholder in ChatPromptTemplate to include conversation history for contextual responses

In this lesson you'll learn how to give a chatbot or other LLM-based application a minimal form of short-term memory (conversation history) by using a `MessagesPlaceholder` inside a chat prompt template. This approach ensures previous messages are included in the prompt so the model can respond with appropriate context.

## Minimal example (no memory)

This example creates a ChatPromptTemplate without any history placeholder and then invokes the model twice. Because the previous exchange is not included in the prompt, the second invocation has no context about the first.

```python theme={null}
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai.chat_models import ChatOpenAI

model = ChatOpenAI()
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You're an assistant who's good at {ability}. Respond in 20 words or fewer"),
        ("human", "{input}"),
    ]
)
base_chain = prompt | model

# First invocation
base_chain.invoke({"ability": "math", "input": "What's a right-angled triangle?"})
```

Example output:

```text theme={null}
AIMessage(content='A triangle with one angle measuring 90 degrees.', response_metadata={...}, id='run-614688a6-...')
```

Now a follow-up question, still without passing any history:

```python theme={null}
# Follow-up invocation without history
base_chain.invoke({"ability": "math", "input": "What are the other types?"})
```

Because the model was not provided the prior exchange as part of the prompt, it typically asks for clarification:

```text theme={null}
AIMessage(content='Could you please provide more context or specify what you are referring to?', response_metadata={...}, id='run-875b6d0b-...')
```

This demonstrates the core problem: LLMs do not retain conversation context across separate calls unless you explicitly include that context in the prompt.

## Adding a MessagesPlaceholder to carry short-term memory

To give the model access to prior turns, add a `MessagesPlaceholder` to the chat prompt template and pass a `history` list on invocation. At runtime the placeholder will be replaced with the provided messages.

```python theme={null}
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_openai.chat_models import ChatOpenAI

model = ChatOpenAI()
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You're an assistant who's good at {ability}. Respond in 20 words or fewer"),
        MessagesPlaceholder(variable_name="history"),
        ("human", "{input}"),
    ]
)
base_chain = prompt | model
```

Create a simple `history` list that represents the prior human/AI exchange, then invoke the chain while passing that history:

```python theme={null}
history = [
    ("human", "What's a right-angled triangle?"),
    ("ai", "A right-angled triangle has one angle of 90 degrees, with the other two angles summing to 90 degrees.")
]

# Now the model receives the previous exchange as part of the prompt
base_chain.invoke({"ability": "math", "input": "What are the other types?", "history": history})
```

With the history included, the model can respond in context:

```text theme={null}
AIMessage(content='Other types of triangles include equilateral (all sides equal), isosceles (two sides equal), and scalene (no sides equal).', response_metadata={...}, id='run-ed7687bf-...')
```

<Callout icon="lightbulb" color="#1CB2FE">
  The `variable_name` you assign to `MessagesPlaceholder` (for example, `"history"`) is the key you must use when passing the list to `invoke`. The name can be anything, but the invocation dictionary key must match the placeholder's `variable_name`.
</Callout>

## Quick reference

|              Concept | Purpose                                                             | Example                                               |
| -------------------: | ------------------------------------------------------------------- | ----------------------------------------------------- |
| Chat prompt template | Define the ordered set of messages the model sees                   | `ChatPromptTemplate.from_messages([...])`             |
|  MessagesPlaceholder | Placeholder for injected conversation turns at runtime              | `MessagesPlaceholder(variable_name="history")`        |
|  History list format | Sequence of prior turns passed to the placeholder                   | `history = [("human", "Hi"), ("ai", "Hello")]`        |
|      Invocation dict | Values passed when running the chain (must include placeholder key) | `{"ability":"math","input":"...","history": history}` |

## Summary and next steps

* Without explicit history included in the prompt, the model has no memory of prior invocations.
* Adding a `MessagesPlaceholder` to your chat prompt template and providing a `history` list at invocation time gives your application short-term conversational memory.
* Use this technique for multi-step workflows, follow-up questions, or any conversational app that needs access to preceding messages.

## Further reading

* [LangChain ChatPromptTemplate docs](https://python.langchain.com/en/latest/modules/prompts/how_to_guides/chat_prompt_template.html)
* [LangChain Concepts & Usage](https://python.langchain.com/en/latest/index.html)
* [OpenAI Chat API reference](https://platform.openai.com/docs/guides/chat)

Experiment: try changing the contents of `history`, the `ability` parameter, or the user `input` to observe how the model's responses change when conversation history is included.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/langchain/module/abd1e527-3f6e-4e04-b421-3b1f8de5c69d/lesson/2b05e60c-8398-432c-8215-1bb3a9e64cb5" />
</CardGroup>
