尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Java RAG 实战(第 7 篇):使用 Qdrant 保存和检索向量

Java RAG 实战(第 7 篇):使用 Qdrant 保存和检索向量 系列导航所属专栏《Java 开发者从零实现 RAG 知识库》学习位置第 7 篇 / 共 12 篇上一篇《第6篇Markdown 知识库与 RAG》下一篇《第8篇Spring Boot RAG 查询 API》上一篇已经用内存检索跑通 RAG。本篇把 Chunk 向量预先保存到 Qdrant并通过官方 Java SDK 完成 Top-K 搜索。完成进度1. 用 Docker 启动 Qdrant2. 创建 1024 维 Cosine Collection3. 理解 Point、Vector 和 payload4. 把 Markdown Chunk 写入 Qdrant5. 使用 Java SDK 完成 Top-K 查询6. 验证相似度阈值会拦截无关资料为什么要学内存版每次运行都要重新读取所有 Chunk 并生成全部向量知识量增加后会浪费时间和计算资源。Qdrant 可以持久化 Point并使用专门的向量索引快速查找相似内容。引入 Qdrant 后查询阶段只需要向量化用户问题再从数据库取回相关 Chunk。它负责保存和检索知识最终答案仍由 qwen3 根据 Prompt 生成。第 1 步启动 Qdrant第一次启动dockerrun-d\--nameqdrant-study\-p6333:6333\-p6334:6334\-vqdrant-study-data:/qdrant/storage\qdrant/qdrant:v1.19.0以后容器停止后只需执行dockerstart qdrant-study这里的两个端口用途不同6333REST API适合使用curl查看状态。6334gRPC当前 Java 官方 SDK 通过它连接 Qdrant。确认服务正常curl-shttp://localhost:6333/collections|jq第 2 步创建 Collectionbge-m3生成 1024 维向量所以 Collection 的向量维度也必须是 1024curl-XPUT http://localhost:6333/collections/kubernetes_chunks\-HContent-Type: application/json\-d{ vectors: { size: 1024, distance: Cosine } }检查配置curl-shttp://localhost:6333/collections/kubernetes_chunks|jq{ status: .result.status, points_count: .result.points_count, vector_size: .result.config.params.vectors.size, distance: .result.config.params.vectors.distance }第 3 步理解 Point 和 payloadQdrant 中的一条 Point 包含三部分Point ID唯一编号例如 2 Vector bge-m3 生成的 1024 个数字 Payload title、content、source 等原始资料Vector 用来计算相似度payload 用来把命中结果还原成人能阅读的知识。RAG 最终交给大模型的是 payload 中的正文不是 1024 个数字。本篇的固定示例使用简单数字 ID 方便观察。后面动态入库时会改用documentId chunkIndex生成稳定 UUID避免更新文档时不断产生重复 Point。第 4 步把 Markdown 写入 Qdrant在仓库根目录运行mvn-f04-qdrant-rag/pom.xml compile exec:java\-Dexec.args--index入库流程是MarkdownKnowledgeLoader按二级标题拆分文档。OllamaEmbeddingClient用bge-m3生成 Chunk 向量。QdrantPointMapper把向量、标题、正文和来源组成 Point。QdrantIndexer通过官方 SDK 的 gRPC 接口执行 upsert。检查 Point 数量curl-shttp://localhost:6333/collections/kubernetes_chunks|\jq.result.points_count当前示例应输出4。第 5 步理解搜索代码查询阶段不再读取并重新向量化全部 Markdown只生成用户问题的一个向量QdrantVectorSearch.search(...) ↓ EmbeddingClient.embed(List.of(query)) ↓ QdrantSearchMapper.toRequest(...) ↓ QdrantClient.searchAsync(...) ↓ QdrantSearchMapper.toResult(...)搜索请求中的关键参数limit 2最多返回两个结果也就是 Top-2。scoreThreshold 0.60低于 0.60 的结果不返回。withPayload true要求结果带回标题、正文和来源。Qdrant 已经按相似度从高到低返回结果Java 不需要再自己遍历所有向量计算余弦相似度。对应源码04-qdrant-rag/src/main/java/com/example/ai/rag/QdrantVectorSearch.java 04-qdrant-rag/src/main/java/com/example/ai/rag/QdrantSearchMapper.java查询方法的核心只有三步double[]queryEmbeddingembeddingClient.embed(List.of(query)).get(0);SearchPointsrequestmapper.toRequest(collectionName,queryEmbedding,limit,minimumScore);ListScoredPointpointssearchOperation.search(request);returnpoints.stream().map(mapper::toResult).toList();mapper.toRequest(...)会把教程中的三个检索要求真正写入 Qdrant SDK 请求returnSearchPoints.newBuilder().setCollectionName(collectionName).addAllVector(vector).setLimit(limit).setScoreThreshold((float)minimumScore).setWithPayload(WithPayloadSelector.newBuilder().setEnable(true).build()).build();withPayload true不能省略。如果只返回 Point ID 和分数Java 就无法取回要放入 Prompt 的标题和正文。第 6 步运行 Qdrant 版完整 RAG确认 Ollama 和 Qdrant 已启动然后执行mvn-f04-qdrant-rag/pom.xml compile exec:java知识库内问题的示例输出问题Pod 重建后 IP 会变化应该怎样提供稳定访问地址 Qdrant 检索结果最低相似度 0.60 1. Service相似度 0.7388Point ID 2 AI 回答 可以通过 Service 为 Pod 提供稳定的集群内访问地址和负载均衡。也可以传入自己的问题mvn-f04-qdrant-rag/pom.xml compile exec:java\-Dexec.args密码、令牌和证书应该保存在哪里第 7 步观察阈值保护查询知识库没有覆盖的内容mvn-f04-qdrant-rag/pom.xml compile exec:java\-Dexec.argsIngress 应该怎样配置 TLS 证书如果没有结果达到0.60程序不会调用聊天模型而是直接输出根据现有资料无法确定。这可以减少无关上下文和不必要的模型调用但阈值不是越高越好。过高会漏掉有用资料过低会把无关资料交给模型需要根据真实问题和知识库评估后调整。第 8 步运行 Qdrant 模块测试mvn-f04-qdrant-rag/pom.xmltest测试会隔离外部 Ollama 和 Qdrant重点验证double[]是否正确转换成 Qdrant 的 float 向量。Collection、Top-K、阈值和 payload 开关是否正确。Qdrant 返回值是否正确还原成 Chunk。搜索过程是否只向量化用户问题。常见问题Connection refused: localhost:6334Qdrant 没有启动执行dockerstart qdrant-studydockerps--filternameqdrant-studyCollection 不存在先执行“第 2 步”创建kubernetes_chunks然后再运行入库程序。Collection 是空的Collection 只定义了存储结构还没有资料。使用“第 4 步”的--index模式完成入库。向量维度错误Embedding 模型与 Collection 配置不一致。当前bge-m3输出 1024 维因此 Collection 的size必须是 1024。成功标准kubernetes_chunks状态为green并且有 4 个 Point。03-markdown-rag能使用内存检索完成一次 RAG 回答。默认问题能检索到Service。知识库外问题不会调用qwen3:14b。mvn -f 04-qdrant-rag/pom.xml test全部通过。下一步下一阶段可以把命令行程序改造成 Spring Boot HTTP 服务让浏览器或其他应用通过接口提交问题并获得 RAG 回答。本篇自测Qdrant Point 中的 Vector 和 payload 分别有什么用查询时为什么只需要向量化用户问题Top-K 和相似度阈值有什么区别Java SDK 为什么连接 6334而curl通常访问 6333参考答案Vector 用于相似度计算payload 用于还原正文知识向量已经在入库时保存Top-K 限制最多返回数阈值排除低分结果6334 是 gRPC6333 是 REST。本篇小结Qdrant 预先保存 Chunk 向量查询时无需重新向量化全部知识。Collection 维度必须和 Embedding 模型一致bge-m3对应 1024 维。一条 Point 由 ID、Vector 和 payload 构成Java 通过官方 SDK 执行写入和搜索。Top-K 与最低相似度共同控制进入 Prompt 的资料数量和质量。下一篇 本专栏下一篇《第8篇Spring Boot RAG 查询 API》完整代码都在 GitHub欢迎 Star ⭐本专栏的全部示例代码都已开源包含 5 个可独立运行的 Maven 模块、自动化测试和完整分篇教程。建议Fork / Clone下来边读边跑 https://github.com/bysbsh/ai-rag-learning-guide代码与教程同步更新对照每一篇动手实践效果最好。如果这份教程帮到了你点个Star就是对我最大的支持也方便你之后找回最新版本。遇到问题或发现错漏欢迎在仓库提 Issue / PR。项目采用 MIT 协议可自由学习与二次创作。
返回列表