LangGraph integration for Zep
Project description
Zep LangGraph Integration
Give LangGraph agents durable, cross-session memory backed by Zep's temporal Context Graph. The package ships two layers:
- Node / tool helpers (primary) — call Zep directly inside your graph nodes: inject the user's Context Block into the system prompt, persist each turn, and expose a graph-search tool. This matches Zep's own LangGraph guide.
ZepStore(secondary) — a hybrid-delegateBaseStoreforcreate_react_agent(store=...)and langmem's memory tools.
Installation
pip install zep-langgraph
See SETUP.md for creating a Zep account, getting an API key, and running the example end to end.
Quick Start (primary path)
Inject Zep context with a prompt callable, expose a graph-search tool, and
persist each turn. Identity (the user, thread, and the user's real name) is yours
to manage — create the Zep user and thread out-of-band before the first turn.
import os
from langchain_core.messages import AIMessage, HumanMessage
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from zep_cloud import Message
from zep_cloud.client import AsyncZep
from zep_langgraph import build_system_message, create_graph_search_tool, persist_messages
zep = AsyncZep(api_key=os.environ["ZEP_API_KEY"])
async def prompt(state):
system = await build_system_message(
zep, thread_id="thread-1", base_instructions="You are a helpful assistant."
)
return [system, *state["messages"]]
agent = create_react_agent(
model=ChatOpenAI(model="gpt-5"),
tools=[create_graph_search_tool(zep, user_id="user-1")],
prompt=prompt,
)
result = await agent.ainvoke({"messages": [HumanMessage(content="Where do I work?")]})
reply = result["messages"][-1]
await persist_messages(
zep,
thread_id="thread-1",
messages=[Message(role="user", content="Where do I work?", name="Alice Smith"), reply],
)
A complete runnable version is in examples/react_agent.py.
How It Works
The Zep loop is the same everywhere: create user → create thread → add messages → retrieve context. This package wraps each step as a helper you call from inside a graph node.
Context injection — build_system_message / get_zep_context
thread.get_user_context(thread_id) returns a token-efficient Context Block
assembled from the entire user graph (the thread only scopes what is relevant
right now). build_system_message fetches it and folds it into a
SystemMessage together with your base instructions, ready to prepend to the
model's message list. get_zep_context returns just the raw block.
Implemented in src/zep_langgraph/context.py.
Persistence — persist_messages
Wraps thread.add_messages. Accepts LangChain BaseMessage objects (converted
automatically — human→user, ai→assistant, …) or native Zep Message
objects, flattens multimodal content to text, truncates over-long messages, and
maps names so Zep can resolve identity. Pass return_context=True to fold
persist + retrieve into one round-trip.
Implemented in src/zep_langgraph/persistence.py.
On-demand search — create_graph_search_tool
Returns a LangChain StructuredTool over graph.search. Bind it to a model or
pass it to create_react_agent(tools=[...]) and the model decides when to search
the graph. The target (user_id for a personal graph, graph_id for a shared
standalone graph) and the search parameters (scope, reranker, limit) are
fixed at construction so the model only supplies the query.
Implemented in src/zep_langgraph/tools.py.
ZepStore — a BaseStore for the langmem audience
BaseStore is LangGraph's cross-thread long-term-memory interface;
create_react_agent(store=...) and langmem's
create_manage_memory_tool / create_search_memory_tool require one. Zep is a
temporal knowledge graph, not a KV store, so ZepStore uses a hybrid-delegate
design: a backing KV BaseStore (default InMemoryStore) serves exact-key
get / put / delete / list_namespaces faithfully and synchronously, while
every put is also ingested into Zep and search is routed to Zep's semantic
graph.search. Only the two abstract methods (batch / abatch) are
implemented; everything else is inherited and delegates to them.
from zep_langgraph import ZepStore
store = ZepStore(zep) # default backing store: InMemoryStore
await store.aput(("memories", "user-1"), "m1", {"text": "Alice works at Acme."})
item = await store.aget(("memories", "user-1"), "m1") # exact-key, synchronous
hits = await store.asearch(("memories", "user-1"), query="where does Alice work?")
Zep ingestion is asynchronous. A value written with
putis available immediately for exact-keyget(served by the backing store), but its extracted facts are not instantly returned bysearch— there is no read-after-write of graph facts within a turn.ZepStoreis the long-term memory layer, not the checkpointer, so graph execution and short-term state are unaffected.
Implemented in src/zep_langgraph/store.py; see examples/store_agent.py.
Public API
| Symbol | Kind | Purpose |
|---|---|---|
get_zep_context / get_zep_context_sync |
async / sync fn | Fetch the Context Block for a thread |
build_system_message / build_system_message_sync |
async / sync fn | Build a SystemMessage with the Context Block |
format_context_block |
fn | Combine base instructions with a Context Block |
persist_messages / persist_messages_sync |
async / sync fn | Persist a turn (LangChain or Zep messages) |
to_zep_message / to_zep_messages |
fn | Convert LangChain messages to Zep messages |
create_graph_search_tool / create_graph_search_tool_sync |
fn | Build a graph.search StructuredTool |
ZepStore |
class | Hybrid-delegate BaseStore |
Both an AsyncZep (async helpers, recommended) and a synchronous Zep client
are supported. Reuse a single client instance.
Error Handling
Every helper handles Zep failures gracefully: context retrieval and persistence
log a warning and return None/an empty result, the search tool returns an error
string, and ZepStore keeps serving KV operations from its backing store. A
Zep failure never crashes the host agent.
Configuration
export ZEP_API_KEY="your-zep-api-key"
export OPENAI_API_KEY="your-openai-api-key" # for the example's model
Examples
- examples/react_agent.py —
create_react_agentwith Zep context injection, the graph-search tool, and per-turn persistence. - examples/store_agent.py —
ZepStoreas aBaseStore, showing the KV round-trip and Zep-routed semantic search.
Development
git clone https://github.com/getzep/zep.git
cd zep/integrations/langgraph/python
make install # uv sync --extra dev
make format # ruff format .
make lint # ruff check .
make type-check # mypy src/
make test # pytest tests/ -v
make all # all of the above
make build # uv build
Requirements
- Python 3.11+
zep-cloud>=3.23.0langgraph>=1.2.5(pulls inlangchain-core)
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_langgraph-0.1.0.tar.gz.
File metadata
- Download URL: zep_langgraph-0.1.0.tar.gz
- Upload date:
- Size: 32.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a5db2d7c2c46dcf851800313fa9d54bc54aff70a6e30a1a3c661d78cb923644
|
|
| MD5 |
c9eda028b0bc4aa6f733f6f890268b80
|
|
| BLAKE2b-256 |
d6294f6394800ae3851a816299f03dbd565407d6eea49bc69a75f52b04d29812
|
Provenance
The following attestation bundles were made for zep_langgraph-0.1.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_langgraph-0.1.0.tar.gz -
Subject digest:
4a5db2d7c2c46dcf851800313fa9d54bc54aff70a6e30a1a3c661d78cb923644 - Sigstore transparency entry: 1954926855
- Sigstore integration time:
-
Permalink:
getzep/zep@db65994287fd6ad943eeabf6abbe45f056065a4c -
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@db65994287fd6ad943eeabf6abbe45f056065a4c -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file zep_langgraph-0.1.0-py3-none-any.whl.
File metadata
- Download URL: zep_langgraph-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13249d7b54d8a8e5a949538110f640913ac47390df1c00f69b604f8fe76a3845
|
|
| MD5 |
5456ccfefb397f5cd67af781c099b374
|
|
| BLAKE2b-256 |
c0f70fe4ca052e417203935278616f9d66e899fdf79a52a09cc4eeb75d7658b6
|
Provenance
The following attestation bundles were made for zep_langgraph-0.1.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_langgraph-0.1.0-py3-none-any.whl -
Subject digest:
13249d7b54d8a8e5a949538110f640913ac47390df1c00f69b604f8fe76a3845 - Sigstore transparency entry: 1954926925
- Sigstore integration time:
-
Permalink:
getzep/zep@db65994287fd6ad943eeabf6abbe45f056065a4c -
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@db65994287fd6ad943eeabf6abbe45f056065a4c -
Trigger Event:
workflow_dispatch
-
Statement type: