一、背景
学习SpringAi框架时使用ChromaDb作为向量数据库,使用过程中并非一帆风顺,此文便是记录一下使用中的问题以及排查过程。环境如下
| ChromaDb | docker版本:latest |
|---|---|
| SpringAi | 1.0.0.2 |
二、问题
2.1 需要显性创建数据库
未通过Chroma提供的Swagger Api 显式创建 Collection,直接通过Spirng Ai 官网所写配置参数启动项目时,不会创建相应 Collection,从而导致项目启动失败。可以通过源码观察,其封装 Rest 请求获取 Chroma 的连接
@Nullable
public Collection getCollection(String tenantName, String databaseName, String collectionName) {
try {
return this.restClient.get()
.uri("/api/v2/tenants/{tenant_name}/databases/{database_name}/collections/{collection_name}",
tenantName, databaseName, collectionName)
.headers(this::httpHeaders)
.retrieve()
.toEntity(Collection.class)
.getBody();
}
catch (HttpServerErrorException | HttpClientErrorException e) {
String msg = this.getErrorMessage(e);
if (String.format("Collection [%s] does not exists", collectionName).equals(msg)) {
return null;
}
throw new RuntimeException(msg, e);
}
}
Swagger Api文档为: http://部署ip:8000/docs,如下图:
2.2 已创建并配置 Collection,仍然 404
由于Chroma还有两个概念,**tenant** 和 **database**,所以需要创建并配置此两项。再启动时,发现初始化创建与 ChromaDb 服务端的连接时,其 tenant 和 database 未生效,还是默认值。由于是通过配置类(ChromaVectorStoreProperties)进行管理,肯定会有一个Spring自动配置类将其注入Spring容器进行管理。可以看到在ChromaVectorStoreAutoConfiguration类中注入ChromaVectorStore过程中仅赋值collectionName属性,而根据Api文档,三个参数都是路径参数是必需的。
@Bean
@ConditionalOnMissingBean
public ChromaVectorStore vectorStore(EmbeddingModel embeddingModel, ChromaApi chromaApi,
ChromaVectorStoreProperties storeProperties, ObjectProvider<ObservationRegistry> observationRegistry,
ObjectProvider<VectorStoreObservationConvention> customObservationConvention,
BatchingStrategy chromaBatchingStrategy) {
return ChromaVectorStore.builder(chromaApi, embeddingModel)
.collectionName(storeProperties.getCollectionName())
.initializeSchema(storeProperties.isInitializeSchema())
.observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))
.customObservationConvention(customObservationConvention.getIfAvailable(() -> null))
.batchingStrategy(chromaBatchingStrategy)
.build();
}
解决方案,在项目中自定义注入ChromaVectorStore即可。
@Bean
public ChromaVectorStore vectorStore(EmbeddingModel embeddingModel, ChromaApi chromaApi,
ChromaVectorStoreProperties storeProperties, ObjectProvider<ObservationRegistry> observationRegistry,
ObjectProvider<VectorStoreObservationConvention> customObservationConvention,
BatchingStrategy chromaBatchingStrategy) {
return ChromaVectorStore.builder(chromaApi, embeddingModel)
.tenantName(storeProperties.getTenantName())
.databaseName(storeProperties.getDatabaseName())
.collectionName(storeProperties.getCollectionName())
.initializeSchema(storeProperties.isInitializeSchema())
.observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))
.customObservationConvention(customObservationConvention.getIfAvailable(() -> null))
.batchingStrategy(chromaBatchingStrategy)
.build();
}
三、结语
通过对框架代码进行分析以及Debug慢慢解决问题,使我收获良多。其次现在AI相关更新迭代太快,此次可能就是chromaDb一直在迭代,从而导致使用的版本框架代码报错,所以这也是记录本文的原因,希望能帮助大家。参考资料: