Vector Embeddings
Vector embeddings convert unstructured content (text, images, and so on) into numeric vectors that encode semantics (meaning). Comparing these vectors enables semantic search, recommendations, and enhanced generative AI features in your CAP application. For example retrieving related records, ranking results by relevance, or augmenting prompts for LLMs.
Choose an Embedding Model
Choose an embedding model that fits your use case and data (for example English or multilingual text). The model determines the number of dimensions of the resulting output vector. Check the documentation of the respective embedding model for details.
Use the SAP Generative AI Hub for unified consumption of embedding models and LLMs across different vendors and open-source models. Check for available models on the SAP AI Launchpad.
Add Embeddings to Your CDS Model
Use the built-in CDL Vector type in your CDS model to store embeddings. Set the vector dimensions to match the embedding model (for example, 768 for SAP_GXY.20250407).
extend Incidents with {
embedding : Vector(768);
}Generate Embeddings
Use an embedding model to convert your data (for example, incident titles and summaries) into vectors.
Evolve embeddings with your model
Store embeddings when you create or update your data. Regenerate embeddings if you change your embedding model.
Generate Embeddings on the Database
To generate vector embeddings on write in SAP HANA, you can use the vector_embedding function as calculated element on-write with embedding models from SAP HANA NLP or a configured remote source from SAP AI Core:
extend Incidents with {
@cds.api.ignore
embedding : Vector(768) = vector_embedding(
'Title: ' || title || ', Summary: ' || summary,
'DOCUMENT', 'SAP_GXY.20250407'
) stored;
}Prefer calculated elements for vector embeddings
If the database calculates vector embeddings on write it automatically regenerates the embedding if the input data changes.
Local Testing with H2 and SQLite
On H2 and SQLite the CQL.vectorEmbedding function is emulated to support local testing.
Java only and Beta
The vector_embedding function is currently in beta and only supported by the CAP Java runtime.
Learn more about Vector Embeddings in CAP Java
Generate Embeddings Programmatically
Alternatively, you can compute vector embeddings in your application layer using the SAP Cloud SDK for AI to call SAP AI Core services for generating embeddings.
Example using SAP Cloud SDK for AI
var aiClient = OpenAiClient.forModel(OpenAiModel.TEXT_EMBEDDING_3_SMALL);
var response = aiClient.embedding(
new OpenAiEmbeddingRequest(List.of(book.getDescription())));
book.setEmbedding(CdsVector.of(response.getEmbeddingVectors().get(0)));Use SAP Cloud SDK for AI
Use the SAP Cloud SDK for AI for unified access to embedding models and large language models (LLMs) from SAP AI Core.
Learn more about the SAP Cloud SDK for AI (Java) or the SAP Cloud SDK for AI (JavaScript)
Query for Similarity
At runtime, use vector functions to search for similar items. In an example Retrieval-Augmented Generation (RAG) scenario, use CQL.cosineSimilarity to enhance the context of a user query for the LLM. First, compute the vector embedding of the user query and use it to find related incidents.
// Compute embedding for user question
var query = CQL.val(
"Any incidents with solar inverters this month? How were they resolved?");
var embedding = CQL.vectorEmbedding(query, TextType.QUERY, "SAP_GXY.20250407");
// Compute similarity between user question and incident embeddings
var similarity = CQL.cosineSimilarity(CQL.get(Incidents.EMBEDDING), embedding);
// Find Incidents related to user question ordered by relevance
Select.from(INCIDENTS)
.columns(i -> similarity.times(100).as("relevance"),
i -> i.ID(), i -> i.title(), i -> i.summary(), i -> i.date())
.where(i -> similarity.gt(0.75))
.orderBy(i -> i.get("relevance").desc());const response = await new AzureOpenAiEmbeddingClient(
'text-embedding-3-small'
).run({
input: 'Any incidents with solar inverters this month? How were they resolved?'
});
const questionEmbedding = response.getEmbedding();
let similarIncidents = await SELECT.from('Incidents')
.where`cosine_similarity(embedding, to_real_vector(${questionEmbedding})) > 0.75`;