Blog · Beginner Guide

Build an AI Assistant That
Actually Remembers You

Every AI assistant you've ever used has the same flaw: you have to re-introduce yourself every single time. Your preferred coding language, the project you're working on, the fact that you hate verbose responses — gone. Each session starts from scratch.

This guide walks you through building a personal AI assistant that actually accumulates knowledge about you. We're keeping it simple: pure Python, the OpenAI API, and Memstore. No complex frameworks required. By the end, you'll have an assistant that remembers you the same way a good colleague does — without you having to repeat yourself.


What We're Building

A command-line AI assistant that:

What you'll need


Step 1: Set Up Your Project

Install dependencies bash
pip install openai requests python-dotenv

Create a .env file in your project directory:

.env env
OPENAI_API_KEY=sk-...your-openai-key...
MEMSTORE_API_KEY=ms-...your-memstore-key...

Step 2: The Memory Layer

We'll write two functions: one to save a memory, one to search for relevant memories. That's all Memstore requires.

memory.py Python
import requests
import os
from dotenv import load_dotenv

load_dotenv()

_headers = {"Authorization": f"Bearer {os.getenv('MEMSTORE_API_KEY')}"}
_base = "https://memstore.dev/v1/memory"

def save_memory(fact: str) -> None:
    """Save a fact to persistent memory."""
    requests.post(
        f"{_base}/remember",
        json={"content": fact},
        headers=_headers
    ).raise_for_status()

def find_memories(about: str, n: int = 5) -> list[str]:
    """Find memories relevant to a topic."""
    r = requests.get(
        f"{_base}/recall",
        params={"q": about, "limit": n},
        headers=_headers
    )
    r.raise_for_status()
    return [m["content"] for m in r.json().get("memories", [])]

Step 3: The Assistant Logic

The key to making memory feel natural is implicit storage. Rather than asking users to explicitly say "remember this", we have the AI extract memorable facts from the conversation automatically.

assistant.py Python
from openai import OpenAI
from memory import save_memory, find_memories
import os

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

def extract_and_save_memories(conversation: str) -> None:
    """Ask the AI to extract memorable facts from the conversation."""
    response = client.chat.completions.create(
        model="gpt-4o-mini",  # Use the cheap model for extraction
        messages=[{
            "role": "system",
            "content": (
                "Extract facts worth remembering from this conversation. "
                "Output one fact per line. Only include genuinely useful long-term facts. "
                "Skip small talk, greetings, and questions. If nothing is worth saving, output NONE."
            )
        }, {
            "role": "user",
            "content": conversation
        }]
    )
    facts_text = response.choices[0].message.content.strip()
    if facts_text == "NONE":
        return
    for fact in facts_text.split("\n"):
        fact = fact.strip()
        if fact:
            save_memory(fact)

def chat_with_memory(user_input: str, history: list) -> str:
    """Run a single turn of conversation with memory context."""
    # Load relevant past memories
    memories = find_memories(user_input)
    memory_context = (
        "What I remember about you:\n" + "\n".join(f"- {m}" for m in memories)
        if memories else "No relevant memories yet."
    )

    system_msg = f"""You are a helpful personal assistant with persistent memory.

{memory_context}

Use this context to give personalized, relevant responses. Be concise."""

    messages = [{"role": "system", "content": system_msg}] + history
    messages.append({"role": "user", "content": user_input})

    response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages
    )
    return response.choices[0].message.content

Step 4: The Main Loop

main.py — run this to chat Python
from assistant import chat_with_memory, extract_and_save_memories

def main():
    print("AI Assistant (type 'quit' to exit)\n")
    history = []
    conversation_log = []

    while True:
        user_input = input("You: ").strip()
        if user_input.lower() in ("quit", "exit", ""):
            break

        response = chat_with_memory(user_input, history)
        print(f"\nAssistant: {response}\n")

        # Update conversation history for multi-turn context
        history.append({"role": "user", "content": user_input})
        history.append({"role": "assistant", "content": response})
        conversation_log.append(f"User: {user_input}\nAssistant: {response}")

    # Save memories from this session when exiting
    if conversation_log:
        print("\nSaving memories...")
        full_conversation = "\n\n".join(conversation_log)
        extract_and_save_memories(full_conversation)
        print("Done. See you next time!")

if __name__ == "__main__":
    main()
Why save on exit? Extracting memories at the end of a session is cheaper than extracting after every message. You only pay for one extraction call per session, and you have the full conversation context to work with.

Try It Yourself

Run the assistant and tell it a few things about yourself: what you're building, your preferred tech stack, how you like responses formatted. Then quit, restart, and ask it a question. It'll already know who you are.

The more you use it, the more useful it gets. That's the compounding effect of persistent memory — every session adds to the foundation.

Ideas for extending this

Build something that actually remembers.

Memstore gives your assistant a free, hosted memory layer. Get started in minutes.

Get your free API key →