Redis 向量检索完全指南:原理、HNSW 算法、实战与选型(2026 最新)
适用技术栈:Redis 8 / Redis Stack、Python(redis-py)、Java(Spring AI / Jedis) 适用读者:后端 / AI 应用开发者、RAG 系统设计者、面试备考者
作者:一位想进大厂的树先生:Mr.Tree。
目录
一、什么是向量检索
1.1 从"关键词检索"到"语义检索"
传统检索(如 MySQL LIKE、Elasticsearch 倒排)依赖关键词精确匹配:你搜"苹果手机",它匹配不到只写了"iPhone"的文档,因为字面不一样。
向量检索(Vector Search) 把内容映射成高维空间中的一个点(向量),语义相近的内容在空间中距离也近。"苹果手机"和"iPhone"虽然字面不同,但向量位置很接近,因此能被搜到。
#mermaid-svg-id4G1LHth8io1NNw{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-id4G1LHth8io1NNw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-id4G1LHth8io1NNw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-id4G1LHth8io1NNw .error-icon{fill:#552222;}#mermaid-svg-id4G1LHth8io1NNw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-id4G1LHth8io1NNw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-id4G1LHth8io1NNw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-id4G1LHth8io1NNw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-id4G1LHth8io1NNw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-id4G1LHth8io1NNw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-id4G1LHth8io1NNw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-id4G1LHth8io1NNw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-id4G1LHth8io1NNw .marker.cross{stroke:#333333;}#mermaid-svg-id4G1LHth8io1NNw svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-id4G1LHth8io1NNw p{margin:0;}#mermaid-svg-id4G1LHth8io1NNw .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-id4G1LHth8io1NNw .cluster-label text{fill:#333;}#mermaid-svg-id4G1LHth8io1NNw .cluster-label span{color:#333;}#mermaid-svg-id4G1LHth8io1NNw .cluster-label span p{background-color:transparent;}#mermaid-svg-id4G1LHth8io1NNw .label text,#mermaid-svg-id4G1LHth8io1NNw span{fill:#333;color:#333;}#mermaid-svg-id4G1LHth8io1NNw .node rect,#mermaid-svg-id4G1LHth8io1NNw .node circle,#mermaid-svg-id4G1LHth8io1NNw .node ellipse,#mermaid-svg-id4G1LHth8io1NNw .node polygon,#mermaid-svg-id4G1LHth8io1NNw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-id4G1LHth8io1NNw .rough-node .label text,#mermaid-svg-id4G1LHth8io1NNw .node .label text,#mermaid-svg-id4G1LHth8io1NNw .image-shape .label,#mermaid-svg-id4G1LHth8io1NNw .icon-shape .label{text-anchor:middle;}#mermaid-svg-id4G1LHth8io1NNw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-id4G1LHth8io1NNw .rough-node .label,#mermaid-svg-id4G1LHth8io1NNw .node .label,#mermaid-svg-id4G1LHth8io1NNw .image-shape .label,#mermaid-svg-id4G1LHth8io1NNw .icon-shape .label{text-align:center;}#mermaid-svg-id4G1LHth8io1NNw .node.clickable{cursor:pointer;}#mermaid-svg-id4G1LHth8io1NNw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-id4G1LHth8io1NNw .arrowheadPath{fill:#333333;}#mermaid-svg-id4G1LHth8io1NNw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-id4G1LHth8io1NNw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-id4G1LHth8io1NNw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-id4G1LHth8io1NNw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-id4G1LHth8io1NNw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-id4G1LHth8io1NNw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-id4G1LHth8io1NNw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-id4G1LHth8io1NNw .cluster text{fill:#333;}#mermaid-svg-id4G1LHth8io1NNw .cluster span{color:#333;}#mermaid-svg-id4G1LHth8io1NNw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-id4G1LHth8io1NNw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-id4G1LHth8io1NNw rect.text{fill:none;stroke-width:0;}#mermaid-svg-id4G1LHth8io1NNw .icon-shape,#mermaid-svg-id4G1LHth8io1NNw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-id4G1LHth8io1NNw .icon-shape p,#mermaid-svg-id4G1LHth8io1NNw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-id4G1LHth8io1NNw .icon-shape .label rect,#mermaid-svg-id4G1LHth8io1NNw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-id4G1LHth8io1NNw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-id4G1LHth8io1NNw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-id4G1LHth8io1NNw :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
向量检索
查询:苹果手机
语义距离
能匹配:iPhone(语义相近)
关键词检索
查询:苹果手机
字面匹配
匹配不到:iPhone
1.2 什么是向量嵌入(Embedding)
Embedding 是把文本、图片、商品等对象,通过模型转换成一串浮点数(向量)。例如 OpenAI 的 text-embedding 模型输出 1536 维向量,bge 等开源模型常见 768 / 1024 维。
#mermaid-svg-jkDBGRXAmOU6oOB0{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jkDBGRXAmOU6oOB0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jkDBGRXAmOU6oOB0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jkDBGRXAmOU6oOB0 .error-icon{fill:#552222;}#mermaid-svg-jkDBGRXAmOU6oOB0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jkDBGRXAmOU6oOB0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jkDBGRXAmOU6oOB0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jkDBGRXAmOU6oOB0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jkDBGRXAmOU6oOB0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jkDBGRXAmOU6oOB0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jkDBGRXAmOU6oOB0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jkDBGRXAmOU6oOB0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jkDBGRXAmOU6oOB0 .marker.cross{stroke:#333333;}#mermaid-svg-jkDBGRXAmOU6oOB0 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jkDBGRXAmOU6oOB0 p{margin:0;}#mermaid-svg-jkDBGRXAmOU6oOB0 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-jkDBGRXAmOU6oOB0 .cluster-label text{fill:#333;}#mermaid-svg-jkDBGRXAmOU6oOB0 .cluster-label span{color:#333;}#mermaid-svg-jkDBGRXAmOU6oOB0 .cluster-label span p{background-color:transparent;}#mermaid-svg-jkDBGRXAmOU6oOB0 .label text,#mermaid-svg-jkDBGRXAmOU6oOB0 span{fill:#333;color:#333;}#mermaid-svg-jkDBGRXAmOU6oOB0 .node rect,#mermaid-svg-jkDBGRXAmOU6oOB0 .node circle,#mermaid-svg-jkDBGRXAmOU6oOB0 .node ellipse,#mermaid-svg-jkDBGRXAmOU6oOB0 .node polygon,#mermaid-svg-jkDBGRXAmOU6oOB0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jkDBGRXAmOU6oOB0 .rough-node .label text,#mermaid-svg-jkDBGRXAmOU6oOB0 .node .label text,#mermaid-svg-jkDBGRXAmOU6oOB0 .image-shape .label,#mermaid-svg-jkDBGRXAmOU6oOB0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-jkDBGRXAmOU6oOB0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-jkDBGRXAmOU6oOB0 .rough-node .label,#mermaid-svg-jkDBGRXAmOU6oOB0 .node .label,#mermaid-svg-jkDBGRXAmOU6oOB0 .image-shape .label,#mermaid-svg-jkDBGRXAmOU6oOB0 .icon-shape .label{text-align:center;}#mermaid-svg-jkDBGRXAmOU6oOB0 .node.clickable{cursor:pointer;}#mermaid-svg-jkDBGRXAmOU6oOB0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-jkDBGRXAmOU6oOB0 .arrowheadPath{fill:#333333;}#mermaid-svg-jkDBGRXAmOU6oOB0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jkDBGRXAmOU6oOB0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jkDBGRXAmOU6oOB0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jkDBGRXAmOU6oOB0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-jkDBGRXAmOU6oOB0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jkDBGRXAmOU6oOB0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-jkDBGRXAmOU6oOB0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jkDBGRXAmOU6oOB0 .cluster text{fill:#333;}#mermaid-svg-jkDBGRXAmOU6oOB0 .cluster span{color:#333;}#mermaid-svg-jkDBGRXAmOU6oOB0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-jkDBGRXAmOU6oOB0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-jkDBGRXAmOU6oOB0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-jkDBGRXAmOU6oOB0 .icon-shape,#mermaid-svg-jkDBGRXAmOU6oOB0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jkDBGRXAmOU6oOB0 .icon-shape p,#mermaid-svg-jkDBGRXAmOU6oOB0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-jkDBGRXAmOU6oOB0 .icon-shape .label rect,#mermaid-svg-jkDBGRXAmOU6oOB0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jkDBGRXAmOU6oOB0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-jkDBGRXAmOU6oOB0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-jkDBGRXAmOU6oOB0 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
文本/图片/商品
Embedding 模型
高维向量,如 1536 个浮点数
存入 Redis 并建立索引
1.3 典型应用场景
| RAG(检索增强生成) | 先从知识库检索相关文档,再交给大模型生成答案 |
| 语义搜索 | 按"意思"而非字面搜索商品、文档、问答 |
| 推荐系统 | “喜欢 X 的人也喜欢……”,找相似向量 |
| 文本分类 | 用最近邻的类别投票归类 |
| 去重 / 异常检测 | 找近重复内容;找离正常模式很远的异常点 |
二、Redis 向量检索的发展与整体架构
2.1 演进时间线
- RediSearch 2.4(2021):首次引入向量相似度搜索。
- Redis Stack:把 RediSearch、RedisJSON 等模块打包。
- Redis 8(2025):查询引擎(Query Engine)成为 Redis 标准组件,开源可用,无需单独装模块;同时新增原生数据类型 Vector Sets。
2.2 Redis 提供两套向量能力
| Query Engine | 原 RediSearch | HASH / JSON | 功能最全:多字段、全文、标签、地理、混合查询 |
| Vector Sets(VSET) | 原生数据类型 | 自带 | 类似有序集合,内置量化(Q8/BIN),轻量省内存 |
#mermaid-svg-dLJDcEbJMY2Or5Dl{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dLJDcEbJMY2Or5Dl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dLJDcEbJMY2Or5Dl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dLJDcEbJMY2Or5Dl .error-icon{fill:#552222;}#mermaid-svg-dLJDcEbJMY2Or5Dl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dLJDcEbJMY2Or5Dl .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dLJDcEbJMY2Or5Dl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dLJDcEbJMY2Or5Dl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dLJDcEbJMY2Or5Dl .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dLJDcEbJMY2Or5Dl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dLJDcEbJMY2Or5Dl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dLJDcEbJMY2Or5Dl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dLJDcEbJMY2Or5Dl .marker.cross{stroke:#333333;}#mermaid-svg-dLJDcEbJMY2Or5Dl svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dLJDcEbJMY2Or5Dl p{margin:0;}#mermaid-svg-dLJDcEbJMY2Or5Dl .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-dLJDcEbJMY2Or5Dl .cluster-label text{fill:#333;}#mermaid-svg-dLJDcEbJMY2Or5Dl .cluster-label span{color:#333;}#mermaid-svg-dLJDcEbJMY2Or5Dl .cluster-label span p{background-color:transparent;}#mermaid-svg-dLJDcEbJMY2Or5Dl .label text,#mermaid-svg-dLJDcEbJMY2Or5Dl span{fill:#333;color:#333;}#mermaid-svg-dLJDcEbJMY2Or5Dl .node rect,#mermaid-svg-dLJDcEbJMY2Or5Dl .node circle,#mermaid-svg-dLJDcEbJMY2Or5Dl .node ellipse,#mermaid-svg-dLJDcEbJMY2Or5Dl .node polygon,#mermaid-svg-dLJDcEbJMY2Or5Dl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dLJDcEbJMY2Or5Dl .rough-node .label text,#mermaid-svg-dLJDcEbJMY2Or5Dl .node .label text,#mermaid-svg-dLJDcEbJMY2Or5Dl .image-shape .label,#mermaid-svg-dLJDcEbJMY2Or5Dl .icon-shape .label{text-anchor:middle;}#mermaid-svg-dLJDcEbJMY2Or5Dl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dLJDcEbJMY2Or5Dl .rough-node .label,#mermaid-svg-dLJDcEbJMY2Or5Dl .node .label,#mermaid-svg-dLJDcEbJMY2Or5Dl .image-shape .label,#mermaid-svg-dLJDcEbJMY2Or5Dl .icon-shape .label{text-align:center;}#mermaid-svg-dLJDcEbJMY2Or5Dl .node.clickable{cursor:pointer;}#mermaid-svg-dLJDcEbJMY2Or5Dl .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dLJDcEbJMY2Or5Dl .arrowheadPath{fill:#333333;}#mermaid-svg-dLJDcEbJMY2Or5Dl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dLJDcEbJMY2Or5Dl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dLJDcEbJMY2Or5Dl .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dLJDcEbJMY2Or5Dl .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dLJDcEbJMY2Or5Dl .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dLJDcEbJMY2Or5Dl .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dLJDcEbJMY2Or5Dl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dLJDcEbJMY2Or5Dl .cluster text{fill:#333;}#mermaid-svg-dLJDcEbJMY2Or5Dl .cluster span{color:#333;}#mermaid-svg-dLJDcEbJMY2Or5Dl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dLJDcEbJMY2Or5Dl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dLJDcEbJMY2Or5Dl rect.text{fill:none;stroke-width:0;}#mermaid-svg-dLJDcEbJMY2Or5Dl .icon-shape,#mermaid-svg-dLJDcEbJMY2Or5Dl .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dLJDcEbJMY2Or5Dl .icon-shape p,#mermaid-svg-dLJDcEbJMY2Or5Dl .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dLJDcEbJMY2Or5Dl .icon-shape .label rect,#mermaid-svg-dLJDcEbJMY2Or5Dl .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dLJDcEbJMY2Or5Dl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dLJDcEbJMY2Or5Dl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dLJDcEbJMY2Or5Dl :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
应用
Query Engine(原 RediSearch)
Vector Sets 原生数据类型
HASH 存储:向量为原始字节
JSON 存储:向量为浮点数组
VSET:内置 HNSW 与量化
怎么选:需要把向量和文本、标签、数值等多字段做复杂混合查询 → Query Engine;只做"给向量找相似"、追求极致省内存和简单 → Vector Sets。
三、核心原理:Embedding 与相似度
3.1 向量数据类型
| FLOAT32 | 最常用,单精度,精度与内存平衡 |
| FLOAT64 | 双精度,更准但更占内存 |
| FLOAT16 / BFLOAT16 | 半精度,省内存(需查询引擎 v2.10+) |
3.2 三种距离度量
设两个向量 u、v:
| L2 | 欧几里得距离(直线距离) | 根号下各维度差的平方和 | 通用、空间距离直观 |
| IP | 内积 | 1 减去 u·v | 向量已归一化时 |
| COSINE | 余弦距离(看方向夹角) | 1 减去余弦相似度 | 文本语义最常用,不受长度影响 |
#mermaid-svg-XYkiUB83mihoSn0a{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-XYkiUB83mihoSn0a .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XYkiUB83mihoSn0a .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XYkiUB83mihoSn0a .error-icon{fill:#552222;}#mermaid-svg-XYkiUB83mihoSn0a .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XYkiUB83mihoSn0a .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XYkiUB83mihoSn0a .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XYkiUB83mihoSn0a .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XYkiUB83mihoSn0a .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XYkiUB83mihoSn0a .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XYkiUB83mihoSn0a .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XYkiUB83mihoSn0a .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XYkiUB83mihoSn0a .marker.cross{stroke:#333333;}#mermaid-svg-XYkiUB83mihoSn0a svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XYkiUB83mihoSn0a p{margin:0;}#mermaid-svg-XYkiUB83mihoSn0a .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-XYkiUB83mihoSn0a .cluster-label text{fill:#333;}#mermaid-svg-XYkiUB83mihoSn0a .cluster-label span{color:#333;}#mermaid-svg-XYkiUB83mihoSn0a .cluster-label span p{background-color:transparent;}#mermaid-svg-XYkiUB83mihoSn0a .label text,#mermaid-svg-XYkiUB83mihoSn0a span{fill:#333;color:#333;}#mermaid-svg-XYkiUB83mihoSn0a .node rect,#mermaid-svg-XYkiUB83mihoSn0a .node circle,#mermaid-svg-XYkiUB83mihoSn0a .node ellipse,#mermaid-svg-XYkiUB83mihoSn0a .node polygon,#mermaid-svg-XYkiUB83mihoSn0a .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XYkiUB83mihoSn0a .rough-node .label text,#mermaid-svg-XYkiUB83mihoSn0a .node .label text,#mermaid-svg-XYkiUB83mihoSn0a .image-shape .label,#mermaid-svg-XYkiUB83mihoSn0a .icon-shape .label{text-anchor:middle;}#mermaid-svg-XYkiUB83mihoSn0a .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-XYkiUB83mihoSn0a .rough-node .label,#mermaid-svg-XYkiUB83mihoSn0a .node .label,#mermaid-svg-XYkiUB83mihoSn0a .image-shape .label,#mermaid-svg-XYkiUB83mihoSn0a .icon-shape .label{text-align:center;}#mermaid-svg-XYkiUB83mihoSn0a .node.clickable{cursor:pointer;}#mermaid-svg-XYkiUB83mihoSn0a .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-XYkiUB83mihoSn0a .arrowheadPath{fill:#333333;}#mermaid-svg-XYkiUB83mihoSn0a .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-XYkiUB83mihoSn0a .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-XYkiUB83mihoSn0a .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XYkiUB83mihoSn0a .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-XYkiUB83mihoSn0a .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XYkiUB83mihoSn0a .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-XYkiUB83mihoSn0a .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-XYkiUB83mihoSn0a .cluster text{fill:#333;}#mermaid-svg-XYkiUB83mihoSn0a .cluster span{color:#333;}#mermaid-svg-XYkiUB83mihoSn0a div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-XYkiUB83mihoSn0a .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-XYkiUB83mihoSn0a rect.text{fill:none;stroke-width:0;}#mermaid-svg-XYkiUB83mihoSn0a .icon-shape,#mermaid-svg-XYkiUB83mihoSn0a .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XYkiUB83mihoSn0a .icon-shape p,#mermaid-svg-XYkiUB83mihoSn0a .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-XYkiUB83mihoSn0a .icon-shape .label rect,#mermaid-svg-XYkiUB83mihoSn0a .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XYkiUB83mihoSn0a .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-XYkiUB83mihoSn0a .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-XYkiUB83mihoSn0a :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
两个向量
选择度量
L2:看直线距离
IP:看内积
COSINE:看方向夹角,文本首选
关键理解:
- 距离值越小越相似。
- 余弦距离上限为 2,L2 无上限。
- 文本 Embedding 通常已经归一化,此时 COSINE 与 IP 等价,绝大多数 RAG 场景选 COSINE。
四、索引算法原理:FLAT 与 HNSW
4.1 精确 vs 近似:KNN 与 ANN
- KNN(精确最近邻):拿查询向量和所有向量逐一比较,保证找到真值,但数据量大时极慢。
- ANN(近似最近邻):用特殊索引结构快速逼近,牺牲极小准确率(召回率通常 95% 到 99%),换数量级的提速。
4.2 FLAT 索引(暴力精确)
查询时把查询向量与每一个已存向量比较、排序,返回前 K 个。结果 100% 准确,但耗时随数据量线性增长。
#mermaid-svg-QR1oZUTrJsKFnvAm{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QR1oZUTrJsKFnvAm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QR1oZUTrJsKFnvAm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QR1oZUTrJsKFnvAm .error-icon{fill:#552222;}#mermaid-svg-QR1oZUTrJsKFnvAm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QR1oZUTrJsKFnvAm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QR1oZUTrJsKFnvAm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QR1oZUTrJsKFnvAm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QR1oZUTrJsKFnvAm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QR1oZUTrJsKFnvAm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QR1oZUTrJsKFnvAm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QR1oZUTrJsKFnvAm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QR1oZUTrJsKFnvAm .marker.cross{stroke:#333333;}#mermaid-svg-QR1oZUTrJsKFnvAm svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QR1oZUTrJsKFnvAm p{margin:0;}#mermaid-svg-QR1oZUTrJsKFnvAm .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-QR1oZUTrJsKFnvAm .cluster-label text{fill:#333;}#mermaid-svg-QR1oZUTrJsKFnvAm .cluster-label span{color:#333;}#mermaid-svg-QR1oZUTrJsKFnvAm .cluster-label span p{background-color:transparent;}#mermaid-svg-QR1oZUTrJsKFnvAm .label text,#mermaid-svg-QR1oZUTrJsKFnvAm span{fill:#333;color:#333;}#mermaid-svg-QR1oZUTrJsKFnvAm .node rect,#mermaid-svg-QR1oZUTrJsKFnvAm .node circle,#mermaid-svg-QR1oZUTrJsKFnvAm .node ellipse,#mermaid-svg-QR1oZUTrJsKFnvAm .node polygon,#mermaid-svg-QR1oZUTrJsKFnvAm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QR1oZUTrJsKFnvAm .rough-node .label text,#mermaid-svg-QR1oZUTrJsKFnvAm .node .label text,#mermaid-svg-QR1oZUTrJsKFnvAm .image-shape .label,#mermaid-svg-QR1oZUTrJsKFnvAm .icon-shape .label{text-anchor:middle;}#mermaid-svg-QR1oZUTrJsKFnvAm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QR1oZUTrJsKFnvAm .rough-node .label,#mermaid-svg-QR1oZUTrJsKFnvAm .node .label,#mermaid-svg-QR1oZUTrJsKFnvAm .image-shape .label,#mermaid-svg-QR1oZUTrJsKFnvAm .icon-shape .label{text-align:center;}#mermaid-svg-QR1oZUTrJsKFnvAm .node.clickable{cursor:pointer;}#mermaid-svg-QR1oZUTrJsKFnvAm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QR1oZUTrJsKFnvAm .arrowheadPath{fill:#333333;}#mermaid-svg-QR1oZUTrJsKFnvAm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QR1oZUTrJsKFnvAm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QR1oZUTrJsKFnvAm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QR1oZUTrJsKFnvAm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QR1oZUTrJsKFnvAm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QR1oZUTrJsKFnvAm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QR1oZUTrJsKFnvAm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QR1oZUTrJsKFnvAm .cluster text{fill:#333;}#mermaid-svg-QR1oZUTrJsKFnvAm .cluster span{color:#333;}#mermaid-svg-QR1oZUTrJsKFnvAm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QR1oZUTrJsKFnvAm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QR1oZUTrJsKFnvAm rect.text{fill:none;stroke-width:0;}#mermaid-svg-QR1oZUTrJsKFnvAm .icon-shape,#mermaid-svg-QR1oZUTrJsKFnvAm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QR1oZUTrJsKFnvAm .icon-shape p,#mermaid-svg-QR1oZUTrJsKFnvAm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QR1oZUTrJsKFnvAm .icon-shape .label rect,#mermaid-svg-QR1oZUTrJsKFnvAm .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QR1oZUTrJsKFnvAm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QR1oZUTrJsKFnvAm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QR1oZUTrJsKFnvAm :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
查询向量
与向量1比较
与向量2比较
与向量N比较……
全部排序
返回最近K个(精确)
- 适用:小数据集(约 10 万以下)、开发调试、对准确率要求极高。
- 1 万向量约 10ms,100 万可能到 1000ms。
4.3 HNSW 索引(近似,工业界首选)
HNSW(Hierarchical Navigable Small World,分层可导航小世界) 由 Malkov 和 Yashunin 在 2016 年论文提出,是当前综合性能最优、应用最广的向量索引算法。
4.3.1 核心思想:高速公路 + 城市道路
构建一个多层图:
- 第 0 层(最底层):包含全部节点,连接最密集(“城市道路”)。
- 越往上:节点越少(随机采样的子集),连接越稀疏、跨度越大(“高速公路”),用于快速定位大致区域。
#mermaid-svg-lwzIWnrNckwWDz83{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-lwzIWnrNckwWDz83 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-lwzIWnrNckwWDz83 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-lwzIWnrNckwWDz83 .error-icon{fill:#552222;}#mermaid-svg-lwzIWnrNckwWDz83 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-lwzIWnrNckwWDz83 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-lwzIWnrNckwWDz83 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-lwzIWnrNckwWDz83 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-lwzIWnrNckwWDz83 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-lwzIWnrNckwWDz83 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-lwzIWnrNckwWDz83 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-lwzIWnrNckwWDz83 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-lwzIWnrNckwWDz83 .marker.cross{stroke:#333333;}#mermaid-svg-lwzIWnrNckwWDz83 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-lwzIWnrNckwWDz83 p{margin:0;}#mermaid-svg-lwzIWnrNckwWDz83 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-lwzIWnrNckwWDz83 .cluster-label text{fill:#333;}#mermaid-svg-lwzIWnrNckwWDz83 .cluster-label span{color:#333;}#mermaid-svg-lwzIWnrNckwWDz83 .cluster-label span p{background-color:transparent;}#mermaid-svg-lwzIWnrNckwWDz83 .label text,#mermaid-svg-lwzIWnrNckwWDz83 span{fill:#333;color:#333;}#mermaid-svg-lwzIWnrNckwWDz83 .node rect,#mermaid-svg-lwzIWnrNckwWDz83 .node circle,#mermaid-svg-lwzIWnrNckwWDz83 .node ellipse,#mermaid-svg-lwzIWnrNckwWDz83 .node polygon,#mermaid-svg-lwzIWnrNckwWDz83 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lwzIWnrNckwWDz83 .rough-node .label text,#mermaid-svg-lwzIWnrNckwWDz83 .node .label text,#mermaid-svg-lwzIWnrNckwWDz83 .image-shape .label,#mermaid-svg-lwzIWnrNckwWDz83 .icon-shape .label{text-anchor:middle;}#mermaid-svg-lwzIWnrNckwWDz83 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-lwzIWnrNckwWDz83 .rough-node .label,#mermaid-svg-lwzIWnrNckwWDz83 .node .label,#mermaid-svg-lwzIWnrNckwWDz83 .image-shape .label,#mermaid-svg-lwzIWnrNckwWDz83 .icon-shape .label{text-align:center;}#mermaid-svg-lwzIWnrNckwWDz83 .node.clickable{cursor:pointer;}#mermaid-svg-lwzIWnrNckwWDz83 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-lwzIWnrNckwWDz83 .arrowheadPath{fill:#333333;}#mermaid-svg-lwzIWnrNckwWDz83 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-lwzIWnrNckwWDz83 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-lwzIWnrNckwWDz83 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lwzIWnrNckwWDz83 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-lwzIWnrNckwWDz83 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lwzIWnrNckwWDz83 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-lwzIWnrNckwWDz83 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-lwzIWnrNckwWDz83 .cluster text{fill:#333;}#mermaid-svg-lwzIWnrNckwWDz83 .cluster span{color:#333;}#mermaid-svg-lwzIWnrNckwWDz83 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-lwzIWnrNckwWDz83 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-lwzIWnrNckwWDz83 rect.text{fill:none;stroke-width:0;}#mermaid-svg-lwzIWnrNckwWDz83 .icon-shape,#mermaid-svg-lwzIWnrNckwWDz83 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lwzIWnrNckwWDz83 .icon-shape p,#mermaid-svg-lwzIWnrNckwWDz83 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-lwzIWnrNckwWDz83 .icon-shape .label rect,#mermaid-svg-lwzIWnrNckwWDz83 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lwzIWnrNckwWDz83 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-lwzIWnrNckwWDz83 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-lwzIWnrNckwWDz83 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
第0层:全量节点
节点
节点
节点
节点
节点
节点
第1层:子集节点
节点
节点
节点
第2层:最稀疏,高速入口
入口节点
4.3.2 查询原理:从顶层贪心、逐层下降
#mermaid-svg-1QALPOZ91pcYbNR6{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1QALPOZ91pcYbNR6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1QALPOZ91pcYbNR6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1QALPOZ91pcYbNR6 .error-icon{fill:#552222;}#mermaid-svg-1QALPOZ91pcYbNR6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1QALPOZ91pcYbNR6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1QALPOZ91pcYbNR6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1QALPOZ91pcYbNR6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1QALPOZ91pcYbNR6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1QALPOZ91pcYbNR6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1QALPOZ91pcYbNR6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1QALPOZ91pcYbNR6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1QALPOZ91pcYbNR6 .marker.cross{stroke:#333333;}#mermaid-svg-1QALPOZ91pcYbNR6 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1QALPOZ91pcYbNR6 p{margin:0;}#mermaid-svg-1QALPOZ91pcYbNR6 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-1QALPOZ91pcYbNR6 .cluster-label text{fill:#333;}#mermaid-svg-1QALPOZ91pcYbNR6 .cluster-label span{color:#333;}#mermaid-svg-1QALPOZ91pcYbNR6 .cluster-label span p{background-color:transparent;}#mermaid-svg-1QALPOZ91pcYbNR6 .label text,#mermaid-svg-1QALPOZ91pcYbNR6 span{fill:#333;color:#333;}#mermaid-svg-1QALPOZ91pcYbNR6 .node rect,#mermaid-svg-1QALPOZ91pcYbNR6 .node circle,#mermaid-svg-1QALPOZ91pcYbNR6 .node ellipse,#mermaid-svg-1QALPOZ91pcYbNR6 .node polygon,#mermaid-svg-1QALPOZ91pcYbNR6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1QALPOZ91pcYbNR6 .rough-node .label text,#mermaid-svg-1QALPOZ91pcYbNR6 .node .label text,#mermaid-svg-1QALPOZ91pcYbNR6 .image-shape .label,#mermaid-svg-1QALPOZ91pcYbNR6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-1QALPOZ91pcYbNR6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1QALPOZ91pcYbNR6 .rough-node .label,#mermaid-svg-1QALPOZ91pcYbNR6 .node .label,#mermaid-svg-1QALPOZ91pcYbNR6 .image-shape .label,#mermaid-svg-1QALPOZ91pcYbNR6 .icon-shape .label{text-align:center;}#mermaid-svg-1QALPOZ91pcYbNR6 .node.clickable{cursor:pointer;}#mermaid-svg-1QALPOZ91pcYbNR6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1QALPOZ91pcYbNR6 .arrowheadPath{fill:#333333;}#mermaid-svg-1QALPOZ91pcYbNR6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1QALPOZ91pcYbNR6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1QALPOZ91pcYbNR6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1QALPOZ91pcYbNR6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1QALPOZ91pcYbNR6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1QALPOZ91pcYbNR6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1QALPOZ91pcYbNR6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1QALPOZ91pcYbNR6 .cluster text{fill:#333;}#mermaid-svg-1QALPOZ91pcYbNR6 .cluster span{color:#333;}#mermaid-svg-1QALPOZ91pcYbNR6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1QALPOZ91pcYbNR6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1QALPOZ91pcYbNR6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-1QALPOZ91pcYbNR6 .icon-shape,#mermaid-svg-1QALPOZ91pcYbNR6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1QALPOZ91pcYbNR6 .icon-shape p,#mermaid-svg-1QALPOZ91pcYbNR6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1QALPOZ91pcYbNR6 .icon-shape .label rect,#mermaid-svg-1QALPOZ91pcYbNR6 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1QALPOZ91pcYbNR6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1QALPOZ91pcYbNR6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1QALPOZ91pcYbNR6 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
否
从最顶层入口节点开始
在本层贪心走向离查询向量最近的邻居
找到本层局部最近点
还有更底层吗?
下降到下一层,以该点为新起点
返回第0层找到的最近K个节点
就像导航:先走高速公路快速接近目标城市,再逐层下到城市道路、街道,最后精确找到目的地。这样把搜索复杂度降到约 O(log N)。
4.3.3 关键参数
| M | 每个节点每层最大连接数(第0层为 2M) | 16 | 召回更高、但内存和构建时间增加 |
| EF_CONSTRUCTION | 建图时考虑的邻居数 | 200 | 图质量更高、建图更慢 |
| EF_RUNTIME | 查询时保留的候选数 | 10 | 召回更高、查询更慢 |
调优口诀:召回不够先调大 EF_RUNTIME(无需重建索引);还不够再调大 M 并重建。
4.3.4 召回率
HNSW 通常能达到 95% 到 99% 召回,即在 100 个真实最近邻中能找到 95 到 99 个,而速度比 FLAT 快几个数量级。
五、实战一:Query Engine(FT 命令)
5.1 创建索引
FT.CREATE documents
ON HASH
PREFIX 1 docs:
SCHEMA
title TEXT
category TAG
year NUMERIC
embedding VECTOR HNSW 10
TYPE FLOAT32
DIM 1536
DISTANCE_METRIC COSINE
M 16
EF_CONSTRUCTION 200
5.2 写入向量(HASH)
HSET docs:01 embedding <vector_bytes> category sports year 2021
5.3 KNN 查询
FT.SEARCH documents
"*=>[KNN 10 @embedding $BLOB AS vector_distance]"
PARAMS 2 BLOB "\\x12\\xa9\\xf5…"
SORTBY vector_distance
LIMIT 0 10
DIALECT 2
5.4 混合查询(向量 + 元数据过滤)
FT.SEARCH documents
"(@title:Dune @year:[2020 2022])=>[KNN 10 @embedding $BLOB AS vector_distance]"
PARAMS 2 BLOB "\\x12\\xa9\\xf5…"
SORTBY vector_distance
LIMIT 0 10
DIALECT 2
过滤的两种内部模式:
#mermaid-svg-jcK3TXqXwLmoeIxp{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jcK3TXqXwLmoeIxp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jcK3TXqXwLmoeIxp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jcK3TXqXwLmoeIxp .error-icon{fill:#552222;}#mermaid-svg-jcK3TXqXwLmoeIxp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jcK3TXqXwLmoeIxp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jcK3TXqXwLmoeIxp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jcK3TXqXwLmoeIxp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jcK3TXqXwLmoeIxp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jcK3TXqXwLmoeIxp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jcK3TXqXwLmoeIxp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jcK3TXqXwLmoeIxp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jcK3TXqXwLmoeIxp .marker.cross{stroke:#333333;}#mermaid-svg-jcK3TXqXwLmoeIxp svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jcK3TXqXwLmoeIxp p{margin:0;}#mermaid-svg-jcK3TXqXwLmoeIxp .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-jcK3TXqXwLmoeIxp .cluster-label text{fill:#333;}#mermaid-svg-jcK3TXqXwLmoeIxp .cluster-label span{color:#333;}#mermaid-svg-jcK3TXqXwLmoeIxp .cluster-label span p{background-color:transparent;}#mermaid-svg-jcK3TXqXwLmoeIxp .label text,#mermaid-svg-jcK3TXqXwLmoeIxp span{fill:#333;color:#333;}#mermaid-svg-jcK3TXqXwLmoeIxp .node rect,#mermaid-svg-jcK3TXqXwLmoeIxp .node circle,#mermaid-svg-jcK3TXqXwLmoeIxp .node ellipse,#mermaid-svg-jcK3TXqXwLmoeIxp .node polygon,#mermaid-svg-jcK3TXqXwLmoeIxp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jcK3TXqXwLmoeIxp .rough-node .label text,#mermaid-svg-jcK3TXqXwLmoeIxp .node .label text,#mermaid-svg-jcK3TXqXwLmoeIxp .image-shape .label,#mermaid-svg-jcK3TXqXwLmoeIxp .icon-shape .label{text-anchor:middle;}#mermaid-svg-jcK3TXqXwLmoeIxp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-jcK3TXqXwLmoeIxp .rough-node .label,#mermaid-svg-jcK3TXqXwLmoeIxp .node .label,#mermaid-svg-jcK3TXqXwLmoeIxp .image-shape .label,#mermaid-svg-jcK3TXqXwLmoeIxp .icon-shape .label{text-align:center;}#mermaid-svg-jcK3TXqXwLmoeIxp .node.clickable{cursor:pointer;}#mermaid-svg-jcK3TXqXwLmoeIxp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-jcK3TXqXwLmoeIxp .arrowheadPath{fill:#333333;}#mermaid-svg-jcK3TXqXwLmoeIxp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jcK3TXqXwLmoeIxp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jcK3TXqXwLmoeIxp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jcK3TXqXwLmoeIxp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-jcK3TXqXwLmoeIxp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jcK3TXqXwLmoeIxp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-jcK3TXqXwLmoeIxp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jcK3TXqXwLmoeIxp .cluster text{fill:#333;}#mermaid-svg-jcK3TXqXwLmoeIxp .cluster span{color:#333;}#mermaid-svg-jcK3TXqXwLmoeIxp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-jcK3TXqXwLmoeIxp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-jcK3TXqXwLmoeIxp rect.text{fill:none;stroke-width:0;}#mermaid-svg-jcK3TXqXwLmoeIxp .icon-shape,#mermaid-svg-jcK3TXqXwLmoeIxp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jcK3TXqXwLmoeIxp .icon-shape p,#mermaid-svg-jcK3TXqXwLmoeIxp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-jcK3TXqXwLmoeIxp .icon-shape .label rect,#mermaid-svg-jcK3TXqXwLmoeIxp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jcK3TXqXwLmoeIxp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-jcK3TXqXwLmoeIxp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-jcK3TXqXwLmoeIxp :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
带过滤的向量查询
BATCHES 批量模式:分页取最近邻,边过滤边收集
ADHOC_BF 临时暴力:过滤后文档少时直接精算,结果准确
5.5 Python 完整示例(redis-py)
import numpy as np
from redis import Redis
from redis.commands.search.field import VectorField, TagField
from redis.commands.search.indexDefinition import IndexDefinition, IndexType
from redis.commands.search.query import Query
r = Redis(host="localhost", port=6379, decode_responses=False)
# 1. 创建 HNSW 索引
schema = [
TagField("category"),
VectorField("embedding", "HNSW", {
"TYPE": "FLOAT32",
"DIM": 1536,
"DISTANCE_METRIC": "COSINE",
"M": 16,
"EF_CONSTRUCTION": 200,
}),
]
r.ft("documents").create_index(
schema,
definition=IndexDefinition(prefix=["docs:"], index_type=IndexType.HASH),
)
# 2. 写入一条向量(FLOAT32 转字节)
vec = np.array([0.12, –0.34, 0.56], dtype=np.float32) # 实际为 1536 维
r.hset("docs:01", mapping={"embedding": vec.tobytes(), "category": "sports"})
# 3. KNN 向量检索(运行时调大 EF_RUNTIME 提升召回)
k = 10
query = (
Query("*=>[KNN $K @embedding $B]=>{$EF_RUNTIME:$EF}")
.sort_by("embedding")
.paging(0, k)
.dialect(2)
)
result = r.ft("documents").search(
query,
query_params={"B": vec.tobytes(), "K": k, "EF": 200},
)
for doc in result.docs:
print(doc.id, doc.embedding_score)
5.6 Java 示例(Spring AI,概念)
Spring AI 提供 RedisVectorStore,底层自动完成索引创建、写入与 KNN 检索:
/**
* 配置 Redis 向量存储(Spring AI)
* 底层自动调用 FT.CREATE 建立 HNSW 索引
*/
@Bean
public VectorStore vectorStore(JedisConnectionFactory factory, EmbeddingModel embeddingModel) {
RedisVectorStoreConfig config = RedisVectorStoreConfig.builder()
.indexName("documents")
.prefix("docs:")
.indexAlgorithm(IndexAlgorithm.HNSW)
.build();
return new RedisVectorStore(config, factory, embeddingModel, true);
}
// 业务中直接检索,无需手写 FT 命令
List<Document> hits = vectorStore.similaritySearch(
SearchRequest.query("如何提升系统性能").withTopK(5));
提示:不同 Spring AI 版本的配置类略有差异,以官方文档为准;需要精细控制时可直接用 Jedis 的 FT_SEARCH 原生命令。
六、实战二:Vector Sets(VSET 命令)
6.1 添加与检索
# 添加向量(默认 Q8 量化,省4倍内存)
VADD movies VALUES 3 0.1 0.5 0.9 "inception" SETATTR '{"year":2010,"genre":"scifi"}'
# 找相似(按向量)
VSIM movies VALUES 3 0.1 0.5 0.9 COUNT 10 WITHSCORES
# 按已有元素找相似
VSIM movies ELE "inception" COUNT 10 WITHSCORES
# 带属性过滤
VSIM movies VALUES 3 0.1 0.5 0.9 FILTER '.year >= 2000 and .genre == "scifi"' COUNT 10
6.2 常用命令
| VADD | 添加元素和向量 |
| VSIM | 找相似元素 |
| VREM | 删除(真删除,内存回收) |
| VCARD | 元素数量 |
| VDIM | 向量维度 |
| VEMB | 取某元素向量 |
| VINFO | 索引元信息 |
| VSETATTR / VGETATTR | 设置 / 读取 JSON 属性 |
6.3 量化方式
| NOQUANT(FP32) | 4 字节/维 | 基准 | 最好 |
| Q8(默认) | 1 字节/维 | 约 2 倍 | 约 96% |
| BIN(二值) | 1 比特/维 | 约 4 倍 | 约 80% |
6.4 Python 示例
import redis
r = redis.Redis()
# 添加(默认 Q8 量化)
r.execute_command("VADD", "movies", "VALUES", 3, 0.1, 0.5, 0.9,
"inception", "SETATTR", '{"year":2010,"genre":"scifi"}')
# 检索
res = r.execute_command("VSIM", "movies", "VALUES", 3, 0.1, 0.5, 0.9,
"COUNT", 10, "WITHSCORES")
print(res)
七、性能、内存与调优
7.1 内存估算
以 300 维、默认 Q8(Vector Sets) 为例:
- 向量存储:约 1 字节/维。
- 图开销:约每个元素 M×2.5 个指针。
- 合计:约 1KB / 元素。
Query Engine 用 FLOAT32 时约 4 字节/维,再加 HNSW 图连接。
7.2 调优清单
#mermaid-svg-cLmUWtfX0zzRFiPC{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-cLmUWtfX0zzRFiPC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-cLmUWtfX0zzRFiPC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-cLmUWtfX0zzRFiPC .error-icon{fill:#552222;}#mermaid-svg-cLmUWtfX0zzRFiPC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-cLmUWtfX0zzRFiPC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-cLmUWtfX0zzRFiPC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-cLmUWtfX0zzRFiPC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-cLmUWtfX0zzRFiPC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-cLmUWtfX0zzRFiPC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-cLmUWtfX0zzRFiPC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-cLmUWtfX0zzRFiPC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-cLmUWtfX0zzRFiPC .marker.cross{stroke:#333333;}#mermaid-svg-cLmUWtfX0zzRFiPC svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-cLmUWtfX0zzRFiPC p{margin:0;}#mermaid-svg-cLmUWtfX0zzRFiPC .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-cLmUWtfX0zzRFiPC .cluster-label text{fill:#333;}#mermaid-svg-cLmUWtfX0zzRFiPC .cluster-label span{color:#333;}#mermaid-svg-cLmUWtfX0zzRFiPC .cluster-label span p{background-color:transparent;}#mermaid-svg-cLmUWtfX0zzRFiPC .label text,#mermaid-svg-cLmUWtfX0zzRFiPC span{fill:#333;color:#333;}#mermaid-svg-cLmUWtfX0zzRFiPC .node rect,#mermaid-svg-cLmUWtfX0zzRFiPC .node circle,#mermaid-svg-cLmUWtfX0zzRFiPC .node ellipse,#mermaid-svg-cLmUWtfX0zzRFiPC .node polygon,#mermaid-svg-cLmUWtfX0zzRFiPC .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-cLmUWtfX0zzRFiPC .rough-node .label text,#mermaid-svg-cLmUWtfX0zzRFiPC .node .label text,#mermaid-svg-cLmUWtfX0zzRFiPC .image-shape .label,#mermaid-svg-cLmUWtfX0zzRFiPC .icon-shape .label{text-anchor:middle;}#mermaid-svg-cLmUWtfX0zzRFiPC .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-cLmUWtfX0zzRFiPC .rough-node .label,#mermaid-svg-cLmUWtfX0zzRFiPC .node .label,#mermaid-svg-cLmUWtfX0zzRFiPC .image-shape .label,#mermaid-svg-cLmUWtfX0zzRFiPC .icon-shape .label{text-align:center;}#mermaid-svg-cLmUWtfX0zzRFiPC .node.clickable{cursor:pointer;}#mermaid-svg-cLmUWtfX0zzRFiPC .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-cLmUWtfX0zzRFiPC .arrowheadPath{fill:#333333;}#mermaid-svg-cLmUWtfX0zzRFiPC .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-cLmUWtfX0zzRFiPC .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-cLmUWtfX0zzRFiPC .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cLmUWtfX0zzRFiPC .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-cLmUWtfX0zzRFiPC .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cLmUWtfX0zzRFiPC .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-cLmUWtfX0zzRFiPC .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-cLmUWtfX0zzRFiPC .cluster text{fill:#333;}#mermaid-svg-cLmUWtfX0zzRFiPC .cluster span{color:#333;}#mermaid-svg-cLmUWtfX0zzRFiPC div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-cLmUWtfX0zzRFiPC .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-cLmUWtfX0zzRFiPC rect.text{fill:none;stroke-width:0;}#mermaid-svg-cLmUWtfX0zzRFiPC .icon-shape,#mermaid-svg-cLmUWtfX0zzRFiPC .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cLmUWtfX0zzRFiPC .icon-shape p,#mermaid-svg-cLmUWtfX0zzRFiPC .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-cLmUWtfX0zzRFiPC .icon-shape .label rect,#mermaid-svg-cLmUWtfX0zzRFiPC .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cLmUWtfX0zzRFiPC .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-cLmUWtfX0zzRFiPC .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-cLmUWtfX0zzRFiPC :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
是
否
是
否
性能/召回问题
召回率不足?
调大 EF_RUNTIME(不重建)
仍不足?
调大 M 并重建索引
内存吃紧?
用 Q8 或 BIN 量化 / 降维
完成
7.3 水平扩展(分片)
#mermaid-svg-DXpGr3p3RBWg8aJ0{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DXpGr3p3RBWg8aJ0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .error-icon{fill:#552222;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .marker.cross{stroke:#333333;}#mermaid-svg-DXpGr3p3RBWg8aJ0 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DXpGr3p3RBWg8aJ0 p{margin:0;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .cluster-label text{fill:#333;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .cluster-label span{color:#333;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .cluster-label span p{background-color:transparent;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .label text,#mermaid-svg-DXpGr3p3RBWg8aJ0 span{fill:#333;color:#333;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .node rect,#mermaid-svg-DXpGr3p3RBWg8aJ0 .node circle,#mermaid-svg-DXpGr3p3RBWg8aJ0 .node ellipse,#mermaid-svg-DXpGr3p3RBWg8aJ0 .node polygon,#mermaid-svg-DXpGr3p3RBWg8aJ0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .rough-node .label text,#mermaid-svg-DXpGr3p3RBWg8aJ0 .node .label text,#mermaid-svg-DXpGr3p3RBWg8aJ0 .image-shape .label,#mermaid-svg-DXpGr3p3RBWg8aJ0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .rough-node .label,#mermaid-svg-DXpGr3p3RBWg8aJ0 .node .label,#mermaid-svg-DXpGr3p3RBWg8aJ0 .image-shape .label,#mermaid-svg-DXpGr3p3RBWg8aJ0 .icon-shape .label{text-align:center;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .node.clickable{cursor:pointer;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .arrowheadPath{fill:#333333;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DXpGr3p3RBWg8aJ0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DXpGr3p3RBWg8aJ0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DXpGr3p3RBWg8aJ0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .cluster text{fill:#333;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .cluster span{color:#333;}#mermaid-svg-DXpGr3p3RBWg8aJ0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DXpGr3p3RBWg8aJ0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .icon-shape,#mermaid-svg-DXpGr3p3RBWg8aJ0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .icon-shape p,#mermaid-svg-DXpGr3p3RBWg8aJ0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .icon-shape .label rect,#mermaid-svg-DXpGr3p3RBWg8aJ0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DXpGr3p3RBWg8aJ0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DXpGr3p3RBWg8aJ0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DXpGr3p3RBWg8aJ0 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
查询
分片0
分片1
分片2
并行查询,按分数合并取TopK
按元素哈希分片到多个 Redis 实例,并行查询、客户端合并,写入线性扩展。
八、与其他向量数据库对比及选型
8.1 主流产品对比
| Redis | 内存 KV + 向量一体 | 极低延迟、缓存/会话/向量统一、运维简单 | 全内存,超大规模成本高 |
| Milvus | 专用分布式向量库 | 亿级以上、索引类型最全、云原生扩展 | 组件多、运维较重 |
| Qdrant | Rust 向量库 | 性能强、过滤好、轻量 | 生态略小 |
| Weaviate | 一体化向量库 | 模块化、内置混合检索 | 内存占用偏高 |
| Pinecone | 全托管 SaaS | 免运维、上手快 | 闭源、数据上云、成本高 |
| pgvector | PostgreSQL 扩展 | 复用现有 PG、事务一致 | 大规模性能一般 |
8.2 基准参考
- Redis 官方基准(2024):相同召回下,Redis 延迟比 Qdrant 低约 4 倍、比 Milvus 低约 4.67 倍、比 Weaviate 快约 1.71 倍(注意:为厂商自报,口径需自验)。
- 内存:5 万向量规模,Redis 约 559MB,明显低于多数专用向量库。
8.3 选型决策
#mermaid-svg-2QxqUQKTdONPqDA9{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-2QxqUQKTdONPqDA9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2QxqUQKTdONPqDA9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2QxqUQKTdONPqDA9 .error-icon{fill:#552222;}#mermaid-svg-2QxqUQKTdONPqDA9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2QxqUQKTdONPqDA9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2QxqUQKTdONPqDA9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2QxqUQKTdONPqDA9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2QxqUQKTdONPqDA9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2QxqUQKTdONPqDA9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2QxqUQKTdONPqDA9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2QxqUQKTdONPqDA9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2QxqUQKTdONPqDA9 .marker.cross{stroke:#333333;}#mermaid-svg-2QxqUQKTdONPqDA9 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2QxqUQKTdONPqDA9 p{margin:0;}#mermaid-svg-2QxqUQKTdONPqDA9 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-2QxqUQKTdONPqDA9 .cluster-label text{fill:#333;}#mermaid-svg-2QxqUQKTdONPqDA9 .cluster-label span{color:#333;}#mermaid-svg-2QxqUQKTdONPqDA9 .cluster-label span p{background-color:transparent;}#mermaid-svg-2QxqUQKTdONPqDA9 .label text,#mermaid-svg-2QxqUQKTdONPqDA9 span{fill:#333;color:#333;}#mermaid-svg-2QxqUQKTdONPqDA9 .node rect,#mermaid-svg-2QxqUQKTdONPqDA9 .node circle,#mermaid-svg-2QxqUQKTdONPqDA9 .node ellipse,#mermaid-svg-2QxqUQKTdONPqDA9 .node polygon,#mermaid-svg-2QxqUQKTdONPqDA9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2QxqUQKTdONPqDA9 .rough-node .label text,#mermaid-svg-2QxqUQKTdONPqDA9 .node .label text,#mermaid-svg-2QxqUQKTdONPqDA9 .image-shape .label,#mermaid-svg-2QxqUQKTdONPqDA9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-2QxqUQKTdONPqDA9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-2QxqUQKTdONPqDA9 .rough-node .label,#mermaid-svg-2QxqUQKTdONPqDA9 .node .label,#mermaid-svg-2QxqUQKTdONPqDA9 .image-shape .label,#mermaid-svg-2QxqUQKTdONPqDA9 .icon-shape .label{text-align:center;}#mermaid-svg-2QxqUQKTdONPqDA9 .node.clickable{cursor:pointer;}#mermaid-svg-2QxqUQKTdONPqDA9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-2QxqUQKTdONPqDA9 .arrowheadPath{fill:#333333;}#mermaid-svg-2QxqUQKTdONPqDA9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2QxqUQKTdONPqDA9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2QxqUQKTdONPqDA9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2QxqUQKTdONPqDA9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-2QxqUQKTdONPqDA9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2QxqUQKTdONPqDA9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-2QxqUQKTdONPqDA9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2QxqUQKTdONPqDA9 .cluster text{fill:#333;}#mermaid-svg-2QxqUQKTdONPqDA9 .cluster span{color:#333;}#mermaid-svg-2QxqUQKTdONPqDA9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2QxqUQKTdONPqDA9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-2QxqUQKTdONPqDA9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-2QxqUQKTdONPqDA9 .icon-shape,#mermaid-svg-2QxqUQKTdONPqDA9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2QxqUQKTdONPqDA9 .icon-shape p,#mermaid-svg-2QxqUQKTdONPqDA9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-2QxqUQKTdONPqDA9 .icon-shape .label rect,#mermaid-svg-2QxqUQKTdONPqDA9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2QxqUQKTdONPqDA9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-2QxqUQKTdONPqDA9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-2QxqUQKTdONPqDA9 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
百万级以内,已在用 Redis,要低延迟
亿级以上、专用向量、需弹性扩展
已重度使用 PostgreSQL
完全不想运维、接受上云
是
否,需复杂混合查询
数据规模与需求?
选 Redis
选 Milvus
选 pgvector
选 Pinecone
只需简单相似度?
用 Vector Sets
用 Query Engine
九、RAG 完整架构
#mermaid-svg-PNJGmz4BsCCB4Uiu{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-PNJGmz4BsCCB4Uiu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-PNJGmz4BsCCB4Uiu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-PNJGmz4BsCCB4Uiu .error-icon{fill:#552222;}#mermaid-svg-PNJGmz4BsCCB4Uiu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-PNJGmz4BsCCB4Uiu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-PNJGmz4BsCCB4Uiu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-PNJGmz4BsCCB4Uiu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-PNJGmz4BsCCB4Uiu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-PNJGmz4BsCCB4Uiu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-PNJGmz4BsCCB4Uiu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-PNJGmz4BsCCB4Uiu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-PNJGmz4BsCCB4Uiu .marker.cross{stroke:#333333;}#mermaid-svg-PNJGmz4BsCCB4Uiu svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-PNJGmz4BsCCB4Uiu p{margin:0;}#mermaid-svg-PNJGmz4BsCCB4Uiu .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-PNJGmz4BsCCB4Uiu .cluster-label text{fill:#333;}#mermaid-svg-PNJGmz4BsCCB4Uiu .cluster-label span{color:#333;}#mermaid-svg-PNJGmz4BsCCB4Uiu .cluster-label span p{background-color:transparent;}#mermaid-svg-PNJGmz4BsCCB4Uiu .label text,#mermaid-svg-PNJGmz4BsCCB4Uiu span{fill:#333;color:#333;}#mermaid-svg-PNJGmz4BsCCB4Uiu .node rect,#mermaid-svg-PNJGmz4BsCCB4Uiu .node circle,#mermaid-svg-PNJGmz4BsCCB4Uiu .node ellipse,#mermaid-svg-PNJGmz4BsCCB4Uiu .node polygon,#mermaid-svg-PNJGmz4BsCCB4Uiu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-PNJGmz4BsCCB4Uiu .rough-node .label text,#mermaid-svg-PNJGmz4BsCCB4Uiu .node .label text,#mermaid-svg-PNJGmz4BsCCB4Uiu .image-shape .label,#mermaid-svg-PNJGmz4BsCCB4Uiu .icon-shape .label{text-anchor:middle;}#mermaid-svg-PNJGmz4BsCCB4Uiu .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-PNJGmz4BsCCB4Uiu .rough-node .label,#mermaid-svg-PNJGmz4BsCCB4Uiu .node .label,#mermaid-svg-PNJGmz4BsCCB4Uiu .image-shape .label,#mermaid-svg-PNJGmz4BsCCB4Uiu .icon-shape .label{text-align:center;}#mermaid-svg-PNJGmz4BsCCB4Uiu .node.clickable{cursor:pointer;}#mermaid-svg-PNJGmz4BsCCB4Uiu .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-PNJGmz4BsCCB4Uiu .arrowheadPath{fill:#333333;}#mermaid-svg-PNJGmz4BsCCB4Uiu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-PNJGmz4BsCCB4Uiu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-PNJGmz4BsCCB4Uiu .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PNJGmz4BsCCB4Uiu .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-PNJGmz4BsCCB4Uiu .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PNJGmz4BsCCB4Uiu .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-PNJGmz4BsCCB4Uiu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-PNJGmz4BsCCB4Uiu .cluster text{fill:#333;}#mermaid-svg-PNJGmz4BsCCB4Uiu .cluster span{color:#333;}#mermaid-svg-PNJGmz4BsCCB4Uiu div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-PNJGmz4BsCCB4Uiu .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-PNJGmz4BsCCB4Uiu rect.text{fill:none;stroke-width:0;}#mermaid-svg-PNJGmz4BsCCB4Uiu .icon-shape,#mermaid-svg-PNJGmz4BsCCB4Uiu .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PNJGmz4BsCCB4Uiu .icon-shape p,#mermaid-svg-PNJGmz4BsCCB4Uiu .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-PNJGmz4BsCCB4Uiu .icon-shape .label rect,#mermaid-svg-PNJGmz4BsCCB4Uiu .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PNJGmz4BsCCB4Uiu .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-PNJGmz4BsCCB4Uiu .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-PNJGmz4BsCCB4Uiu :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
在线:问答检索
用户提问
问题向量化
Redis 向量检索 TopK(可加过滤)
拼接相关上下文
大模型生成答案
返回答案
离线:知识库构建
原始文档
切分 Chunk
Embedding 向量化
写入 Redis 向量索引
配套最佳实践:
- 文档切分要合理(如 500 到 1000 字一块,带重叠)。
- 检索 TopK 通常 3 到 8,可加"标题/来源/时间"等元数据过滤。
- 可加一层语义缓存(用 Vector Sets 存历史问答,相似度高于阈值直接返回),降低大模型成本。
十、总结与面试要点
10.1 核心结论
10.2 面试高频问题
- 向量检索为什么比关键词强? 语义相近则向量距离近,不受字面限制。
- HNSW 原理? 多层图,顶层稀疏快速定位、底层全量精确,贪心逐层下降。
- HNSW 参数? M(连接数)、EF_CONSTRUCTION(建图)、EF_RUNTIME(查询)。
- 距离度量怎么选? 文本 COSINE,距离直观用 L2,归一化后 IP 等价 COSINE。
- ANN 会不会不准? 会牺牲少量召回(约 1% 到 5%),但快几个数量级。
- Redis 向量库的优势? 极低延迟、与缓存/会话统一、运维简单;不适合纯内存扛不住的超大规模。


