relevance_score.
Parameters
Response
client.retrieve() returns the results list directly, and an empty list when nothing
matches.
Memory types
Every result carries amemory_type. The same content can exist at more than one level,
as raw evidence and as a distilled version of it, so filtering by type asks for exactly
the layer you want.
By default (
prefer_observations: true) a note is returned in place of the facts it
was built from, so you see one distilled result instead of the same content several
times. Set prefer_observations: false to receive the raw facts alongside their note.
Entities and time
Each result carries structured signal beyond the raw text.
The same entities are exposed as a browsable graph. See Graph.
Searching over time
Every memory carries two independent times, and knowing which is which is most of the work:
They differ whenever you import history: a memory about last June that you
upload today has an event time of last June and a record time of today.
as_of and query_timestamp are not variants of each other: one filters, the
other ranks, and both work on record time.
as_of to reproduce a past answer or audit a decision: “why did the agent
say that on June 1st”. Use query_timestamp when the query itself contains a
relative date, or when you want older-but-more-time-relevant memories to rank
higher without excluding anything.
Both take an ISO 8601 instant. A malformed one is rejected as 422 before the
search runs, so a typo costs you nothing.
Under
as_of, retrieval skips its graph-expansion pass and answers from
semantic, keyword and temporal retrieval only. Expansion follows entity links
without a time bound, so it could pull in a memory recorded after the cutoff:
a wrong answer for point-in-time recall rather than a ranking artifact. The
practical effect is that an as_of search is slightly narrower than the same
search without it.Prompt-ready context
Most callers take the results array and join it into a system prompt. Ask forformat: "block" and that is done for you, including the token budget, which
a hand-written loop usually skips.
resultsstays populated, so wanting both costs one round trip, not two.- The block is numbered plain text with no header, so you compose your own prompt around it.
context_max_tokensdrops whole memories, lowest-ranked first. Text is never cut mid-sentence: half a fact still reads as a fact.token_estimateis an estimate, derived from a characters-per-token approximation rather than a tokenizer. Treat it as a guide when budgeting a context window, not an exact count.
format behaves exactly as before.
Scoping within a space
A space is the coarse boundary.user_id, agent_id and session_id partition
it, so one space can serve many end users without their memories mixing, and you do
not need a space per user.
- A scoped search returns only memories written under the same scope. Bob’s memories can never appear in Alice’s results.
- Memories stored without a scope are not returned to a scoped search either. If you turn scoping on for a space that already has history, that history stays visible to unscoped searches but not to scoped ones, so backfill the scope on those memories if you need them.
- Passing several keys ANDs them:
user_id+session_idreturns only that user’s memories from that session. - Consolidated memories are built per user, so a synthesis never mixes two users’ facts. Sessions roll up into the user, which is what lets the memory improve across conversations.
anona: are reserved for this and rejected with
422 reserved_tag, since otherwise a hand-written tag could impersonate another
user’s scope. Use the scope fields instead.
Scoping costs nothing when unused. A request without these fields behaves
exactly as it did before they existed.
Latency modes
mode trades relevance quality against speed.
Error responses
See the full error reference.
Next steps
Reason API
Get a synthesized answer instead of a ranked list.
Graph API
Inspect the entities behind your results.
