Skip to navigation

Steering observations

Guide how Zep generates observations with a custom instruction and observation types
Experimental API

Observation steering is an experimental feature. The API may change in future releases.

Available to Flex Plus and Enterprise customers — the same plans that generate observations.

Why use observation steering

Zep automatically derives observations — durable, evidence-backed patterns — from a graph. By default, Zep decides how each observation is worded and labels every observation with the type generic. Observation steering lets you guide that generation without changing the underlying evidence.

Steering influences generation along two axes. You can set either one on its own, or both together:

  • Instruction: free-text guidance that shapes the wording and relevance of the observations Zep writes. The instruction cannot introduce facts, choose which evidence is used, or change how many observations are produced — evidence always comes from the graph.
  • Observation types: up to ten named categories Zep may assign to an observation. Zep writes the selected type to the observation_type property on the observation node, which you can filter on during graph search. When none of your types fit, Zep falls back to generic.

Steering applies only to observations generated after you configure it. It does not enqueue a job or regenerate existing observations; those update on their own as new evidence arrives.

Use cases

  • Domain vocabulary: Label observations with categories that match your product — commitment, risk, preference, churn_signal — then filter graph search by type.
  • Relevance tuning: Steer wording and emphasis toward what your agent needs, without post-processing.
  • Per-user or per-graph control: Apply distinct guidance to a specific user graph or another graph while keeping a project-wide default.

Basic usage

Use set_observation_steering to replace the configuration at a scope, and get_observation_steering to read it back. Both return the resulting configuration. The project methods address the project-wide default. The graph methods address one graph.

from zep_cloud import Zep, ObservationType
client = Zep(
api_key=API_KEY,
)
# Set the project-wide default.
config = client.project.set_observation_steering(
instruction="Prioritize durable commitments and stated preferences. Keep observations concise.",
types=[
ObservationType(name="commitment", description="A promise or planned action the user has committed to."),
ObservationType(name="preference", description="A durable preference the user has expressed."),
],
)
# Read the current project configuration.
config = client.project.get_observation_steering()
print(config.instruction)
for t in config.types or []:
print(f"{t.name}: {t.description}")

Scoping to a user or graph

Steering resolves at one of two scopes:

  • Project: the default configuration, applied to every graph in the project. Use the project methods.
  • Graph: configuration for a single graph, addressed with the UUID of the graph. Use the graph methods. For a user graph, use the graph_uuid that user.create returns. For another graph, use the uuid that graph.create returns.

A graph configuration is a complete override, not a merge — when a graph has its own configuration, Zep uses it in full and ignores the project default. Reading a graph scope returns its effective configuration. When the graph has no configuration of its own, the response contains the project default and inherited is true.

# Steer observations for one user only.
# zep_graph_uuid is the graph_uuid of the user, from your application database.
client.graph.set_observation_steering(
zep_graph_uuid,
instruction="Focus on support escalations and unresolved issues.",
types=[
ObservationType(name="escalation", description="An issue the user escalated to support."),
],
)
# Read the effective configuration for the user's graph.
config = client.graph.get_observation_steering(zep_graph_uuid)
print(config.inherited) # False: the graph has its own configuration

Observation types

Each entry in types defines a category Zep may assign to an observation. When Zep generates an observation, it selects the best-fitting type and writes the name to the observation_type property on the observation node. If none of your configured types fit — or you configure no types — Zep uses generic.

FieldRules
nameMust match ^[a-z][a-z0-9_]*$ (start with a lowercase letter, then lowercase letters, digits, or underscores); up to 50 characters; unique within the list. generic is reserved and cannot be configured.
descriptionRequired; 1–500 characters. Describes when the type applies, which guides Zep’s selection.

You can configure up to 10 types.

Because the selected type is stored as the observation_type node property, you can retrieve observations of a given type with graph search property filters:

from zep_cloud.types import SearchFilters, PropertyFilter
results = client.graph.search_observations(
zep_graph_uuid,
query="commitments to the customer",
filters=SearchFilters(
property_filters=[
PropertyFilter(
operator="eq",
property_name="observation_type",
value="commitment",
)
]
),
)
for obs in results.items or []:
print(obs.name, obs.score)

Clearing steering

Sending an empty configuration — no instruction and an empty types list — clears steering at the addressed scope. Clearing the project scope removes the default. Clearing a graph scope removes the override, so that graph falls back to the project default.

# Remove the override for a user's graph (falls back to the project default).
client.graph.set_observation_steering(
zep_graph_uuid,
types=[],
)

Configurable parameters

ParameterTypeDescriptionDefaultRequired
graph_uuidstringThe UUID of the graph. Only the graph methods take this parameter. For a user graph, use the graph_uuid of the user.-Yes, for the graph methods
instructionstringGuidance for the wording and relevance of generated observations. Up to 2000 characters. An empty or omitted instruction clears it.-No
typesarrayUp to 10 custom observation types, each with a name and description.[]No

The project methods address the project scope and take no UUID.

Observation type fields

FieldTypeDescription
namestringCategory name. Must match ^[a-z][a-z0-9_]*$, up to 50 characters, unique within the list. generic is reserved.
descriptionstringWhen the type applies. Required, 1–500 characters.

Response

Both get_observation_steering and set_observation_steering return the resulting configuration at the addressed scope:

FieldTypeDescription
instructionstringThe configured instruction. The field is absent when no instruction is set.
typesarrayThe configured observation types, each with a name and description.
inheritedbooleantrue when the graph has no configuration of its own and the response contains the project default.

Reading a graph scope returns its effective configuration, falling back to the project default when that graph has no configuration of its own.

  • Observations — the durable, evidence-backed context that steering shapes.
  • Searching the Graph — filter observations by the observation_type property.
  • Shape the Graph — the other ways to tailor how Zep builds the Context Graph.