Searching the Graph

Zep employs hybrid search, combining semantic similarity with BM25 full-text. Results are merged and ranked. Additional details can be found in the API Reference.

The example below demonstrates a simple search.

1from zep_cloud.client import AsyncZep
2
3client = AsyncZep(
4 api_key=API_KEY,
5)
6
7search_results = await client.graph.search(
8 user_id=user_id,
9 query=query,
10)

Read more about chat message history search.

Best Practices

Keep queries short: they are truncated at 8,192 tokens. Long queries may increase latency without improving search quality. Break down complex searches into smaller, targeted queries. Use precise, contextual queries rather than generic ones

Configurable Search Parameters

Zep allows several parameters to fine-tune search behavior:

ParameterDescriptionDefault
user_id or group_idRequired. Specifies whether to search user-specific or group graphs-
scopeControls search scope - either "edges" or "nodes""edges"
rerankerMethod to rerank results: "rrf", "mmr", "node_distance", "episode_mentions", or "cross_encoder""rrf"
min_scoreMinimum relevance score threshold for results0
limitMaximum number of results to return10

Search Scopes

Nodes are connection points in the graph that represent either:

  • Chat history entities
  • Business data added through the Graph API

Each node maintains a summary of facts from its connections (edges), giving you a quick overview of things related to that node.

Edges represent individual connections between nodes, containing specific interactions or pieces of information. Edge search (the default) is best for finding specific details or conversations, while node search helps you understand the broader context around entities in your graph.

The example below demonstrates a node search.

1from zep_cloud.client import AsyncZep
2
3client = AsyncZep(
4 api_key=API_KEY,
5)
6
7search_results = await client.graph.search(
8 group_id=group_id,
9 query=query,
10 scope="nodes",
11)

Reranking Search Results

Besides the default Reciprocal Rank Fusion (rrf) which combines results from semantic and BM25, Zep supports several reranking methods to improve search results:

Maximal Marginal Relevance Re-Ranking

Standard similarity searches often return highly similar top results, potentially limiting the information added to a prompt. mmr addresses this by re-ranking results to promote diversity, downranking similar results in favor of relevant but distinct alternatives.

Required: mmr_lambda - tunes the balance between relevance and diversity

Example of MMR search:

1from zep_cloud.client import AsyncZep
2
3client = AsyncZep(
4 api_key=API_KEY,
5)
6
7search_results = await client.graph.search(
8 user_id=user_id,
9 query=query,
10 reranker="mmr",
11 mmr_lambda=0.5, # tune diversity vs relevance
12)

Node Distance

node_distance re-ranks search results based on the number of hops between the search result and a center node. This can be useful for finding facts related to a specific node, such as a user or a topic.

Required: center_node_uuid - UUID of the node to use as the center of the search

Example of Node Distance search:

1from zep_cloud.client import AsyncZep
2
3client = AsyncZep(
4 api_key=API_KEY,
5)
6
7search_results = await client.graph.search(
8 user_id=user_id,
9 query=query,
10 reranker="node_distance",
11 center_node_uuid=center_node_uuid,
12)

Episode Mentions

episode_mentions re-ranks search results based on the number of times the node or edge has been mentioned in the chat history.

Example of Episode Mentions search:

1from zep_cloud.client import AsyncZep
2
3client = AsyncZep(
4 api_key=API_KEY,
5)
6
7search_results = await client.graph.search(
8 user_id=user_id,
9 query=query,
10 reranker="episode_mentions",
11)

Cross Encoder

cross_encoder re-ranks search results by using a specialized model that jointly analyzes the query and each search result together, providing more accurate relevance scoring than traditional methods that analyze them separately.

Example of Cross Encoder search:

1from zep_cloud.client import AsyncZep
2
3client = AsyncZep(
4 api_key=API_KEY,
5)
6
7search_results = await client.graph.search(
8 user_id=user_id,
9 query=query,
10 reranker="cross_encoder",
11)
Built with