> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs-beta.getzep.com/v3/observations/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs-beta.getzep.com/_mcp/server. # Observations > Observations are durable, evidence-backed patterns Zep derives from a Context Graph — recurring loops, preferences, commitments, and state transitions across many facts. > **Info** > > Available to [Flex Plus and Enterprise](https://www.getzep.com/pricing) customers. ## Overview An **observation** is a durable, evidence-backed piece of context that Zep automatically derives from a graph. Each observation captures a meaningful change, decision, commitment, constraint, preference, state transition, recurring pattern, or stable relationship involving one or more entities. Observations sit alongside [facts](/facts) and [entity summaries](/entities) as a derived construct on the graph, but they answer a different question: * **Facts** are granular, time-stamped claims stored on a single edge between two entities. * **Entity summaries** are entity-centered narratives that describe the history of a single node. * **Observations** are cross-entity context that captures *why* something matters — the persistent decisions, behaviors, and relationships that span multiple facts and entities. This makes observations especially useful for surfacing context that would otherwise be diluted across many facts: a user's evolving preferences, a recurring failure mode, a long-running commitment, or the way two entities consistently interact over time. ## How Zep creates observations Observations are detected automatically by analyzing structural patterns in the graph — clusters of facts and entities that together describe the same underlying behavior or relationship. Zep then synthesizes a name and summary for each observation it detects. Observations are deduplicated and merged: when new evidence fits an existing observation, the existing observation is regenerated with the new evidence merged in. When a newer observation supersedes an older one, the older observation is retired so the graph reflects the current state of what is known. Observations are read-only — they cannot be created, edited, or deleted directly. They follow the evidence in the graph. ## Steering observations By default, Zep decides how each observation is worded and assigns it a generic type. With [observation steering](/steering-observations), you can guide that generation — shaping the wording and relevance of new observations and assigning custom types you can filter on during search. Steering changes how observations are generated, not the evidence behind them. ## Retrieving observations Use the SDK to list observations for a user or graph, fetch a single observation by UUID, or search a graph specifically for observations. ### List and fetch **`Python`** ```python Python from zep_cloud.client import Zep client = Zep(api_key=API_KEY) # List the observations Zep has materialized for a user's graph. observations = client.graph.observation.get_by_user_id( user_id="emily-painter", limit=20, ) for obs in observations: print(f"{obs.name}: {obs.summary}") # Fetch a single observation by UUID. single = client.graph.observation.get(uuid_=observations[0].uuid_) ``` **`TypeScript`** ```typescript TypeScript import { ZepClient } from "@getzep/zep-cloud"; const client = new ZepClient({ apiKey: API_KEY }); // List the observations Zep has materialized for a user's graph. const observations = await client.graph.observation.getByUserId( "emily-painter", { limit: 20 }, ); for (const obs of observations) { console.log(`${obs.name}: ${obs.summary}`); } // Fetch a single observation by UUID. const single = await client.graph.observation.get(observations[0].uuid); ``` **`Go`** ```go Go import ( "context" "fmt" v3 "github.com/getzep/zep-go/v3" v3client "github.com/getzep/zep-go/v3/client" "github.com/getzep/zep-go/v3/option" ) client := v3client.NewClient( option.WithAPIKey(API_KEY), ) // List the observations Zep has materialized for a user's graph. observations, err := client.Graph.Observation.GetByUserID( context.TODO(), "emily-painter", &v3.GraphObservationsRequest{Limit: v3.Int(20)}, ) for _, obs := range observations { fmt.Printf("%s: %s\n", obs.Name, obs.Summary) } // Fetch a single observation by UUID. single, err := client.Graph.Observation.Get(context.TODO(), observations[0].UUID) ``` For graph-scoped observations, use `get_by_graph_id` (Python), `getByGraphId` (TypeScript), or `GetByGraphID` (Go) with a `graph_id`. List endpoints support UUID-cursor pagination. Pass the UUID of the last item from the previous page as `uuid_cursor` to fetch the next page. ### Search **`Python`** ```python Python results = client.graph.search( user_id="emily-painter", query="account suspension and recovery", scope="observations", limit=5, ) for obs in results.observations or []: print(obs.name, obs.score) ``` **`TypeScript`** ```typescript TypeScript const results = await client.graph.search({ userId: "emily-painter", query: "account suspension and recovery", scope: "observations", limit: 5, }); for (const obs of results.observations ?? []) { console.log(obs.name, obs.score); } ``` **`Go`** ```go Go results, err := client.Graph.Search(context.TODO(), &v3.GraphSearchQuery{ UserID: v3.String("emily-painter"), Query: "account suspension and recovery", Scope: v3.GraphSearchScopeObservations.Ptr(), Limit: v3.Int(5), }) for _, obs := range results.Observations { fmt.Println(obs.Name, obs.Score) } ``` ## Observations and the Context Block The default [Context Block](/retrieving-context) can include observations when Smart Context Assembly selects them. Use a [context template](/context-templates) to always include observations or set a limit. Retrieve observations directly or use [advanced Context Block construction](/advanced-context-block-construction) when you need full control. ## Related * [Steering observations](/steering-observations) — guide how Zep words and categorizes new observations. * [Facts](/facts) — granular, edge-level claims that often serve as evidence for observations. * [Entities](/entities) — entity-level summaries on the Context Graph. * [Episodes](/episodes) — the supporting evidence that observations are grounded in. * [Searching the graph](/searching-the-graph) — how to retrieve observations with graph search. * [Context types](/context-types) — overview of the other context types. > Durable, evidence-backed context that captures meaningful patterns across a graph