Core model interfaces and abstractions for Spring AI framework providing portable API for chat, embeddings, images, audio, and tool calling across multiple AI providers
Vector embedding generation for text and documents, supporting batch processing, configurable dimensions, and integration with vector stores for semantic search and retrieval.
Main interface for generating embeddings from text and documents.
public interface EmbeddingModel extends Model<EmbeddingRequest, EmbeddingResponse> {
/**
* Generate embeddings for the given request.
*
* @param request the embedding request
* @return the embedding response with vectors
*/
EmbeddingResponse call(EmbeddingRequest request);
/**
* Embed a single text string.
*
* @param text the text to embed
* @return the embedding vector
*/
float[] embed(String text);
/**
* Embed a single document.
*
* @param document the document to embed
* @return the embedding vector
*/
float[] embed(Document document);
/**
* Embed multiple text strings.
*
* @param texts the list of texts to embed
* @return list of embedding vectors
*/
List<float[]> embed(List<String> texts);
/**
* Embed documents with options and batching strategy.
*
* @param documents the documents to embed
* @param options the embedding options
* @param strategy the batching strategy
* @return list of embedding vectors
*/
List<float[]> embed(
List<Document> documents,
EmbeddingOptions options,
BatchingStrategy strategy
);
/**
* Embed texts and get full response with metadata.
*
* @param texts the list of texts to embed
* @return the complete embedding response
*/
EmbeddingResponse embedForResponse(List<String> texts);
/**
* Get the dimensionality of embeddings produced by this model.
*
* @return the number of dimensions
*/
int dimensions();
}Model interface specifically for embedding documents.
public interface DocumentEmbeddingModel extends Model<DocumentEmbeddingRequest, EmbeddingResponse> {
/**
* Generate embeddings for documents.
*
* @param request the document embedding request
* @return the embedding response with vectors
*/
EmbeddingResponse call(DocumentEmbeddingRequest request);
}Request for generating embeddings from text strings.
public class EmbeddingRequest implements ModelRequest<List<String>> {
/**
* Construct an EmbeddingRequest with inputs and options.
*
* @param inputs the list of text strings to embed
* @param options the embedding options
*/
public EmbeddingRequest(List<String> inputs, EmbeddingOptions options);
/**
* Get the input texts to embed.
*
* @return list of input texts
*/
List<String> getInstructions();
/**
* Get the embedding options.
*
* @return the embedding options
*/
EmbeddingOptions getOptions();
}Request for generating embeddings from documents.
public class DocumentEmbeddingRequest implements ModelRequest<List<Document>> {
/**
* Construct a DocumentEmbeddingRequest with documents and options.
*
* @param documents the list of documents to embed
* @param options the embedding options
*/
public DocumentEmbeddingRequest(List<Document> documents, EmbeddingOptions options);
/**
* Get the documents to embed.
*
* @return list of documents
*/
List<Document> getInstructions();
/**
* Get the embedding options.
*
* @return the embedding options
*/
EmbeddingOptions getOptions();
}Response containing generated embeddings and metadata.
public class EmbeddingResponse implements ModelResponse<Embedding> {
/**
* Construct an EmbeddingResponse with embeddings.
*
* @param embeddings the list of embeddings
*/
public EmbeddingResponse(List<Embedding> embeddings);
/**
* Construct an EmbeddingResponse with embeddings and metadata.
*
* @param embeddings the list of embeddings
* @param metadata the response metadata
*/
public EmbeddingResponse(List<Embedding> embeddings, EmbeddingResponseMetadata metadata);
/**
* Get the first embedding.
*
* @return the first embedding
*/
Embedding getResult();
/**
* Get all embeddings.
*
* @return list of all embeddings
*/
List<Embedding> getResults();
/**
* Get response metadata.
*
* @return the embedding response metadata
*/
EmbeddingResponseMetadata getMetadata();
}Single embedding result containing a vector.
public class Embedding implements ModelResult<float[]> {
/**
* Construct an Embedding with vector and index.
*
* @param embedding the embedding vector
* @param index the index of this embedding in the batch
*/
public Embedding(float[] embedding, Integer index);
/**
* Construct an Embedding with vector, index, and metadata.
*
* @param embedding the embedding vector
* @param index the index of this embedding in the batch
* @param metadata the result metadata
*/
public Embedding(float[] embedding, Integer index, EmbeddingResultMetadata metadata);
/**
* Get the embedding vector.
*
* @return the float array representing the embedding
*/
float[] getOutput();
/**
* Get the index of this embedding in the batch.
*
* @return the index
*/
Integer getIndex();
/**
* Get result metadata.
*
* @return the embedding result metadata
*/
EmbeddingResultMetadata getMetadata();
}Options for configuring embedding generation.
public interface EmbeddingOptions extends ModelOptions {
/**
* Get the model name to use.
*
* @return the model name
*/
String getModel();
/**
* Get the desired embedding dimensions.
* Some models support variable dimensions.
*
* @return the number of dimensions, or null for model default
*/
Integer getDimensions();
/**
* Create a new options builder.
*
* @return a new builder
*/
static Builder builder();
/**
* Builder interface for constructing EmbeddingOptions.
*/
interface Builder {
/**
* Set the model name.
*
* @param model the model name
* @return this builder
*/
Builder model(String model);
/**
* Set the embedding dimensions.
*
* @param dimensions the number of dimensions
* @return this builder
*/
Builder dimensions(Integer dimensions);
/**
* Build the EmbeddingOptions.
*
* @return the constructed EmbeddingOptions
*/
EmbeddingOptions build();
}
}Default implementation of EmbeddingOptions.
public class DefaultEmbeddingOptions implements EmbeddingOptions {
// Default implementation with standard embedding options
}Metadata for embedding responses.
public class EmbeddingResponseMetadata extends AbstractResponseMetadata {
// Response-level metadata including usage information
}Metadata for individual embedding results.
public class EmbeddingResultMetadata implements ResultMetadata {
/**
* Empty metadata instance.
*/
public static EmbeddingResultMetadata EMPTY = new EmbeddingResultMetadata();
/**
* Construct an EmbeddingResultMetadata with default values.
*/
public EmbeddingResultMetadata();
/**
* Construct an EmbeddingResultMetadata with all details.
*
* @param documentId the document ID
* @param modalityType the modality type
* @param mimeType the MIME type
* @param documentData the document data
*/
public EmbeddingResultMetadata(
String documentId,
ModalityType modalityType,
MimeType mimeType,
Object documentData
);
/**
* Get the modality type.
*
* @return the modality type
*/
ModalityType getModalityType();
/**
* Get the MIME type.
*
* @return the MIME type
*/
MimeType getMimeType();
/**
* Get the document ID.
*
* @return the document ID
*/
String getDocumentId();
/**
* Get the document data.
*
* @return the document data
*/
Object getDocumentData();
/**
* Modality type enumeration.
*/
public enum ModalityType {
TEXT, IMAGE, AUDIO, VIDEO
}
}Abstract base class for implementing embedding models.
public abstract class AbstractEmbeddingModel implements EmbeddingModel {
// Base implementation with common embedding model functionality
}Contract for batching Document objects to optimize embedding token usage. Implementations split documents into sub-batches while preserving order for correct embedding mapping.
public interface BatchingStrategy {
/**
* Split a collection of Documents into optimized sub-batches.
* Order must be preserved for correct embedding-to-document mapping.
*
* @param documents the documents to batch
* @return list of sub-batches containing documents
*/
List<List<Document>> batch(List<Document> documents);
}import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.beans.factory.annotation.Autowired;
@Service
public class EmbeddingService {
@Autowired
private EmbeddingModel embeddingModel;
public float[] embedText(String text) {
// Simple embedding
return embeddingModel.embed(text);
}
public int getEmbeddingSize() {
return embeddingModel.dimensions();
}
}List<String> texts = List.of(
"The quick brown fox",
"jumps over the lazy dog",
"Machine learning is fascinating"
);
// Embed multiple texts
List<float[]> embeddings = embeddingModel.embed(texts);
// Process each embedding
for (int i = 0; i < embeddings.size(); i++) {
float[] embedding = embeddings.get(i);
System.out.println("Text " + i + " embedding dimensions: " + embedding.length);
}import org.springframework.ai.document.Document;
// Create documents
List<Document> documents = List.of(
new Document("First document content"),
new Document("Second document content"),
new Document("Third document content")
);
// Embed documents
List<float[]> embeddings = embeddingModel.embed(documents);
// Store embeddings back in documents
for (int i = 0; i < documents.size(); i++) {
documents.get(i).setEmbedding(embeddings.get(i));
}import org.springframework.ai.embedding.EmbeddingRequest;
import org.springframework.ai.embedding.EmbeddingOptions;
import org.springframework.ai.embedding.EmbeddingResponse;
// Create options
EmbeddingOptions options = EmbeddingOptions.builder()
.model("text-embedding-3-small")
.dimensions(512)
.build();
// Create request
List<String> texts = List.of("Hello", "World");
EmbeddingRequest request = new EmbeddingRequest(texts, options);
// Get response with metadata
EmbeddingResponse response = embeddingModel.call(request);
// Access embeddings
for (Embedding embedding : response.getResults()) {
float[] vector = embedding.getOutput();
Integer index = embedding.getIndex();
System.out.println("Embedding " + index + ": " + vector.length + " dimensions");
}// Embed two texts
float[] embedding1 = embeddingModel.embed("artificial intelligence");
float[] embedding2 = embeddingModel.embed("machine learning");
// Calculate cosine similarity
double similarity = cosineSimilarity(embedding1, embedding2);
System.out.println("Similarity: " + similarity);
// Helper method for cosine similarity
private double cosineSimilarity(float[] a, float[] b) {
double dotProduct = 0.0;
double normA = 0.0;
double normB = 0.0;
for (int i = 0; i < a.length; i++) {
dotProduct += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.document.Document;
@Service
public class SemanticSearchService {
private final EmbeddingModel embeddingModel;
private final List<Document> documentStore;
public SemanticSearchService(EmbeddingModel embeddingModel) {
this.embeddingModel = embeddingModel;
this.documentStore = new ArrayList<>();
}
public void indexDocuments(List<String> texts) {
// Create documents
List<Document> documents = texts.stream()
.map(Document::new)
.toList();
// Generate embeddings
List<float[]> embeddings = embeddingModel.embed(texts);
// Store documents with embeddings
for (int i = 0; i < documents.size(); i++) {
documents.get(i).setEmbedding(embeddings.get(i));
documentStore.add(documents.get(i));
}
}
public List<Document> search(String query, int topK) {
// Embed query
float[] queryEmbedding = embeddingModel.embed(query);
// Calculate similarities
return documentStore.stream()
.map(doc -> new ScoredDocument(
doc,
cosineSimilarity(queryEmbedding, doc.getEmbedding())
))
.sorted((a, b) -> Double.compare(b.score, a.score))
.limit(topK)
.map(sd -> sd.document)
.toList();
}
private static class ScoredDocument {
Document document;
double score;
ScoredDocument(Document document, double score) {
this.document = document;
this.score = score;
}
}
}import org.springframework.ai.embedding.EmbeddingOptions;
// Standard dimensions
EmbeddingOptions standardOpts = EmbeddingOptions.builder()
.model("text-embedding-3-small")
.build();
// Custom dimensions (if model supports it)
EmbeddingOptions customOpts = EmbeddingOptions.builder()
.model("text-embedding-3-small")
.dimensions(256) // Smaller for faster processing
.build();
EmbeddingRequest request = new EmbeddingRequest(
List.of("Sample text"),
customOpts
);
EmbeddingResponse response = embeddingModel.call(request);import org.springframework.ai.embedding.EmbeddingResponse;
// Get full response with metadata
EmbeddingResponse response = embeddingModel.embedForResponse(
List.of("text1", "text2", "text3")
);
// Access metadata
EmbeddingResponseMetadata metadata = response.getMetadata();
// Access individual embeddings with their metadata
for (Embedding embedding : response.getResults()) {
float[] vector = embedding.getOutput();
Integer index = embedding.getIndex();
EmbeddingResultMetadata resultMeta = embedding.getMetadata();
System.out.println("Embedding at index " + index);
}import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingOptions;
List<Document> documents = List.of(
new Document("Document 1 content"),
new Document("Document 2 content")
);
EmbeddingOptions options = EmbeddingOptions.builder()
.model("text-embedding-ada-002")
.build();
// Use batching strategy for large document sets
List<float[]> embeddings = embeddingModel.embed(
documents,
options,
null // Use default batching strategy
);import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class EmbeddingConfig {
@Bean
public EmbeddingOptions defaultEmbeddingOptions() {
return EmbeddingOptions.builder()
.model("text-embedding-3-small")
.dimensions(1536)
.build();
}
}