Quick Start Guide
Zep delivers agent memory at enterprise scale, giving your AI agents the right context at the right time. From a temporal Context Graph, Zep assembles relevant context from chat history, business data, and user behavior—so agents make better decisions with accurate, up-to-date information. With a simple three-line API and sub-200ms retrieval, Zep helps you build personalized, reliable agents without building a context pipeline.
Get started with the example in the video using:
This guide shows you how to integrate Zep into your AI application to provide personalized context for every user interaction. You’ll learn how to ingest user messages and business data, then retrieve assembled context that includes user preferences, traits, and relevant facts—all optimized for your LLM’s context window.
Looking for a more in-depth understanding? Check out our Key Concepts page.
Migrating from Mem0? Check out our Mem0 Migration guide.
Install the Zep SDK
Python
TypeScript
Go
Set up your Python project, ideally with a virtual environment, and then:
Initialize the Zep client
After creating a Zep account, obtaining an API key, and setting the API key as an environment variable, initialize the client once at application startup and reuse it throughout your application.
Initialize Zep client
.env
Create a Zep user for each of your users
Whenever users are created in your application, you need to trigger the creation of a Zep user. Make sure to include at least their first name, and ideally also their last name and email to ensure correct identification of the user in future messages. We recommend setting the Zep user ID equal to your internal user ID.
Backfilling existing users: Run a one-time migration that calls user.add for each existing user.
Provide at least the first name and ideally the last name when calling user.add to ensure Zep correctly associates the user with references in your data. If needed, add this information later using the update user method.
Create a Zep thread for each of your threads
Whenever a user starts a new conversation with your agent, you need to trigger the creation of a Zep thread. Learn more about adding messages.
Backfilling prior conversations: For prior conversations, you will need to run a one-time migration to create Zep threads for those conversations and add the prior messages to the respective Zep threads. zep-ingest is the recommended way to do this: it validates each row, creates the threads, preserves message order, and monitors the import. You can also drive the Batch API yourself.
Add incoming user messages to Zep
When a new user message comes in, add the user message to Zep, providing the user’s name in the message if possible.
It is important to provide the name of the user in the name field if possible, to help with graph construction.
Include the created_at timestamp (RFC3339 format) representing when the message was originally sent. This ensures accurate temporal understanding in the knowledge graph. See Setting message timestamps for more details.
Add streaming business data to Zep
Beyond chat messages, you can provide Zep with additional context about your users by sending business data directly to their knowledge graphs. This includes user interactions with your application, transactions, support tickets, emails, transcripts—essentially any information that gives context about the user and can be represented as text.
Use the graph.add method to send structured, semi-structured, or unstructured text data to Zep. Include a reference to the user—their full name, user ID, or both—so Zep can correctly associate the data with the user in their knowledge graph. Read more about adding business data.
Any text can be sent to Zep—structured JSON, semi-structured logs, or plain text descriptions. The example below shows a JSON event, but you could also send "User Jane Smith listened to 'Bohemian Rhapsody' by Queen" as plain text. See Adding business data for more data type options.
Retrieve a Zep Context Block
Retrieve a Context Block after you add the user message and before the model generates a response. The block contains relevant information from the user’s graph.
The Context Block can contain user or external content. Pass it through your model provider’s untrusted-data channel, as described in Memory security best practices.
Use the default Context Block
Zep assembles the default Context Block with semantic search, full-text search, and graph search. The four most recent messages from the thread form the query.
The Context Block has a latency of less than 200 ms at the 95th percentile.
The Context Block can include all six context types. Smart Context Assembly selects available types that are relevant to the recent messages.
This example contains a user summary and facts:
Use a custom Context Block
Use a context template to control the Context Block format. Pass the template ID to thread.get_user_context().
Create a context template
Create a context template for your Zep project and save the template ID. The context templates guide lists the supported syntax and variables.
Retrieve custom context block using thread.get_user_context()
Retrieve your custom context block using the thread.get_user_context() method, passing in your template ID.
Add context block to agent context window
As outlined in our retrieval philosophy, Zep optimizes for high recall over precision, meaning we err on the side of including more results even if some are less relevant. Most agents will automatically reference only the most relevant information when responding to the user message.
The Context Block can contain text that came from end users, documents, tools, or other external sources. A privileged message gives that text higher instruction priority than ordinary input. Keep the Context Block out of system messages, developer messages, and other privileged instruction channels.
Follow your model provider’s documented method for separating instructions from data:
- For the OpenAI Responses API, send preloaded context through ordinary
inputor ausermessage. Usefunction_call_outputonly for the result of an actual function call. - For the Anthropic Messages API, design retrieval as a tool call when context can contain third-party data. Return the context in a
tool_resultblock linked to the originaltool_use_id. - For other providers, use the documented untrusted-data channel. If the provider does not define one, use an ordinary user-level message with explicit data framing.
OpenAI with preloaded context
Place the Context Block after the conversation history and before the latest user request. Everything before the block stays unchanged between turns, so this order preserves the cacheable prefix that prompt caching needs. Replace the previous turn’s block instead of appending a second one.
If the model requests memory through a function, return the Context Block as function_call_output linked to the original call_id.
OpenAI Chat Completions with tool-retrieved context
Anthropic with tool-retrieved context
Do not create a tool message for preloaded context unless the provider documents that pattern. A tool-result type must remain linked to the model’s actual tool request.
Read Memory security best practices for provider-specific mappings, write controls, action authorization, and recovery guidance.
Add assistant response to Zep
After generating the assistant response, add it to Zep to continue building the user’s knowledge graph.
Next steps
Now that you’ve integrated Zep into your application, you can explore additional features:
- Customize graph structure to your domain - Define custom entity and edge types to structure domain-specific information.
- Add user interactions and metadata - Add ongoing interactions or user profile information to the user’s graph.
- Custom context templates - Design custom context block formats tailored to your application’s needs.
- User summary instructions - Specify how Zep generates user summaries.