报错是这么冒出来的。Redis Stack 7.2 里用 redis-py 的 ft().search 做 KNN,查询串是 *=>[KNN 10 @vec $BLOB AS score],报 Syntax error at offset 78 near score,同样的串在 redis-cli 里也报,把 SORTBY 挪到前面无效,加上 DIALECT 2 才通。

中间走过弯路,把「PARAMS 的数量与占位符不匹配」当成主因,改完现象没变。

把日志和配置对完,能解释这个现象的基本就这几处。向量 KNN 语法只在 dialect 2 下解析。少数情况下是redis-py 低版本默认 dialect 1。

还有一种情况,SORTBY 的位置写在 RETURN 之后不合语法。

动手时先用 redis-cli 明确加 DIALECT 2 跑一遍

redis-cli FT.SEARCH idx '*=>[KNN 10 @vec $BLOB AS score]' PARAMS 2 BLOB "$BLOB" SORTBY score DIALECT 2

Python 调用时显式传 dialect

python -c "import redis;from redis.commands.search.query import Query;r=redis.Redis();q=Query('*=>[KNN 10 @vec $BLOB AS score]').sort_by('score').dialect(2);print(r.ft('idx').search(q,query_params={'BLOB':b'\x00'*3072}))"

接着核对 PARAMS 个数与占位符数量

python check_params.py --query knn.query --expect 2

剩下的就是把查询封装成统一带 dialect 的函数

python search_vec.py --index idx --topk 10 --dialect 2

排查用的命令都是临时敲的,没有写成脚本,事后才整理。

手上没有现成的复现脚本,就照着线上请求手工拼了一个。

怎么算真的好了,看的是同一批现象。返回 10 条结果且每条都带 score 字段,score 升序排列,与手工算出的余弦距离一致。

容易忽略的是,RediSearch 2.4 之前根本没有 KNN 指令,报语法错时先看模块版本,别只改查询串。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189