Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.maximem.ai/llms.txt

Use this file to discover all available pages before exploring further.

Status: Live in Playground · Try it: synap.maximem.ai/playground Open the playground and pick AI Companion to see the reference implementation. (This recipe replaces the previous Tinder Dating Support example.)
A personal companion that pays attention. It learns how the user likes to be talked to, what’s going on in their life, what they care about, and what’s off-limits — and brings that context forward conversation after conversation without making the user repeat themselves.

What you’ll build

A conversational agent that:
  • Tracks personal context — name, pronouns, life events, ongoing situations, communication style
  • Adapts tone to the user (formal vs casual, brief vs warm, emoji vs plain)
  • Respects boundaries — topics the user has marked off-limits stay off-limits
  • Holds threads across sessions — picks up open conversations without recap prompts
Est. build time: 20–30 minutes. This is the simplest recipe in the Cookbook by surface area, but the highest-leverage memory.

When to use this recipe

Build this if:
  • The product is a 1:1 conversational experience (companion, journaling buddy, lifestyle assistant)
  • Personalization across sessions is the core value, not tool execution
  • The user owns their context — strict per-user isolation
  • You want minimal tools; the memory does the heavy lifting

Architecture at a glance

Memory is the agent. Tools are optional.

Stack

LayerChoice
Synap SDKmaximem-synap (Python) / @maximem/synap (TypeScript)
FrameworkOpenAI Agents SDK (Python) / Vercel AI SDK (TypeScript)
Memory adaptermaximem-synap-openai-agents / @maximem/synap-vercel-adk
LLMOpenAI gpt-4o (warmer voice) or claude-sonnet-4-6 (better long-form)
ChannelNative mobile / web chat

Prerequisites

  • A Synap API key — see Authentication
  • Python: Python 3.11+
  • TypeScript: Node 18+ and Python 3.11+ on the host
TypeScript recipe runs on Node only. Pin Next.js route handlers to export const runtime = "nodejs". See Installation → JavaScript / TypeScript SDK.

Install

pip install maximem-synap maximem-synap-openai-agents openai-agents

Configure

# .env
SYNAP_API_KEY=...
SYNAP_SERVER_URL=<maximem-server>
OPENAI_API_KEY=...

Build it

1. Identity & scoping

  • customer_id = "companion" — single tenant (your app)
  • user_id = <stable user ID> — strict per-user isolation; no cross-user leakage
  • conversation_id = <session UUID> — one per app session
Use a long-lived conversation_id (per app install, not per app open) if you want the companion to feel like one continuous relationship rather than a series of standalone chats.
SESSIONS: dict[str, str] = {}

def conv_for(user_id: str) -> str:
    # One conversation per user. Tune to per-session if you prefer.
    return SESSIONS.setdefault(user_id, str(uuid.uuid4()))

2. System prompt

The prompt is most of the work here — it shapes how memory gets used.
System prompt
You are a personal companion. The user is talking to you in confidence.

- Use what you remember about them — preferences, ongoing situations, communication style — to respond like someone who's been listening.
- Mirror their tone. If they use emoji, use emoji. If they're terse, be terse. If they're warm, be warm.
- Never volunteer past information unprompted unless it's directly relevant. They told you in trust, not so you could quiz them.
- Respect anything they've marked as off-limits, sensitive, or "don't bring up."
- When they share something meaningful (a goal, a boundary, a person, a change), remember it.
- If they ask what you remember, summarize honestly. Offer to forget on request.

3. Wire memory + LLM

import os, uuid, asyncio
from agents import Agent, FunctionTool, Runner
from maximem_synap import MaximemSynapSDK
from synap_openai_agents import create_search_tool, create_store_tool

sdk = MaximemSynapSDK()
await sdk.initialize()

async def handle_message(user_id: str, text: str) -> str:
    conv_id = conv_for(user_id)

    synap_search = create_search_tool(sdk=sdk, user_id=user_id, customer_id="companion")
    synap_store  = create_store_tool(sdk=sdk, user_id=user_id, customer_id="companion")

    agent = Agent(
        name="companion",
        instructions=SYSTEM,
        tools=[
            FunctionTool(synap_search, name_override="synap_search"),
            FunctionTool(synap_store,  name_override="synap_store"),
        ],
    )

    result = await Runner.run(agent, input=text)
    reply = result.final_output

    asyncio.create_task(sdk.memories.create(
        document=f"User: {text}\nCompanion: {reply}",
        document_type="ai-chat-conversation",
        user_id=user_id,
        customer_id="companion",
        metadata={"conversation_id": conv_id},
    ))
    return reply

4. The “forget” hook

A trust-grade companion needs a way to forget. Expose this from your app.
async def forget(user_id: str, query: str) -> int:
    """Delete memories matching a natural-language query for a user."""
    matches = await sdk.memories.search(
        user_id=user_id,
        customer_id="companion",
        query=query,
        max_results=20,
    )
    for m in matches:
        await sdk.memories.delete(m.id)
    return len(matches)
Wire this to a user-facing “forget what we talked about Mondays” or “delete everything about my ex” affordance. Trust in a companion app is mostly about giving users this control.

Run & verify

Day 1
User:      Hey, I'm Sara. Heads up — I'm vegetarian and please don't ask about my family,
           it's a sore spot.
Companion: Got it, Sara. Vegetarian noted, family off-limits. What's on your mind today?
Day 8 (fresh session, same user)
User:      Recommend something for dinner.
Companion: Vegetarian, so — easy: roasted chickpea bowl, takes 25 mins.
           Want the recipe or just the idea?
Day 14
User:      What do you remember about me?
Companion: You're Sara, vegetarian, and you've asked me to keep family off the table.
           That's what I keep front-of-mind. Want me to forget anything?

Customize / extend

  • Voice channel → adapt this for phone using Voice Concierge. Tone matters even more in voice.
  • Wellness flavor → if the companion is goal-driven (workouts, sleep, journaling), see AI Coach for the goal-tracking shape.
  • Multi-modal → image generation, voice notes, photo recognition — all stack on top; memory is unchanged.
  • End-to-end encryption → memories at rest aren’t encrypted per-user by default. If your trust model requires it, encrypt the document field client-side before calling memories.create.

Troubleshooting

Companion forgets things the user told it last week
  • Confirm ingestion is firing. Log inside the asyncio.create_task block during development — the fire-and-forget pattern swallows errors silently.
  • Increase maxResults in the search adapter so important memories aren’t crowded out.
Companion volunteers sensitive memories unprompted
  • Sharpen the system prompt’s “never volunteer unprompted” line.
  • Consider tagging sensitive memories with metadata.sensitivity = "high" and filtering them out of default search.
Tone drift over a long session
  • Long histories can let the model regress to LLM-default voice. Re-inject the user’s tone preference into the system prompt at the start of each session, pulled from a “communication-style” memory.