Skip to main content
Swap Agno’s in-memory database for a Synap-backed one. Agents that use enable_user_memories=True keep working without code changes. They just gain a persistent, semantically searchable memory store.
Requires Python 3.11+.

Overview

This guide shows how to add Synap to an Agno application to build agents that:
  • Persist user memories across processes and deployments
  • Retrieve memories semantically rather than by raw key lookup
  • Serve many users from a single database instance, scoped per-call by user_id
The Synap Agno integration ships a single class: a subclass of Agno’s InMemoryDb that routes memory operations through Synap.

Setup

Install the package alongside Agno:
The pip package is maximem-synap-agno, but the import drops the maximem- prefix and uses underscores: from synap_agno import ....
Configure your API key. Generate one from the Synap Dashboard.
.env
Initialize the SDK once at application startup:
See SDK Initialization for the full lifecycle and configuration options.

Basic integration

The smallest useful integration constructs a SynapDb, hands it to an Agent, and turns on enable_user_memories. Each agent.run(..., user_id=...) call now reads and writes against Synap rather than a process-local dict:
Notice that user_id is supplied per call. SynapDb is constructed once and serves all users in the process. The customer_id (organization scope) is fixed at construction. Memory reads degrade gracefully on Synap outages; writes raise so silent data loss is impossible.

Core concepts

SynapDb

SynapDb extends Agno’s InMemoryDb and overrides the four user-memory methods. Everything else (session state, non-memory storage) is inherited unchanged, so existing Agno code continues to work:
The overridden methods map to Synap as follows:

Per-call user scoping

Agno passes user_id as a runtime argument to every memory call rather than baking it into the database. That means one SynapDb instance can serve any number of users:
Each call hits Synap with its own user_id scope, so memories never leak between users, even though the database object is shared.

Complete example: long-lived agent serving many users

The pattern below is what most production Agno deployments end up with: one SynapDb and one Agent at module load, and a thin handler that supplies user_id per request:
Three things to notice in this pattern:
  1. One SynapDb, many users. The database is constructed once; user_id is the per-call scope.
  2. The customer_id is the tenant boundary. All users sharing a SynapDb instance are inside the same customer_id. For cross-tenant services, build a separate SynapDb per tenant.
  3. Agno’s behavior is unchanged. enable_user_memories, description, and run signatures all work exactly as in vanilla Agno; you’ve only swapped the storage layer.

Advanced patterns

Multi-tenant scoping

SynapDb takes the customer-tenant scope at construction (customer_id) and the user scope per call (user_id). customer_id is required on B2B Synap instances and ignored on single-tenant ones. See Memory Scopes.
For services that serve many tenants, route requests to the matching SynapDb rather than mixing tenants on one instance.

Memory topic discovery

get_all_memory_topics is implemented as a broad Synap search and returns unique topics across the user’s memory pool. Useful for building UIs that let a user browse what’s been remembered about them, or for prompt enrichment (“Here are the topics we’ve discussed: …”).

Failure semantics

The integration follows the Synap-wide contract:
  • get_user_memory / get_user_memories degrade gracefully: return empty results and log an error if Synap is unreachable.
  • upsert_user_memory surfaces failures: raises SynapIntegrationError so the agent and caller know persistence failed.
This is by design: read failures shouldn’t break a user-facing answer, but silent write failures would let memory drift away from reality.

Going further


Next steps

Google ADK

FunctionTool factory for Google ADK agents.

OpenAI Agents

Function tools for the OpenAI Agents SDK.

Memory Scopes

How user_id and customer_id interact across reads and writes.

Ingestion

Direct ingestion API for pipelines that need finer control than upsert_user_memory.