In Spring AI Vector Embedding tutorial, learn what is a vector or embedding, how it helps in semantic searches, and how to generate embeddings using popular LLM models such as OpenAI and Mistral.
1. What is a Vector Embedding?
In the context of LLMs, a vector (also called embedding) is an array of numbers that represent an object. The object can be a word, sentence, audio or video part, or even structured data such as a product description. Vectors are used to find the relatedness of an object with respect to other objects by finding the distance between two vectors. Small distances suggest high relatedness and large distances suggest low relatedness.
In a vector (array of numbers), each number is called a component and corresponds to a dimension in high dimensional space. Each dimension is a distinct feature or attribute of the data.
Let us take an example word “happiness“. Its vector embedding will be like [2.5, 1.3, 0.8]
. Each of the components in the vector represents a linguistic feature of the word.
- The first component, or 2.5, quantifies emotional positivity.
- The second component, or negative 1.3, shows the emotional intensity.
- The third component, or O, 0.8, represents the context where the word is used.
It is important to understand that the actual numbers within the vector are not meaningful on their own. It is the relative values and relationships between the numbers that capture the semantic information.
With this vector, the LLM can better understand and process the word ‘happiness’. This means that the same word can have different embeddings based on its contextual use. Note that the type of model you use will be critical in terms of the quality of the results.
2. Semantic or Similarity Search
Vectors are mostly used for similarity search i.e. finding the closeness of vectors in the embedding space. Instead of relying on exact word matches, semantic search can understand the context and semantics of a query. This can allow for much better results.
Similarity search is used in applications like RAG (Retrieval-Augmented Generation), search engines, recommendation engines, document management systems, etc. This semantic search enables Google to perform intelligent searches that deliver real answers or lead us to the very answer we are looking for on a web page; and sometimes it has nothing to do with the search query we used.
3. EmbeddingModel Interface
In Spring AI, EmbeddingModel interface is at the core of all embedding features. Its primary function is to convert text into numerical vectors (or embeddings). It provides embed() method that can accept different types of input (text, document, etc), call the configured backend embedding model, and return the generated vectors.
public interface EmbeddingModel extends Model<EmbeddingRequest, EmbeddingResponse> {
List<Double> embed(String text);
List<Double> embed(Document document);
EmbeddingResponse embedForResponse(List<String> texts);
EmbeddingResponse call(EmbeddingRequest request);
//...
}
The embedForResponse() method provides a more comprehensive output with additional information about the embeddings.
Given an EmbeddingModel bean, we can call its methods as follows:
String text = "...";
List<Double> embeddings = embeddingModel.embed(text);
To programmatically override the default values, we can supply them as follows:
String text = "...";
List<Double> embeddings = embeddingModel.call(
new EmbeddingRequest(List.of(text), OpenAiEmbeddingOptions.builder()
.withModel("text-embedding-3-small")
.withUser("jon.snow")
.build()))
.getResult().getOutput();
4. EmbeddingModel Implementations
Spring AI supports a large number of embedding models. For each model, a concrete implementation of EmbeddingModel interface is provided.
For the complete and current list of supported providers and models, please refer to the official guide.
Provider | Implementation Class | Supported Models |
---|---|---|
OpenAI | OpenAiEmbeddingModel | text-embedding-ada-002 text-embedding-3-large text-embedding-3-small |
Azure OpenAI | AzureOpenAiEmbeddingModel | text-embedding-ada-002 |
Ollama | OllamaEmbeddingModel | mistral |
PostgresML | PostgresMlEmbeddingModel | distilbert-base-uncased |
Mistral AI | MistralAiEmbeddingModel | mistral-embed |
MiniMax | MiniMaxEmbeddingModel | embo-01 |
QianFan | QianFanEmbeddingModel | bge_large_zh |
Amazon Bedrock Titan | BedrockTitanEmbeddingModel | amazon.titan-embed-image-v1 |
Amazon Bedrock Cohere | BedrockCohereEmbeddingModel | cohere.embed-multilingual-v3 |
5. Demo: Generate Vector Embedding with OpenAI
In this demo, we will use the OpenAiEmbeddingModel class to generate the vector embeddings using OpenAI’s text-embedding-ada-002 model. Please note the steps remain the same for other providers and models.
5.1. Maven
Start with adding spring-ai-openai-spring-boot-starter dependency which triggers the Spring Boot auto-configuration for the OpenAI Embedding Model. For complete information of setting up the project from scratch, please refer to Getting Started with Spring AI.
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
Also, do not forget to add the OpenAI API key to the properties file.
spring.ai.openai.api-key=${OPENAI_API_KEY}
5.2. OpenAiEmbeddingModel Bean
Once the spring-ai-openai-spring-boot-starter
dependency is found, Spring boot autoconfiguration will automatically create an OpenAiEmbeddingModel bean with default configuration values. We can inject this bean into a Spring managed class, and start using it.
@RestController
class EmbeddingController {
private final EmbeddingModel embeddingModel;
EmbeddingController(EmbeddingModel embeddingModel) {
this.embeddingModel = embeddingModel;
}
//...
}
To change anything into the default values, we can specify the respective properties in to application.properties file.
spring.ai.openai.embedding.options.model=text-embedding-3
spring.ai.openai.embedding.options.encodingFormat=base64 # float or base64
spring.ai.openai.embedding.options.user=howtodoinjava # representing the end-user to monitor and detect abuse
spring.ai.openai.embedding.options.dimensions=3000 # only supported in text-embedding-3 and later models
For the complete list of properties and default values, refer to the properties section.
5.3. Generating Embedding Vector
Once the OpenAiEmbeddingModel bean has been initialized, we can use its embed() method for generating the vectors from the supplied text or documents. Finally, these vectors are stored in a vector database.
By default, the length of the embedding vector will be 1536 for text-embedding-3-small or 3072 for text-embedding-3-large.
@RestController
class EmbeddingController {
@Autowired
EmbeddingModel embeddingModel;
@PostMapping("/embed")
Response embed(@RequestBody String message) {
var embeddings = embeddingModel.embed(message);
return new Response(embeddings.size(), embeddings);
}
}
record Response(int dimension, List<Double> vector){
}
Invoke the API in any REST testing tool and verify the response:

6. Summary
This Spring AI vector embedding example discussed the following:
- A vector or embedding is an array of numbers that represent an object such as a word, sentence, or audio/video part.
- Semantic search is referred to as finding the closeness of vectors in the multi-dimensional embedding space.
- The basics of the EmbeddingModel interface and its methods.
- Most common embedding models and their respective implementation classes to access them.
- How the EmbeddingModel bean is initialized with default configuration, and how we can override them in the properties file.
- Finally, we saw a demo of generating the vector embeddings using OpenAI’s text-embedding-3-small model and OpenAiEmbeddingModel bean.
Happy Learning !!
Comments