LiveKit integration
Add long-term agent memory to LiveKit voice agents
The zep-livekit package adds long-term agent memory to LiveKit voice agents. It wraps LiveKit’s Agent so that completed conversation turns are persisted to Zep and relevant context is injected before each response. Choose between user thread memory or structured knowledge graph memory.
Core benefits
- Persistent voice memory: Each completed turn is stored in Zep and contributes to the user’s temporal knowledge graph
- Automatic context injection: Relevant context is retrieved and added as a system message before the agent’s next response
- Two access patterns:
ZepUserAgentfor thread-based conversation memory,ZepGraphAgentfor direct knowledge graph access - Drop-in replacement: Both classes subclass LiveKit’s
Agentand accept all standardAgentparameters
How it works
LiveKit’s AgentSession owns the audio pipeline — speech-to-text, voice activity detection, turn detection, and text-to-speech. Zep does not touch audio. Instead, the Zep agent hooks into LiveKit’s turn lifecycle and runs a write-then-read cycle on each completed user turn:
- Persist the turn — when LiveKit fires
on_user_turn_completed, the user message is written to Zep (a thread forZepUserAgent, the graph forZepGraphAgent). Assistant responses are captured separately via theconversation_item_addedsession event. - Retrieve context — the agent fetches a context block (
thread.get_user_contextforZepUserAgent) or runs hybrid graph search across edges, nodes, and episodes (ZepGraphAgent). - Inject context — the retrieved context is added to the turn as a system message, so the LLM’s next response is grounded in prior conversation.
Allow time for indexing: Turns are ingested and knowledge is extracted asynchronously, so facts from the current turn are not searchable within that same turn. Context retrieved on a given turn reflects knowledge extracted from earlier turns.
Installation
Requires LiveKit Agents v1.0+ (not v0.x) and a Zep Cloud API key. The examples use the v1.0 AgentSession API. Get your API key from app.getzep.com.
Set up your environment variables:
LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET come from a LiveKit Cloud project or a self-hosted LiveKit server. They configure the LiveKit infrastructure your agent connects to and are unrelated to Zep.
Agent types
ZepUserAgent: Uses user threads for conversation memory with automatic context injectionZepGraphAgent: Reads and writes a knowledge graph, optionally shaped by custom entity models
Identity and isolation
The example below derives a stable user_id from your application’s auth system and scopes the thread_id (and graph_id) to the LiveKit room. Use a stable, durable user ID — do not derive user_id from the room name. A room is a per-session construct, so a room-derived user_id fragments a returning user’s history across rooms and prevents Zep from accumulating long-term memory for that person.
Scope thread_id or graph_id to the room when you want per-session isolation while still attributing every session to the same long-lived user.
User memory agent
ZepUserAgent stores each turn in a Zep thread and injects a context block before the next response.
Automatic memory integration: ZepUserAgent captures each voice turn and injects relevant context from previous conversations, enabling continuity across sessions without manual memory management.
ZepUserAgent configuration
ZepUserAgent accepts the following parameters in addition to all standard LiveKit Agent parameters (stt, llm, tts, instructions, tools, chat_ctx, etc.):
The context_mode parameter is deprecated and ignored; the Zep V3 context block returns a structured format and no longer accepts a mode selector.
Knowledge graph agent
ZepGraphAgent writes each turn directly to a knowledge graph and retrieves context with hybrid search over edges (facts), nodes (entities), and episodes. You can optionally shape the graph with custom entity models.
Search filters: The search_filters parameter constrains which results the agent retrieves. Use node_labels to filter by entity types defined in your ontology.
Graph memory context: ZepGraphAgent writes each turn to the graph and injects relevant facts, entities, and episodes as context, grounding responses in prior conversations.
ZepGraphAgent configuration
ZepGraphAgent accepts the following parameters in addition to all standard LiveKit Agent parameters:
Best practices
- Use a stable user ID — derive
user_idfrom your auth system, not the room name, so a returning user’s memory accumulates instead of fragmenting across sessions - Scope sessions with the thread or graph — use the room name for
thread_idorgraph_idwhen you want per-session isolation, keepinguser_idconstant - Let LiveKit own audio —
AgentSessionhandles STT, VAD, turn detection, and TTS; Zep only persists turns and injects context - Allow time for indexing — Zep extracts knowledge asynchronously, so facts from a turn are not instantly searchable
Next steps
- Explore customizing graph structure for advanced knowledge organization
- Learn about searching the graph and how to tune search
- See code examples for additional patterns