kevy4.0

AI 应用

数据,和找到数据的方式,
同一个存储

RAG 和 agent 记忆通常意味着三套系统:一个缓存、一个向量数据库、一个搜索索引——同样的事实存三份,然后慢慢彼此对不上。kevy 把向量 KNN、BM25 全文检索和变更流都放在引擎里,直接建在你已经写进去的那些 key 上。

为什么合适

RAG 这一套里,贵的不是检索,而是让三份事实保持同步:你写了一篇文档,然后你还得记住去做 embedding、去建索引、去让缓存失效。这里每一步都是一个可能忘掉的地方。

在 kevy 里,索引是一句声明,不是一条流水线。你告诉引擎是哪些 key、哪个字段,写入路径就会把索引维持在最新。事后没有东西要跑,也没有东西会落后。

kevy 不做的那件事,是生成 embedding。引擎里没有模型,以后也不会有——推理不该待在存储引擎里,硬塞进去只会把你的向量格式绑死在我们的发版节奏上。向量由你给出;kevy 负责存它、索引它、检索它。

怎么做——向量检索

在你的 key 的某个字段上建一个 HNSW 索引。声明一次,之后由写入路径维持最新。
# declare it once. the engine backfills, and answers
# INDEXBUILDING while it does.
IDX.CREATE idx:sem ON PREFIX doc: FIELD vec TYPE vector KIND ann  DIM 768 DISTANCE cosine M 16 EF 200

# write a document the way you already write documents
HSET doc:4410 title "Ada on pipelining" vec "<768 f32, little-endian>"

# nearest ten. no separate system, no sync step.
IDX.QUERY idx:sem KNN "<query vector>" LIMIT 10
-> 1) doc:4410
   2) doc:9982

怎么做——全文检索,以及两者合用

在同一批 key 上做 BM25,用一次混合查询把两种排序融合起来,还有一条可以持续跟读的变更流。
IDX.CREATE idx:ft ON PREFIX doc: FIELD title TYPE str KIND text

IDX.QUERY idx:ft MATCH "pipelining"
-> 1) 1) "doc:1"
      2) "0.2877"          # the BM25 score

# hybrid: fuse the text ranking and the vector ranking (RRF)
IDX.QUERY HYBRID idx:ft MATCH "pipelining" idx:sem KNN "<vector>"  LIMIT 20 RRFK 60

# a change feed: tail every write from another process.
# needs [feed] enabled = true in kevy.toml
FEED.SHARDS                 -> (integer) 16
FEED.TAIL 0                 -> 1) (integer) 1     # generation
                               2) (integer) 1     # offset
FEED.READ 0 1 0 COUNT 2     -> the writes themselves, replayable
代价是什么

建索引是对匹配到的 key 做 O(N) 的工作,在它追平之前,索引会回答 INDEXBUILDING——第一次建索引要提前安排,不要等它自己撞上来。向量索引是 HNSW,是近似的:召回率是一个可调参数(EF),不是一个保证。还有,这里没有 embedding 模型——如果你原本指望 kevy 帮你调一个,它不会,而这件事你应该在做规划之前就知道。向量检索指南全文检索指南都写得很具体。

如果读这些文档的是一个 agent

llms-full.txt 一次抓取就够:每条命令的真实代价、相对 Redis 的真实偏差,加上全部二十四篇指南的完整正文。它是从引擎自己的命令表生成的,所以不会和服务端的实际行为脱节。

接下来