diff --git a/guides/databases/vector-embeddings.md b/guides/databases/vector-embeddings.md index 96344915f..181617e50 100644 --- a/guides/databases/vector-embeddings.md +++ b/guides/databases/vector-embeddings.md @@ -53,7 +53,7 @@ On H2 and SQLite the `CQL.vectorEmbedding` function is emulated using a hash-bas > [!warning] Java only and > The `vector_embedding` function is currently in beta and only supported by the CAP Java runtime. -[Learn more about Vector Embeddings in CAP Java](../../java/cds-data#vector-embeddings) {.learn-more} +[Learn more about Vector Embeddings in CAP Java](../../java/ai#vector-embeddings) {.learn-more} ### Generate Embeddings Programmatically diff --git a/java/ai.md b/java/ai.md new file mode 100644 index 000000000..5c1788294 --- /dev/null +++ b/java/ai.md @@ -0,0 +1,212 @@ +--- +description: > + This section describes AI integration in CAP Java: building agents on top of your + CDS services and configuring the LLM chat models they use. +--- + +# AI Integration { #ai } + + + +{{ $frontmatter.description }} + + + +## Agents { #ai-agents } + +An agent turns a CDS service into a conversational endpoint. It answers natural-language +requests by using the service's entities, actions, and functions as tools, backed by an +LLM. Agents speak the [A2A protocol](https://a2a-protocol.org/), so any A2A-compatible +client can talk to them. + +### Adding the Dependency + +Add the agent adapter to your `srv/pom.xml`: + +```xml + + com.sap.cds + cds-adapter-agent + +``` + +### Defining an Agent + +Annotate a service with `@agent` to expose it as an agent: + +```cds +@agent +service CatalogService { + entity Books as projection on my.Books; + action orderBook(book: Books:ID, quantity: Integer); +} +``` + +The agent exposes all entities and actions of the service as tools: + +- Entities become query tools, so the LLM can read data via CDS QL. +- Actions and functions become callable tools, invoked by name. + +By default the agent is served under `/a2a/`, with its +[agent card](https://a2a-protocol.org/latest/topics/agent-discovery/) available at the +corresponding `.../card` endpoint. Change the base path with `cds.agent.endpoint.path`. + +During development, a built-in chat UI lets you try out your agents in the browser. It's +enabled by default and can be turned off with `cds.agent.preview.enabled: false`. + +### Customizing an Agent + +Without further configuration, the agent derives a system prompt and its advertised skills +from the CDS model. To customize both, add resources under `-agent/` on the +classpath (for example `srv/src/main/resources/CatalogService-agent/`): + +```txt +CatalogService-agent/ +├── AGENTS.md # system prompt + agent card metadata +└── skills/ + ├── browse-books/SKILL.md + └── order-book/SKILL.md +``` + +`AGENTS.md` holds the system prompt as its body, with optional YAML frontmatter for the +agent card: + +```md +--- +name: Bookshop Assistant +version: 2.0.0 +description: Helps customers browse and order books +--- +You are a helpful bookshop assistant. Help customers find and order books. +Always use the provided tools to answer questions — do not make up data. +``` + +Each `skills//SKILL.md` describes one skill advertised in the agent card: + +```md +--- +name: browse-books +description: Browse and search the book catalog +metadata: + tags: [books, catalog] + examples: + - Show me all available books + - Find books about Java +--- +Use this skill to browse the book catalog. +``` + +## Chat Model Configuration { #ai-chat-config } + +Agents use a named chat model configuration. Configure models under `cds.ai.chat.models`, +where the key is the configuration name: + +```yaml +cds: + ai.chat.models: + llm: + kind: aicore + model: anthropic--claude-4.6-sonnet + temperature: 0.0 +``` + +| Property | Description | +| ------------- | ------------------------------------------------------------------ | +| `kind` | The model provider: `aicore`, `ollama`, or `mocked`. | +| `model` | The provider-specific model name. | +| `temperature` | Sampling temperature (`0.0`–`1.0`). Defaults to the provider's. | +| `options` | Additional provider-specific parameters. | + +An agent picks its model configuration via the `@agent.llm` annotation, which defaults to +the configuration named `llm`. If no configuration matches, CAP Java falls back to `aicore` +when an SAP AI Core service binding is present, and to `mocked` otherwise. + +To bind a specific configuration to an agent, define it under a name of your choice and +reference it with `@agent.llm`: + +```yaml +cds: + ai.chat.models: + llm: + kind: aicore + model: anthropic--claude-4.6-sonnet + reasoning: + kind: aicore + model: anthropic--claude-4.8-opus + temperature: 0.2 +``` + +```cds +@agent +@agent.llm: 'reasoning' // use the 'reasoning' config instead of the default model +service CatalogService { ... } +``` + +### SAP AI Core + +With an `aicore` service binding, requests run through +[SAP AI Core orchestration](https://help.sap.com/docs/sap-ai-core). Set `model` to the +model you want to use; if omitted, a default model is used. + +### Running Locally with Ollama + +To run an agent against a local model served by [Ollama](https://ollama.com/), pull a model +(for example `ollama pull gemma4:26b`) and point a configuration at it: + +```yaml +cds: + ai.chat.models: + llm: + kind: ollama + model: gemma4:26b # a model pulled in Ollama + # options: + # url: http://localhost:11434 # Ollama base URL (this is the default) +``` + +Add the LangChain4j Ollama integration to your `srv/pom.xml`: + +```xml + + dev.langchain4j + langchain4j-ollama + + 1.19.0 + +``` + +::: tip Testcontainers +Alternatively, Ollama can be started via [Testcontainers](https://testcontainers.com/) for +local tests. Note that reasoning on a containerized model can be slow. +::: + +### Mocked + +The `mocked` kind returns static responses without calling any model. It's the default when +no other provider is configured or bound, which keeps local runs and tests working out of +the box. + +## Vector Embeddings { #vector-embeddings } + +In CDS, [vector embeddings](../guides/databases/vector-embeddings) are stored in elements of type `Vector`. + +CAP Java supports the vector type on SAP HANA, as well as H2 and SQLite for local testing. On Postgres (beta) support for vectors requires the [pgvector](https://github.com/pgvector/pgvector) extension. + +In CAP Java, vectors are represented by the `CdsVector` type, which allows a unified handling of different vector representations such as `float[]` and `String`: + +```Java +// Vector embedding of text via SAP Cloud SDK for AI +float[] embedding = embeddingModel.embedding( + new OpenAiEmbeddingRequest(List.of(text))).getEmbeddingVectors().get(0); + +CdsVector v1 = CdsVector.of(embedding); // float[] format +``` + +::: info +In CDS QL queries, elements of type `Vector` are excluded from the select list by default. +::: + +CAP Java supports multiple [vector functions](./working-with-cql/query-api.md#vector-functions) that allow you to compute vector embeddings, similarity, and distance directly in the database. diff --git a/java/cds-data.md b/java/cds-data.md index f5920fad8..90ef72dae 100644 --- a/java/cds-data.md +++ b/java/cds-data.md @@ -41,7 +41,7 @@ The [predefined CDS types](../cds/types) are mapped to Java types and as follows | `cds.LargeString` | `java.lang.String` | `java.io.Reader` (1) if annotated with `@Core.MediaType` | | `cds.Binary` | `byte[]` | | | `cds.LargeBinary` | `byte[]` | `java.io.InputStream` (1) if annotated with `@Core.MediaType` | -| `cds.Vector` | `com.sap.cds.CdsVector` | for [vector embeddings](#vector-embeddings) | +| `cds.Vector` | `com.sap.cds.CdsVector` | for [vector embeddings](./ai#vector-embeddings) | | `cds.Map` | `java.util.Map` | for schemaless [structured data](#cds-map) | ### SAP HANA-Specific Data Types @@ -328,28 +328,6 @@ On the database, this data is serialized to [JSON](https://www.json.org/)(1 Map data can be nested and may contain nested maps and lists, which are serialized to JSON objects and arrays, respectively. -## Vector Embeddings { #vector-embeddings } - -In CDS [vector embeddings](../guides/databases/vector-embeddings) are stored in elements of type `Vector`: - -CAP Java support the vector type on SAP HANA, as well as H2 and SQLite for local testing. On Postgres (beta) support for vectors requires the [pgvector](https://github.com/pgvector/pgvector) extension. - -In CAP Java, vectors are represented by the `CdsVector` type, which allows a unified handling of different vector representations such as `float[]` and `String`: - -```Java -// Vector embedding of text via SAP Cloud SDK for AI -float[] embedding = embeddingModel.embedding( - new OpenAiEmbeddingRequest(List.of(text))).getEmbeddingVectors().get(0); - -CdsVector v1 = CdsVector.of(embedding); // float[] format -``` - -::: info -In CDS QL queries, elements of type `Vector` are excluded from the select list by default. -::: - -CAP Java supports multiple [vector functions](./working-with-cql/query-api.md#vector-functions) that allow you to compute vector embeddings, similarity, and distance directly in the database. - ## Data in CDS Query Language (CQL) This section shows examples using structured data in [CQL](../cds/cql) statements. diff --git a/java/working-with-cql/query-api.md b/java/working-with-cql/query-api.md index 944627e6e..f96245182 100644 --- a/java/working-with-cql/query-api.md +++ b/java/working-with-cql/query-api.md @@ -1679,7 +1679,7 @@ These methods allow you to compute the difference between timestamps: #### Vector Functions -Vector functions allow you to compute similarity and distance of [vectors](../cds-data.md#vector-embeddings), as well as [vector embeddings](../../guides/databases/vector-embeddings) of text data directly in the database. +Vector functions allow you to compute similarity and distance of [vectors](../ai.md#vector-embeddings), as well as [vector embeddings](../../guides/databases/vector-embeddings) of text data directly in the database. ::: warning Not supported with local MTXS on SQLite Using vector functions in [stored calculated elements](../../cds/cdl#on-write) with [local MTXS](../../guides/multitenancy/mtxs#test-drive-locally) on SQLite isn't supported.