Skip to content

Commit 9cfa2ec

Browse files
committed
Update docs
1 parent 58636f3 commit 9cfa2ec

File tree

5 files changed

+86
-123
lines changed

5 files changed

+86
-123
lines changed

docs/guides/ORCHESTRATION_CHAT_COMPLETION.md

Lines changed: 64 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -68,90 +68,79 @@ In addition to the prerequisites above, we assume you have already set up the fo
6868
```
6969

7070
</details>
71-
72-
### Chat completion with Templates
7371

74-
Use a chat completion template to generate a response in German:
72+
### Create a Client
73+
74+
To use the Orchestration service, create a client and a configuration object:
7575

7676
```java
77-
var llmConfig = LLMModuleConfig.create().modelName("gpt-35-turbo").modelParams(Map.of());
77+
var client = new OrchestrationClient();
7878

79-
var inputParams =
80-
Map.of("input", "Reply with 'Orchestration Service is working!' in German");
81-
var template = ChatMessage.create().role("user").content("{{?input}}");
82-
var templatingConfig = TemplatingModuleConfig.create().template(template);
79+
var config = new OrchestrationModuleConfig()
80+
.withLlmConfig(LLMModuleConfig.create().modelName("gpt-35-turbo").modelParams(Map.of()));
81+
```
82+
83+
Please also refer to [our sample code](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OrchestrationController.java) for this and all following code examples.
84+
85+
### Chat Completion
8386

84-
var config =
85-
CompletionPostRequest.create()
86-
.orchestrationConfig(
87-
OrchestrationConfig.create()
88-
.moduleConfigurations(
89-
ModuleConfigs.create()
90-
.llmModuleConfig(llmConfig)
91-
.templatingModuleConfig(templatingConfig)))
92-
.inputParams(inputParams);
87+
Use the Orchestration service to generate a response to a user message:
88+
89+
```java
90+
var prompt = new OrchestrationPrompt("Hello world! Why is this phrase so famous?");
9391

94-
CompletionPostResponse result =
95-
new OrchestrationClient().chatCompletion(config);
92+
var result = client.chatCompletion(prompt, config);
9693

9794
String messageResult =
98-
result.getOrchestrationResult().getChoices().get(0).getMessage().getContent();
95+
result.getOrchestrationResult().getChoices().get(0).getMessage().getContent();
9996
```
10097

101-
See [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OrchestrationController.java)
98+
In this example, the Orchestration service generates a response to the user message "Hello world! Why is this phrase so famous?".
99+
The LLM response is available as the first choice under the `result.getOrchestrationResult()` object.
102100

103-
### Message history
101+
### Chat completion with Templates
104102

105-
Include a message history to maintain context in the conversation:
103+
Use a prepared template and execute requests with by passing only the input parameters:
106104

107105
```java
108-
var llmConfig = LLMModuleConfig.create().modelName("gpt-35-turbo").modelParams(Map.of());
106+
var template = ChatMessage.create().role("user").content("{{?input}}");
107+
var templatingConfig = TemplatingModuleConfig.create().template(template);
109108

110-
List<ChatMessage> messagesHistory =
111-
List.of(
112-
ChatMessage.create().role("user").content("What is the capital of France?"),
113-
ChatMessage.create().role("assistant").content("The capital of France is Paris."));
109+
var inputParams =
110+
Map.of("input", "Reply with 'Orchestration Service is working!' in German");
111+
var prompt = new OrchestrationPrompt(inputParams);
114112

113+
var result = client.chatCompletion(prompt, config.withTemplateConfig(templatingConfig));
114+
```
115+
116+
### Message history
117+
118+
Include a message history to maintain context in the conversation:
119+
120+
```java
121+
var messagesHistory =
122+
List.of(
123+
ChatMessage.create().role("user").content("What is the capital of France?"),
124+
ChatMessage.create().role("assistant").content("The capital of France is Paris."));
115125
var message =
116-
ChatMessage.create().role("user").content("What is the typical food there?");
117-
var templatingConfig = TemplatingModuleConfig.create().template(message);
118-
119-
var config =
120-
CompletionPostRequest.create()
121-
.orchestrationConfig(
122-
OrchestrationConfig.create()
123-
.moduleConfigurations(
124-
ModuleConfigs.create()
125-
.llmModuleConfig(llmConfig)
126-
.templatingModuleConfig(templatingConfig)))
127-
.messagesHistory(messagesHistory);
128-
129-
CompletionPostResponse result =
130-
new OrchestrationClient().chatCompletion(config);
126+
ChatMessage.create().role("user").content("What is the typical food there?");
131127

132-
String messageResult =
133-
result.getOrchestrationResult().getChoices().get(0).getMessage().getContent();
134-
```
128+
var prompt = new OrchestrationPrompt(message).messageHistory(messagesHistory);
135129

136-
See [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OrchestrationController.java)
130+
var result = new OrchestrationClient().chatCompletion(prompt, config);
131+
```
137132

138133
### Chat completion filter
139134

140135
Apply content filtering to the chat completion:
141136

142137
```java
143-
var llmConfig = LLMModuleConfig.create().modelName("gpt-35-turbo").modelParams(Map.of());
144-
145-
var inputParams =
146-
Map.of(
147-
"disclaimer",
148-
"```DISCLAIMER: The area surrounding the apartment is known for prostitutes and gang violence including armed conflicts, gun violence is frequent.");
149-
var template =
150-
ChatMessage.create()
151-
.role("user")
152-
.content(
153-
"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}}");
154-
var templatingConfig = TemplatingModuleConfig.create().template(template);
138+
var prompt = new OrchestrationPrompt(
139+
"""
140+
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!
141+
142+
```DISCLAIMER: The area surrounding the apartment is known for prostitutes and gang violence including armed conflicts, gun violence is frequent.
143+
""");
155144

156145
var filterStrict =
157146
FilterConfig.create()
@@ -176,40 +165,19 @@ var filterLoose =
176165
var filteringConfig =
177166
FilteringModuleConfig.create()
178167
// changing the input to filterLoose will allow the message to pass
179-
.input(FilteringConfig.create().filters(filterStrict))
180-
.output(FilteringConfig.create().filters(filterStrict));
181-
182-
var config =
183-
CompletionPostRequest.create()
184-
.orchestrationConfig(
185-
OrchestrationConfig.create()
186-
.moduleConfigurations(
187-
ModuleConfigs.create()
188-
.llmModuleConfig(llmConfig)
189-
.templatingModuleConfig(templatingConfig)
190-
.filteringModuleConfig(filteringConfig)))
191-
.inputParams(inputParams);
168+
.input(InputFilteringConfig.create().filters(filterStrict))
169+
.output(OutputFilteringConfig.create().filters(filterStrict));
192170

193171
// this fails with Bad Request because the strict filter prohibits the input message
194-
CompletionPostResponse result =
195-
new OrchestrationClient().chatCompletion(config);
196-
197-
String messageResult =
198-
result.getOrchestrationResult().getChoices().get(0).getMessage().getContent();
172+
var result =
173+
new OrchestrationClient().chatCompletion(prompt, config.withFilteringConfig(filteringConfig));
199174
```
200175

201-
See [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OrchestrationController.java)
202-
203176
### Data masking
204177

205178
Use the data masking module to anonymize personal information in the input:
206179

207180
```java
208-
var inputParams = Map.of("privateInfo", "Patrick Morgan +49 (970) 333-3833");
209-
var template =
210-
ChatMessage.create().role("user").content("What is the nationality of {{?privateInfo}}");
211-
var templatingConfig = TemplatingModuleConfig.create().template(template);
212-
213181
var maskingProvider =
214182
MaskingProviderConfig.create()
215183
.type(MaskingProviderConfig.TypeEnum.SAP_DATA_PRIVACY_INTEGRATION)
@@ -219,28 +187,24 @@ var maskingProvider =
219187
DPIEntityConfig.create().type(DPIEntities.PERSON));
220188
var maskingConfig = MaskingModuleConfig.create().maskingProviders(maskingProvider);
221189

222-
CompletionPostRequest config =
223-
CompletionPostRequest.create()
224-
.orchestrationConfig(
225-
OrchestrationConfig.create()
226-
.moduleConfigurations(
227-
ModuleConfigs.create()
228-
.llmModuleConfig(LLM_CONFIG)
229-
.templatingModuleConfig(templatingConfig)
230-
.maskingModuleConfig(maskingConfig)))
231-
.inputParams(inputParams);
190+
var systemMessage = ChatMessage.create()
191+
.role("system")
192+
.content("Please evaluate the following user feedback and judge if the sentiment is positive or negative.");
193+
var userMessage = ChatMessage.create()
194+
.role("user")
195+
.content("""
196+
I think the SDK is good, but could use some further enhancements.
197+
My architect Alice and manager Bob pointed out that we need the grounding capabilities, which aren't supported yet.
198+
""");
232199

233-
CompletionPostResponse result =
234-
new OrchestrationClient().chatCompletion(config);
200+
var prompt = new OrchestrationPrompt(systemMessage, userMessage);
235201

236-
String messageResult =
237-
result.getOrchestrationResult().getChoices().get(0).getMessage().getContent();
202+
var result =
203+
new OrchestrationClient().chatCompletion(prompt, config.withMaskingConfig(maskingConfig));
238204
```
239205

240206
In this example, the input will be masked before the call to the LLM. Note that data cannot be unmasked in the LLM output.
241207

242-
See [an example in our Spring Boot application](../../sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/controllers/OrchestrationController.java)
243-
244208
### Set model parameters
245209

246210
Change your LLM module configuration to add model parameters:

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ final class ConfigToRequestTransformer {
1919
@Nonnull
2020
static CompletionPostRequest toCompletionPostRequest(
2121
@Nonnull final OrchestrationPrompt prompt, @Nonnull final OrchestrationModuleConfig config) {
22-
val template = toTemplateModuleConfig(prompt, config.getTemplate());
22+
val template = toTemplateModuleConfig(prompt, config.getTemplateConfig());
2323
// note that the config is immutable and implicitly copied here
2424
// copying is required here, to not alter the original config object, which might be reused for
2525
// subsequent requests
26-
val configCopy = config.withTemplate(template);
26+
val configCopy = config.withTemplateConfig(template);
2727

2828
return CompletionPostRequest.create()
2929
.orchestrationConfig(
@@ -62,7 +62,7 @@ static ModuleConfigs toModuleConfigs(@Nonnull final OrchestrationModuleConfig co
6262
val moduleConfig =
6363
ModuleConfigs.create()
6464
.llmModuleConfig(llmConfig)
65-
.templatingModuleConfig(config.getTemplate());
65+
.templatingModuleConfig(config.getTemplateConfig());
6666

6767
Option.of(config.getFilteringConfig()).forEach(moduleConfig::filteringModuleConfig);
6868
Option.of(config.getMaskingConfig()).forEach(moduleConfig::maskingModuleConfig);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class OrchestrationModuleConfig {
4141
* A template to be populated with input parameters. Upon request execution, this template will be
4242
* enhanced with any messages and parameter values from {@link OrchestrationPrompt}.
4343
*/
44-
@Nullable TemplatingModuleConfig template;
44+
@Nullable TemplatingModuleConfig templateConfig;
4545

4646
/** A masking configuration to pseudonymous or anonymize sensitive data in the input. */
4747
@Nullable MaskingModuleConfig maskingConfig;

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

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.sap.ai.sdk.orchestration.client.model.MaskingModuleConfig;
1717
import com.sap.ai.sdk.orchestration.client.model.MaskingProviderConfig;
1818
import com.sap.ai.sdk.orchestration.client.model.OutputFilteringConfig;
19+
import com.sap.ai.sdk.orchestration.client.model.TemplatingModuleConfig;
1920
import java.util.Arrays;
2021
import java.util.List;
2122
import java.util.Map;
@@ -29,14 +30,11 @@
2930
@RestController
3031
@RequestMapping("/orchestration")
3132
class OrchestrationController {
33+
static final LLMModuleConfig LLM_CONFIG =
34+
LLMModuleConfig.create().modelName("gpt-35-turbo").modelParams(Map.of());
3235

33-
private static final OrchestrationClient CLIENT = new OrchestrationClient();
34-
35-
static final String MODEL = "gpt-35-turbo";
36-
37-
private static final LLMModuleConfig LLM_CONFIG =
38-
LLMModuleConfig.create().modelName(MODEL).modelParams(Map.of());
39-
private static final OrchestrationModuleConfig CONFIG =
36+
private final OrchestrationClient client = new OrchestrationClient();
37+
private final OrchestrationModuleConfig config =
4038
new OrchestrationModuleConfig().withLlmConfig(LLM_CONFIG);
4139

4240
/**
@@ -47,10 +45,9 @@ class OrchestrationController {
4745
@GetMapping("/completion")
4846
@Nonnull
4947
public CompletionPostResponse completion() {
50-
5148
final var prompt = new OrchestrationPrompt("Hello world! Why is this phrase so famous?");
5249

53-
return CLIENT.chatCompletion(prompt, CONFIG);
50+
return client.chatCompletion(prompt, config);
5451
}
5552

5653
/**
@@ -61,12 +58,14 @@ public CompletionPostResponse completion() {
6158
@GetMapping("/template")
6259
@Nonnull
6360
public CompletionPostResponse template() {
64-
final var message = ChatMessage.create().role("user").content("{{?input}}");
61+
final var template = ChatMessage.create().role("user").content("{{?input}}");
62+
final var templatingConfig = TemplatingModuleConfig.create().template(template);
63+
6564
final var inputParams =
6665
Map.of("input", "Reply with 'Orchestration Service is working!' in German");
6766

68-
final var prompt = new OrchestrationPrompt(inputParams, message);
69-
return CLIENT.chatCompletion(prompt, CONFIG);
67+
final var prompt = new OrchestrationPrompt(inputParams);
68+
return client.chatCompletion(prompt, config.withTemplateConfig(templatingConfig));
7069
}
7170

7271
/**
@@ -86,7 +85,7 @@ public CompletionPostResponse messagesHistory() {
8685

8786
final var prompt = new OrchestrationPrompt(message).messageHistory(messagesHistory);
8887

89-
return CLIENT.chatCompletion(prompt, CONFIG);
88+
return client.chatCompletion(prompt, config);
9089
}
9190

9291
/**
@@ -99,7 +98,6 @@ public CompletionPostResponse messagesHistory() {
9998
@Nonnull
10099
public CompletionPostResponse filter(
101100
@Nonnull @PathVariable("threshold") final AzureThreshold threshold) {
102-
103101
final var prompt =
104102
new OrchestrationPrompt(
105103
"""
@@ -109,7 +107,7 @@ public CompletionPostResponse filter(
109107
""");
110108
final var filterConfig = createAzureContentFilter(threshold);
111109

112-
return CLIENT.chatCompletion(prompt, CONFIG.withFilteringConfig(filterConfig));
110+
return client.chatCompletion(prompt, config.withFilteringConfig(filterConfig));
113111
}
114112

115113
/**
@@ -163,7 +161,7 @@ public CompletionPostResponse maskingAnonymization() {
163161
final var maskingConfig =
164162
createMaskingConfig(MaskingProviderConfig.MethodEnum.ANONYMIZATION, DPIEntities.PERSON);
165163

166-
return CLIENT.chatCompletion(prompt, CONFIG.withMaskingConfig(maskingConfig));
164+
return client.chatCompletion(prompt, config.withMaskingConfig(maskingConfig));
167165
}
168166

169167
/**
@@ -203,7 +201,7 @@ public CompletionPostResponse maskingPseudonymization() {
203201
DPIEntities.PERSON,
204202
DPIEntities.EMAIL);
205203

206-
return CLIENT.chatCompletion(prompt, CONFIG.withMaskingConfig(maskingConfig));
204+
return client.chatCompletion(prompt, config.withMaskingConfig(maskingConfig));
207205
}
208206

209207
/**

sample-code/spring-app/src/test/java/com/sap/ai/sdk/app/controllers/OrchestrationTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void testTemplate() {
4141
assertThat(llm.getId()).isNotEmpty();
4242
assertThat(llm.getObject()).isEqualTo("chat.completion");
4343
assertThat(llm.getCreated()).isGreaterThan(1);
44-
assertThat(llm.getModel()).isEqualTo(OrchestrationController.MODEL);
44+
assertThat(llm.getModel()).isEqualTo(OrchestrationController.LLM_CONFIG.getModelName());
4545
var choices = llm.getChoices();
4646
assertThat(choices.get(0).getIndex()).isZero();
4747
assertThat(choices.get(0).getMessage().getContent()).isNotEmpty();
@@ -53,7 +53,8 @@ void testTemplate() {
5353
assertThat(usage.getTotalTokens()).isGreaterThan(1);
5454
assertThat(result.getOrchestrationResult().getObject()).isEqualTo("chat.completion");
5555
assertThat(result.getOrchestrationResult().getCreated()).isGreaterThan(1);
56-
assertThat(result.getOrchestrationResult().getModel()).isEqualTo(OrchestrationController.MODEL);
56+
assertThat(result.getOrchestrationResult().getModel())
57+
.isEqualTo(OrchestrationController.LLM_CONFIG.getModelName());
5758
choices = result.getOrchestrationResult().getChoices();
5859
assertThat(choices.get(0).getIndex()).isZero();
5960
assertThat(choices.get(0).getMessage().getContent()).isNotEmpty();

0 commit comments

Comments
 (0)