Skip to content

Commit 248b049

Browse files
feat: [Orchestration] Enable grounding via help.sap.com (#372)
* Make it work * Add unit test * Add docs and release notes * Add e2e test * Small changes, adjust test coverage * Update docs/guides/ORCHESTRATION_CHAT_COMPLETION.md Co-authored-by: Charles Dubois <[email protected]> * Update orchestration/src/test/resources/__files/groundingHelpSapComResponse.json Co-authored-by: Charles Dubois <[email protected]> * Update orchestration/src/test/resources/__files/groundingHelpSapComResponse.json Co-authored-by: Charles Dubois <[email protected]> * Update ORCHESTRATION_CHAT_COMPLETION.md * small fix --------- Co-authored-by: Jonas Israel <[email protected]> Co-authored-by: Charles Dubois <[email protected]>
1 parent 774ca42 commit 248b049

File tree

10 files changed

+202
-3
lines changed

10 files changed

+202
-3
lines changed

docs/guides/ORCHESTRATION_CHAT_COMPLETION.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,10 @@ In this example, the input will be masked before the call to the LLM and will re
227227

228228
Use the grounding module to provide additional context to the AI model.
229229

230+
### Vector Data Repository
231+
232+
One way to provide grounding is by using a vector data repository. This can be done as follows.
233+
230234
```java
231235
// optional filter for collections
232236
var documentMetadata =
@@ -250,7 +254,20 @@ var result = client.chatCompletion(prompt, configWithGrounding);
250254

251255
In this example, the AI model is provided with additional context in the form of grounding information.
252256

253-
`Grounding.create()` is by default a document grounding service with a vector data repository.
257+
### Grounding via *help.sap.com*
258+
259+
You can also use grounding based on *help.sap.com* for convenient SAP specific grounding. This can be achieved as follows.
260+
261+
```java
262+
var groundingHelpSapCom =
263+
DocumentGroundingFilter.create()
264+
.dataRepositoryType(DataRepositoryType.HELP_SAP_COM);
265+
var groundingConfig = Grounding.create().filters(groundingHelpSapCom);
266+
var configWithGrounding = config.withGrounding(groundingConfig);
267+
268+
var prompt = groundingConfig.createGroundingPrompt("What is a fuzzy search?");
269+
var response = client.chatCompletion(prompt, configWithGrounding);
270+
```
254271

255272
Please find [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OrchestrationService.java).
256273

docs/release-notes/release_notes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
- [Orchestration] [Add Spring AI Chat Memory support](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/SPRING_AI_INTEGRATION.md#chat-memory)
1616
- [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)
17+
- [Orchestration] [Grounding via *help.sap.com* is enabled.](https://github.com/SAP/ai-sdk-java/tree/main/docs/guides/ORCHESTRATION_CHAT_COMPLETION.md#grounding)
1718

1819
### 📈 Improvements
1920

orchestration/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
<coverage.complexity>83%</coverage.complexity>
3535
<coverage.line>94%</coverage.line>
3636
<coverage.instruction>94%</coverage.instruction>
37-
<coverage.branch>75%</coverage.branch>
37+
<coverage.branch>77%</coverage.branch>
3838
<coverage.method>93%</coverage.method>
3939
<coverage.class>100%</coverage.class>
4040
</properties>

orchestration/src/main/java/com/sap/ai/sdk/orchestration/Grounding.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ public GroundingModuleConfig createConfig() {
8585
.outputParam("groundingContext")
8686
.filters(filters);
8787

88+
if (filters.contains(
89+
DocumentGroundingFilter.create().dataRepositoryType(DataRepositoryType.HELP_SAP_COM))) {
90+
groundingConfigConfig.setMetadataParams(null);
91+
}
92+
8893
return GroundingModuleConfig.create()
8994
.type(documentGroundingService)
9095
.config(groundingConfigConfig);

orchestration/src/test/java/com/sap/ai/sdk/orchestration/OrchestrationUnitTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,34 @@ void testGrounding() throws IOException {
206206
}
207207
}
208208

209+
@Test
210+
void testGroundingWithHelpSapCom() throws IOException {
211+
stubFor(
212+
post(urlPathEqualTo("/completion"))
213+
.willReturn(
214+
aResponse()
215+
.withBodyFile("groundingHelpSapComResponse.json")
216+
.withHeader("Content-Type", "application/json")));
217+
val groundingHelpSapCom =
218+
DocumentGroundingFilter.create().dataRepositoryType(DataRepositoryType.HELP_SAP_COM);
219+
val groundingConfig = Grounding.create().filters(groundingHelpSapCom);
220+
val configWithGrounding = config.withGrounding(groundingConfig);
221+
222+
val prompt = groundingConfig.createGroundingPrompt("What is a fuzzy search?");
223+
val response = client.chatCompletion(prompt, configWithGrounding);
224+
225+
assertThat(
226+
response.getOriginalResponse().getModuleResults().getGrounding().getData().toString())
227+
.contains(
228+
"A fuzzy search is a search technique that is designed to be fast and tolerant of errors");
229+
assertThat(response.getContent()).startsWith("A fuzzy search is a search technique");
230+
231+
try (var requestInputStream = fileLoader.apply("groundingHelpSapComRequest.json")) {
232+
final String request = new String(requestInputStream.readAllBytes());
233+
verify(postRequestedFor(urlPathEqualTo("/completion")).withRequestBody(equalToJson(request)));
234+
}
235+
}
236+
209237
@Test
210238
void testTemplating() throws IOException {
211239
stubFor(
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"request_id": "47ee9f8c-3c54-4028-aabe-358f89409de9",
3+
"module_results": {
4+
"grounding": {
5+
"message": "grounding result",
6+
"data": {
7+
"grounding_query": "grounding call",
8+
"grounding_result": "A fuzzy search is a search technique that is designed to be fast and tolerant of errors"
9+
}
10+
},
11+
"templating": [
12+
{
13+
"role": "user",
14+
"content": "What is a fuzzy search? Use the following information as additional context: A fuzzy search is a search technique that is designed to be fast and tolerant of errors"
15+
}
16+
],
17+
"llm": {
18+
"id": "chatcmpl-B7fExAgihXpKnBaaJ3uXnLgmaC6Ox",
19+
"object": "chat.completion",
20+
"created": 1741166523,
21+
"model": "gpt-4o-2024-08-06",
22+
"system_fingerprint": "fp_b705f0c291",
23+
"choices": [
24+
{
25+
"index": 0,
26+
"message": {
27+
"role": "assistant",
28+
"content": "A fuzzy search is a search technique that is designed to be fast and tolerant of errors, such as additional or missing characters or other types of spelling mistakes. This feature is particularly useful in scenarios where exact matches are not required or when dealing with imperfect data"
29+
},
30+
"finish_reason": "length"
31+
}
32+
],
33+
"usage": {
34+
"completion_tokens": 50,
35+
"prompt_tokens": 1222,
36+
"total_tokens": 1272
37+
}
38+
}
39+
},
40+
"orchestration_result": {
41+
"id": "chatcmpl-B7fExAgihXpKnBaaJ3uXnLgmaC6Ox",
42+
"object": "chat.completion",
43+
"created": 1741166523,
44+
"model": "gpt-4o-2024-08-06",
45+
"system_fingerprint": "fp_b705f0c291",
46+
"choices": [
47+
{
48+
"index": 0,
49+
"message": {
50+
"role": "assistant",
51+
"content": "A fuzzy search is a search technique that is designed to be fast and tolerant of errors, such as additional or missing characters or other types of spelling mistakes. This feature is particularly useful in scenarios where exact matches are not required or when dealing with imperfect data"
52+
},
53+
"finish_reason": "length"
54+
}
55+
],
56+
"usage": {
57+
"completion_tokens": 50,
58+
"prompt_tokens": 1222,
59+
"total_tokens": 1272
60+
}
61+
}
62+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"orchestration_config" : {
3+
"module_configurations" : {
4+
"llm_module_config" : {
5+
"model_name" : "gpt-4o",
6+
"model_params" : {
7+
"max_tokens" : 50,
8+
"temperature" : 0.1,
9+
"frequency_penalty" : 0,
10+
"presence_penalty" : 0,
11+
"top_p" : 1,
12+
"n" : 1
13+
},
14+
"model_version" : "latest"
15+
},
16+
"templating_module_config" : {
17+
"template" : [ {
18+
"role" : "user",
19+
"content" : "{{?userMessage}} Use the following information as additional context: {{?groundingContext}}"
20+
} ],
21+
"defaults" : { },
22+
"tools" : [ ]
23+
},
24+
"grounding_module_config" : {
25+
"type" : "document_grounding_service",
26+
"config" : {
27+
"filters" : [ {
28+
"data_repositories" : [ "*" ],
29+
"data_repository_type" : "help.sap.com",
30+
"data_repository_metadata" : [ ],
31+
"document_metadata" : [ ],
32+
"chunk_metadata" : [ ]
33+
} ],
34+
"input_params" : [ "userMessage" ],
35+
"output_param" : "groundingContext"
36+
}
37+
}
38+
},
39+
"stream" : false
40+
},
41+
"input_params" : {
42+
"userMessage" : "What is a fuzzy search?"
43+
},
44+
"messages_history" : [ ]
45+
}

sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OrchestrationController.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,17 @@ Object grounding(
191191
return response.getContent();
192192
}
193193

194+
@GetMapping("/groundingHelpSapCom")
195+
@Nonnull
196+
Object groundingHelpSapCom(
197+
@Nullable @RequestParam(value = "format", required = false) final String format) {
198+
final var response = service.groundingHelpSapCom("What is a fuzzy search?");
199+
if ("json".equals(format)) {
200+
return response;
201+
}
202+
return response.getContent();
203+
}
204+
194205
@GetMapping("/image")
195206
@Nonnull
196207
Object imageInput(@RequestParam(value = "format", required = false) final String format) {

sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OrchestrationService.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,26 @@ public OrchestrationChatResponse grounding(@Nonnull final String userMessage) {
340340
return client.chatCompletion(prompt, configWithGrounding);
341341
}
342342

343+
/**
344+
* Using grounding via *help.sap.com* to provide additional SAP-specific context to the AI model.
345+
*
346+
* @link <a href="https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/grounding">SAP
347+
* AI Core: Orchestration - Grounding</a>
348+
* @param userMessage the user message to provide grounding for
349+
* @return the assistant response object
350+
*/
351+
@Nonnull
352+
public OrchestrationChatResponse groundingHelpSapCom(@Nonnull final String userMessage) {
353+
val groundingHelpSapCom =
354+
DocumentGroundingFilter.create().dataRepositoryType(DataRepositoryType.HELP_SAP_COM);
355+
val groundingConfig = Grounding.create().filters(groundingHelpSapCom);
356+
val configWithGrounding = config.withGrounding(groundingConfig);
357+
358+
val prompt = groundingConfig.createGroundingPrompt(userMessage);
359+
360+
return client.chatCompletion(prompt, configWithGrounding);
361+
}
362+
343363
/**
344364
* Chat request to OpenAI through the Orchestration service using response format with JSON
345365
* schema.

sample-code/spring-app/src/main/resources/static/index.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,17 @@ <h2>Orchestration</h2>
349349
</div>
350350
</div>
351351
</li>
352-
352+
<li class="list-group-item">
353+
<div class="info-tooltip">
354+
<button type="submit" formaction="/orchestration/groundingHelpSapCom"
355+
class="link-offset-2-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover endpoint">
356+
<code>/orchestration/groundingHelpSapCom</code>
357+
</button>
358+
<div class="tooltip-content">
359+
Using grounding via *help.sap.com* to provide additional SAP-specific context to the AI model.
360+
</div>
361+
</div>
362+
</li>
353363
<li class="list-group-item">
354364
<div class="info-tooltip">
355365
<button type="submit" formaction="/orchestration/image"

0 commit comments

Comments
 (0)