ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Milvus 核心原理与 RAG 实践:从架构、索引到面试考点全解析

Milvus 核心原理与 RAG 实践:从架构、索引到面试考点全解析 大模型应用落地时Milvus 是出现频率最高的开源向量数据库之一。不管你是做 RAG、知识库问答还是相似度检索都需要理解它的存储架构、索引机制和查询语义否则生产环境一上量问题就很难定位。到了 2026 年Milvus 的迭代速度仍然很快很多新特性已经从“能用”进入“生产可用”的范围面试时考官也不会只问“你写过 pymilvus 的 insert 吗”更会追问动态字段怎么设计、索引怎么选、一致性怎么保证、召回率低时先查哪一层。本文围绕 Milvus 的新特性和面试考点展开按“架构认知 - 环境安装 - 最小闭环 - 原理细节 - 排错实践 - 面试速答”的顺序组织。读完后你能完成一次从写入到查询的完整链路也能用自己的话解释为什么 Milvus 在大模型 RAG 项目里值得使用以及遇到问题该从哪里排查。1. 先搞清楚 Milvus 为什么是大模型方向的高频考点1.1 向量数据库在大模型基础设施中的位置大模型本身有知识截止时间输入上下文长度也有限。要让模型回答企业私有文档、内部知识库或实时变化的内容常见做法是 RAG先把文档切片并交给 Embedding 模型转换成向量再存入向量数据库用户提问时再把问题向量化从向量库中检索最相关的片段把片段和问题一起交给大模型生成回答。这一步的核心在于“相似度检索”。如果数据量只有几百条可以用内存数组加余弦相似度硬算但数据量到百万、千万甚至亿级后就必须依赖专门为大规模向量检索设计的系统。Milvus 是开源方案里支持水平扩展、能处理大规模向量数据、又支持标量字段过滤的选项这也是大模型工程师面试里高频出现它的原因。1.2 面试官真正考察的核心能力面试官并不期待你把 Milvus 的每个 API 都背下来而是希望看到你能说清几个关键判断向量数据库和普通数据库加余弦相似度有什么区别精确搜索和近似近邻搜索ANNS为什么需要区分索引类型 HNSW、IVF、FLAT、DiskANN 分别适合什么规模数据写入后为什么不一定立刻能查到动态字段$meta是什么、怎么读写RAG 项目里召回率低时问题可能出现在 Embedding、索引参数、过滤条件还是查询语句。这些能力的共同点是你不再把 Milvus 当成一个“替换 MySQL 的搜索工具”而是当成一个有存储、索引、查询、一致性、资源管理多个环节的系统。1.3 Milvus 与 Chroma、pgvector 的选型差异很多面试题会让你对比向量数据库选型。常见对比对象是 Chroma、pgvector、Milvus。理解差异比背结论更重要。维度MilvusChromapgvector定位独立分布式向量数据库轻量级向量存储偏向原型验证PostgreSQL 扩展数据规模可到亿级支持水平扩展中小规模单机为主受 PostgreSQL 单机性能限制能力范围向量 标量过滤 动态字段 分区 多索引向量检索为主管理简单向量 SQL 联合查询更自然运维成本较高需要管理 etcd、MinIO、Milvus 组件低适合本地实验已有 PostgreSQL 时成本低典型场景生产级 RAG、知识库、推荐检索小工具、教学、快速 Demo业务数据已存在 PG需要同时做向量过滤实际选型建议是如果数据量小且只是验证想法Chroma 足够如果业务已经重度使用 PostgreSQL且向量数据量不大pgvector 更省运维如果是大模型知识库方向、预期数据量快速上涨、需要水平扩展Milvus 更适合。面试回答时先反问数据量、QPS、是否需要扩展能体现工程意识。2. 从架构和部署理解 Milvus 的工作方式2.1 先理解存算分离架构Milvus 2.x 不再采用 1.x 时代那种简单的主从分片思路而是把存储、元数据、计算节点拆开。Standalone 模式下虽然所有服务都装在同一个 Docker Compose 环境里但组件职责仍然清晰。Etcd保存 collection schema、索引信息、节点状态等元数据。MinIO 或 S3保存日志、索引文件、数据文件等持久化对象。Proxy接收客户端请求负责鉴权、路由和请求校验。Datanode处理数据写入把数据打包后写入对象存储。Querynode处理查询请求加载数据段和索引到内存或磁盘执行检索。Coordinator 与 IndexNode负责调度、元数据协调和索引构建任务。这种架构带来的好处是扩展点清晰。数据量大时可以扩展 Datanode查询压力大时可以扩展 Querynode对象存储本身可以独立扩容。面试时如果能画一条写入链路和查询链路会非常有说服力。写入链路大致是客户端通过 gRPC 请求 ProxyProxy 做校验后把消息交给 DatanodeDatanode 批量写入并最终把数据段持久化到 MinIO同时更新 Etcd 中的元数据。查询链路大致是Proxy 接收搜索请求由 Querynode 根据元数据定位到相关数据段加载本地缓存或从对象存储读取索引执行向量检索和标量过滤最后合并结果返回客户端。2.2 Standalone 与 Cluster 怎么选Milvus 的部署模式通常分为 Standalone 和 Cluster。Standalone 适合学习和中小业务验证Cluster 适合大数据量和生产高可用场景。对比项StandaloneCluster组件数量etcd、minio、milvus standaloneProxy、Datanode、Querynode、IndexNode、Coordinator、etcd、MinIO 等部署复杂度低Docker Compose 可启动高通常用 Kubernetes 编排扩展能力单节点扩展有限可按职责水平扩展高可用依赖单机恢复可通过多副本和多节点实现适合场景学习、Demo、小规模知识库生产级、大规模数据、高并发我用最简单的说法给新人建议还在学 pymilvus 怎么用先跑 Standalone要接生产流量再考虑 Cluster。不要在理解数据写入链路之前直接部署一套 Kubernetes 集群遇到问题会很难定位。2.3 使用 Docker Compose 安装 Standalone学习环境安装 Milvus Standalone 最直接的方式是 Docker Compose。下面给出一份简化但可运行的配置文件用于说明组件关系。实际生产环境中建议从 Milvus 官方文档获取对应版本的标准 compose 文件并把镜像版本固定到具体标签避免使用latest造成不可控升级。version: 3.5 services: etcd: image: quay.io/coreos/etcd:v3.5.5 environment: - ETCD_AUTO_COMPACTION_MODErevision - ETCD_AUTO_COMPACTION_RETENTION1000 - ETCD_QUOTA_BACKEND_BYTES4294967296 command: etcd -advertise-client-urlshttp://etcd:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd volumes: - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd:/etcd minio: image: minio/minio:latest environment: MINIO_ACCESS_KEY: minioadmin MINIO_SECRET_KEY: minioadmin command: minio server /minio_data ports: - 9000:9000 - 9001:9001 volumes: - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/minio:/minio_data standalone: image: milvusdb/milvus:latest command: [milvus, run, standalone] environment: ETCD_ENDPOINTS: etcd:2379 MINIO_ADDRESS: minio:9000 ports: - 19530:19530 - 9091:9091 volumes: - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus depends_on: - etcd - minio把文件保存为docker-compose.yml然后在同一目录执行docker compose up -d等待一段时间后查看状态docker compose ps正常情况下可以看到 etcd、minio、standalone 三个容器处于运行状态。这里要注意MinIO 和 Milvus 的latest标签会导致版本漂移所以这个配置只适合本机快速验证不能直接照搬到生产环境。2.4 安装后如何验证服务可用服务启动后不要只盯着容器状态还要验证端口和连接是否真正可用。telnet localhost 19530或者用 Python 快速连接pip install pymilvus python -c from pymilvus import connections; connections.connect(default, hostlocalhost, port19530); print(connected)如果没有报错说明 gRPC 端口可以访问。端口 19530 是客户端连接端口9091 是 Prometheus 指标端口。容器日志也很重要docker logs milvus容器名称观察日志中有没有proxy、querynode启动完成的信息。如果容器反复重启优先检查 etcd 和 MinIO 是否已经就绪、磁盘空间是否不足、端口是否被占用。不要一上来就改 Milvus 参数先确认基础组件健康。3. 用 pymilvus 跑通一个最小检索闭环3.1 准备 Python 环境与依赖建议使用虚拟环境避免污染系统 Python。mkdir -p milvus-demo cd milvus-demo python -m venv .venv source .venv/bin/activate pip install pymilvus numpy安装完成后检查版本方便后续排查 SDK 和 Milvus 服务端的兼容性python -c import pymilvus; print(pymilvus.__version__)我建议直接安装最新稳定版 pymilvus。如果服务端版本较老再根据官方文档选择匹配的 SDK 版本。版本不匹配最常见的问题就是connection refused或unsupported api一类报错。3.2 创建 Collection 并设计 SchemaMilvus 中Collection 可以理解成关系数据库里的表但多了一个向量字段。创建前必须先定义 Schema。下面示例使用 8 维向量方便本地运行真实项目中向量维度由 Embedding 模型决定例如text-embedding-3-small输出维度可能是 1536BGE 系列可能是 1024。from pymilvus import ( connections, CollectionSchema, FieldSchema, DataType, Collection, utility, ) connections.connect(hostlocalhost, port19530) fields [ FieldSchema(nameid, dtypeDataType.INT64, is_primaryTrue, auto_idFalse), FieldSchema(nametitle, dtypeDataType.VARCHAR, max_length256), FieldSchema(namecontent, dtypeDataType.VARCHAR, max_length4096), FieldSchema(nameembedding, dtypeDataType.FLOAT_VECTOR, dim8), ] schema CollectionSchema( fields, descriptionbook knowledge base, enable_dynamic_fieldTrue, ) collection_name book_demo if utility.has_collection(collection_name): utility.drop_collection(collection_name) collection Collection(namecollection_name, schemaschema, usingdefault, shards_num2) print(collection created:, collection.name)这里有几个关键点要重点解释。is_primaryTrue的字段是主键必须有唯一值。max_length对于VARCHAR字段是必填参数取值过小会导致中文或长文本插入失败。dim必须与后续写入的向量长度一致一旦 collection 创建成功不能随意改维度。enable_dynamic_fieldTrue表示启用动态字段允许插入未在 Schema 中预定义的字段这是 Milvus 新特性里特别重要的一个点。3.3 插入数据并触发 flush插入数据时可以传入字典列表。每条数据里除了 Schema 中定义的字段还可以附加额外字段例如tag这个字段会被自动保存到动态字段$meta中。import numpy as np rows [ { id: 1, title: Milvus 入门, content: 学习向量数据库基础概念与安装方式, tag: tech, embedding: np.random.rand(8).astype(np.float32), }, { id: 2, title: RAG 实践, content: 使用 Embedding 模型构建知识库检索链路, tag: rag, embedding: np.random.rand(8).astype(np.float32), }, { id: 3, title: 大模型部署, content: 本地模型推理服务与向量检索结合, tag: llm, embedding: np.random.rand(8).astype(np.float32), }, ] insert_result collection.insert(rows) collection.flush() print(inserted rows:, collection.num_entities)insert成功后数据可能还在内存或日志缓冲区里flush()会强制把数据写入持久化存储并更新元数据。真实项目中批量导入时不会每条数据都 flush高频写入时 flush 过于频繁会影响性能。3.4 创建索引并执行搜索没有索引的 Collection 也可以查询但 Milvus 在大规模场景下必须依赖索引。这里使用 HNSW 索引并指定 COSINE 作为相似度度量方式。index_params { index_type: HNSW, metric_type: COSINE, params: {M: 8, efConstruction: 64}, } collection.create_index(field_nameembedding, index_paramsindex_params) collection.load()创建索引后要执行load()把所有 Segment 加载到可查询状态。这一步很容易被忽略如果忘了 load搜索时会报collection not loaded。下面执行一次搜索。为了让结果可验证先直接把第 1 条数据的向量作为查询向量理想情况下 id1 应该排在第一位分数接近 1.0。query_vec rows[0][embedding].reshape(1, -1) search_params { metric_type: COSINE, params: {ef: 64}, } results collection.search( dataquery_vec, anns_fieldembedding, paramsearch_params, limit3, output_fields[id, title, $meta], ) for hits in results: for hit in hits: print(hit.id, hit.score, hit.entity.get(title), hit.entity.get($meta))output_fields用于指定返回的标量字段$meta是动态字段的保留字段名。返回值中hit.id是主键hit.score是相似度分数hit.entity.get(title)可以取出标量字段。3.5 验证运行结果并理解排序正常输出第一条记录会是 id1。因为查询向量就是 id1 的向量本身COSINE 相似度应该等于 1.0。后两条结果取决于随机向量之间的相似度可能不稳定但排序顺序一定是从高到低。这个最小闭环最重要的意义是你能亲眼看到 Embedding 向量如何被写入、索引如何构建、查询如何返回。后续替换成真实文本数据时只要把随机向量换成 Embedding 模型输出即可。注意只验证程序能启动不够还要验证输入、输出、异常分支和日志是否符合预期。比如把查询向量换成随机向量后如果返回结果为空就需要怀疑 collection 是否 load、索引是否创建、向量维度是否一致。4. Milvus 新特性与面试考点动态字段、标量过滤和索引4.1 动态 Schema 和 $meta 字段早期使用向量数据库时每一列都必须提前定义好。业务一旦增加字段就要重建 Schema 或迁移数据。Milvus 的动态 Schema 解决的是“先写入后扩展字段”的问题。只要创建 Collection 时启用enable_dynamic_fieldTrue插入数据时出现 Schema 中未定义的字段Milvus 会自动把它保存到$meta字段里。举个例子上面的tag字段就没有在 Schema 中定义插入后会被放到底层$metaJSON 结构里。查询时用output_fields[$meta]就能把它取出来。C# SDK 获取$meta的思路和 Python 一致。启用动态字段后查询结果里会带有$meta这个特殊字段。问题在于强类型客户端经常无法直接用实体去映射它所以要先从原始返回结果中取字典再手动解析。// 示意代码API 名称以当前 SDK 版本为准 var result await client.QueryAsync(new QueryParams { CollectionName book_demo, OutputFields { id, title, $meta }, Expr id in [1, 2] }); foreach (var row in result.RowData) { var meta row[$meta]; // 根据 SDK 类型把 meta 转为字典或 JSON 字符串 Console.WriteLine(meta); }如果你的 C# SDK 版本无法直接取到$meta建议检查两点创建 Collection 时有没有开启enable_dynamic_fieldTrue查询时OutputFields是否显式包含$meta。动态字段属于便利能力但不要把所有业务字段都塞进$meta。需要高频参与过滤或排序的字段最好还是预定义 Schema否则过滤性能和可读性都会下降。4.2 常见索引类型对比面试中经常问“你会选哪种索引”。理解索引的出发点不是记名字而是理解你要在“精度、延迟、内存、构建时间”之间做权衡。索引类型核心思路优点缺点适合场景FLAT暴力遍历全部向量精确、实现简单慢内存占用随数据量线性增长小数据集、验证结果IVF_FLAT先聚类再在候选桶内搜索比 FLAT 快精度可控聚类参数影响召回构建时间较长百万级到千万级数据IVF_SQ8对向量做 8-bit 量化压缩节省内存精度有损内存受限精度要求不极端HNSW构建多层图索引搜索时跳表式查找查询快、召回率高内存占用大构建时间长高 QPS、高召回需求DiskANN使用磁盘支持的图索引可处理超大向量集合依赖磁盘 IO延迟可能比内存索引高内存无法容纳的超大规模数据AUTOINDEX让 Milvus 自动选择索引使用简单需要了解当前版本默认索引策略开发环境、快速验证AUTOINDEX 很方便但生产环境我仍建议根据数据大小和数据分布手动确认索引类型。索引选错不会直接报错但会表现为查询慢、内存占用高或召回率低。4.3 索引参数nlist、nprobe、M、ef面试时只说出索引名字还不够需要会调参数。参数所属索引含义调大影响调小影响nlistIVF 系列聚类中心数量召回更准但构建更慢查询候选更多构建快但召回可能下降nprobeIVF 系列查询参数搜索时选取的聚类桶数量召回更高但查询更慢查询快但召回下降MHNSW 构建参数每个节点的最大连接数图连接更密集召回更高内存占用变大内存更小但图可能不连通efConstructionHNSW 构建参数构建图时的候选队列大小构建质量更好构建更慢构建快但召回可能下降efHNSW 查询参数查询时的候选队列大小召回更高但查询更慢查询快但召回下降一个常见错误是HNSW 索引检索时忘了设置ef导致使用的默认值过小召回率偏低。另一个常见错误是IVF 索引的nlist设置过大单条查询时却使用了过小的nprobe大量聚类中心没被搜索到重复查询会得到不稳定结果。4.4 混合搜索、全文检索和 RAG 链路Milvus 的定位早已不只是一个“向量搜索工具”。它支持在向量检索时叠加标量条件例如只查某个用户上传的文档只查content_type pdf的数据只查create_time 某个时间点。这种“向量相似度 标量过滤”的混合检索能力在 RAG 场景里非常关键。比如企业知识库要按部门隔离数据就不能只做全局向量搜索必须过滤部门的标量字段或分区键。另一个方向是全文检索和稀疏向量的结合。RAG 里经常出现这样的问题查询词是“Milvus 安装”但向量召回结果却包含大量“Milvus 面试”因为语义相近但关键词不匹配。纯稠密向量对低频专有名词不够敏感所以很多生产方案开始做“稠密向量 BM25/稀疏向量”的混合召回再用 Reranker 重排。在 Dify、LlamaIndex 这类编排工具中Milvus 一般作为向量存储组件出现。你可以在编排工具里配置 Milvus 的连接信息和 collection 名称但真正决定检索质量的仍然是 collection 的字段设计、索引类型、过滤表达式和查询参数。下面是一个典型 RAG 数据链路文档解析 - 文本切片 - Embedding 模型生成向量 - 写入 Milvus - 用户提问向量化 - Milvus 检索 标量过滤 - Reranker 重排 - 拼接 Prompt - 大模型生成回答。面试时能把这条链路说清楚比背十个 API 更有价值。4.5 一致性等级和分区设计Milvus 提供了多个一致性等级常见包括Strong、Session、Bounded、Eventually实际枚举名以 SDK 和版本为准。强一致性保证写入后立刻能读到最终一致性则可能在一段时间内读不到最新数据但换取更高吞吐。面试题经常这样出你从 MySQL 同步数据到 Milvus同步完成后立刻查不到最新记录为什么答案方向是写入请求已经返回成功但查询请求读到的数据快照时间戳可能早于写入时间戳。如果你业务明确要求“写完必须马上查到”应该使用强一致性或 session 一致性并在查询参数里指定。分区设计同样重要。按时间或业务 ID 作为分区键可以让查询跳过无关数据段。比如一个知识库按日期分区查最近 7 天数据时Milvus 可以根据分区信息只扫描相关 Segment而不是全量扫描所有历史数据。注意不要把所有过滤需求都压到向量检索完成之后再手动处理。如果一次召回 1000 条再在应用层过滤掉 900 条性能和结果稳定性都会很差。应该把高频过滤字段提前预定义通过表达式下推到 Milvus 查询层。5. 常见问题排查与生产落地建议5.1 安装启动类问题安装是很多新人第一次受挫的地方。下面表格整理了我见过的高频问题。问题现象常见原因检查方式处理建议Python 连接时报 connection refusedMilvus 容器未启动 / 端口映射错误 / 防火墙拦截docker compose ps、telnet localhost 19530先确认容器状态和端口再检查防火墙规则Milvus 容器反复重启etcd 或 MinIO 未就绪 / 磁盘不足 / 内存不足docker logs 容器名查看日志中的具体报错确认 etcd 和 MinIO 健康SDK 版本与服务端不兼容pymilvus 版本过新或过旧查看 pymilvus 与服务端版本对应表固定 pymilvus 和服务端版本避免latest漂移访问 MinIO 控制台失败MinIO 未启动 / 端口被占用docker compose ps、浏览器访问 9001检查端口映射和容器健康状态创建 collection 后无法插入主键重复 / 字段长度超限 / 向量维度不一致查看 insert 返回错误信息检查主键唯一性、max_length、向量维度如果日志里出现etcdserver: request timed out优先检查 etcd 容器是否健康而不是反复重启 Milvus。Milvus 依赖 etcd 协调元数据etcd 不稳定时后续所有操作都会异常。5.2 查询召回和性能问题查询变慢或者召回率低是生产中最常见的问题。排查顺序很重要不要一上来就换索引。优先检查这几个点查询向量和写入向量是否来自同一个 Embedding 模型Collection 是否执行了load()索引类型和查询参数是否匹配过滤条件是否过强导致候选集合太小返回字段是否过多导致传输和序列化耗时数据量是百万级还是十亿级索引是否需要重新调参Milvus 指标端口 9091 是否暴露了 CPU、内存、查询耗时指标。比如你使用 HNSW查询时ef设置成 8召回率会明显下降。解决方法是先调大ef观察延迟与召回变化再决定是否需要增加更多内存。如果同一个 collection 既要做高 QPS 在线检索又要做离线批量分析建议拆成不同的 collection 或使用不同索引配置避免互相影响。5.3 生产环境的安全、权限、备份学习环境里使用默认的 MinIO 账号和 Milvus 默认配置没问题但生产环境必须立刻调整。开启 Milvus 用户认证设置强密码开启 MinIO 或 S3 的访问密钥管理不要继续用minioadmin/minioadmin不把端口 19530 直接暴露到公网对 etcd、MinIO、Milvus 数据库分别做备份升级版本前先备份元数据和数据文件并准备好回滚方案使用监控系统采集请求量、错误率、查询延迟、内存使用率等指标。数据备份不能只靠 docker volume 复制尤其是 Milvus Cluster 模式下元数据在 etcd、数据在对象存储备份工具需要同时处理两者。建议查看 Milvus 官方提供的 backup 工具并在测试环境验证恢复流程。5.4 RAG 项目落地最佳实践从可行 Demo 到生产系统通常要经过这些调整使用真实业务数据而不只是随机向量把切片策略和 Embedding 模型版本一起管理模型升级后要重建索引对文档来源、上传时间、权限范围做标量字段预定义方便过滤查询链路中增加 Reranker提高检索精度为常用查询结果加缓存避免重复查询压垮检索集群监控检索召回率和端到端回答质量。下面是一份可复用的落地检查清单[ ] 确认 Embedding 模型输出维度与 Collectiondim一致[ ] 确认高频过滤字段已在 Schema 中预定义[ ] 确认 Collection 已创建索引并执行load()[ ] 查询前确认过滤表达式语法正确[ ] 索引参数先做小样本召回率验证再发布到生产[ ] 开启监控关注查询延迟、内存使用、错误率[ ] 制定备份和恢复演练计划。6. 面试高频问题速答清单6.1 基础概念类什么是向量数据库向量数据库是用于存储和检索向量数据的系统核心能力是支持大规模向量相似度检索并通常附带标量字段过滤能力。Milvus 支持哪些索引常见有 FLAT、IVF_FLAT、IVF_SQ8、HNSW、DiskANN 以及 AUTOINDEX。选择索引要基于数据规模、内存、查询延迟和召回率要求。精确检索和近似检索的区别精确检索会遍历全部向量结果无损失但大数据量下性能不可接受。近似检索ANNS牺牲少量精度换取极高查询速度是向量数据库的核心价值。L2、IP、COSINE 有什么区别L2 计算欧式距离越小越相似IP 计算内积适合归一化向量COSINE 计算余弦相似度对向量长度不敏感适合文本语义检索。6.2 机制与原理类HNSW 为什么快HNSW 构建多层图结构高层图跳跃跨度大底层图包含精细邻居。搜索时从高层快速定位到接近目标的区域再在底层精细化寻找避免遍历全部节点。IVF 为什么快IVF 先在数据上做聚类查询时只搜索邻近的若干聚类中心桶。如果数据分布不均匀某些桶的向量数量差异大会影响查询效果。为什么 Milvus 需要 etcd 和 MinIOetcd 保存元数据MinIO 保存数据文件和索引文件。二者分离后计算节点无状态化便于扩容和故障恢复。动态字段$meta是怎么实现的Collection 开启动态字段后未预定义的字段会被统一封装到$meta字段中底层以 JSON 形态保存。查询时可以通过$meta读取这些额外属性。写入后为什么查不到可能原因包括一致性等级设置、索引未构建、Collection 未 load、缓存延迟、写入失败但客户端没捕获异常。排错时需要先确认写入返回是否成功再确认查询一致性设置。6.3 项目经验类遇到召回率低怎么排查先确认查询向量和写入向量来自同一个 Embedding 模型再排除标量过滤是否过强然后切换 FLAT 索引验证精确召回结果如果 FLAT 召回也低问题出在数据切分和 Embedding而不是向量数据库如果 FLAT 正常而 HNSW 召回低调整索引参数。百万级向量怎么选索引如果内存足够且高并发优先 HNSW如果内存紧张考虑 IVF_FLAT 或 IVF_SQ8如果是超大向量集考虑按分区拆分或使用 DiskANN。如何做知识库更新把文档切分和 Embedding 模型纳入版本管理更新时按文档 ID 删除旧数据再写入新数据。更新后必须重建相关索引或等待索引自动构建并重新 load。为什么 RAG 要用向量数据库因为 RAG 需要根据用户问题快速从大量知识片段中召回语义相关文本。普通数据库的精确匹配抓不住“意思相近但表述不同”的内容向量数据库用相似度检索解决这个问题。6.4 准备建议这篇内容里最值得动手的部分是第三章的最小闭环。建议不要只复制代码而是自己一步步创建 Collection、插入数据、创建索引、搜索然后故意制造几个错误比如忘记load()、故意设置错误维度、用不同长度的
返回列表