Short-Term Conversation Memory › Memory with Tool Use
Michael BrenndoerferJuly 1, 20252 min read
AI Agent HandbookAll chapters Part 6 of 15Memory and Retrieval - How Agents Remember
Short-Term Conversation Memory › Memory with Tool UseOne section · Sections in this chapter7 / 15 ↓
Sections in this chapter15
Memory becomes even more important when your agent uses tools. The agent needs to remember:
- What tools it has called
- What results it received
- How those results relate to the user's questions
Let's extend our conversational agent to support tools:
In[10]:
Codedef calculate(expression: str) -> dict:
"""Simple calculator tool."""
try:
result = eval(expression)
return {"success": True, "result": result}
except Exception as e:
return {"success": False, "error": str(e)}
calculator_tool = {
"name": "calculate",
"description": "Perform mathematical calculations",
"input_schema": {
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "Math expression to evaluate"
}
},
"required": ["expression"]
}
}
class ConversationalAgentWithTools:
"""Agent with memory and tool use."""
def __init__(self):
self.client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
self.conversation_history = []
self.tools = {"calculate": calculate}
def chat(self, user_message: str) -> str:
"""Chat with tool use support."""
# Add user message
self.conversation_history.append({
"role": "user",
"content": user_message
})
# Get response
response = self.client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
tools=[calculator_tool],
messages=self.conversation_history
)
# Handle tool use if needed
if response.stop_reason == "tool_use":
# Extract tool call
tool_use_block = next(
block for block in response.content
if block.type == "tool_use"
)
# Call the tool
tool_result = self.tools[tool_use_block.name](
**tool_use_block.input
)
# Add tool use to history
self.conversation_history.append({
"role": "assistant",
"content": response.content
})
# Add tool result to history
self.conversation_history.append({
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": tool_use_block.id,
"content": str(tool_result)
}]
})
# Get final response
final_response = self.client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
tools=[calculator_tool],
messages=self.conversation_history
)
assistant_message = final_response.content[0].text
else:
assistant_message = response.content[0].text
# Add final response to history
self.conversation_history.append({
"role": "assistant",
"content": assistant_message
})
return assistant_messageNow watch how memory works with tools:
In[11]:
Codeagent = ConversationalAgentWithTools()
print(agent.chat("What's 1234 times 5678?"))
## Agent uses calculator tool
## "1,234 times 5,678 equals 7,006,652."
print(agent.chat("What if I double that?"))
## Agent remembers the previous result
## Agent calculates 7006652 * 2
## "Doubling that gives you 14,013,304."
print(agent.chat("And what's 10% of the original number?"))
## Agent remembers 7,006,652 was the original
## Agent calculates 7006652 * 0.1
## "10% of the original number (7,006,652) is 700,665.2."Out[11]:
Console1234 times 5678 equals **7,006,652**.
If you double that, you get **14,013,304**.
10% of the original number (7,006,652) is **700,665.2**.
The agent remembers both the conversation and the tool results. "Double that" refers to the previous calculation. "The original number" refers to the first result, not the doubled one.
This is powerful. The agent can build on its own work, reference previous calculations, and maintain context across multiple tool uses.