|
| 1 | +--- |
| 2 | +label: Vector Embeddings |
| 3 | +--- |
| 4 | +# Vector Embeddings |
| 5 | + |
| 6 | +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. |
| 7 | + |
| 8 | +## Choose an Embedding Model |
| 9 | + |
| 10 | +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. |
| 11 | + |
| 12 | +Use the [SAP Generative AI Hub](https://www.sap.com/products/artificial-intelligence/generative-ai-hub.html) for unified consumption of embedding models and LLMs across different vendors and open-source models. Check for available models on the [SAP AI Launchpad](https://help.sap.com/docs/ai-launchpad/sap-ai-launchpad-user-guide/models-and-scenarios-in-generative-ai-hub-fef463b24bff4f44a33e98bb1e4f3148#models). |
| 13 | + |
| 14 | +## Add Embeddings to Your CDS Model |
| 15 | +Use the built-in CDL [Vector type](../../cds/types) in your CDS model to store embeddings. Set the vector dimensions to match the embedding model (for example, 768 for *SAP_GXY.20250407*). |
| 16 | + |
| 17 | +```cds |
| 18 | +extend Incidents with { |
| 19 | + embedding : Vector(768); |
| 20 | +} |
| 21 | +``` |
| 22 | + |
| 23 | +## Generate Embeddings |
| 24 | +Use an embedding model to convert your data (for example, incident titles and summaries) into vectors. |
| 25 | + |
| 26 | +:::warning Evolve embeddings with your model |
| 27 | +Store embeddings when you create or update your data. Regenerate embeddings if you change your embedding model. |
| 28 | +::: |
| 29 | + |
| 30 | +### Generate Embeddings on the Database |
| 31 | + |
| 32 | +To generate vector embeddings on write in SAP HANA, you can use the [vector_embedding](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-sql-reference-guide/vector-embedding-function-vector) function as calculated element [on-write](../../cds/cdl#on-write) with embedding models from [SAP HANA NLP](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-vector-engine-guide/creating-text-embeddings-with-nlp-51eb170d038d4099a9bbb85c08fda888) or a configured remote source from SAP AI Core: |
| 33 | + |
| 34 | +```cds |
| 35 | +extend Incidents with { |
| 36 | + @cds.api.ignore |
| 37 | + embedding : Vector(768) = vector_embedding( |
| 38 | + 'Title: ' || title || ', Summary: ' || summary, |
| 39 | + 'DOCUMENT', 'SAP_GXY.20250407' |
| 40 | + ) stored; |
| 41 | +} |
| 42 | +``` |
| 43 | + |
| 44 | +:::tip Prefer calculated elements for vector embeddings |
| 45 | +If the database calculates vector embeddings on write it automatically regenerates the embedding if the input data changes. |
| 46 | +::: |
| 47 | + |
| 48 | +::: info Local Testing with H2 and SQLite |
| 49 | +On H2 and SQLite the `CQL.vectorEmbedding` function is emulated to support local testing. |
| 50 | +::: |
| 51 | + |
| 52 | +> [!warning] Java only and <Beta/> |
| 53 | +> The `vector_embedding` function is currently in beta and only supported by the CAP Java runtime. |
| 54 | +
|
| 55 | +[Learn more about Vector Embeddings in CAP Java](../../java/cds-data#vector-embeddings) {.learn-more} |
| 56 | + |
| 57 | +### Generate Embeddings Programmatically |
| 58 | + |
| 59 | +Alternatively, you can compute vector embeddings in your application layer using the [SAP Cloud SDK for AI](https://sap.github.io/ai-sdk/) to call SAP AI Core services for generating embeddings. |
| 60 | + |
| 61 | +:::details Example using SAP Cloud SDK for AI |
| 62 | +```Java |
| 63 | +var aiClient = OpenAiClient.forModel(OpenAiModel.TEXT_EMBEDDING_3_SMALL); |
| 64 | +var response = aiClient.embedding( |
| 65 | + new OpenAiEmbeddingRequest(List.of(book.getDescription()))); |
| 66 | +book.setEmbedding(CdsVector.of(response.getEmbeddingVectors().get(0))); |
| 67 | +``` |
| 68 | +::: |
| 69 | + |
| 70 | +:::tip Use SAP Cloud SDK for AI |
| 71 | +Use the [SAP Cloud SDK for AI](https://sap.github.io/ai-sdk/) for unified access to embedding models and large language models (LLMs) from [SAP AI Core](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/what-is-sap-ai-core). |
| 72 | +::: |
| 73 | + |
| 74 | +Learn more about the [SAP Cloud SDK for AI (Java)](https://sap.github.io/ai-sdk/docs/java/getting-started) or the [SAP Cloud SDK for AI (JavaScript)](https://sap.github.io/ai-sdk/docs/js/getting-started) {.learn-more} |
| 75 | + |
| 76 | +## Query for Similarity |
| 77 | +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. |
| 78 | + |
| 79 | +::: code-group |
| 80 | +```Java [Java] |
| 81 | +// Compute embedding for user question |
| 82 | +var query = CQL.val( |
| 83 | + "Any incidents with solar inverters this month? How were they resolved?"); |
| 84 | +var embedding = CQL.vectorEmbedding(query, TextType.QUERY, "SAP_GXY.20250407"); |
| 85 | + |
| 86 | +// Compute similarity between user question and incident embeddings |
| 87 | +var similarity = CQL.cosineSimilarity(CQL.get(Incidents.EMBEDDING), embedding); |
| 88 | + |
| 89 | +// Find Incidents related to user question ordered by relevance |
| 90 | +Select.from(INCIDENTS) |
| 91 | + .columns(i -> similarity.times(100).as("relevance"), |
| 92 | + i -> i.ID(), i -> i.title(), i -> i.summary(), i -> i.date()) |
| 93 | + .where(i -> similarity.gt(0.75)) |
| 94 | + .orderBy(i -> i.get("relevance").desc()); |
| 95 | +``` |
| 96 | + |
| 97 | +```js [Node.js] |
| 98 | +const response = await new AzureOpenAiEmbeddingClient( |
| 99 | + 'text-embedding-3-small' |
| 100 | +).run({ |
| 101 | + input: 'Any incidents with solar inverters this month? How were they resolved?' |
| 102 | +}); |
| 103 | + |
| 104 | +const questionEmbedding = response.getEmbedding(); |
| 105 | +let similarIncidents = await SELECT.from('Incidents') |
| 106 | + .where`cosine_similarity(embedding, to_real_vector(${questionEmbedding})) > 0.75`; |
| 107 | +``` |
| 108 | +::: |
| 109 | + |
0 commit comments