You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Extract VectorStoreRetriever interface from VectorStore (#3827)
- Created new VectorStoreRetriever functional interface for read-only operations
- Modified VectorStore to extend VectorStoreRetriever
- Removed duplicate similaritySearch methods from VectorStore
- Updated API documentation to reflect the interface separation
- Added package-info.java documentation for clarity
This change follows the principle of least privilege by providing a read-only
interface for retrieval operations while maintaining the full functionality
in VectorStore.
Fixes#1290
Signed-off-by: Mark Pollack <[email protected]>
@@ -22,12 +22,32 @@ The last section is intended to demystify the underlying approach of similarity
22
22
== API Overview
23
23
This section serves as a guide to the `VectorStore` interface and its associated classes within the Spring AI framework.
24
24
25
-
Spring AI offers an abstracted API for interacting with vector databases through the `VectorStore` interface.
25
+
Spring AI offers an abstracted API for interacting with vector databases through the `VectorStore` interface and its read-only counterpart, the `VectorStoreRetriever` interface.
26
26
27
-
Here is the `VectorStore` interface definition:
27
+
=== VectorStoreRetriever Interface
28
+
29
+
Spring AI provides a read-only interface called `VectorStoreRetriever` that exposes only the document retrieval functionality:
This functional interface is designed for use cases where you only need to retrieve documents from a vector store without performing any mutation operations. It follows the principle of least privilege by exposing only the necessary functionality for document retrieval.
44
+
45
+
=== VectorStore Interface
46
+
47
+
The `VectorStore` interface extends `VectorStoreRetriever` and adds mutation capabilities:
28
48
29
49
```java
30
-
public interface VectorStore extends DocumentWriter {
50
+
public interface VectorStore extends DocumentWriter, VectorStoreRetriever {
31
51
32
52
default String getName() {
33
53
return this.getClass().getSimpleName();
@@ -41,17 +61,15 @@ public interface VectorStore extends DocumentWriter {
The `VectorStore` interface combines both read and write operations, allowing you to add, delete, and search for documents in a vector database.
71
+
72
+
=== SearchRequest Builder
55
73
56
74
```java
57
75
public class SearchRequest {
@@ -392,32 +410,163 @@ For example, with OpenAI's ChatGPT, we use the `OpenAiEmbeddingModel` and a mode
392
410
393
411
The Spring Boot starter's auto-configuration for OpenAI makes an implementation of `EmbeddingModel` available in the Spring application context for dependency injection.
394
412
395
-
The general usage of loading data into a vector store is something you would do in a batch-like job, by first loading data into Spring AI's `Document` class and then calling the `save` method.
413
+
=== Writing to a Vector Store
414
+
415
+
The general usage of loading data into a vector store is something you would do in a batch-like job, by first loading data into Spring AI's `Document` class and then calling the `add` method on the `VectorStore` interface.
396
416
397
417
Given a `String` reference to a source file that represents a JSON file with data we want to load into the vector database, we use Spring AI's `JsonReader` to load specific fields in the JSON, which splits them up into small pieces and then passes those small pieces to the vector store implementation.
398
418
The `VectorStore` implementation computes the embeddings and stores the JSON and the embedding in the vector database:
399
419
400
420
```java
401
-
@Autowired
402
-
VectorStore vectorStore;
403
-
404
-
void load(String sourceFile) {
405
-
JsonReader jsonReader = new JsonReader(new FileSystemResource(sourceFile),
Later, when a user question is passed into the AI model, a similarity search is done to retrieve similar documents, which are then "'stuffed'" into the prompt as context for the user's question.
432
+
=== Reading from a Vector Store
433
+
434
+
Later, when a user question is passed into the AI model, a similarity search is done to retrieve similar documents, which are then "stuffed" into the prompt as context for the user's question.
435
+
436
+
For read-only operations, you can use either the `VectorStore` interface or the more focused `VectorStoreRetriever` interface:
This separation of concerns helps create more maintainable and secure applications by limiting access to mutation operations only to components that truly need them.
492
+
493
+
== Retrieval Operations with VectorStoreRetriever
494
+
495
+
The `VectorStoreRetriever` interface provides a read-only view of a vector store, exposing only the similarity search functionality. This follows the principle of least privilege and is particularly useful in RAG (Retrieval-Augmented Generation) applications where you only need to retrieve documents without modifying the underlying data.
496
+
497
+
=== Benefits of Using VectorStoreRetriever
498
+
499
+
1. **Separation of Concerns**: Clearly separates read operations from write operations.
500
+
2. **Interface Segregation**: Clients that only need retrieval functionality aren't exposed to mutation methods.
501
+
3. **Functional Interface**: Can be implemented with lambda expressions or method references for simple use cases.
502
+
4. **Reduced Dependencies**: Components that only need to perform searches don't need to depend on the full `VectorStore` interface.
503
+
504
+
=== Example Usage
505
+
506
+
You can use `VectorStoreRetriever` directly when you only need to perform similarity searches:
507
+
508
+
```java
509
+
@Service
510
+
public class DocumentRetrievalService {
511
+
512
+
private final VectorStoreRetriever retriever;
513
+
514
+
public DocumentRetrievalService(VectorStoreRetriever retriever) {
515
+
this.retriever = retriever;
516
+
}
517
+
518
+
public List<Document> findSimilarDocuments(String query) {
519
+
return retriever.similaritySearch(query);
520
+
}
521
+
522
+
public List<Document> findSimilarDocumentsWithFilters(String query, String country) {
523
+
SearchRequest request = SearchRequest.builder()
524
+
.query(query)
525
+
.topK(5)
526
+
.filterExpression("country == '" + country + "'")
527
+
.build();
528
+
529
+
return retriever.similaritySearch(request);
530
+
}
531
+
}
532
+
```
533
+
534
+
In this example, the service only depends on the `VectorStoreRetriever` interface, making it clear that it only performs retrieval operations and doesn't modify the vector store.
535
+
536
+
=== Integration with RAG Applications
537
+
538
+
The `VectorStoreRetriever` interface is particularly useful in RAG applications, where you need to retrieve relevant documents to provide context for an AI model:
539
+
540
+
```java
541
+
@Service
542
+
public class RagService {
543
+
544
+
private final VectorStoreRetriever retriever;
545
+
private final ChatModel chatModel;
546
+
547
+
public RagService(VectorStoreRetriever retriever, ChatModel chatModel) {
548
+
this.retriever = retriever;
549
+
this.chatModel = chatModel;
550
+
}
551
+
552
+
public String generateResponse(String userQuery) {
0 commit comments