Google ADK integration for Zep
Project description
Zep Google ADK Integration
A memory integration package that enables Google ADK agents to leverage Zep's long-term memory platform for persistent conversation storage and context-aware responses.
Installation
pip install zep-adk
Quick Start
Define one agent, shared across all users. Per-user identity is passed via ADK session state.
import os
from google.adk.agents import Agent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from zep_cloud.client import AsyncZep
from zep_adk import ZepContextTool, create_after_model_callback
# Initialize Zep client
zep = AsyncZep(api_key=os.getenv("ZEP_API_KEY"))
# One shared agent definition
agent = Agent(
name="my_agent",
model="gemini-2.5-flash",
instruction="You are a helpful assistant with long-term memory.",
tools=[ZepContextTool(zep_client=zep)],
after_model_callback=create_after_model_callback(zep_client=zep),
)
session_service = InMemorySessionService()
runner = Runner(agent=agent, app_name="my_app", session_service=session_service)
# Per-user session: user_id → Zep user, session_id → Zep thread
await session_service.create_session(
app_name="my_app",
user_id="user_123", # automatically used as Zep user ID
session_id="session_abc", # automatically used as Zep thread ID
state={
"zep_first_name": "Jane",
"zep_last_name": "Smith",
"zep_email": "jane@example.com", # optional
},
)
Session State Keys
Identity is resolved at runtime from ADK session state and session metadata. The ADK user_id is used as the Zep user ID and the session_id is used as the Zep thread ID -- both automatically, no state keys needed.
Set these optional keys when creating a session to enrich the Zep user profile:
| Key | Required | Default | Description |
|---|---|---|---|
zep_first_name |
Recommended | "Anonymous" |
User's first name. Zep uses this to anchor the user's identity node in the knowledge graph. |
zep_last_name |
Optional | "User" |
User's last name. |
zep_email |
Optional | None |
User's email address. |
zep_user_id |
Optional | ADK user_id |
Override the Zep user ID if it differs from the ADK user ID. |
zep_thread_id |
Optional | ADK session_id |
Override the Zep thread ID if it differs from the ADK session ID. |
How It Works
The integration uses two components that work together to give your ADK agent persistent memory:
ZepContextTool
A BaseTool subclass that hooks into ADK's process_llm_request() lifecycle method (the same pattern ADK's own PreloadMemoryTool uses). On every LLM turn it:
- Extracts the user's latest message from the invocation context.
- Resolves the user's Zep identity from session state.
- Persists the message to Zep via
thread.add_messages(return_context=True)-- storing the message and retrieving relevant context in a single API call. - Injects the returned context (facts, relationships, prior knowledge) into the LLM's system instructions.
The tool is never called by the model directly; it modifies the outgoing LLM request before it is sent.
create_after_model_callback
A factory function that returns an after_model_callback for persisting assistant responses to Zep. This ensures both sides of the conversation are stored in Zep's memory. The callback also resolves the thread ID from session state at runtime.
Both components include per-thread message deduplication to handle ADK's tool-use cycles, where the framework may call hooks multiple times per turn.
Adding Zep to an Existing Agent
If you already have an ADK agent serving all users, adding Zep memory requires only three changes -- no restructuring needed:
- Add
ZepContextToolto your agent's tools list:
from zep_adk import ZepContextTool
agent = Agent(
name="my_existing_agent",
model="gemini-2.5-flash",
instruction="...",
tools=[your_existing_tool, ZepContextTool(zep_client=zep)],
after_model_callback=create_after_model_callback(zep_client=zep),
)
- Include the user's name in session state when creating sessions (you're already creating sessions -- just add the keys):
await session_service.create_session(
app_name="my_app",
user_id=user_id, # automatically used as Zep user ID
session_id=session_id, # automatically used as Zep thread ID
state={
**your_existing_state,
"zep_first_name": first_name,
"zep_last_name": last_name,
},
)
- That's it. No factory function, no per-session agent instances.
Features
- Shared-agent architecture -- one Agent definition serves all users
- Session-state-driven identity -- per-user configuration via ADK's standard mechanism
- Single round-trip -- persist messages and retrieve context in one API call
- Lazy resource creation -- Zep user and thread are created on first use
- Per-thread deduplication -- prevents double-persistence during tool-use cycles
- Graceful error handling -- Zep API failures are logged but never crash the agent
- Context injection -- Zep's knowledge graph context is injected as system instructions
- Per-user setup hook --
on_user_createdcallback for configuring ontology, instructions, and summaries per user - On-demand graph search --
ZepGraphSearchToollets the model actively search the knowledge graph - Configurable graph search -- pin parameters at construction or let the model choose
Configuration
Environment Variables
# Required
export ZEP_API_KEY="your-zep-api-key"
export GOOGLE_API_KEY="your-google-api-key"
Constructor Parameters
ZepContextTool
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
zep_client |
AsyncZep |
Yes | -- | Initialised Zep async client |
context_builder |
ContextBuilder |
No | None |
Custom async callable for context retrieval |
ignore_roles |
list[str] |
No | None |
Roles to exclude from graph ingestion |
on_user_created |
UserSetupHook |
No | None |
Async callback fired once after a new Zep user is created. Use for per-user ontology, custom instructions, or user summary instructions. |
create_after_model_callback
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
zep_client |
AsyncZep |
Yes | -- | Initialised Zep async client |
assistant_name |
str |
No | "Assistant" |
Display name for the assistant in Zep |
ignore_roles |
list[str] |
No | None |
Roles to exclude from graph ingestion |
ZepGraphSearchTool
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
zep_client |
AsyncZep |
Yes | -- | Initialised Zep async client |
graph_id |
str |
No | None |
Fixed graph ID for shared-graph search |
name |
str |
No | "zep_graph_search" |
Tool name visible to the model |
description |
str |
No | (default) | Tool description visible to the model |
search_filters |
dict |
No | None |
Zep search filters (constructor-only) |
bfs_origin_node_uuids |
list[str] |
No | None |
BFS seed node UUIDs (constructor-only) |
**pinned |
any | No | -- | Pin any search param: scope, reranker, limit, mmr_lambda, center_node_uuid |
Examples
See the examples/ directory for complete working examples:
- basic_agent.py -- Full example with fact seeding and memory recall using the shared-agent pattern
Development
Setup
git clone https://github.com/getzep/zep.git
cd integrations/python/zep_adk
make install
Commands
make format # Format code with ruff
make lint # Run linting checks
make type-check # Run mypy type checking
make test # Run test suite
make all # Run all checks
make pre-commit # Development workflow with auto-fixes
make ci # Strict CI checks
Requirements
- Python 3.10+
zep-cloud>=3.0.0google-adk>=1.0.0
Support
License
Apache 2.0 - see LICENSE for details.
Contributing
Contributions are welcome! Please see our Contributing Guide for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file zep_adk-0.2.0.tar.gz.
File metadata
- Download URL: zep_adk-0.2.0.tar.gz
- Upload date:
- Size: 30.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a1201eebd159303800601c7bf80a16bc073278d6c0e94482862ab0487eccfd46
|
|
| MD5 |
a3a5c8d4922989afb09239f83a960a31
|
|
| BLAKE2b-256 |
8bab096d1dcb76e1ea57cf33c6c4208cfa9bd01d7bba8040297b5dde6ed8f6b4
|
Provenance
The following attestation bundles were made for zep_adk-0.2.0.tar.gz:
Publisher:
release-integrations.yml on getzep/zep
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zep_adk-0.2.0.tar.gz -
Subject digest:
a1201eebd159303800601c7bf80a16bc073278d6c0e94482862ab0487eccfd46 - Sigstore transparency entry: 1250819519
- Sigstore integration time:
-
Permalink:
getzep/zep@cd57d691ae7d22f357635dc57aa78bf0062aa9d1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/getzep
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-integrations.yml@cd57d691ae7d22f357635dc57aa78bf0062aa9d1 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file zep_adk-0.2.0-py3-none-any.whl.
File metadata
- Download URL: zep_adk-0.2.0-py3-none-any.whl
- Upload date:
- Size: 16.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c75b04d5f7f168acf78b2693bad69cf417283a854f507a281e736fad65ac648
|
|
| MD5 |
fb07d79ff4dcc20e01a2895a6868886e
|
|
| BLAKE2b-256 |
b0806acce0dba80cc9b12cf9c205ea8bacccf4a13f0fe01ee658d59f0642f2d8
|
Provenance
The following attestation bundles were made for zep_adk-0.2.0-py3-none-any.whl:
Publisher:
release-integrations.yml on getzep/zep
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zep_adk-0.2.0-py3-none-any.whl -
Subject digest:
4c75b04d5f7f168acf78b2693bad69cf417283a854f507a281e736fad65ac648 - Sigstore transparency entry: 1250819923
- Sigstore integration time:
-
Permalink:
getzep/zep@cd57d691ae7d22f357635dc57aa78bf0062aa9d1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/getzep
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-integrations.yml@cd57d691ae7d22f357635dc57aa78bf0062aa9d1 -
Trigger Event:
workflow_dispatch
-
Statement type: