Skip to content

Core concepts

Filters & metadata

Filters are repeated FILTER triples, ANDed together, evaluated before anything is scored. That ordering is what keeps a query off the whole namespace.

The shape of a filter

Each filter is three arguments: a field, an operator, and a value. Repeat the triple to add conditions; they are combined with AND.

const hits = await db.memory.query("user:123", {
  text: "delivery",
  vector: [0.10, 0.79, 0.46],
  topK: 5,
  filters: [
    { field: "type", op: "EQ", value: "shipping" },
    { field: "@importance", op: "GTE", value: 0.6 },
    { field: "region", op: "IN", value: "eu,uk" },
  ],
});

Operators

OperatorMeaningExample
EQ / NEEqual, not equalFILTER type EQ preference
GT / GTEGreater than, greater or equalFILTER @importance GTE 0.8
LT / LTELess than, less or equalFILTER @created_at LT 1757462400000
INMember of a comma-separated listFILTER region IN "eu,uk,us"
CONTAINSSubstring match on the valueFILTER source CONTAINS zendesk

Values that parse as numbers compare numerically, and everything else compares as bytes. No schema is declared anywhere, so FILTER @importance GTE 0.8 and FILTER type EQ preference both work on the same index.

Record fields

A field name beginning with @ reads the record itself rather than its metadata.

FieldTypeTypical use
@idbytesFetch or exclude a known record
@textbytesSubstring conditions with CONTAINS
@importancenumberOnly recall what was marked as mattering
@created_atunix millisecondsRestrict to a window of time
@updated_atunix millisecondsFind records revised since a checkpoint

Managing metadata

klyro
# Write metadata with the record
MEM.ADD user:123 TEXT "Escalated ticket 4821." FVEC 4 0.2 0.3 0.4 0.5 \
  META type ticket META source zendesk META region eu
$1
3

# Add or overwrite fields afterwards
MEM.SETMETA user:123 3 status resolved priority high
:2

# Remove fields
MEM.DELMETA user:123 3 priority
:1

Scanning with filters

MEM.SCAN takes the same filters, which turns them into a maintenance tool: page through everything matching a condition and act on it, without scoring anything.

klyro
# Every low-importance record from an old source
MEM.SCAN user:123 0 COUNT 200 \
  FILTER source EQ zendesk FILTER @importance LT 0.3
1) "512"
2) 1) "18"
   2) "27"
   3) "44"

MEM.DEL user:123 18 27 44
:3

Useful patterns

  • Kind of memory. META type preference, fact, event, summary. Query one kind at a time when the agent needs a specific sort of recall.
  • Provenance. META source with the system the memory came from, so a bad importer can be undone with one MEM.SCAN plus MEM.DEL.
  • Tenancy inside an index. When one index serves several logical scopes, a META scope field plus FILTER scope EQ keeps them apart without a key per scope.
  • Confidence gates. FILTER @importance GTE for prompts where only firm facts belong in context.