> ## 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.

# Lab Walkthrough Agent Memory in Action

> Hands-on lab demonstrating a sliding-window memory manager for multi-turn agents, preserving system prompt while trimming conversation history to control tokens, cost, and latency.

Time for hands-on practice. In this lab you'll run a multi-turn agent conversation, watch the messages list grow with every turn, and implement a sliding-window memory manager to control token usage, cost, and latency.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/WUKBeXdogksN49S5/images/AI-Agents-for-Beginners-OpenClaw-Case-Study/Building-AI-Agents/Lab-Walkthrough-Agent-Memory-in-Action/agent-memory-in-action-lab.jpg?fit=max&auto=format&n=WUKBeXdogksN49S5&q=85&s=a74674b37bff8128eaa04fb02bd8d404" alt="A dark slide that reads &#x22;AGENT MEMORY IN ACTION&#x22; in large yellow pixelated text. Above it is a turquoise &#x22;HANDS-ON LAB&#x22; badge and below is the subtitle &#x22;Multi-turn conversation · Watch memory grow.&#x22;" width="1920" height="1080" data-path="images/AI-Agents-for-Beginners-OpenClaw-Case-Study/Building-AI-Agents/Lab-Walkthrough-Agent-Memory-in-Action/agent-memory-in-action-lab.jpg" />
</Frame>

## What you'll accomplish

* Run a multi-turn conversation with an agent that uses a calendar tool.
* Observe how the conversation history (messages) grows and why that matters.
* Implement `trim_history()` — a sliding-window memory manager that preserves the system prompt and keeps the most recent N messages.

## Prerequisites

* Python 3.11 with a virtual environment active.
* The OpenAI SDK is pre-installed. See: [OpenAI API (Python)](https://platform.openai.com/docs/api-reference?lang=python)
* Working directory: `/root/code`
* Repo already contains:
  * `agent_memory.py` — the agent loop wired up and importing a `calendar` tool from `tools.py`
  * `tools.py` — contains `tools` and `execute_tool`

Quick file reference:

| File | Purpose |
| - | - |
| `agent_memory.py` | Agent loop: messages list, run\_agent function, and where you will set the system prompt and add questions |
| `tools.py` | Tool implementations (e.g., `calendar`) used by the agent |
| `requirements.txt` | Pre-installed SDKs (OpenAI SDK already present) |

## Starter client snippet (already in the repo)

The repo contains this OpenAI client setup. You do not need to change it, but it shows how the client is instantiated:

```python theme={null}
import os
import json
from openai import OpenAI
from tools import tools, execute_tool

client = OpenAI(
    api_key=os.getenv("OPENAI_API_KEY"),
    base_url=os.getenv("OPENAI_API_BASE"),
)
```

## 1) Set the system prompt

Open `agent_memory.py`. Locate the `messages` list and the system prompt variable at the top of the conversation history.

Set a concise system prompt to define the agent's identity and tool usage expectations. Example guidance:

* Tell the agent it is a helpful personal assistant.
* Instruct it to use tools (like the calendar tool) when it needs verified or real data.
* Keep the system prompt as the very first message in `messages` so the trimming logic can always preserve it.

Example system prompt assignment (place this as `messages[0]`):

```python theme={null}
system_prompt = {
    "role": "system",
    "content": (
        "You are a helpful personal assistant. Use available tools (e.g., the calendar tool) "
        "to fetch or verify real data when appropriate. Always be concise and confirm when you use a tool."
    ),
}

messages = [system_prompt]
```

Why this matters: the trimming function will always preserve `messages[0]` (the system prompt), so keep it compact and authoritative.

## 2) Add conversational questions that test memory

Add a sequence of user questions that force the agent to rely on conversational state across turns. Below is an example set of five questions. Append each user question to `messages`, call the agent, then observe the growth of `messages`.

Example loop to add in `agent_memory.py`:

```python theme={null}
questions = [
    "What's on my calendar today?",
    "Tell me about the standup.",
    "What time is my dentist?",
    "Am I free at 3pm?",
    "Summarise my day.",
]

for q in questions:
    messages.append({"role": "user", "content": q})
    answer = run_agent(messages)   # run_agent should call the API and append assistant response
    print(f"Q: {q}")
    print(f"A: {answer}")
    print(f"Messages in history: {len(messages)}")
```

Example run output you might see:

```bash theme={null}
root@controlplane ~/code via 🐍 v3.11 (venv) python3 agent_memory.py
Q: What's on my calendar today?
A: You have a standup at 10am and a dentist appointment at 2pm.

Messages in history: 4

Q: Tell me about the standup.
A: Your standup is at 10am — a daily team sync.

Messages in history: 8

Q: What time is my dentist?
A: Your dentist appointment is at 2pm.

Messages in history: 12
```

Note: Every new user and assistant turn increases the messages list. If `run_agent` appends assistant responses, your list grows quickly and every API call will include that full history.

## 3) Why trimming is necessary

Long message histories:

* Use more tokens per API call
* Increase cost and latency
* Can hit the model context limit

A simple and effective strategy: sliding-window memory that keeps the system prompt plus the most recent N-1 user/assistant messages.

## 4) Implement a sliding-window memory manager

Create a function named `trim_history` in `agent_memory.py`. Default `max_messages=6` is a good starting point (1 system message + 5 recent turns).

```python theme={null}
def trim_history(messages, max_messages=6):
    """
    Keep the system prompt (messages[0]) and the most recent (max_messages - 1)
    user/assistant messages. If the messages list is already short enough,
    return it unchanged.
    """
    if len(messages) > max_messages:
        # Preserve the first (system) message and keep the most recent (max_messages - 1) other messages
        return [messages[0]] + messages[-(max_messages - 1):]
    return messages
```

Where to call it:

* After appending the assistant response to `messages`, and before the next user turn, call `trim_history(messages, max_messages=6)`.

Example integration inside the interaction loop:

```python theme={null}
# After the assistant's response is appended
messages = trim_history(messages, max_messages=6)

# Then the next iteration will append the next user message
```

This keeps the system prompt intact as `messages[0]` while limiting the rest of the retained history to the most recent conversation turns.

<Callout icon="lightbulb" color="#1CB2FE">
  Keep the [system prompt](https://platform.openai.com/docs/guides/chat) at `messages[0]`. The trimming function assumes that the first message is the agent's system prompt and always preserves it.
</Callout>

## 5) Re-run the script and observe

Run `agent_memory.py` again after adding `trim_history` and integrating it into your loop. You should observe the message count stabilise around `max_messages` (6 by default). The agent will continue to act coherently because:

* The system instruction remains preserved.
* The most recent turns (the most relevant context) are kept.

This sliding-window approach provides a simple, production-ready memory manager:

* System prompt always preserved
* History capped to control token usage
* Reduces cost and latency while keeping recent context

## Further reading and references

* OpenAI Chat Guides: [https://platform.openai.com/docs/guides/chat](https://platform.openai.com/docs/guides/chat)
* OpenAI Python API reference: [https://platform.openai.com/docs/api-reference?lang=python](https://platform.openai.com/docs/api-reference?lang=python)

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/WUKBeXdogksN49S5/images/AI-Agents-for-Beginners-OpenClaw-Case-Study/Building-AI-Agents/Lab-Walkthrough-Agent-Memory-in-Action/retro-memory-managed-green-check.jpg?fit=max&auto=format&n=WUKBeXdogksN49S5&q=85&s=ca78c5e3fb925593ee8b613579d92a9c" alt="A retro-style graphic with a green checkmark and bold yellow pixelated text reading &#x22;MEMORY MANAGED.&#x22; Below it are smaller lines saying &#x22;System prompt always preserved · History capped at 6&#x22; and &#x22;A working memory manager for production agents.&#x22;" width="1920" height="1080" data-path="images/AI-Agents-for-Beginners-OpenClaw-Case-Study/Building-AI-Agents/Lab-Walkthrough-Agent-Memory-in-Action/retro-memory-managed-green-check.jpg" />
</Frame>

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/ai-agents-for-beginner-openclaw-case-study/module/d77598d4-d1d3-4768-97da-03ead60bf984/lesson/ac62dd16-008d-4476-b551-697a4cbe2809" />

  <Card title="Practice Lab" icon="flask-conical" cta="Learn more" href="https://learn.kodekloud.com/user/courses/ai-agents-for-beginner-openclaw-case-study/module/d77598d4-d1d3-4768-97da-03ead60bf984/lesson/6e14762d-324a-4678-aae6-63822b2c174c" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.