In [Chapter 6: ChatCompletionContext](06_chatcompletioncontext.md), we saw how agents manage the *short-term* history of a single conversation before talking to an LLM. It's like remembering what was just said in the last few minutes.
But what if an agent needs to remember things for much longer, across *multiple* conversations or tasks? For example, imagine an assistant agent that learns your preferences:
* You tell it: "Please always write emails in a formal style for me."
* Weeks later, you ask it to draft a new email.
How does it remember that preference? The short-term `ChatCompletionContext` might have forgotten the earlier instruction, especially if using a strategy like `BufferedChatCompletionContext`. The agent needs a **long-term memory**.
This is where the **`Memory`** abstraction comes in. Think of it as the agent's **long-term notebook or database**. While `ChatCompletionContext` is the scratchpad for the current chat, `Memory` holds persistent information the agent can add to or look up later.
## Motivation: Remembering Across Conversations
Our goal is to give an agent the ability to store a piece of information (like a user preference) and retrieve it later to influence its behavior, even in a completely new conversation. `Memory` provides the mechanism for this long-term storage and retrieval.
## Key Concepts: How the Notebook Works
1.**What it Stores (`MemoryContent`):** Agents can store various types of information in their memory. This could be:
* Plain text notes (`text/plain`)
* Structured data like JSON (`application/json`)
* Even images (`image/*`)
Each piece of information is wrapped in a `MemoryContent` object, which includes the data itself, its type (`mime_type`), and optional descriptive `metadata`.
content: Union[str, bytes, Dict[str, Any]] # The actual data
mime_type: str # What kind of data (e.g., "text/plain")
metadata: Dict[str, Any] | None = None # Extra info (optional)
```
This standard format helps manage different kinds of memories.
2. **Adding to Memory (`add`):** When an agent learns something important it wants to remember long-term (like the user's preferred style), it uses the `memory.add(content)` method. This is like writing a new entry in the notebook.
3. **Querying Memory (`query`):** When an agent needs to recall information, it can use `memory.query(query_text)`. This is like searching the notebook for relevant entries. How the search works depends on the specific memory implementation (it could be a simple text match, or a sophisticated vector search in more advanced memories).
4. **Updating Chat Context (`update_context`):** This is a crucial link! Before an agent talks to the LLM (using the `ChatCompletionClient` from [Chapter 5](05_chatcompletionclient.md)), it can use `memory.update_context(chat_context)` method. This method:
* Looks at the current conversation (`chat_context`).
* Queries the long-term memory (`Memory`) for relevant information.
* Injects the retrieved memories *into* the `chat_context`, often as a `SystemMessage`.
This way, the LLM gets the benefit of the long-term memory *in addition* to the short-term conversation history, right before generating its response.
5. **Different Memory Implementations:** Just like there are different `ChatCompletionContext` strategies, there can be different `Memory` implementations:
* `ListMemory`: A very simple memory that stores everything in a Python list (like a simple chronological notebook).
* *Future Possibilities*: More advanced implementations could use databases or vector stores for more efficient storage and retrieval of vast amounts of information.
## Use Case Example: Remembering User Preferences with `ListMemory`
Let's implement our user preference use case using the simple `ListMemory`.
**Goal:**
1. Create a `ListMemory`.
2. Add a user preference ("formal style") to it.
3. Start a *new* chat context.
4. Use `update_context` to inject the preference into the new chat context.
5. Show how the chat context looks *before* being sent to the LLM.
**Step 1: Create the Memory**
We'll use `ListMemory`, the simplest implementation provided by AutoGen Core.
1. User prefers all communication to be written in a formal style.
- [UserMessage]: Draft an email to the team about the Q3 results.
```
Look! The `ListMemory.update_context` method automatically queried the memory (in this simple case, it just takes *all* entries) and added a `SystemMessage` to the `new_chat_context`. This message explicitly tells the LLM about the stored preference *before* it sees the user's request to draft the email.
**Step 5: (Conceptual) Sending to LLM**
Now, if we were to send `messages_for_llm` to the `ChatCompletionClient` (Chapter 5):
The LLM would receive both the instruction about the formal style preference (from Memory) and the request to draft the email. It's much more likely to follow the preference now!
**Step 6: Direct Query (Optional)**
We can also directly query the memory if needed, without involving a chat context.
```python
# File: query_memory.py
import asyncio
# Assume user_prefs_memory exists
async def main():
# Query the memory (ListMemory returns all items regardless of query text)
This shows the straightforward logic of `ListMemory`: store in a list, retrieve the whole list, and inject the whole list as a single system message into the chat context. More complex memories might use smarter retrieval (e.g., based on the `query` in `query()` or the last message in `update_context`) and inject memories differently.
## Next Steps
You've learned about `Memory`, AutoGen Core's mechanism for giving agents long-term recall beyond the immediate conversation (`ChatCompletionContext`). We saw how `MemoryContent` holds information, `add` stores it, `query` retrieves it, and `update_context` injects relevant memories into the LLM's working context. We explored the simple `ListMemory` as a basic example.
Memory systems are crucial for agents that learn, adapt, or need to maintain state across interactions.
This concludes our deep dive into the core abstractions of AutoGen Core! We've covered Agents, Messaging, Runtime, Tools, LLM Clients, Chat Context, and now Memory. There's one final concept that ties many of these together from a configuration perspective:
* [Chapter 8: Component](08_component.md): Understand the general `Component` model in AutoGen Core, how it allows pieces like `Memory`, `ChatCompletionContext`, and `ChatCompletionClient` to be configured and managed consistently.
---
Generated by [AI Codebase Knowledge Builder](https://github.com/The-Pocket/Tutorial-Codebase-Knowledge)