Building Persistent Memory for a Therapy AI Assistant
Building Persistent Memory for a Therapy AI Assistant
Quick Takeaways
- The previous post covered the architecture problem: therapy AI systems capture session notes well, but after enough sessions, clinically useful details get buried.
- At referral, those details get compressed into a short letter.
- Mem0 helps to extract structured facts to be stored and makes them independently queryable.
- While the referral letter preserves some context, the memory store preserves all as structured facts.
- Mem0's benchmarks on this kind of cross-session retrieval: 91% lower p95 latency (1.44s vs 17.12s), 90% fewer tokens per query (~7,000 vs 25,000+), and 26% higher accuracy than full-context replay on the LOCOMO benchmark.
If your therapy AI assistant has been running for more than 10 sessions, context burial is already happening. The trigger identified in session 3 is already unreachable in session 15. The coping strategy abandoned in session 7 is missing from the active context. The question is not whether your system has this problem. It is how much clinical context your assistant has already lost access to, because the referral letter contains four sentences: the diagnosis, one medication tried, current techniques, and the reason for the referral.
That is not wrong, but it is too compressed. That's why we require a structured memory that can store all the important information.
Practical Demo: Build a Therapy AI Assistant
In this tutorial, we'll see how Mem0 helps us solve this problem. Here is a quick look at what we'll build:
⭐️You can access the complete code repository on GitHub
The app has two tabs: Therapy Sessions and Handoff. The top row gives the whole system state at a glance:
| Metric | Value |
|---|---|
| Structured facts stored | 14 |
| Source | 3 therapy sessions, 1 provider |
| Referral letter | 4 sentences |
| Retrieval speed | <2 seconds, ~7,000 tokens per query |
Note: The referral letter is small because it is compressed. The memory store is small because it is structured. Here, both are compact, but only one is queryable.
Step 1: Build memory across therapy sessions
The demo has three pre-filled therapy transcripts, but feel free to test it with your own transcripts.
Session 3 captures the first important facts like panic attacks correlate with Sunday evenings, sertraline 50mg was stopped in week 3 because of GI side effects, CBT grounding was introduced, and the patient has a penicillin allergy.
When the user clicks Save Session 3, the app runs:
from mem0 import MemoryClient
import os
mem0 = MemoryClient(api_key=os.environ["MEM0_API_KEY"])
mem0.add(
[
{"role": "user", "content": session_3_transcript}
],
user_id="alex-rivera",
agent_id="therapist",
run_id="session_3",
metadata={
"provider": "dr_chen",
"session_type": "therapy",
"session_number": 3
}
)
The important architectural move is not saving the transcript. It is extracting facts that can be retrieved later. Mem0's extraction model automatically identifies structured facts from the session: diagnoses, medications, coping strategies, triggers, treatment goals. You don't have to write extraction rules.
Session 7 adds that progressive muscle relaxation was tried and abandoned, grounding is effective for mild episodes but not severe ones, and journaling was introduced.
Session 11 adds declining sleep (5.2h average), box breathing for pre-sleep anxiety, and the referral decision.
By the end of Session 11, the memory store contains fourteen facts across diagnosis, medications, coping strategies, treatment goals, triggers, sleep, preferences, and allergies. Each fact is independently retrievable.
The therapist does not need to remember where each detail appeared. Just a single search() call returns the relevant subset.
Step 2: The compression gap
The Handoff tab generates a referral letter, and next to the letter, the UI flags what was lost:
The referral letter is not useless. It is useful as a human-readable summary. But it should not be the primary source of context for an AI intake assistant. The primary context source should be queryable memory.
Step 3: Run the intake comparison
The demo uses the same patient message in both panels:
"Hi, I'm here for the medication evaluation."
Without Mem0
The assistant only has the referral letter. Its response:
"Welcome Alex. Can you tell me about your mental health history? What medications have you tried before?"
The patient repeats the context. Fifteen minutes of a thirty-minute appointment spent on information the therapist's system already captured.
With Mem0
Before responding, the assistant retrieves relevant patient memories:
context = mem0.search(
"mental health history medications coping strategies treatment goals",
filters={"user_id": "alex-rivera"},
top_k=10
)
The retrieved memories include:
The numbers behind the difference: Mem0 retrieval used approximately 7,000 tokens and returned in under 2 seconds. Full-context replay (loading all three session transcripts into the prompt) would have consumed 25,000+ tokens with 91% higher latency. The accuracy improvement is measurable: 26% higher on the LOCOMO benchmark compared to full-context approaches, because selective retrieval surfaces the specific facts relevant to the query rather than hoping the model extracts them from a wall of text.
Run the demo yourself:
You can access the complete code repository on GitHub or simply follow these steps:
git clone https://github.com/aashidutt-mem0/Persistent-Memory-for-a-Therapy-AI-Assistant.git
cd therapy-memory-demo
pip install -r requirements.txt
Set your environment variables:
MEM0_API_KEY=your-mem0-api-key # free at app.mem0.ai
OPENAI_API_KEY=your-openai-key # or equivalent
Then run:
streamlit run streamlit_app.py
Click through the two tabs. Save the three sessions, inspect the referral gap, and run the intake comparison.
Production architecture
In production, the pattern is the same.
After every therapy session:
mem0.add(
session_notes,
user_id=patient_mrn,
agent_id="therapist",
run_id=f"session_{session_id}",
metadata={
"provider": "dr_chen",
"session_type": "therapy"
}
)
Before psychiatry intake:
context = mem0.search(
"medication history reactions side effects coping strategies treatment goals",
filters={"user_id": patient_mrn},
top_k=10
)
Then inject the retrieved facts into the intake assistant's system prompt.
For teams that need patient data to stay inside their infrastructure: Mem0 supports self-hosted Docker deployment, private Kubernetes, and fully air-gapped environments. Same API, same code, different data residency. SOC 2 Type I certified, HIPAA compliant, BYOK encryption.
Note:
This demo uses fictional data.
For real mental health workflows, memory architecture must support extracted facts instead of raw psychotherapy transcripts (45 CFR 164.501 restricts psychotherapy notes from the general medical record), consent-gated retrieval for substance use records (42 CFR Part 2), audit logging for every add() and search() call (required by the 2025 HIPAA Security Rule amendments for all AI systems touching PHI), minimum necessary retrieval so the intake assistant gets medication history and treatment goals rather than entire therapy transcripts, and scoped access by patient, provider role, session, and organization.
Conclusion
The previous post made the architecture case: clinical AI needs persistent memory because session notes get buried, referral letters are lossy, and prose notes are hard to query.
This one makes the case visual with a demo.
The user sees fourteen facts accumulated across therapy sessions. Then they see those facts compressed into a four-sentence referral letter. Then they see the intake assistant behave differently when it can retrieve the original structured memories: 91% lower latency, 90% fewer tokens, 26% higher accuracy. The patient does not have to repeat themselves because the provider already starts with context. The AI assistant retrieves what matters.