OpenAI Agents SDK + HatiData: Persistent Memory
Add persistent memory to OpenAI agents. Agents remember past conversations across sessions.
What You'll Build
An OpenAI agent with cross-session memory using store_memory and search_memory MCP tools.
Prerequisites
$pip install hatidata-agent openai
$hati init
$OpenAI API key
Architecture
┌──────────────┐ ┌──────────────┐
│ OpenAI │───▶│ HatiData │
│ Agent │ │ MCP Server │
└──────┬───────┘ └──────┬───────┘
│ ┌──────▼───────┐
└───────────▶│ Agent Memory │
└──────────────┘Key Concepts
- ●Cross-session persistence: memories survive agent restarts and new sessions because they are stored in HatiData's local DuckDB database, not in-process state.
- ●MCP tool integration: the OpenAI Agents SDK discovers store_memory and search_memory automatically via MCP, requiring zero custom tool definitions.
- ●Semantic memory search: search_memory uses vector embeddings to find contextually relevant memories, not just keyword matches.
- ●SQL-queryable agent state: every memory is stored in a standard SQL table, enabling analytics, audits, and bulk operations with familiar tools.
Step-by-Step Implementation
Install dependencies
Install the HatiData agent library and the OpenAI Agents SDK.
pip install hatidata-agent openai-agentsNote: Requires Python 3.10+. The openai-agents package includes the Agents SDK with MCP support.
Configure HatiData for agent memory
Create a HatiData configuration file and start the local MCP server.
# .hati/config.toml
[storage]
path = "./agent_data"
[memory]
default_namespace = "openai_agent"
embedding_dimensions = 384
[proxy]
port = 5439
host = "127.0.0.1"
# Initialize HatiData
# In your terminal:
# hati initNote: Run 'hati init' to create the local database and config.
Create the memory-enabled OpenAI agent
Build an OpenAI agent that uses HatiData's store_memory and search_memory MCP tools for persistent recall.
import asyncio
from openai_agents import Agent, Runner
from openai_agents.mcp import MCPServerStdio
# Connect to HatiData MCP server
hatidata_mcp = MCPServerStdio(
command="hati",
args=["mcp", "--port", "8741"],
)
agent = Agent(
name="MemoryAgent",
model="gpt-4o",
instructions="""You are a helpful assistant with persistent memory.
MEMORY RULES:
- When the user shares important information (preferences, facts, context),
call store_memory to save it with descriptive tags.
- When the user asks a question, FIRST call search_memory to check if you
already know the answer from a previous session.
- Always tell the user when you recall something from memory.
""",
mcp_servers=[hatidata_mcp],
)
async def chat(user_input: str, session_id: str):
"""Run the agent with a user message."""
result = await Runner.run(
agent,
input=user_input,
context={"session_id": session_id},
)
return result.final_output
# Run a quick test
async def main():
response = await chat(
"My name is Alice and I prefer dark mode.",
session_id="session_001",
)
print(response)
asyncio.run(main())I'll remember that! I've stored your name (Alice) and your
preference for dark mode in my memory. Next time we chat,
I'll recall these details automatically.Test cross-session memory persistence
Demonstrate that the agent remembers information from a completely separate session.
import asyncio
from openai_agents import Agent, Runner
from openai_agents.mcp import MCPServerStdio
hatidata_mcp = MCPServerStdio(
command="hati",
args=["mcp", "--port", "8741"],
)
agent = Agent(
name="MemoryAgent",
model="gpt-4o",
instructions="""You are a helpful assistant with persistent memory.
When asked a question, FIRST call search_memory to check for relevant context.
Always tell the user when you recall something from memory.""",
mcp_servers=[hatidata_mcp],
)
async def main():
# Session 2 — completely new session
result = await Runner.run(
agent,
input="What's my name? Do you know my preferences?",
context={"session_id": "session_002"},
)
print(result.final_output)
asyncio.run(main())I searched my memory and found your information from a previous
conversation! Your name is Alice, and you prefer dark mode.
This was stored during our earlier session.Note: The agent runs in a completely new session (session_002) but recalls data stored in session_001. Memory persists across sessions because HatiData stores it in the local DuckDB database.
Query memory with SQL
Connect directly to HatiData and query all stored memories using SQL, including semantic relevance ranking.
from hatidata_agent import HatiDataAgent
client = HatiDataAgent(host="localhost", port=5439, agent_id="openai-memory-agent", framework="openai")
# List all stored memories for this agent
results = client.query("""
SELECT memory_id, content, tags, created_at
FROM _hatidata_memory.memories
WHERE namespace = 'openai_agent'
ORDER BY created_at DESC
LIMIT 10
""")
for row in results:
print(f"[{row['created_at']}] {row['content']}")
print(f" Tags: {row['tags']}")
# Semantic search with relevance scoring
relevant = client.query("""
SELECT content, tags,
semantic_rank(embedding, 'user interface preferences') AS relevance
FROM _hatidata_memory.memories
WHERE namespace = 'openai_agent'
ORDER BY relevance DESC
LIMIT 5
""")
print("\nMost relevant memories for 'user interface preferences':")
for row in relevant:
print(f" [{row['relevance']:.3f}] {row['content']}")[2025-01-15 10:30:00] User's name is Alice
Tags: ['identity', 'name']
[2025-01-15 10:30:00] User prefers dark mode
Tags: ['preference', 'ui']
Most relevant memories for 'user interface preferences':
[0.912] User prefers dark mode
[0.534] User's name is AliceNote: HatiData exposes all agent memory as queryable SQL tables. You can run analytics, build dashboards, or audit agent behavior using standard SQL.
Related Use Case
Operations
Customer Support
Agents That Remember Every Customer
Ready to build?
Install HatiData locally and start building with OpenAI Agents SDK in minutes.
Join Waitlist