Skip to main content

Build a Chatbot with Memory

Build a chatbot that remembers users across conversations. Takes about 15 minutes.

What You'll Build

A chatbot that:

  • Remembers user preferences and facts
  • Retrieves relevant context for each message
  • Learns automatically from conversations

Prerequisites

  • Python 3.9+
  • Tensorheart API key (sign up)
  • OpenAI API key

Step 1: Set Up

Install dependencies:

pip install openai requests

Set your API keys:

export TENSORHEART_API_KEY="mem_live_..."
export OPENAI_API_KEY="sk-..."

Step 2: Create Memory Functions

Create a file called memory.py:

import os
import requests

MEMORY_API = "https://api.memory.tensorheart.com/v1"
API_KEY = os.environ["TENSORHEART_API_KEY"]

def save_memory(user_id: str, text: str):
"""Save a memory for a user."""
requests.post(
f"{MEMORY_API}/memories",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"text": text,
"space_id": f"user_{user_id}"
}
)

def get_memories(user_id: str, query: str, max_results: int = 5) -> list[str]:
"""Get relevant memories for a user."""
response = requests.post(
f"{MEMORY_API}/query",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"context": query,
"space_id": f"user_{user_id}",
"max_memories": max_results
}
)
data = response.json()
return [m["text"] for m in data.get("data", {}).get("memories", [])]

def extract_memories(user_id: str, conversation: str):
"""Auto-extract memories from a conversation."""
requests.post(
f"{MEMORY_API}/query/extract",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"content": conversation,
"content_type": "conversation",
"space_id": f"user_{user_id}"
}
)

Step 3: Create the Chatbot

Create chatbot.py:

import os
from openai import OpenAI
from memory import get_memories, extract_memories

openai = OpenAI()

def chat(user_id: str, message: str, history: list) -> str:
"""Process a chat message with memory context."""

# 1. Get relevant memories
memories = get_memories(user_id, message)
memory_text = "\n".join(f"- {m}" for m in memories) if memories else "None yet."

# 2. Build the prompt
system_prompt = f"""You are a friendly assistant with memory.

What you remember about this user:
{memory_text}

Use this context naturally. Don't list facts—weave them in."""

# 3. Get response
messages = [
{"role": "system", "content": system_prompt},
*history,
{"role": "user", "content": message}
]

response = openai.chat.completions.create(
model="gpt-4o",
messages=messages
)

assistant_reply = response.choices[0].message.content

# 4. Learn from this exchange
exchange = f"User: {message}\nAssistant: {assistant_reply}"
extract_memories(user_id, exchange)

return assistant_reply

Step 4: Run the Chatbot

Create main.py:

from chatbot import chat

def main():
user_id = "demo_user"
history = []

print("Chatbot ready! Type 'quit' to exit.\n")

while True:
user_input = input("You: ")
if user_input.lower() == "quit":
break

response = chat(user_id, user_input, history)
print(f"Bot: {response}\n")

# Update history
history.append({"role": "user", "content": user_input})
history.append({"role": "assistant", "content": response})

if __name__ == "__main__":
main()

Run it:

python main.py

Step 5: Test Memory

Try this conversation:

You: Hi! I'm Alex and I work at Stripe.
Bot: Nice to meet you, Alex! Working at Stripe must be exciting...

You: quit

Start a new session:

python main.py
You: What company do I work at?
Bot: You work at Stripe!

The bot remembers across sessions.

How It Works

┌────────────────────────────────────────────────┐
│ Chat Flow │
│ │
│ User Message │
│ │ │
│ ▼ │
│ ┌─────────┐ relevant ┌───────────────┐ │
│ │ Memory │───memories──▶│ LLM + context│ │
│ │ Query │ │ │ │
│ └─────────┘ └───────┬───────┘ │
│ │ │
│ ▼ │
│ Response │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Extract & │ │
│ │ Save New │ │
│ │ Memories │ │
│ └─────────────┘ │
└────────────────────────────────────────────────┘

Improvements to Try

Add Metadata

Tag memories with categories:

def save_memory(user_id: str, text: str, category: str = "general"):
requests.post(
f"{MEMORY_API}/memories",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"text": text,
"space_id": f"user_{user_id}",
"metadata": {"category": category}
}
)

Filter by Relevance

Only use high-confidence memories:

def get_memories(user_id: str, query: str) -> list[str]:
response = requests.post(
f"{MEMORY_API}/query",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"context": query,
"space_id": f"user_{user_id}",
"relevance_threshold": 0.7 # Only high relevance
}
)
# ...

Handle Errors Gracefully

def get_memories(user_id: str, query: str) -> list[str]:
try:
response = requests.post(...)
return [m["text"] for m in response.json().get("data", {}).get("memories", [])]
except Exception:
return [] # Continue without memories

Complete Code

See the full example: GitHub Gist

Next Steps