diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 25ecc5e13..d551873f5 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -16,5 +16,5 @@ Please provide a short description of what your change does and why it is needed - [ ] Tests cover the scope above - [ ] Error handling created / updated & covered by the tests above - [ ] ~Aligned changes with the JavaScript SDK~ -- [ ] Documentation updated +- [ ] [Documentation](https://github.com/SAP/ai-sdk/tree/main/docs-java) updated - [ ] Release notes updated diff --git a/README.md b/README.md index 39eb7534f..b545fed2b 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ To use the SDK in a Java application, it is necessary to understand the technica - Java 17 or higher. - Access to an **SAP AI Core Service** instance. -Please refer to [this documentation on **how to connect the SDK to AI Core**](docs/guides/CONNECTING_TO_AICORE.md). +Please refer to [this documentation on **how to connect the SDK to AI Core**](https://sap.github.io/ai-sdk/docs/java/guides/connecting-to-ai-core). The following table lists the required versions, based on the latest release: @@ -119,26 +119,26 @@ export AICORE_SERVICE_KEY='{ "clientid": "...", "clientsecret": "...", "url": ". mvn spring-boot:run ``` -Please find **detailed instructions** and more examples [in this documentation](docs/guides/CONNECTING_TO_AICORE.md#using-the-aicore_service_key-environment-variable). +Please find **detailed instructions** and more examples [in this documentation](https://sap.github.io/ai-sdk/docs/java/guides/connecting-to-ai-core#using-the-aicore_service_key-environment-variable). ### Explore Further Capabilities Check out the options available for the `OrchestrationPrompt` and `OrchestrationModuleConfig` classes. You can use templating, content filtering, data masking and more. -Please refer to [this documentation](docs/guides/ORCHESTRATION_CHAT_COMPLETION.md) for more information. +Please refer to [this documentation](https://sap.github.io/ai-sdk/docs/java/guides/orchestration-chat-completion) for more information. ## Documentation For more detailed information and advanced usage, please refer to the following: -- [ Connecting to AI Core](docs/guides/CONNECTING_TO_AICORE.md) -- [ Orchestration Chat Completion](docs/guides/ORCHESTRATION_CHAT_COMPLETION.md) -- [ OpenAI Chat Completion](docs/guides/OPENAI_CHAT_COMPLETION.md) -- [ Spring AI Integration](docs/guides/SPRING_AI_INTEGRATION.md) -- [🧰 AI Core Deployment](docs/guides/AI_CORE_DEPLOYMENT.md) -- [ AI Core Grounding](docs/guides/GROUNDING.md) +- [ Connecting to AI Core](https://sap.github.io/ai-sdk/docs/java/guides/connecting-to-ai-core) +- [ Orchestration Chat Completion](https://sap.github.io/ai-sdk/docs/java/guides/orchestration-chat-completion) +- [ OpenAI Chat Completion](https://sap.github.io/ai-sdk/docs/java/guides/openai-chat-completion) +- [ Spring AI Integration](https://sap.github.io/ai-sdk/docs/java/guides/spring-ai-integration) +- [🧰 AI Core Deployment](https://sap.github.io/ai-sdk/docs/java/guides/ai-core-deployment) +- [ AI Core Grounding](https://sap.github.io/ai-sdk/docs/java/guides/document-grounding) -For updating versions, please refer to the [**Release Notes**](docs/release-notes/release-notes-0-to-14.md). +For updating versions, please refer to the [**Release Notes**](https://sap.github.io/ai-sdk/docs/java/release-notes). ## Build the Project @@ -177,7 +177,7 @@ OrchestrationClient client = new OrchestrationClient(destination); OpenAiClient client2 = OpenAiClient.withCustomDestination(destination); ``` -For more information, please refer to the [AI Core connectivity guide](./docs/guides/CONNECTING_TO_AICORE.md) and the [SAP Cloud SDK documentation](https://sap.github.io/cloud-sdk/docs/java/features/connectivity/http-destinations). +For more information, please refer to the [AI Core connectivity guide](https://sap.github.io/ai-sdk/docs/java/guides/connecting-to-ai-core) and the [SAP Cloud SDK documentation](https://sap.github.io/cloud-sdk/docs/java/features/connectivity/http-destinations). ### _"There's a vulnerability warning `CVE-2021-41251`?"_ diff --git a/docs/blog/Introducing.md b/docs/blog/Introducing.md index 8ed84e2bc..7f311c4bd 100644 --- a/docs/blog/Introducing.md +++ b/docs/blog/Introducing.md @@ -41,7 +41,7 @@ String id = deployment.getId(); AiExecutionStatus status = deployment.getStatus(); ``` -You can learn more about the SDK's capabilities for SAP AI Core [in the public repository guide](https://github.com/SAP/ai-sdk-java/blob/main/docs/guides/AI_CORE_DEPLOYMENT.md). +You can learn more about the SDK's capabilities for SAP AI Core [in this guide](https://sap.github.io/ai-sdk/docs/java/guides/ai-core-deployment). ## AI Core - Orchestration @@ -72,7 +72,7 @@ var result = client.chatCompletion(prompt, config); String messageResult = result.getContent(); ``` -You can learn more about the SDK's capabilities for Orchestration Service [in the public repository guide](https://github.com/SAP/ai-sdk-java/blob/main/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md). +You can learn more about the SDK's capabilities for Orchestration Service [in this guide](https://sap.github.io/ai-sdk/docs/java/guides/orchestration-chat-completion). ## AI Core - Foundation Models @@ -101,7 +101,7 @@ var result = String resultMessage = result.getContent(); ``` -You can learn more about the SDK's capabilities for foundation models and OpenAI specific features [in the public repository guide](https://github.com/SAP/ai-sdk-java/blob/main/docs/guides/OPENAI_CHAT_COMPLETION.md). +You can learn more about the SDK's capabilities for foundation models and OpenAI specific features [this guide](https://sap.github.io/ai-sdk/docs/java/guides/openai-chat-completion). ## Getting Started diff --git a/docs/guides/AI_CORE_DEPLOYMENT.md b/docs/guides/AI_CORE_DEPLOYMENT.md deleted file mode 100644 index 56bf24013..000000000 --- a/docs/guides/AI_CORE_DEPLOYMENT.md +++ /dev/null @@ -1,108 +0,0 @@ -# AI Core Deployment - -## Table of Contents - -- [Introduction](#introduction) -- [Prerequisites](#prerequisites) - - [Maven Dependencies](#maven-dependencies) -- [Usage](#usage) - - [Create a Deployment](#create-a-deployment) - - [Delete a Deployment](#delete-a-deployment) - -## Introduction - -This guide provides examples on how to create and manage deployments in SAP AI Core using the SAP AI SDK for Java. - -> [!WARNING] -> The below examples rely on generated model classes. -> Please be aware of the [implications described here](/README.md#general-requirements). - -## Prerequisites - -Before using the AI Core module, ensure that you have met all the general requirements outlined in the [README.md](../../README.md#general-requirements). -Additionally, include the necessary Maven dependency in your project. - -### Maven Dependencies - -Add the following dependency to your `pom.xml` file: - -```xml - - com.sap.ai.sdk - core - ${ai-sdk.version} - -``` - -See [an example pom in our Spring Boot application](../../sample-code/spring-app/pom.xml) - -## Usage - -In addition to the prerequisites above, we assume you have already set up the following to carry out the examples in this guide: - -- **An AI Core Configuration** created in SAP AI Core. - -
- Example configuration from the AI Core /configuration endpoint - - ```json - { - "createdAt": "2024-07-03T12:44:08Z", - "executableId": "azure-openai", - "id": "12345-123-123-123-123456abcdefg", - "inputArtifactBindings": [], - "name": "gpt-4o-mini", - "parameterBindings": [ - { - "key": "modelName", - "value": "gpt-4o-mini" - }, - { - "key": "modelVersion", - "value": "latest" - } - ], - "scenarioId": "foundation-models" - } - ``` -
- -## Create a Deployment - -Use the following code snippet to create a deployment in SAP AI Core: - -```java -var api = new DeploymentApi(); -var resourceGroupId = "default"; -var configurationId = "12345-123-123-123-123456abcdefg"; - -var request = AiDeploymentCreationRequest.create().configurationId(configurationId); -var deployment = api.create(resourceGroupId, request); - -String id = deployment.getId(); -AiExecutionStatus status = deployment.getStatus(); -``` - -Refer to the [DeploymentController.java](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/DeploymentController.java) in our Spring Boot application for a complete example. - -## Delete a Deployment - -```java -AiDeploymentCreationResponse deployment; // provided -String deploymentId = deployment.getId(); - -var api = new DeploymentApi(); -var resourceGroupId = "default"; - -if (deployment.getStatus() == AiExecutionStatus.RUNNING) { - // Only RUNNING deployments can be STOPPED - api.modify( - resourceGroupId, - deploymentId, - AiDeploymentModificationRequest.create().targetStatus(AiDeploymentTargetStatus.STOPPED)); -} -// Wait a few seconds for the deployment to stop -// Only UNKNOWN and STOPPED deployments can be DELETED -api.delete(resourceGroupId, deployment.getId()); -``` - -Refer to the [DeploymentController.java](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/DeploymentController.java) in our Spring Boot application for a complete example. diff --git a/docs/guides/CONNECTING_TO_AICORE.md b/docs/guides/CONNECTING_TO_AICORE.md deleted file mode 100644 index ca89d55ad..000000000 --- a/docs/guides/CONNECTING_TO_AICORE.md +++ /dev/null @@ -1,175 +0,0 @@ -# Connecting to AI Core - -## Table of Contents - -- [Using a Service Binding](#using-a-service-binding) - - [Providing a Service Binding Locally](#providing-a-service-binding-locally) - - [Using the `AICORE_SERVICE_KEY` Environment Variable](#using-the-aicore_service_key-environment-variable) -- [Using a Destination from the BTP Destination Service](#using-a-destination-from-the-btp-destination-service) -- [Creating a Custom Destination](#creating-a-custom-destination) - - -The AI SDK uses the [`Destination` concept of the SAP Cloud SDK](https://sap.github.io/cloud-sdk/docs/java/features/connectivity/destination-service) to connect to AI Core. -This allows for a seamless integration in BTP and offers a wide variety of managing the credentials for the connection. - -## Using a Service Binding - -By default, the AI SDK will look for an `aicore` service binding in the environment of the application. - -When running on SAP BTP, [create an instance of the AI Core service](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-service-instance) and bind it to your application. -The AI SDK will automatically detect the service binding and use it to connect to AI Core. - -If no service binding could be found (and no other destination has been given), the AI SDK will throw an exception: - -> Could not find any matching service bindings for service identifier 'aicore' - -To run your code outside SAP BTP (e.g. locally), you will have to provide the credentials manually. - -### Providing a Service Binding Locally - -For local development, you can provide the service credentials locally in various ways. - -#### Using CAP Hybrid Testing - -When developing a [CAP application](https://cap.cloud.sap/docs/), you can use the [hybrid testing](https://cap.cloud.sap/docs/advanced/hybrid-testing#services-on-cloud-foundry) approach. -Assuming your AI Core service instance is called `aicore`, the following command runs a Maven command with the credentials of the service instance: - -```bash -cds bind --to aicore --exec mvn spring-boot:run -``` - -#### Using the `AICORE_SERVICE_KEY` Environment Variable - -You can also provide the service credentials in the `AICORE_SERVICE_KEY` environment variable. -First, [create a service key for your AI Core service instance](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-service-key). -Copy the resulting JSON object. - -Then set the environment variable `AICORE_SERVICE_KEY` to be defined for however you want to run your code. -How exactly to set this depends on how you run your code (e.g. via IDE, command line etc.) and potentially on your operating system. - -Here are three examples of how this can be done: - -1.
- Using a `.env` file - - Create a `.env` file in the **working directory** from which you run your code. - Add the following line: - - ```txt - AICORE_SERVICE_KEY={ "clientid": "...", "clientsecret": "...", "url": "...", "serviceurls": { "AI_API_URL": "..." } } - ``` - - > [!IMPORTANT] - > The value of `AICORE_SERVICE_KEY` must be a single line, so remove any line breaks from the service key JSON. - -
- -2.
- Using the command line on Mac OS - - Run your code with the following command: - - ```bash - export AICORE_SERVICE_KEY='{ "clientid": "...", "clientsecret": "...", "url": "...", "serviceurls": { "AI_API_URL": "..." } }' - mvn ... - ``` - -
- -3.
- Using PowerShell on Windows - - Run your code with the following command: - - ```shell - $env:AICORE_SERVICE_KEY='{ "clientid": "...", "clientsecret": "...", "url": "...", "serviceurls": { "AI_API_URL": "..." } }' - mvn ... - ``` - -
- -4.
- Using an IntelliJ run configuration - - In IntelliJ, go to `Run` > `Edit Configurations...` > `Environment variables`. - Add a new environment variable with the name `AICORE_SERVICE_KEY` and paste the service key as value. - - For more information, see the [official IntelliJ documentation](https://www.jetbrains.com/help/idea/run-debug-configuration-application.html#configure-environment-variables). - -
- -## Using a Destination from the BTP Destination Service - -You can define a destination in the BTP Destination Service and use that to connect to AI Core. - -
-How to create a Destination in the SAP BTP Cockpit - -1. [Create a service key for your AI Core service instance](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-service-key). - -2. Create a new Destination in the SAP BTP Cockpit with the following properties: - - - **Name**: `my-aicore` - - **Type**: `HTTP` - - **URL**: `[serviceurls.AI_API_URL]` - - **Proxy Type**: `Internet` - - **Authentication**: `OAuth2ClientCredentials` - - **Client ID**: `[clientid]` - - **Client Secret**: `[clientsecret]` - - **Token Service URL Type**: `Dedicated` - - **Token Service URL**: `[url]/oauth/token` - - Fill in the values for URL, client ID, client secret, and token service URL from the service key JSON. - Make sure to add `/oauth/token` in the token service URL. - -
- -To use the destination, ensure you have created an instance of the BTP Destination Service and bound it to your application. - -> [!Tip] -> If you are using CAP, you can again use Hybrid Testing to bind the destination service to your application when running **locally**. - -```java -Destination destination = DestinationAccessor.getDestination("my-aicore").asHttp(); -AiCoreService aiCoreService = new AiCoreService().withBaseDestination(destination); -``` - -Now you can use the `AiCoreService` as follows: - -```java -// To create an OpenAiClient: -var openAiDestination = aiCoreService.getInferenceDestination().forModel(OpenAiModel.TEXT_EMBEDDING_3_LARGE); -var client = OpenAiClient.withCustomDestination(openAiDestination); - -// To create an OrchestrationClient: -var orchestrationDestination = aiCoreService.getInferenceDestination().forScenario("orchestration"); -var client = new OrchestrationClient(orchestrationDestination); - -// To create any of the com.sap.ai.sdk.core.client.* classes (e.g. DeploymentApi): -new DeploymentApi(aiCoreService); -``` - -> [!IMPORTANT] -> The `destination` obtained from BTP destination service will expire once the contained OAuth2 token expires. -> Please run the above code for each request to ensure the destination is up-to-date. -> Destinations are cached by default, so this does not come with a performance penalty. -> To learn more, see the [SAP Cloud SDK documentation](https://sap.github.io/cloud-sdk/docs/java/features/connectivity/destination-service). - -## Creating a Custom Destination - -If the above options are not suitable for your use case (e.g. because you are obtaining the credentials in a completely different way), you can also use a custom-built destination: - -```java -var destination = OAuth2DestinationBuilder - .forTargetUrl("https://") - .withTokenEndpoint("https:///oauth/token") - .withClient(new ClientCertificate("", "", ""), OnBehalfOf.TECHNICAL_USER_PROVIDER) - .build(); - -AiCoreService aiCoreService = new AiCoreService().withBaseDestination(destination); -``` - -The above example assumes you are using a client certificate for authentication and have stored the relevant credentials somewhere. -You are free to use X509 certificates (also via the Zero Trust Identity Service) or a client secret. - -For more details, refer to the [SAP Cloud SDK documentation](https://sap.github.io/cloud-sdk/docs/java/features/connectivity/destination-service). \ No newline at end of file diff --git a/docs/guides/GROUNDING.md b/docs/guides/GROUNDING.md deleted file mode 100644 index e106478da..000000000 --- a/docs/guides/GROUNDING.md +++ /dev/null @@ -1,155 +0,0 @@ -# Document Grounding Services - -## Table of Contents - -- [Introduction](#introduction) - - [Prerequisites](#prerequisites) - - [Maven Dependencies](#maven-dependencies) -- [Usage](#usage) - - [Data Ingestion](#data-ingestion) - - [Pipeline API](#pipeline-api) - - [Vector API](#vector-api) - - [Data Retrieval](#retrieval-api) - - [Retrieval API](#create-a-deployment) - - [Grounding via Orchestration](#grounding-via-orchestration) - -## Introduction - -This guide provides examples on how to manage data in SAP Document Grounding. -It's divided into two main sections: Data Ingestion and Data Retrieval. - -> [!WARNING] -> The below examples rely on generated model classes. -> Please be aware of the [implications described here](/README.md#general-requirements). - -## Prerequisites - -Before using the Document Grounding module, ensure that you have met all the general requirements outlined in the [README.md](../../README.md#general-requirements). -Additionally, include the necessary Maven dependency in your project. - -### Maven Dependencies - -Add the following dependency to your `pom.xml` file: - -```xml - - com.sap.ai.sdk - document-grounding - ${ai-sdk.version} - -``` - -See [an example pom in our Spring Boot application](../../sample-code/spring-app/pom.xml) - -## Usage - -In addition to the prerequisites above, we assume you have already set up the following to carry out the examples in this guide: - -- A running instance of SAP AI Core with correctly setup credentials, including a resource group id. - -## Data Ingestion - -The following APIs are available for data ingestion: Pipeline and Vector. - -### Pipeline API - -Consider the following code sample to read pipelines, create a new one and get its status: - -```java -var api = new GroundingClient().pipelines(); -var resourceGroupId = "default"; - -// get all pipelines -Pipelines pipelines = api.getAllPipelines(resourceGroupId); - -// create new pipeline -var type = "MSSharePoint"; // or "S3" or "SFTP" -var pipelineSecret = "my-secret-name"; -var config = PipelinePostRequstConfiguration.create().destination(pipelineSecret); -var request = PipelinePostRequst.create().type(type)._configuration(config); -PipelineId pipeline = api.createPipeline(resourceGroupId, request); - -// get pipeline status -PipelineStatus status = api.getPipelineStatus(resourceGroupId, pipeline.getPipelineId()); -``` - -### Vector API - -```java -var api = new GroundingClient().vector(); -var resourceGroupId = "default"; - -// resolve collection id -var collectionId = UUID.fromString("12345-123-123-123-0123456abcdef"); - -var request = DocumentCreateRequest.create() - .documents(BaseDocument.create() - .chunks(TextOnlyBaseChunk.create() - .content("The dog makes _woof_") - .metadata(KeyValueListPair.create() - .key("animal").value("dog"))) - .metadata(DocumentKeyValueListPair.create() - .key("topic").value("sound"))); -DocumentsListResponse response = api.createDocuments(resourceGroupId, collectionId, request); -``` - -Refer to the [DeploymentController.java](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/DeploymentController.java) in our Spring Boot application for a complete example. - -## Data Retrieval - -The following APIs are available for data retrieval: Retrieval and Orchestration. - - -### Retrieval API - -Consider the following code sample to search for relevant document grounding data based on a query: - -```java -var api = new GroundingClient().retrieval(); -var resourceGroupId = "default"; - -var filter = - RetrievalSearchFilter.create() - .id("question") - .dataRepositoryType(DataRepositoryType.VECTOR) - .dataRepositories(List.of("*")) - .searchConfiguration(SearchConfiguration.create().maxChunkCount(10)); -var search = RetrievalSearchInput.create().query("What is SAP Cloud SDK for AI?").filters(filter); -RetievalSearchResults results = api.search(resourceGroupId, search); -``` - -### Grounding via Orchestration - -You can use the grounding service via orchestration. -Please find the [documentation on Orchestration client in the dedicated document](ORCHESTRATION_CHAT_COMPLETION.md). - -```java -OrchestrationClient client; - -var databaseFilter = - DocumentGroundingFilter.create() - .dataRepositoryType(DataRepositoryType.VECTOR) - .searchConfig(GroundingFilterSearchConfiguration.create().maxChunkCount(3)); -var groundingConfigConfig = - GroundingModuleConfigConfig.create() - .inputParams(List.of("query")) - .outputParam("results") - .addFiltersItem(databaseFilter); -var groundingConfig = - GroundingModuleConfig.create() - .type(GroundingModuleConfig.TypeEnum.DOCUMENT_GROUNDING_SERVICE) - .config(groundingConfigConfig); -var configWithGrounding = - new OrchestrationModuleConfig() - .withLlmConfig(GPT_4O) - .withGroundingConfig(groundingConfig); - -var inputParams = Map.of("query", "What is SAP Cloud SDK for AI?"); - -var prompt = - new OrchestrationPrompt( - inputParams, - Message.system("Context message with embedded grounding results. {{?results}}")); - -OrchestrationChatResponse response = client.chatCompletion(prompt, configWithGrounding); -``` \ No newline at end of file diff --git a/docs/guides/OPENAI_CHAT_COMPLETION.md b/docs/guides/OPENAI_CHAT_COMPLETION.md deleted file mode 100644 index a9b0596a5..000000000 --- a/docs/guides/OPENAI_CHAT_COMPLETION.md +++ /dev/null @@ -1,312 +0,0 @@ -# OpenAI Chat Completion - -## Table of Contents - -- [Introduction](#introduction) - - [New User Interface (v1.4.0)](#new-user-interface-v140) -- [Prerequisites](#prerequisites) -- [Maven Dependencies](#maven-dependencies) -- [Usage](#usage) - - [Simple Chat Completion](#simple-chat-completion) - - [Message History](#message-history) - - [Chat Completion with Custom Model](#chat-completion-with-custom-model) - - [Stream Chat Completion](#stream-chat-completion) - - [Asynchronous Streaming](#asynchronous-streaming) - - [Aggregating Total Output](#aggregating-total-output) - - [Spring Boot Example](#spring-boot-example) - -## Introduction - -This guide demonstrates how to use the SAP AI SDK for Java to perform chat completion tasks using OpenAI models deployed on SAP AI Core. - -### New User Interface (v1.4.0) - -We're excited to introduce a new user interface for OpenAI chat completions starting with **version 1.4.0**. This update is designed to improve the SDK by: - -- **Decoupling Layers:** Separating the convenience layer from the model classes to deliver a more stable and maintainable experience. -- **Staying Current:** Making it easier for the SDK to adapt to the latest changes in the OpenAI API specification. -- **Consistent Design:** Aligning with the Orchestrator convenience API for a smoother transition and easier adoption. - -**Please Note:** - -- The new interface is gradually being rolled out across the SDK. -- We welcome your feedback to help us refine this interface. -- The existing interface (v1.0.0) remains available for compatibility. - -## Prerequisites - -Before using the AI Core module, ensure that you have met all the general requirements outlined in the [README.md](../../README.md#general-requirements). -Additionally, include the necessary Maven dependency in your project. - -### Maven Dependencies - -Add the following dependency to your `pom.xml` file: - -```xml - - - com.sap.ai.sdk.foundationmodels - openai - ${ai-sdk.version} - - -``` - -See [an example pom in our Spring Boot application](../../sample-code/spring-app/pom.xml) - -## Usage - -In addition to the prerequisites above, we assume you have already set up the following to carry out the examples in this guide: - -- **A Deployed OpenAI Model in SAP AI Core** - - Refer - to [How to deploy a model to AI Core](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-deployment-for-generative-ai-model-in-sap-ai-core) - for setup instructions. - - In case the model is deployed in a custom resource group, refer to [this section](#using-a-custom-resource-group). - -
- Example deployed model from the AI Core /deployments endpoint - - ```json - { - "id": "d123456abcdefg", - "deploymentUrl": "https://api.ai.region.aws.ml.hana.ondemand.com/v2/inference/deployments/d123456abcdefg", - "configurationId": "12345-123-123-123-123456abcdefg", - "configurationName": "gpt-4o-mini", - "scenarioId": "foundation-models", - "status": "RUNNING", - "statusMessage": null, - "targetStatus": "RUNNING", - "lastOperation": "CREATE", - "latestRunningConfigurationId": "12345-123-123-123-123456abcdefg", - "ttl": null, - "details": { - "scaling": { - "backendDetails": {} - }, - "resources": { - "backendDetails": { - "model": { - "name": "gpt-4o-mini", - "version": "latest" - } - } - } - }, - "createdAt": "2024-07-03T12:44:22Z", - "modifiedAt": "2024-07-16T12:44:19Z", - "submissionTime": "2024-07-03T12:44:51Z", - "startTime": "2024-07-03T12:45:56Z", - "completionTime": null - } - ``` - -
- -## Simple chat completion - -```java -var result = - OpenAiClient.forModel(GPT_4O_MINI) - .withSystemPrompt("You are a helpful AI") - .chatCompletion("Hello World! Why is this phrase so famous?"); - -String resultMessage = result.getContent(); -``` - -## Using a Custom Resource Group - -```java -var destination = new AiCoreService() - .getInferenceDestination("custom-rg") - .forModel(GPT_4O); -OpenAiClient.withCustomDestination(destination); -``` - -## Message history - -**Since v1.4.0** - -```java -var request = - new OpenAiChatCompletionRequest( - OpenAiMessage.system("You are a helpful assistant"), - OpenAiMessage.user("Hello World! Why is this phrase so famous?")); - -var response = OpenAiClient.forModel(GPT_4O).chatCompletion(request).getContent(); -``` - -
-Since v1.0.0 - -```java -var systemMessage = - new OpenAiChatSystemMessage().setContent("You are a helpful assistant"); -var userMessage = - new OpenAiChatUserMessage().addText("Hello World! Why is this phrase so famous?"); -var request = - new OpenAiChatCompletionParameters().addMessages(systemMessage, userMessage); - -var result = OpenAiClient.forModel(GPT_4O_MINI).chatCompletion(request); - -String resultMessage = result.getContent(); -``` - -See [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OpenAiService.java) - -
- -## Chat Completion with Specific Model Version - -By default, when no version is specified, the system selects one of the available deployments of the specified model, regardless of its version. -To target a specific version, you can specify the model version along with the model. - -```java -OpenAiChatCompletionOutput result = - OpenAiClient.forModel(GPT_4O_MINI.withVersion("1106")).chatCompletion(request); -``` - -## Chat completion with Custom Model - -You can also use a custom OpenAI model for chat completion by creating an `OpenAiModel` object. - -```java -OpenAiChatCompletionOutput result = - OpenAiClient.forModel(new OpenAiModel("custom-model", "v1")).chatCompletion(request); -``` - -Ensure that the custom model is deployed in SAP AI Core. - -## Stream chat completion - -It's possible to pass a stream of chat completion delta elements, e.g. from the application backend to the frontend in real-time. - -### Asynchronous Streaming - Blocking - -This is a blocking example for streaming and printing directly to the console: - -```java -String msg = "Can you give me the first 100 numbers of the Fibonacci sequence?"; - -OpenAiClient client = OpenAiClient.forModel(GPT_4O_MINI); - -// try-with-resources on stream ensures the connection will be closed -try (Stream stream = client.streamChatCompletion(msg)) { - stream.forEach( - deltaString -> { - System.out.print(deltaString); - System.out.flush(); - }); -} -``` - -### Asynchronous Streaming - Non-blocking - -**Since v1.4.0** - -The following example demonstrate how you can leverage a concurrency-safe container (like an AtomicReference) to "listen" for usage information in any incoming delta. - -```java -String question = "Can you give me the first 100 numbers of the Fibonacci sequence?"; -var userMessage = OpenAiMessage.user(question); -var request = new OpenAiChatCompletionRequest(userMessage); - -OpenAiClient client = OpenAiClient.forModel(GPT_4O); -var usageRef = new AtomicReference(); - -// Prepare the stream before starting the thread to handle any initialization exceptions -Stream stream = client.streamChatCompletionDeltas(request); - -// Create a new thread for asynchronous, non-blocking processing -Thread streamProcessor = - new Thread( - () -> { - // try-with-resources ensures the stream is closed after processing - try (stream) { - stream.forEach( - delta -> { - usageRef.compareAndExchange(null, delta.getCompletionUsage()); - System.out.println("Content: " + delta.getDeltaContent()); - }); - } - }); - -// Start the processing thread; the main thread remains free (non-blocking) -streamProcessor.start(); -// Wait for the thread to finish (blocking) -streamProcessor.join(); - -// Access information caught from completion usage -Integer tokensUsed = usageRef.get().getCompletionTokens(); -System.out.println("Tokens used: " + tokensUsed); -``` - -
-Since v1.0.0 - -The following example is non-blocking and demonstrates how to aggregate the complete response. -Any asynchronous library can be used, such as the classic Thread API. - -```java -var question = "Can you give me the first 100 numbers of the Fibonacci sequence?"; - -var userMessage = - new OpenAiChatMessage.OpenAiChatUserMessage().addText(question); -var requestParameters = - new OpenAiChatCompletionParameters().addMessages(userMessage); - -var client = OpenAiClient.forModel(GPT_4O_MINI); -var totalOutput = new OpenAiChatCompletionOutput(); - -// Prepare the stream before starting the thread to handle any initialization exceptions -Stream stream = - client.streamChatCompletionDeltas(requestParameters); - -var streamProcessor = - new Thread( - () -> { - // try-with-resources ensures the stream is closed after processing - try (stream) { - stream.peek(totalOutput::addDelta).forEach(System.out::println); - } - }); - -streamProcessor.start(); // Start processing in a separate thread (non-blocking) -streamProcessor.join(); // Wait for the thread to finish (blocking) - -// Access aggregated information from total output -Integer tokensUsed = totalOutput.getUsage().getCompletionTokens(); -System.out.println("Tokens used: " + tokensUsed); -``` - -Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OpenAiService.java). It shows the usage of Spring -Boot's `ResponseBodyEmitter` to stream the chat completion delta messages to the frontend in real-time. - -
- -## Embedding - -**Since v1.4.0** - -Get the embeddings of a text input in list of float values: - -```java -var request = new OpenAiEmbeddingRequest(List.of("Hello World")); - -OpenAiEmbeddingResponse response = OpenAiClient.forModel(TEXT_EMBEDDING_3_SMALL).embedding(request); -float[] embedding = embedding.getEmbeddings().get(0); -``` - -
-Since v1.0.0 - -```java -var request = new OpenAiEmbeddingParameters().setInput("Hello World"); - -OpenAiEmbeddingOutput embedding = OpenAiClient.forModel(TEXT_EMBEDDING_3_SMALL).embedding(request); - -float[] embedding = embedding.getData().get(0).getEmbedding(); -``` - -See [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OpenAiService.java) - -
diff --git a/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md b/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md deleted file mode 100644 index b81e9c688..000000000 --- a/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md +++ /dev/null @@ -1,459 +0,0 @@ -# Orchestration Chat Completion - -## Table of Contents - -- [Introduction](#introduction) -- [Prerequisites](#prerequisites) - - [Maven Dependencies](#maven-dependencies) -- [Usage](#usage) - - [Chat completion with Templates](#chat-completion-with-templates) - - [Message history](#message-history) - - [Chat Completion Filter](#chat-completion-filter) - - [Data Masking](#data-masking) - - [Grounding](#grounding) - - [Stream chat completion](#stream-chat-completion) - - [Add images and multiple text inputs to a message](#add-images-and-multiple-text-inputs-to-a-message) - - [Set a Response Format](#set-a-response-format) - - [Set Model Parameters](#set-model-parameters) - - [Using a Configuration from AI Launchpad](#using-a-configuration-from-ai-launchpad) - -## Introduction - -This guide provides examples of how to use the Orchestration service in SAP AI Core for chat completion tasks using the SAP AI SDK for Java. - -## Prerequisites - -Before using the AI Core module, ensure that you have met all the general requirements outlined in the [README.md](../../README.md#general-requirements). -Additionally, include the necessary Maven dependency in your project. - -### Maven Dependencies - -Add the following dependency to your `pom.xml` file: - -```xml - - - com.sap.ai.sdk - orchestration - ${ai-sdk.version} - - -``` - -See [an example `pom.xml` in our Spring Boot application](../../sample-code/spring-app/pom.xml). - -## Usage - -In addition to the prerequisites above, we assume you have already set up the following to carry out the examples in this guide: - -- **A Deployed Orchestration Service in SAP AI Core** - - Refer to the [Orchestration Documentation](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/orchestration) for setup instructions. - -
- Example orchestration deployment from the AI Core /deployments endpoint - - ```json - { - "id": "d123456abcdefg", - "deploymentUrl": "https://api.ai.intprod-eu12.eu-central-1.aws.ml.hana.ondemand.com/v2/inference/deployments/d123456abcdefg", - "configurationId": "12345-123-123-123-123456abcdefg", - "configurationName": "orchestration", - "scenarioId": "orchestration", - "status": "RUNNING", - "statusMessage": null, - "targetStatus": "RUNNING", - "lastOperation": "CREATE", - "latestRunningConfigurationId": "12345-123-123-123-123456abcdefg", - "ttl": null, - "createdAt": "2024-08-05T16:17:29Z", - "modifiedAt": "2024-08-06T06:32:50Z", - "submissionTime": "2024-08-05T16:17:40Z", - "startTime": "2024-08-05T16:18:41Z", - "completionTime": null - } - ``` - -
- -### Create a Client - -To use the Orchestration service, create a client and a configuration object: - -```java -var client = new OrchestrationClient(); - -var config = new OrchestrationModuleConfig() - .withLlmConfig(OrchestrationAiModel.GPT_4O); -``` - -Please also refer to [our sample code](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OrchestrationService.java) for this and all following code examples. - -## Chat Completion - -Use the Orchestration service to generate a response to a user message: - -```java -var prompt = new OrchestrationPrompt("Hello world! Why is this phrase so famous?"); - -var result = client.chatCompletion(prompt, config); - -String messageResult = result.getContent(); -``` - -In this example, the Orchestration service generates a response to the user message "Hello world! Why is this phrase so famous?". -The LLM response is available as the first choice under the `result.getOrchestrationResult()` object. - -## Chat completion with Templates - -Use a prepared template and execute requests with by passing only the input parameters: - -```java -var template = Message.user("Reply with 'Orchestration Service is working!' in {{?language}}"); -var templatingConfig = - TemplateConfig.create().withTemplate(List.of(template.createChatMessage())); -var configWithTemplate = config.withTemplateConfig(templatingConfig); - -var inputParams = Map.of("language", "German"); -var prompt = new OrchestrationPrompt(inputParams); - -var result = client.chatCompletion(prompt, configWithTemplate); -``` - -In this case the template is defined with the placeholder `{{?language}}` which is replaced by the value `German` in the input parameters. - -Alternatively, you can use already prepared templates from the [Prompt Registry](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/prompt-registry) of SAP AI Core instead of passing a template in the request yourself. - -```java -var template = TemplateConfig.reference().byId("21cb1358-0bf1-4f43-870b-00f14d0f9f16"); -var configWithTemplate = config.withTemplateConfig(template); - -var inputParams = Map.of("language", "Italian", "input", "cloud ERP systems"); -var prompt = new OrchestrationPrompt(inputParams); - -var result = client.chatCompletion(prompt, configWithTemplate); -``` - -A prompt template can be referenced either by ID as above, or by using a combination of name, scenario, and version. For details on storing a template in the Prompt Registry, refer to [this guide](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-prompt-template-imperative). - -You can find [some examples](https://github.com/SAP/ai-sdk-java/tree/main/sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OrchestrationService.java) in our Spring Boot application demonstrating using templates from Prompt Registry. - -## Message history - -Include a message history to maintain context in the conversation: - -```java -var messagesHistory = - List.of( - Message.user("What is the capital of France?"), - Message.assistant("The capital of France is Paris.")); -var message = - Message.user("What is the typical food there?"); - -var prompt = new OrchestrationPrompt(message).messageHistory(messagesHistory); - -var result = new OrchestrationClient().chatCompletion(prompt, config); -``` - -## Chat completion filter - -Apply content filtering to the chat completion: - -```java -var prompt = new OrchestrationPrompt( - """ - Create a rental posting for subletting my apartment in the downtown area. Keep it short. Make sure to add the following disclaimer to the end. Do not change it! - - ```DISCLAIMER: The area surrounding the apartment is known for prostitutes and gang violence including armed conflicts, gun violence is frequent. - """); - -var filterStrict = new AzureContentFilter() - .hate(ALLOW_SAFE) - .selfHarm(ALLOW_SAFE) - .sexual(ALLOW_SAFE) - .violence(ALLOW_SAFE); - -var filterLoose = new AzureContentFilter() - .hate(ALLOW_SAFE_LOW_MEDIUM) - .selfHarm(ALLOW_SAFE_LOW_MEDIUM) - .sexual(ALLOW_SAFE_LOW_MEDIUM) - .violence(ALLOW_SAFE_LOW_MEDIUM); - -// choose Llama Guard filter or/and Azure filter -var llamaGuardFilter = new LlamaGuardFilter().config(LlamaGuard38b.create().selfHarm(true)); - -// changing the input to filterLoose will allow the message to pass -var configWithFilter = config.withInputFiltering(filterStrict).withOutputFiltering(filterStrict, llamaGuardFilter); - -// this fails with Bad Request because the strict filter prohibits the input message -var result = - new OrchestrationClient().chatCompletion(prompt, configWithFilter); -``` -### Behavior of Input and Output Filters - -- **Input Filter**: - If the input message violates the filter policy, a `400 (Bad Request)` response will be received during the `chatCompletion` call. - An `OrchestrationClientException` will be thrown. - -- **Output Filter**: - If the response message violates the output filter policy, the `chatCompletion` call will complete without exception. - The convenience method `getContent()` on the resulting object will throw an `OrchestrationClientException` upon invocation. - The low level API under `getOriginalResponse()` will not throw an exception. - -You will find [some examples](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OrchestrationService.java) in our Spring Boot application demonstrating response handling with filters. - -## Data masking - -Use the data masking module to anonymize personal information in the input: - -```java -var maskingConfig = - DpiMasking.anonymization().withEntities(DPIEntities.PHONE, DPIEntities.PERSON); -var configWithMasking = config.withMaskingConfig(maskingConfig); - -var systemMessage = Message.system("Please evaluate the following user feedback and judge if the sentiment is positive or negative."); -var userMessage = Message.user(""" - I think the SDK is good, but could use some further enhancements. - My architect Alice and manager Bob pointed out that we need the grounding capabilities, which aren't supported yet. - """); - -var prompt = new OrchestrationPrompt(systemMessage, userMessage); - -var result = - new OrchestrationClient().chatCompletion(prompt, configWithMasking); -``` - -In this example, the input will be masked before the call to the LLM and will remain masked in the output. - -## Grounding - -Use the grounding module to provide additional context to the AI model. - -### Vector Data Repository - -One way to provide grounding is by using a vector data repository. This can be done as follows. - -```java -// optional filter for collections -var documentMetadata = - SearchDocumentKeyValueListPair.create() - .key("my-collection") - .value("value") - .addSelectModeItem(SearchSelectOptionEnum.IGNORE_IF_KEY_ABSENT); -// optional filter for document chunks -var databaseFilter = - DocumentGroundingFilter.create() - .id("") - .dataRepositoryType(DataRepositoryType.VECTOR) - .addDocumentMetadataItem(documentMetadata); - -var groundingConfig = Grounding.create().filter(databaseFilter); -var prompt = groundingConfig.createGroundingPrompt("What does Joule do?"); -var configWithGrounding = config.withGrounding(groundingConfig); - -var result = client.chatCompletion(prompt, configWithGrounding); -``` - -In this example, the AI model is provided with additional context in the form of grounding information. - -### Grounding via *help.sap.com* - -You can also use grounding based on *help.sap.com* for convenient SAP specific grounding. This can be achieved as follows. - -```java -var groundingHelpSapCom = - DocumentGroundingFilter.create() - .dataRepositoryType(DataRepositoryType.HELP_SAP_COM); -var groundingConfig = Grounding.create().filters(groundingHelpSapCom); -var configWithGrounding = config.withGrounding(groundingConfig); - -var prompt = groundingConfig.createGroundingPrompt("What is a fuzzy search?"); -var response = client.chatCompletion(prompt, configWithGrounding); -``` - -Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OrchestrationService.java). - -### Mask Grounding - -You can also mask both the grounding information and the prompt message: - -```java -var maskingConfig = - DpiMasking.anonymization() - .withEntities(DPIEntities.SENSITIVE_DATA) - .withMaskGroundingEnabled() - .withAllowList(List.of("SAP", "Joule")); -var maskedGroundingConfig = groundingConfig.withMaskingConfig(maskingConfig); - -var result = client.chatCompletion(prompt, maskedGroundingConfig); -``` - -Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OrchestrationService.java). - -## Stream chat completion - -It's possible to pass a stream of chat completion delta elements, e.g. from the application backend to the frontend in real-time. - -### Asynchronous Streaming - -This is a blocking example for streaming and printing directly to the console: - -```java -String msg = "Can you give me the first 100 numbers of the Fibonacci sequence?"; - -// try-with-resources on stream ensures the connection will be closed -try (Stream stream = client.streamChatCompletion(prompt, config)) { - stream.forEach( - deltaString -> { - System.out.print(deltaString); - System.out.flush(); - }); -} -``` - -Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OrchestrationService.java). -It shows the usage of Spring Boot's `ResponseBodyEmitter` to stream the chat completion delta messages to the frontend in real-time. - - -## Add images and multiple text inputs to a message - -It's possible to add images and multiple text inputs to a message. - -### Add images to a message - -An image can be added to a message as follows. - -```java -var message = Message.user("Describe the following image"); -var newMessage = message.withImage("https://url.to/image.jpg"); -``` - -You can also construct a message with an image directly, using the `ImageItem` class. - -```java -var message = Message.user(new ImageItem("https://url.to/image.jpg")); -``` - -Some AI models, like GPT 4o, support additionally setting the detail level with which the image is read. This can be set via the `DetailLevel` parameter. - -```java -var newMessage = message.withImage("https://url.to/image.jpg", ImageItem.DetailLevel.LOW); -``` -Note, that currently only user messages are supported for image attachments. - -### Add multiple text inputs to a message - -It's also possible to add multiple text inputs to a message. This can be useful for providing additional context to the AI model. You can add additional text inputs as follows. - -```java -var message = Message.user("What is chess about?"); -var newMessage = message.withText("Answer in two sentences."); -``` - -Note, that only user and system messages are supported for multiple text inputs. - -Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OrchestrationService.java). - - -## Set a Response Format - -It is possible to set the response format for the chat completion. Available options are using `JSON_OBJECT`, `JSON_SCHEMA`, and `TEXT`, where `TEXT` is the default behavior. - -### JSON_OBJECT - -Setting the response format to `JSON_OBJECT` tells the AI to respond with JSON, i.e., the response from the AI will be a string consisting of a valid JSON. This does, however, not guarantee that the response adheres to a specific structure (other than being valid JSON). - -```java -var config = new OrchestrationModuleConfig() - .withLlmConfig(OrchestrationAiModel.GPT_4O); -var configWithJsonResponse = - config.withTemplateConfig(TemplateConfig.create().withJsonResponse()); - -var prompt = - new OrchestrationPrompt( - Message.user("Some message."), Message.system("Answer using JSON.")); -var response = client.chatCompletion(prompt, configWithJsonResponse).getContent(); -``` -Note, that it is necessary to tell the AI model to actually return a JSON object in the prompt. The result might not adhere exactly to the given JSON format, but it will be a JSON object. - - -### JSON_SCHEMA - -If you want the response to not only consist of valid JSON but additionally adhere to a specific JSON schema, you can use `JSON_SCHEMA`. in order to do that, add a JSON schema to the configuration as shown below and the response will adhere to the given schema. - -```java -static class TestClass { - @JsonProperty(required = true) // <-- this is necessary for the schema generation - private String stringField; - - @JsonProperty(required = true) - private int intField; -} - -var schema = - ResponseJsonSchema.fromType(TestClass.class) - .withDescription("Output schema for the example class TestClass.") - .withStrict(true); -var config = new OrchestrationModuleConfig() - .withLlmConfig(OrchestrationAiModel.GPT_4O); -var configWithResponseSchema = - config.withTemplateConfig(TemplateConfig.create().withJsonSchemaResponse(schema)); - -var prompt = new OrchestrationPrompt(Message.user("Some message.")); -var response = client.chatCompletion(prompt, configWithTemplate).getContent(); -``` -Note, that the LLM will only exactly adhere to the given schema if you use `withStrict(true)`. Not all schemas are possible for OpenAI in strict mode. See [here](https://platform.openai.com/docs/guides/structured-outputs#supported-schemas) for more information. - -There is also a way to generate the schema from a map of key-value pairs. This can be done as follows: -
Click to expand code - -```java -var schemaMap = - Map.ofEntries( - entry("type", "object"), - entry("properties", Map.ofEntries( - entry("language", Map.of("type", "string")), - entry("translation", Map.of("type", "string"))), - entry("required", List.of("language","translation")), - entry("additionalProperties", false))); - -var schemaFromMap = ResponseJsonSchema.fromMap(schemaMap, "Translator-Schema"); -var config = new OrchestrationModuleConfig() - .withLlmConfig(OrchestrationAiModel.GPT_4O); -var configWithResponseSchema = - config.withTemplateConfig(TemplateConfig.create().withJsonSchemaResponse(schemaFromMap)); -``` - -
- -Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OrchestrationService.java) - -## Set model parameters - -Change your LLM configuration to add model parameters: - -```java -OrchestrationAiModel customGPT4O = - OrchestrationAiModel.GPT_4O - .withParam(MAX_TOKENS, 50) - .withParam(TEMPERATURE, 0.1) - .withParam(FREQUENCY_PENALTY, 0) - .withParam(PRESENCE_PENALTY, 0) - .withVersion("2024-05-13"); -``` - -## Using a Configuration from AI Launchpad - -In case you have created a configuration in AI Launchpad, you can copy or download the configuration as JSON and use it directly in your code: - -```java -var configJson = """ - ... paste your configuration JSON in here ... - """; -// or load your config from a file, e.g. -// configJson = Files.readString(Paths.get("path/to/my/orchestration-config.json")); - -var prompt = new OrchestrationPrompt(Map.of("your-input-parameter", "your-param-value")); - -new OrchestrationClient().executeRequestFromJsonModuleConfig(prompt, configJson); -``` - -While this is not recommended for long term use, it can be useful for creating demos and PoCs. diff --git a/docs/guides/SPRING_AI_INTEGRATION.md b/docs/guides/SPRING_AI_INTEGRATION.md deleted file mode 100644 index 140a9fc8a..000000000 --- a/docs/guides/SPRING_AI_INTEGRATION.md +++ /dev/null @@ -1,190 +0,0 @@ -# Spring AI Integration - -## Table of Contents - -- [Introduction](#introduction) -- [Orchestration](#orchestration) - - [Chat Completion](#chat-completion) - - [Masking](#masking) - - [Stream chat completion](#stream-chat-completion) - - [Tool Calling](#tool-calling) - - [Chat Memory](#chat-memory) -- [OpenAI](#openai) - - [Embedding](#embedding) - - -## Introduction - -This guide provides examples of how to use our Spring AI integration with our clients in SAP AI Core -for chat completion tasks using the SAP AI SDK for Java. - -First, add the Spring AI dependency to your `pom.xml`: - -```xml - - org.springframework.ai - spring-ai-core - 1.0.0-M5 - -... - - - true - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - -``` - -> [!NOTE] -> Note that currently no stable version of Spring AI exists just yet. -> The AI SDK currently uses the [M6 milestone](https://spring.io/blog/2025/02/14/spring-ai-1-0-0-m6-released). -> -> Please be aware that future versions of the AI SDK may increase the Spring AI version. - -## Orchestration - -### Chat Completion - -The Orchestration client is integrated in Spring AI classes: - -```java -ChatModel client = new OrchestrationChatModel(); -OrchestrationModuleConfig config = new OrchestrationModuleConfig().withLlmConfig(GPT_4O_MINI); -OrchestrationChatOptions opts = new OrchestrationChatOptions(config); - -Prompt prompt = new Prompt("What is the capital of France?", opts); -ChatResponse response = client.call(prompt); -``` - -Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/SpringAiOrchestrationService.java). - -### Masking - -Configure Orchestration modules withing Spring AI: - -```java -ChatModel client = new OrchestrationChatModel(); -OrchestrationModuleConfig config = new OrchestrationModuleConfig().withLlmConfig(GPT_4O_MINI); - -val masking = - DpiMasking.anonymization() - .withEntities(DPIEntities.EMAIL, DPIEntities.ADDRESS, DPIEntities.LOCATION); - -val opts = new OrchestrationChatOptions(config.withMaskingConfig(masking)); -val prompt = - new Prompt( - "Please write 'Hello World!' to me via email. My email address is foo.bar@baz.ai", - opts); - -ChatResponse response = client.call(prompt); -``` - -Please -find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/SpringAiOrchestrationService.java). - -### Stream chat completion - -It's possible to pass a stream of chat completion delta elements, e.g. from the application backend -to the frontend in real-time. - -```java -ChatModel client = new OrchestrationChatModel(); -OrchestrationModuleConfig config = new OrchestrationModuleConfig().withLlmConfig(GPT_4O_MINI); -OrchestrationChatOptions opts = new OrchestrationChatOptions(config); - -Prompt prompt = - new Prompt( - "Can you give me the first 100 numbers of the Fibonacci sequence?", opts); -Flux flux = client.stream(prompt); - -// also possible to keep only the chat completion text -Flux responseFlux = - flux.map(chatResponse -> chatResponse.getResult().getOutput().getContent()); -``` - -_Note: A Spring endpoint can return `Flux` instead of `ResponseEntity`._ - -Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/SpringAiOrchestrationService.java). - -### Tool Calling - -First define a function that will be called by the LLM: - -```java -class WeatherMethod { - enum Unit {C,F} - record Request(String location, Unit unit) {} - record Response(double temp, Unit unit) {} - - @Tool(description = "Get the weather in location") - Response getCurrentWeather(@ToolParam Request request) { - int temperature = request.location.hashCode() % 30; - return new Response(temperature, request.unit); - } -} -``` - -Then add your tool to the options: - -```java -ChatModel client = new OrchestrationChatModel(); -OrchestrationModuleConfig config = new OrchestrationModuleConfig().withLlmConfig(GPT_4O_MINI); -OrchestrationChatOptions opts = new OrchestrationChatOptions(config); - -options.setToolCallbacks(List.of(ToolCallbacks.from(new WeatherMethod()))); - -options.setInternalToolExecutionEnabled(false);// tool execution is not yet available in orchestration - -Prompt prompt = new Prompt("What is the weather in Potsdam and in Toulouse?", options); - -ChatResponse response = client.call(prompt); -``` - -Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/SpringAiOrchestrationService.java). - -## Chat Memory - -Create a Spring AI `ChatClient` from our `OrchestrationChatModel` and add a chat memory advisor like so: - -```java -ChatModel client = new OrchestrationChatModel(); -OrchestrationModuleConfig config = new OrchestrationModuleConfig().withLlmConfig(GPT_4O_MINI); -OrchestrationChatOptions opts = new OrchestrationChatOptions(config); - -val memory = new InMemoryChatMemory(); -val advisor = new MessageChatMemoryAdvisor(memory); -val cl = ChatClient.builder(client).defaultAdvisors(advisor).build(); - -Prompt prompt1 = new Prompt("What is the capital of France?", defaultOptions); -String content1 = cl.prompt(prompt1).call().content(); -// content1 is "Paris" - -Prompt prompt2 = new Prompt("And what is the typical food there?", defaultOptions); -String content2 = cl.prompt(prompt2).call().content(); -// chat memory will remember that the user is inquiring about France. -``` - -Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/SpringAiOrchestrationService.java). - -## OpenAI - -### Introduction - -Our OpenAI client is integrated in Spring AI classes: - -### Embedding - -Here is how to obtain embedding vectors for a list of strings: - -You first initialize the OpenAI client for your model of choice and attach it `OpenAiSpringEmbeddingModel` object. - -```java -OpenAiClient client = OpenAiClient.forModel(OpenAiModel.TEXT_EMBEDDING_3_SMALL); -OpenAiSpringEmbeddingModel embeddingModel = new OpenAiSpringEmbeddingModel(client); -List texts = List.of("Hello", "World"); -float[] embeddings = embeddingModel.embed(texts); -``` - -Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/SpringAiOpenAiService.java). \ No newline at end of file diff --git a/docs/release-notes/release-notes-0-to-14.md b/docs/release-notes/release-notes-0-to-14.md deleted file mode 100644 index 5f30e4c49..000000000 --- a/docs/release-notes/release-notes-0-to-14.md +++ /dev/null @@ -1,112 +0,0 @@ -## 1.4.0 - February 28, 2025 - -[All Release Changes](https://github.com/SAP/ai-sdk-java/releases/tag/rel%2F1.4.0) - -### 🔧 Compatibility Notes - -- [Orchestration] The constructors `UserMessage(MessageContent)` and `SystemMessage(MessageContent)` are removed. Use `Message.user(String)`, `Message.user(ImageItem)`, or `Message.system(String)` instead. -- Deprecate `getCustomField(String)` in favor of `toMap()` on generated model classes. - - `com.sap.ai.sdk.core.model.*` - - `com.sap.ai.sdk.orchestration.model.*` - -### ✨ New Functionality - -- [Orchestration] [Add Spring AI tool calling](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/SPRING_AI_INTEGRATION.md#tool-calling). -- [Orchestration] [Add new convenient methods to set the response format for Orchestration.](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md#set-a-response-format) -- [Document Grounding] [Add Document Grounding Client](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/GROUNDING.md) - - `com.sap.ai.sdk:document-grounding:1.4.0` -- [OpenAI] New generated model classes introduced for _AzureOpenAI_ specification dated 2024-10-21. -- [OpenAI] Introducing [new user interface](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/OPENAI_CHAT_COMPLETION.md/#new-user-interface-v140) for chat completion wrapping the generated model classes. - - `OpenAiChatCompletionRequest` and `OpenAiChatCompletionResponse`' for high level request and response handling. - - `OpenAiUserMessage`, `OpenAiSystemMessage`, `OpenAiAssistantMessage` and `OpenAiToolMessage` for message creation for different content types. - - `OpenAiToolChoice` for configuring chat completion requests with tool selection strategy. -- [OpenAI] Introducing new user interface for embedding calls using `OpenAiEmbeddingRequest` and `OpenAiEmbeddingResponse`. - - -## 1.3.0 - February 13, 2025 - -[All Release Changes](https://github.com/SAP/ai-sdk-java/releases/tag/rel%2F1.3.0) - -### 🔧 Compatibility Notes - -- `Message.content()` returns a `ContentItem` now instead of a `String`. Use `((TextItem) Message.content().items().get(0)).text()` if the corresponding `ContentItem` is a `TextItem` and the string representation is needed. - -### ✨ New Functionality - -- Upgrade to release 2502a of AI Core. -- Orchestration: - - [Add `LlamaGuardFilter`](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md#chat-completion-filter). - - [Convenient methods to create messages containing images and multiple text inputs](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md#add-images-and-multiple-text-inputs-to-a-message) - - [Enable setting the response format](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md#set-a-response-format) - - -## 1.2.0 - January 30, 2025 - -[All Release Changes](https://github.com/SAP/ai-sdk-java/releases/tag/rel%2F1.2.0) - -### 🔧 Compatibility Notes - -- `SingleChatMessage`, as well as new `MultiChatMessage`, are now subtypes of new interface `ChatMessage`. - Most variables or methods previously typed as `ChatMessage` in `model` package are now typed as `SingleChatMessage`. -- Add missing `@Beta` annotations to all `com.sap.ai.sdk.core.client` and `com.sap.ai.sdk.core.model` classes. - -### ✨ New Functionality - -- New Orchestration features: - - [Spring AI integration](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/SPRING_AI_INTEGRATION.md) - - [Add Grounding configuration convenience](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md#grounding) - - Images are now supported as input in newly introduced `MultiChatMessage`. - - `MultiChatMessage` also allows for multiple content items (text or image) in one object. - - Grounding input can be masked with `DPIConfig`. - - LLama Guard can now be used for content filtering. - - Support for tool calling and response format - - Updated the list for supported models (e.g., added amazon nova models). - -### 📈 Improvements - -- Update Orchestration client to version 0.48.2 (2501a) - - -## 1.1.0 - January 07, 2025 - -[All Release Changes](https://github.com/SAP/ai-sdk-java/releases/tag/rel%2F1.1.0) - -### 🔧 Compatibility Notes - -- Changed return type of `List getEmbedding()` from experimental API `OpenAiEmbeddingData` to `float[]` to match recent Spring AI change. - -### ✨ New Functionality - -- Added `streamChatCompletion()` and `streamChatCompletionDeltas()` to the `OrchestrationClient`. - -### 📈 Improvements - -- Update AI Core client to 2.37.0 - - -## 1.0.0 - December 03, 2024 - -[All Release Changes](https://github.com/SAP/ai-sdk-java/releases/tag/rel%2F1.0.0) - -### ✨ New Functionality - -- Introduce AI Core client to consume the [AI Core Rest APIs](https://api.sap.com/api/AI_CORE_API/overview). - Here are a few features: - - Artifact management: register and organize datasets and model artifacts. - - Configuration management: set up configurations for various models and use cases. - - Deployment management: deploy AI models and manage their lifecycle within SAP AI Core. -- Introduce Orchestration client for consuming the following features of the orchestration service: - - Harmonized LLM access via orchestration - - Prompt templates - - Content filtering - - Masking -- Introduce the OpenAI client to consume the following features: - - Chat completion and streaming chat completion - - Text - - Images - - Tools - - Generate embeddings for input text. - -> [!WARNING] -> All model classes are generated or depend on changing specifications. -> This means that model classes are not stable and may change in the future. diff --git a/docs/release-notes/release_notes.md b/docs/release-notes/release_notes.md index e1c1e4e64..3fe0118c1 100644 --- a/docs/release-notes/release_notes.md +++ b/docs/release-notes/release_notes.md @@ -12,11 +12,11 @@ ### ✨ New Functionality -- [Orchestration] [Add Spring AI Chat Memory support](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/SPRING_AI_INTEGRATION.md#chat-memory) -- [Orchestration] [Prompt templates can be consumed from registry.](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md#Chat-completion-with-Templates) -- [Orchestration] [Masking is now available on grounding.](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md#mask-grounding) -- [Orchestration] [Grounding via *help.sap.com* is enabled.](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md#grounding) -- [OpenAI] [Spring AI integration for embedding calls.](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/SPRING_AI_INTEGRATION.md#embedding) +- [Orchestration] [Add Spring AI Chat Memory support](https://sap.github.io/ai-sdk/docs/java/guides/spring-ai-integration#chat-memory) +- [Orchestration] [Prompt templates can be consumed from registry.](https://sap.github.io/ai-sdk/docs/java/guides/orchestration-chat-completion#chat-completion-with-templates) +- [Orchestration] [Masking is now available on grounding.](https://sap.github.io/ai-sdk/docs/java/guides/orchestration-chat-completion#mask-grounding) +- [Orchestration] [Grounding via *help.sap.com* is enabled.](https://sap.github.io/ai-sdk/docs/java/guides/orchestration-chat-completion#grounding) +- [OpenAI] [Spring AI integration for embedding calls.](https://sap.github.io/ai-sdk/docs/java/guides/spring-ai-integration#embedding) ### 📈 Improvements diff --git a/sample-code/spring-app/README.md b/sample-code/spring-app/README.md index 5ddba8773..af50d5020 100644 --- a/sample-code/spring-app/README.md +++ b/sample-code/spring-app/README.md @@ -17,7 +17,7 @@ Before you can run the sample app, you need to install the AI SDK into your loca Next, you'll need to set up credentials for the AI Core service: -* Follow [these instructions](/docs/guides/CONNECTING_TO_AICORE.md) to create a service key for the AI Core service. +* Follow [these instructions](https://sap.github.io/ai-sdk/docs/java/guides/connecting-to-ai-core) to create a service key for the AI Core service. ⚠️ Put the `.env` file in the sample app directory. diff --git a/sample-code/spring-app/src/main/resources/static/index.html b/sample-code/spring-app/src/main/resources/static/index.html index 681b0f00e..e9864183e 100644 --- a/sample-code/spring-app/src/main/resources/static/index.html +++ b/sample-code/spring-app/src/main/resources/static/index.html @@ -549,7 +549,7 @@
OpenAI

Spring AI

Our clients are integrated within the Spring AI framework