Building AI Agents from Scratch
Conversation Context and Memory
Keep message history, respect the context window, and summarize when short-term memory gets too long.
The model only sees the messages list you send. If you start a new list every turn, it has amnesia. If you never trim, you blow the context window and the bill.
Short-term memory is the list
Hold messages on the agent object. Each user turn appends. Each run continues the same list. That is conversation context.
class Agent:
def __init__(self):
self.messages = [
{"role": "system", "content": "You scout a local project. Be brief."}
]
def ask(self, user_text: str) -> str:
self.messages.append({"role": "user", "content": user_text})
answer = self.run_loop()
return answerThe window is finite
Every tool result and every assistant paragraph stays until you drop it. A 4k-character file read, five times, is how hobby agents die. Cap tool payloads (you already sliced [:4000]). Cap the list.
Summarize, then drop
When token estimate or message count crosses a line, ask the model once to summarize the older turns into a short system or assistant note, then keep only: system, the summary, and the last few turns (including in-flight tool calls).
def maybe_compact(self) -> None:
if len(self.messages) < 24:
return
older = self.messages[1:-6]
summary = think([
{"role": "system", "content": "Summarize this agent trace in 8 bullets. Keep paths and decisions."},
{"role": "user", "content": json.dumps(older)[:12000]},
]).content
self.messages = [self.messages[0], {"role": "system", "content": "Prior work:\n" + (summary or "")}] + self.messages[-6:]Two asks in one process should refer to the first. After you force 30 dummy turns, the list should shrink and the agent should still know the project name. Next: remember across processes.