Skip to content

Commit eed03e6

Browse files
committed
Require essential dependencies in vector store builder constructors
This commit refactors the builder pattern implementation across all VectorStore implementations to make the EmbeddingModel a required constructor parameter rather than an optional builder method. Key changes include: - Move embeddingModel from being a builder method to a required constructor parameter - Make embeddingModel final in AbstractVectorStoreBuilder - Remove redundant validate() methods since EmbeddingModel validation now happens in constructor - Update all VectorStore builder instantiations to pass EmbeddingModel in builder creation - Add @nullable annotations to appropriate methods in VectorStore interface This change improves the API design by: 1. Enforcing that EmbeddingModel is provided at builder creation time 2. Removing the possibility of forgotten EmbeddingModel configuration 3. Simplifying the builder implementation by moving validation to construction 4. Making the dependency on EmbeddingModel more explicit in the API Breaking Changes: - VectorStore builders must now be created with an EmbeddingModel parameter - The embeddingModel() builder method has been removed from all implementations
1 parent 2e5ee43 commit eed03e6

File tree

101 files changed

+382
-581
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+382
-581
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2023-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Provides the API for embedding observations.
19+
*/
20+
@NonNullApi
21+
@NonNullFields
22+
package org.springframework.ai.embedding;
23+
24+
import org.springframework.lang.NonNullApi;
25+
import org.springframework.lang.NonNullFields;

spring-ai-core/src/main/java/org/springframework/ai/vectorstore/AbstractVectorStoreBuilder.java

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,18 @@
3333
public abstract class AbstractVectorStoreBuilder<T extends AbstractVectorStoreBuilder<T>>
3434
implements VectorStore.Builder<T> {
3535

36-
protected EmbeddingModel embeddingModel;
36+
protected final EmbeddingModel embeddingModel;
3737

3838
protected ObservationRegistry observationRegistry = ObservationRegistry.NOOP;
3939

4040
@Nullable
4141
protected VectorStoreObservationConvention customObservationConvention;
4242

43+
public AbstractVectorStoreBuilder(EmbeddingModel embeddingModel) {
44+
Assert.notNull(embeddingModel, "EmbeddingModel must be configured");
45+
this.embeddingModel = embeddingModel;
46+
}
47+
4348
public EmbeddingModel getEmbeddingModel() {
4449
return this.embeddingModel;
4550
}
@@ -71,20 +76,9 @@ public T observationRegistry(ObservationRegistry observationRegistry) {
7176
}
7277

7378
@Override
74-
public T customObservationConvention(VectorStoreObservationConvention convention) {
79+
public T customObservationConvention(@Nullable VectorStoreObservationConvention convention) {
7580
this.customObservationConvention = convention;
7681
return self();
7782
}
7883

79-
@Override
80-
public T embeddingModel(EmbeddingModel embeddingModel) {
81-
Assert.notNull(embeddingModel, "EmbeddingModel must not be null");
82-
this.embeddingModel = embeddingModel;
83-
return self();
84-
}
85-
86-
protected void validate() {
87-
Assert.notNull(this.embeddingModel, "EmbeddingModel must be configured");
88-
}
89-
9084
}

spring-ai-core/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStore.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ public SimpleVectorStore(EmbeddingModel embeddingModel) {
9292
@Deprecated(forRemoval = true, since = "1.0.0-M5")
9393
public SimpleVectorStore(EmbeddingModel embeddingModel, ObservationRegistry observationRegistry,
9494
VectorStoreObservationConvention customObservationConvention) {
95-
this(builder().embeddingModel(embeddingModel)
96-
.observationRegistry(observationRegistry)
95+
this(builder(embeddingModel).observationRegistry(observationRegistry)
9796
.customObservationConvention(customObservationConvention));
9897
}
9998

@@ -106,8 +105,8 @@ protected SimpleVectorStore(SimpleVectorStoreBuilder builder) {
106105
* Creates an instance of SimpleVectorStore builder.
107106
* @return the SimpleVectorStore builder.
108107
*/
109-
public static SimpleVectorStoreBuilder builder() {
110-
return new SimpleVectorStoreBuilder();
108+
public static SimpleVectorStoreBuilder builder(EmbeddingModel embeddingModel) {
109+
return new SimpleVectorStoreBuilder(embeddingModel);
111110
}
112111

113112
@Override
@@ -297,9 +296,12 @@ public static float norm(float[] vector) {
297296

298297
public static final class SimpleVectorStoreBuilder extends AbstractVectorStoreBuilder<SimpleVectorStoreBuilder> {
299298

299+
private SimpleVectorStoreBuilder(EmbeddingModel embeddingModel) {
300+
super(embeddingModel);
301+
}
302+
300303
@Override
301304
public SimpleVectorStore build() {
302-
validate();
303305
return new SimpleVectorStore(this);
304306
}
305307

spring-ai-core/src/main/java/org/springframework/ai/vectorstore/VectorStore.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
import org.springframework.ai.document.Document;
2525
import org.springframework.ai.document.DocumentWriter;
26-
import org.springframework.ai.embedding.EmbeddingModel;
2726
import org.springframework.ai.vectorstore.observation.DefaultVectorStoreObservationConvention;
2827
import org.springframework.ai.vectorstore.observation.VectorStoreObservationConvention;
2928
import org.springframework.lang.Nullable;
@@ -59,6 +58,7 @@ default void accept(List<Document> documents) {
5958
* @param idList list of document ids for which documents will be removed.
6059
* @return Returns true if the documents were successfully deleted.
6160
*/
61+
@Nullable
6262
Optional<Boolean> delete(List<String> idList);
6363

6464
/**
@@ -68,6 +68,7 @@ default void accept(List<Document> documents) {
6868
* topK, similarity threshold and metadata filter expressions.
6969
* @return Returns documents th match the query request conditions.
7070
*/
71+
@Nullable
7172
List<Document> similaritySearch(SearchRequest request);
7273

7374
/**
@@ -77,6 +78,7 @@ default void accept(List<Document> documents) {
7778
* @return Returns a list of documents that have embeddings similar to the query text
7879
* embedding.
7980
*/
81+
@Nullable
8082
default List<Document> similaritySearch(String query) {
8183
return this.similaritySearch(SearchRequest.query(query));
8284
}
@@ -90,8 +92,6 @@ default List<Document> similaritySearch(String query) {
9092
*/
9193
interface Builder<T extends Builder<T>> {
9294

93-
T embeddingModel(EmbeddingModel embeddingModel);
94-
9595
/**
9696
* Sets the registry for collecting observations and metrics. Defaults to
9797
* {@link ObservationRegistry#NOOP} if not specified.

spring-ai-core/src/main/java/org/springframework/ai/vectorstore/observation/AbstractObservationVectorStore.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ public abstract class AbstractObservationVectorStore implements VectorStore {
4545
@Nullable
4646
private final VectorStoreObservationConvention customObservationConvention;
4747

48-
@Nullable
4948
protected final EmbeddingModel embeddingModel;
5049

5150
/**
@@ -59,8 +58,7 @@ public AbstractObservationVectorStore(ObservationRegistry observationRegistry,
5958
this(null, observationRegistry, customObservationConvention);
6059
}
6160

62-
private AbstractObservationVectorStore(@Nullable EmbeddingModel embeddingModel,
63-
ObservationRegistry observationRegistry,
61+
private AbstractObservationVectorStore(EmbeddingModel embeddingModel, ObservationRegistry observationRegistry,
6462
@Nullable VectorStoreObservationConvention customObservationConvention) {
6563
this.embeddingModel = embeddingModel;
6664
this.observationRegistry = observationRegistry;
@@ -94,6 +92,7 @@ public void add(List<Document> documents) {
9492
}
9593

9694
@Override
95+
@Nullable
9796
public Optional<Boolean> delete(List<String> deleteDocIds) {
9897

9998
VectorStoreObservationContext observationContext = this
@@ -107,6 +106,7 @@ public Optional<Boolean> delete(List<String> deleteDocIds) {
107106
}
108107

109108
@Override
109+
@Nullable
110110
public List<Document> similaritySearch(SearchRequest request) {
111111

112112
VectorStoreObservationContext searchObservationContext = this

spring-ai-core/src/test/java/org/springframework/ai/vectorstore/SimpleVectorStoreTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ void setUp() {
5757
when(this.mockEmbeddingModel.dimensions()).thenReturn(3);
5858
when(this.mockEmbeddingModel.embed(any(String.class))).thenReturn(new float[] { 0.1f, 0.2f, 0.3f });
5959
when(this.mockEmbeddingModel.embed(any(Document.class))).thenReturn(new float[] { 0.1f, 0.2f, 0.3f });
60-
this.vectorStore = new SimpleVectorStore(SimpleVectorStore.builder().embeddingModel(this.mockEmbeddingModel));
60+
this.vectorStore = new SimpleVectorStore(SimpleVectorStore.builder(this.mockEmbeddingModel));
6161
}
6262

6363
@Test

spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/azure/AzureVectorStoreAutoConfiguration.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,7 @@ public AzureVectorStore vectorStore(SearchIndexClient searchIndexClient, Embeddi
8484
ObjectProvider<VectorStoreObservationConvention> customObservationConvention,
8585
BatchingStrategy batchingStrategy) {
8686

87-
var builder = AzureVectorStore.builder()
88-
.searchIndexClient(searchIndexClient)
89-
.embeddingModel(embeddingModel)
87+
var builder = AzureVectorStore.builder(searchIndexClient, embeddingModel)
9088
.initializeSchema(properties.isInitializeSchema())
9189
.filterMetadataFields(List.of())
9290
.observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))

spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/cassandra/CassandraVectorStoreAutoConfiguration.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public CassandraVectorStore vectorStore(EmbeddingModel embeddingModel, Cassandra
6262
ObjectProvider<VectorStoreObservationConvention> customObservationConvention,
6363
BatchingStrategy batchingStrategy) {
6464

65-
return CassandraVectorStore.builder()
65+
return CassandraVectorStore.builder(embeddingModel)
6666
.session(cqlSession)
6767
.keyspace(properties.getKeyspace())
6868
.table(properties.getTable())
@@ -72,7 +72,6 @@ public CassandraVectorStore vectorStore(EmbeddingModel embeddingModel, Cassandra
7272
.fixedThreadPoolExecutorSize(properties.getFixedThreadPoolExecutorSize())
7373
.disallowSchemaChanges(!properties.isInitializeSchema())
7474
.returnEmbeddings(properties.getReturnEmbeddings())
75-
.embeddingModel(embeddingModel)
7675
.observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))
7776
.customObservationConvention(customObservationConvention.getIfAvailable(() -> null))
7877
.batchingStrategy(batchingStrategy)

spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/chroma/ChromaVectorStoreAutoConfiguration.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,7 @@ public ChromaVectorStore vectorStore(EmbeddingModel embeddingModel, ChromaApi ch
8686
ChromaVectorStoreProperties storeProperties, ObjectProvider<ObservationRegistry> observationRegistry,
8787
ObjectProvider<VectorStoreObservationConvention> customObservationConvention,
8888
BatchingStrategy chromaBatchingStrategy) {
89-
return ChromaVectorStore.builder()
90-
.chromaApi(chromaApi)
91-
.embeddingModel(embeddingModel)
89+
return ChromaVectorStore.builder(chromaApi, embeddingModel)
9290
.collectionName(storeProperties.getCollectionName())
9391
.initializeSchema(storeProperties.isInitializeSchema())
9492
.observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))

spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/vectorstore/elasticsearch/ElasticsearchVectorStoreAutoConfiguration.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,8 @@ ElasticsearchVectorStore vectorStore(ElasticsearchVectorStoreProperties properti
7373
elasticsearchVectorStoreOptions.setSimilarity(properties.getSimilarity());
7474
}
7575

76-
return ElasticsearchVectorStore.builder()
77-
.restClient(restClient)
76+
return ElasticsearchVectorStore.builder(restClient, embeddingModel)
7877
.options(elasticsearchVectorStoreOptions)
79-
.embeddingModel(embeddingModel)
8078
.initializeSchema(properties.isInitializeSchema())
8179
.observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))
8280
.customObservationConvention(customObservationConvention.getIfAvailable(() -> null))

0 commit comments

Comments
 (0)