Skip to main content

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:

  1. Extracts the user's latest message from the invocation context.
  2. Resolves the user's Zep identity from session state.
  3. Persists the message to Zep via thread.add_messages(return_context=True) -- storing the message and retrieving relevant context in a single API call.
  4. 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:

  1. Add ZepContextTool to 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),
)
  1. 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,
    },
)
  1. 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_created callback for configuring ontology, instructions, and summaries per user
  • On-demand graph search -- ZepGraphSearchTool lets 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.0
  • google-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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zep_adk-0.2.0.tar.gz (30.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zep_adk-0.2.0-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

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

Hashes for zep_adk-0.2.0.tar.gz
Algorithm Hash digest
SHA256 a1201eebd159303800601c7bf80a16bc073278d6c0e94482862ab0487eccfd46
MD5 a3a5c8d4922989afb09239f83a960a31
BLAKE2b-256 8bab096d1dcb76e1ea57cf33c6c4208cfa9bd01d7bba8040297b5dde6ed8f6b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for zep_adk-0.2.0.tar.gz:

Publisher: release-integrations.yml on getzep/zep

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for zep_adk-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4c75b04d5f7f168acf78b2693bad69cf417283a854f507a281e736fad65ac648
MD5 fb07d79ff4dcc20e01a2895a6868886e
BLAKE2b-256 b0806acce0dba80cc9b12cf9c205ea8bacccf4a13f0fe01ee658d59f0642f2d8

See more details on using hashes here.

Provenance

The following attestation bundles were made for zep_adk-0.2.0-py3-none-any.whl:

Publisher: release-integrations.yml on getzep/zep

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page