kevy
kevy 6.3.0 · AI applications

One store for the data
and the way you find it

RAG and agent memory usually mean three systems: a cache, a vector database, and a search index — with the same facts in all three, drifting apart. kevy has vector KNN, BM25 full-text and a change feed in the engine, over the keys you already wrote.

Why this fits

The expensive part of a RAG stack is not the search. It is keeping three copies of the truth in step: you write a document, then you have to remember to embed it, index it, and invalidate the cache. Every one of those is a place to forget.

In kevy the index is a declaration, not a pipeline. You tell the engine which keys and which field, and the write path keeps the index current. There is nothing to run afterwards and nothing to fall behind.

What kevy does not do is produce the embedding. There is no model in the engine and there will not be one — inference does not belong in a storage engine, and pretending otherwise would tie your vector format to our release cycle. You bring the vector; kevy stores it, indexes it and searches it.

Search your keys by meaning

KNN over a field of the keys you already write. Declared once; the write path keeps it current, with nothing to sync.

Declare the index once
IDX.CREATE idx:sem ON PREFIX doc: FIELD vec TYPE vector KIND ann  DIM 768 DISTANCE cosine M 16 EF 200
-> OK

The engine backfills existing keys, answering INDEXBUILDING while it does.

Write documents the way you already do
HSET doc:4410 title "Ada on pipelining" vec "<768 f32, little-endian>"
Nearest ten
IDX.QUERY idx:sem KNN "<query vector>" LIMIT 10
-> 1) doc:4410
   2) doc:9982

Cost & limits The index is HNSW, which is approximate: recall is a tuning parameter (EF), not a guarantee. The first build is O(N) over the matching keys — plan it, do not discover it. And there is no embedding model: you bring the vector. The vector guide has the tuning knobs.

Full text, and both rankings fused

BM25 over the same keys, and a hybrid query that fuses the text ranking with the vector ranking in one command.

A text index over the same keys
IDX.CREATE idx:ft ON PREFIX doc: FIELD title TYPE str KIND text
-> OK
Match, ranked by BM25
IDX.QUERY idx:ft MATCH "pipelining"
-> 1) 1) "doc:1"
      2) "0.2877"          # the BM25 score
Hybrid: fuse both rankings (RRF)
IDX.QUERY HYBRID idx:ft MATCH "pipelining" idx:sem KNN "<vector>"  LIMIT 20 RRFK 60

Cost & limits Indexes are paid for on every write to a matching key — the right trade for read-heavy retrieval, the wrong one for a key you rewrite thousands of times a second. Tokenisation (including CJK) and where BM25 stops are in the text guide.

Keep an agent's memory in step

Tail every write from another process — embed on change, not on a schedule, and resume from where you stopped.

Enable the feed
# kevy.toml
[feed]
enabled = true
Find your cursors
FEED.SHARDS                 -> (integer) 16
FEED.TAIL 0                 -> 1) (integer) 1     # generation
                               2) (integer) 1     # offset
Read, process, resume
FEED.READ 0 1 0 COUNT 2     -> the writes themselves, replayable

Cost & limits The feed is per shard: FEED.SHARDS tells you how many cursors you own, and your consumer tracks one offset per shard. It is off by default — flipping [feed] on is what buys the write-path bookkeeping. The change-feed guide covers resuming across restarts.

If the thing reading these docs is an agent

llms-full.txt is one fetch: every command with its real cost and its real deviation from Redis, plus the complete text of every guide. It is generated from the engine's own verb table, so it cannot drift from what the server does.

Next

Guide

Vector search

HNSW, the tuning knobs, and what approximate actually means here.

Read it →

Guide

Full-text search

BM25, tokenisation including CJK, and where it stops.

Read it →

Guide

The change feed

Tail every write from another process, with resumable offsets.

Read it →