Add persistent, per-user memory to a Pydantic AI agent in two lines. The integration leans on Pydantic AI’s dependency-injection model — scope and SDK travel throughDocumentation Index
Fetch the complete documentation index at: https://docs.maximem.ai/llms.txt
Use this file to discover all available pages before exploring further.
deps, and the search/store tools are registered onto the agent automatically.
Overview
This guide shows how to add Synap to a Pydantic AI application to build agents that:- Recall user-specific facts, preferences, and past conversations
- Persist new information surfaced during a conversation
- Stay type-safe and testable end-to-end — every dependency is a dataclass
deps dataclass and a one-shot registration function.
| Export | Purpose |
|---|---|
SynapDeps | Dataclass holding the SDK instance and user scope |
register_synap_tools(agent) | Registers synap_search and synap_store tools plus a system-prompt fragment |
Setup
Install the package alongside Pydantic AI:.env
Basic integration
Declare an agent withdeps_type=SynapDeps, call register_synap_tools(agent) once, then pass SynapDeps per request:
register_synap_tools does three things:
- Registers
synap_search— a tool the agent can call to retrieve memories - Registers
synap_store— a tool the agent can call to persist new memories - Appends a system-prompt fragment instructing the agent to use both tools
user_id or customer_id directly — it pulls them from RunContext[SynapDeps] inside the tool implementations, so the model cannot spoof scope.
Core concepts
SynapDeps
SynapDeps is the dependency container Pydantic AI injects into every tool call. It carries the SDK and the scoping triple:
SynapDeps per request, which means the same agent instance can serve any number of users without bleeding scope between them.
register_synap_tools
register_synap_tools(agent) attaches the two memory tools to your agent. After registration, every run that passes SynapDeps exposes:
synap_search(query: str, max_results: int = 5)— returns a list of memory objects scoped todeps.user_id(anddeps.customer_idif set)synap_store(content: str, memory_type: str = "fact")— persists a new memory under the same scope
synap_search for recall questions and synap_store when the user shares a new fact.
Complete example: per-user assistant
The following pattern is what most production deployments end up with: a singleAgent defined at module load, fresh SynapDeps per inbound request, and a thin handler around it.
- The agent is defined once. Pydantic AI’s dependency injection makes it safe to share — each
run()gets its owndeps. - Scope is request-local. Different users get different
SynapDeps; the model only ever sees a scope-stripped tool surface. - The system prompt is the policy. Want recall to be optional? Loosen the prompt. Want stores to be aggressive? Tighten it. The tools obey whatever the prompt tells the model.
Advanced patterns
Multi-tenant scoping
SynapDeps carries the same scoping triple every Synap integration uses — user_id (required), optional customer_id, optional conversation_id. customer_id is required on B2B Synap instances and ignored on single-tenant ones. See Memory Scopes.
Testing with mock deps
BecauseSynapDeps is just a dataclass, you can substitute a fake SDK in tests:
Failure semantics
The integration follows the Synap-wide contract:synap_searchdegrades gracefully — returns[]and logs an error if Synap is unreachable, so the agent can continue.synap_storesurfaces failures — raisesSynapIntegrationErrorso the caller knows persistence failed.
Next steps
OpenAI Agents
Function tools for the OpenAI Agents SDK.
CrewAI
Storage backend for CrewAI crews.
Context Fetch
The retrieval API that powers
synap_search — modes, scopes, and response shapes.Memory Scopes
How
user_id, customer_id, and conversation_id interact across reads.