Building a Chatbot with Memory
Step-by-step tutorial to create a chatbot that remembers user preferences and past conversations using Memoid and OpenAI in Python.
Prerequisites
- Memoid account with API key ([sign up free](/register))
- OpenAI API key (for chat responses)
- Python 3.8+
In this tutorial, we’ll build a complete chatbot that remembers everything users tell it across conversations.
Note: Memoid handles all memory operations — extraction, embeddings, and search — server-side. You only need your own LLM key (OpenAI/etc.) for generating chat responses. No LLM key is needed for memory.
What We’re Building
A chatbot that:
- Remembers user preferences and facts
- Retrieves relevant context for each response
- Maintains conversation history
- Gets smarter over time
Project Setup
- Sign up for Memoid and get your API key from the dashboard
- Create a project in the dashboard
mkdir memoid-chatbot
cd memoid-chatbot
python -m venv venv
source venv/bin/activate # On Windows: venvScriptsactivate
pip install openai requests The Core Memory System
Memoid stores and searches memories — you just send conversations and query them. OpenAI generates the chat responses.
# memory_chat.py
import os
import requests
from openai import OpenAI
MEMOID_API_KEY = os.environ["MEMOID_API_KEY"]
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
MEMOID_BASE_URL = "https://api.memoid.dev/v1"
class MemoryChat:
def __init__(self):
self.openai = OpenAI(api_key=OPENAI_API_KEY)
self.headers = {
"Authorization": f"Bearer {MEMOID_API_KEY}",
"Content-Type": "application/json"
}
def get_context(self, user_id: str, message: str, limit: int = 5) -> str:
"""Retrieve relevant memories from Memoid."""
response = requests.post(
f"{MEMOID_BASE_URL}/search",
headers=self.headers,
json={"query": message, "user_id": user_id, "limit": limit}
)
if response.status_code == 200:
memories = response.json().get("results", [])
if memories:
lines = [f"- {m['memory']}" for m in memories]
return "What you know about this user:\n" + "\n".join(lines)
return "No previous context available."
def chat(self, user_id: str, message: str) -> str:
"""Generate a response with memory context."""
context = self.get_context(user_id, message)
system_prompt = f"""You are a friendly, helpful assistant with memory.
You remember things users tell you and use that information to personalize responses.
{context}
Guidelines:
- Reference relevant memories naturally in conversation
- Don't repeat everything you know, just what's relevant
- If you learn something new, acknowledge it"""
response = self.openai.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": message}
]
)
assistant_message = response.choices[0].message.content
# Store the conversation in Memoid (extraction happens server-side)
requests.post(
f"{MEMOID_BASE_URL}/memories",
headers=self.headers,
json={
"messages": [
{"role": "user", "content": message},
{"role": "assistant", "content": assistant_message}
],
"user_id": user_id
}
)
return assistant_message Adding a Web Interface
# app.py
from flask import Flask, request, jsonify
from memory_chat import MemoryChat
app = Flask(__name__)
chat = MemoryChat()
@app.route("/chat", methods=["POST"])
def handle_chat():
data = request.json
user_id = data.get("user_id")
message = data.get("message")
if not user_id or not message:
return jsonify({"error": "Missing user_id or message"}), 400
response = chat.chat(user_id, message)
return jsonify({"response": response})
if __name__ == "__main__":
app.run(debug=True, port=5000) Running the Chatbot
export MEMOID_API_KEY="your-memoid-key" # from dashboard
export OPENAI_API_KEY="your-openai-key" # for chat responses only
python app.py Testing It Out
# First conversation
curl -X POST http://localhost:5000/chat
-H "Content-Type: application/json"
-d '{"user_id": "user_1", "message": "Hi! My name is Sarah and I work as a data scientist."}'
# Response: "Nice to meet you, Sarah! Data science is such an exciting field..."
# Later conversation (could be days later)
curl -X POST http://localhost:5000/chat
-H "Content-Type: application/json"
-d '{"user_id": "user_1", "message": "Can you recommend some books for me?"}'
# Response: "Of course, Sarah! Given your work in data science, you might enjoy..." The chatbot remembers Sarah’s name and profession, and uses that to personalize recommendations.
Using Recall for Richer Context
For agents that need graph context alongside memories, use the /v1/recall endpoint:
def get_full_context(self, user_id: str, message: str) -> str:
response = requests.post(
f"{MEMOID_BASE_URL}/recall",
headers=self.headers,
json={
"query": message,
"user_id": user_id,
"include_graph": True,
"memory_limit": 10
}
)
if response.status_code == 200:
data = response.json()
lines = [f"- {m['memory']}" for m in data.get("memories", [])]
for e in data.get("entities", []):
lines.append(f"- Entity: {e['name']} ({e['type']})")
for r in data.get("relationships", []):
lines.append(f"- {r['subject']} {r['predicate']} {r['object']}")
return "\n".join(lines)
return "" Next Steps
- Add Knowledge Graphs to extract relationships
- Customer Support Agent for multi-user features
Complete Code
The full code for this tutorial is available on GitHub.