Giving Claude Agents Persistent Memory Between Sessions
Free · Open source (MIT) · Works with LangChain, CrewAI, AutoGen · No signup
Claude agents lose their memory every time your script restarts. Conversations, user preferences, learned facts — all gone. This breaks real-world agent experiences where users expect continuity. BotWire Memory gives Claude persistent state that survives restarts, crashes, and deployments with zero configuration.
The Problem: Claude's Vanishing Memory
The Claude API is stateless. Each conversation starts fresh, with no memory of previous interactions. Your agent might learn that a user prefers Python over JavaScript in one session, but forget it completely when your server restarts.
import anthropic
client = anthropic.Anthropic()
# Session 1: Agent learns user prefers Python
response = client.messages.create(
model="claude-3-sonnet-20240229",
max_tokens=100,
messages=[{"role": "user", "content": "I love Python programming"}]
)
# Server restarts...
# Session 2: Agent has no memory of user's Python preference
response = client.messages.create(
model="claude-3-sonnet-20240229",
max_tokens=100,
messages=[{"role": "user", "content": "What should I learn next?"}]
)
# Claude suggests random languages, forgetting user loves Python
This creates frustrating user experiences where agents constantly reintroduce themselves and lose context about ongoing projects, preferences, and conversation history.
The Fix: Persistent Agent Memory
BotWire Memory provides persistent key-value storage that survives process restarts. Install it and give your Claude agent permanent memory:
pip install botwire
import anthropic
from botwire import Memory
# Initialize Claude and persistent memory
client = anthropic.Anthropic()
memory = Memory("claude-agent")
# Store user preferences
memory.set("user_123_language", "python")
memory.set("user_123_project", "web scraper for e-commerce")
# Later (even after restart), recall stored information
user_language = memory.get("user_123_language") # "python"
current_project = memory.get("user_123_project") # "web scraper for e-commerce"
# Use memory in Claude conversation
messages = [
{"role": "user", "content": "What's the best way to handle rate limiting?"},
{"role": "system", "content": f"User prefers {user_language} and is working on: {current_project}"}
]
response = client.messages.create(
model="claude-3-sonnet-20240229",
max_tokens=200,
messages=messages
)
How It Works
BotWire Memory creates persistent key-value storage using namespaces. Each namespace acts like a separate memory space for different agents or users. The memory persists across processes, servers, and deployments.
from botwire import Memory
# Create memory instances for different contexts
user_memory = Memory("user-sessions")
agent_memory = Memory("claude-agent-state")
# Store complex data structures
user_memory.set("user_456", {
"name": "Sarah",
"preferred_language": "python",
"skill_level": "intermediate",
"last_topic": "async programming"
})
# Retrieve and use in conversations
user_data = user_memory.get("user_456")
if user_data:
context = f"User {user_data['name']} is {user_data['skill_level']} at {user_data['preferred_language']}"
else:
context = "New user, no previous context"
Memory operations handle missing keys gracefully - get() returns None for non-existent keys. You can also list all keys in a namespace and delete specific entries:
# List all stored keys
all_users = user_memory.list_keys() # Returns list of keys
# Clean up old data
user_memory.delete("inactive_user_789")
# Check if key exists before using
if user_memory.get("user_456"):
# Use existing user data
pass
else:
# Initialize new user
user_memory.set("user_456", {"interactions": 0})
Integration with Agent Frameworks
For LangChain agents, BotWire provides a drop-in chat history replacement that persists conversation memory:
from langchain_anthropic import ChatAnthropic
from botwire import BotWireChatHistory
# Create persistent chat history
chat_history = BotWireChatHistory(session_id="user-sarah-123")
# Use with LangChain Claude
llm = ChatAnthropic(model="claude-3-sonnet-20240229")
# Conversation history automatically persists
chat_history.add_user_message("I'm building a Python web scraper")
chat_history.add_ai_message("Great! I can help with that. What sites are you scraping?")
# Later session (after restart) - history is still there
messages = chat_history.messages # Previous conversation loaded automatically
For CrewAI agents, use the memory tools helper:
from botwire.memory import memory_tools
# Get remember/recall/list tools for your crew
tools = memory_tools("crew-ecommerce-project")
# Tools include: remember(key, value), recall(key), list_memory()
# Your crew agents can now remember facts between sessions
When NOT to Use BotWire Memory
- Vector/semantic search: BotWire stores key-value data, not embeddings. Use Pinecone or Weaviate for similarity search.
- High-throughput applications: Free tier has 1000 writes/day per namespace. For production scale, consider Redis or self-hosting.
- Sub-millisecond latency: Network calls add ~50-200ms. For real-time applications, use in-memory storage.
FAQ
Why not just use Redis? Redis requires setup, hosting, and configuration. BotWire works immediately with zero config - perfect for prototypes and small agents.
Is this actually free? Yes, permanently. 1000 writes/day per namespace, 50MB storage, unlimited reads. No signup required.
What about data privacy? Data is stored on BotWire servers. For sensitive data, self-host the open-source version (single FastAPI + SQLite service).
BotWire Memory solves Claude agent memory in one line of code. Install it and give your agents the persistent memory they need: pip install botwire. Get started at https://botwire.dev.