SpringBoot3+LangChain4j+Qdrant RAG 开发踩坑两篇经典异常总结
技术栈:JDK17 + SpringBoot3.x + LangChain4j + Qdrant (Docker 部署) + 通义千问 text-embedding-v3(固定1024 维向量) 场景:向量 add 入库正常,调用
search()检索连续报错,先后踩坑「集合不存在」「向量长度 0 vs 1024 不匹配」两大经典问题,最终靠升级依赖解决。
一、依赖版本变化
报错版本(出问题)
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-qdrant</artifactId>
<version>1.0.1-beta6</version>
</dependency>
最终可用版本(修复全部异常)
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-qdrant</artifactId>
<version>1.12.1-beta21</version>
</dependency>
二、坑 1:NOT_FOUND: Collection xxx doesn't exist! 集合不存在异常
1. 异常现象
调用embeddingStore.add(Embedding)向量入库直接抛出 grpc 异常:
plaintext
io.grpc.StatusRuntimeException: NOT_FOUND: Not found: Collection `test-qdrant` doesn't exist!
误区:以为 LangChain4j 自动创建 Qdrant 集合,直接 add 数据即可。
2. 报错根因
langchain4j-qdrant:1.0.1-beta6底层不会自动创建 Collection 集合,Qdrant 库无对应集合时无法写入向量;- Qdrant 规则:必须先手动创建集合,指定向量维度 + 距离算法,维度和 Embedding 模型输出完全一致(本例 1024),才能插入向量。
3. 解决方案(二选一)
方案 1:项目启动自动初始化集合(推荐代码实现)
通过原生QdrantClient做幂等创建,项目启动校验集合,不存在则新建:
java
运行
import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.Collections;
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
import javax.annotation.Resource;
@Component
public class QdrantInit {
@Resource
private QdrantClient qdrantClient;
private final String COLL_NAME = "test-qdrant";
// 与embedding模型输出维度保持一致:1024
private final int VEC_SIZE = 1024;
@PostConstruct
public void initColl() throws Exception {
boolean exist = qdrantClient.collectionExistsAsync(COLL_NAME).get();
if (!exist) {
Collections.VectorParams params = Collections.VectorParams.newBuilder()
.setSize(VEC_SIZE)
.setDistance(Collections.Distance.COSINE)
.build();
qdrantClient.createCollectionAsync(COLL_NAME, params).get();
}
}
}
方案 2:可视化面板手动创建
打开 Qdrant WebUI(默认http://ip:6333/dashboard),手动新建集合:
- 集合名:
test-qdrant - 向量维度:
1024 - 距离度量:
Cosine(余弦)
总结铁律:Qdrant:先建集合,后存向量。
三、坑 2:Length of vector a (0) must be equal to the length of vector b (1024) 向量长度不匹配
1. 异常现象
集合创建成功、向量 add 入库正常,控制台打印查询生成向量是标准 1024 维非空,执行embeddingStore.search()直接报错:
plaintext
java.lang.IllegalArgumentException: Length of vector a (0) must be equal to the length of vector b (1024)
关键日志:
- 入参查询向量:维度 = 1024(正常)
- 从 Qdrant 库中取出向量:数组长度 = 0(空数组)
2. 底层原理 & 报错根源
- Qdrant 原生 gRPC 搜索默认配置:
with_vectors=falseQdrant 为节省网络带宽,检索接口默认不返回库中存储的原始向量,只返回 id、score、payload,向量字段为空; - 旧版 1.0.1-beta6 SDK 存在 BUG langchain4j-qdrant 底层
search()方法没有拼接with_vectors=true参数,无法拉取库内向量,拿到float[] length=0空数组; - LangChain4j 内部余弦计算:
查询向量(1024维) VS 库向量(0维)→ 长度不一致抛异常。
重点:入库数据本身是 1024 维没问题,只是查询时 SDK 没有拉取库向量。
3. 两种落地解决方案
方案 1:升级依赖(本人最终方案,最简)
升级langchain4j-qdrant到1.12.1-beta21,新版本修复底层逻辑:
新版 search 请求自动添加
with_vectors=true,强制 Qdrant 返回完整存储向量,两边都是 1024 维,余弦计算正常,异常消失。
方案 2:旧版本兼容方案(不升级依赖)
放弃 LangChain4j 封装的embeddingStore.search(),使用原生QdrantClient手写检索,手动配置 withVectors (true),强制返回向量。
四、整套避坑总结
1. Qdrant 通用规范
- 先建集合,再插入向量,集合 size 必须严格等于 Embedding 模型输出维度(384/768/1024/1536);
- Qdrant 搜索默认不返回向量,对接 SDK 检索必须开启
with_vectors=true; - 更换 Embedding 模型(维度变更),必须删除旧集合,重建对应维度集合。
2. LangChain4j-Qdrant 版本选型建议
- 避坑黑名单:
1.0.0 ~ 1.0.1-beta6,存在不自动拉取库向量底层 BUG; - 推荐版本:
1.12.x-beta20+,官方修复 Qdrant 交互参数问题。
3. 调试排错小技巧
- 向量报错优先打印两处日志:查询向量维度、入库向量维度;
- 使用 Qdrant WebUI 查看集合参数、存量数据,快速区分「入库异常」or「SDK 查询异常」。
五、补充:Controller 简易查询代码
java
运行
@RestController
@RequestMapping("/emb")
public class EmbeddingController {
@Resource
private EmbeddingStore<TextEmbedding> embeddingStore;
@Resource
private EmbeddingModel embeddingModel;
@GetMapping("/query1")
public Object query1(String content) {
// 生成查询向量,打印维度调试
Embedding embedding = embeddingModel.embed(content).content();
System.out.println("向量维度:"+embedding.dimension());
// 相似度检索
List<EmbeddingMatch<TextEmbedding>> list = embeddingStore.search(EmbeddingSearchRequest.builder()
.queryEmbedding(embedding)
.maxResults(3)
.build()).matches();
return list;
}
}
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)