Skip to content

Commit 1e98f82

Browse files
committed
Change Azure embedding and chat options 'model' property to 'deployment-name'
* Azure uses 'deployment-name' when provisioning models and is what needs to be passed in to the client, not the model name. This is a difference with the OpenAI API that doesn't have a deployment-name This change aligns the terminology used with Azure so that there is less confusion when setting configuration property values Fixes #10
1 parent 777b79e commit 1e98f82

File tree

13 files changed

+56
-49
lines changed

13 files changed

+56
-49
lines changed

models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatClient.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public class AzureOpenAiChatClient
7575
extends AbstractFunctionCallSupport<ChatRequestMessage, ChatCompletionsOptions, ChatCompletions>
7676
implements ChatClient, StreamingChatClient {
7777

78-
private static final String DEFAULT_MODEL = "gpt-35-turbo";
78+
private static final String DEFAULT_DEPLOYMENT_NAME = "gpt-35-turbo";
7979

8080
private static final Float DEFAULT_TEMPERATURE = 0.7f;
8181

@@ -93,7 +93,10 @@ public class AzureOpenAiChatClient
9393

9494
public AzureOpenAiChatClient(OpenAIClient microsoftOpenAiClient) {
9595
this(microsoftOpenAiClient,
96-
AzureOpenAiChatOptions.builder().withModel(DEFAULT_MODEL).withTemperature(DEFAULT_TEMPERATURE).build());
96+
AzureOpenAiChatOptions.builder()
97+
.withDeploymentName(DEFAULT_DEPLOYMENT_NAME)
98+
.withTemperature(DEFAULT_TEMPERATURE)
99+
.build());
97100
}
98101

99102
public AzureOpenAiChatClient(OpenAIClient microsoftOpenAiClient, AzureOpenAiChatOptions options) {
@@ -131,12 +134,7 @@ public ChatResponse call(Prompt prompt) {
131134
options.setStream(false);
132135

133136
logger.trace("Azure ChatCompletionsOptions: {}", options);
134-
135137
ChatCompletions chatCompletions = this.callWithFunctionSupport(options);
136-
137-
// ChatCompletions chatCompletions =
138-
// this.openAIClient.getChatCompletions(options.getModel(), options);
139-
140138
logger.trace("Azure ChatCompletions: {}", chatCompletions);
141139

142140
List<Generation> generations = chatCompletions.getChoices()
@@ -323,7 +321,7 @@ private ChatCompletionsOptions merge(ChatCompletionsOptions azureOptions, AzureO
323321
mergedAzureOptions.setUser(azureOptions.getUser() != null ? azureOptions.getUser() : springAiOptions.getUser());
324322

325323
mergedAzureOptions
326-
.setModel(azureOptions.getModel() != null ? azureOptions.getModel() : springAiOptions.getModel());
324+
.setModel(azureOptions.getModel() != null ? azureOptions.getModel() : springAiOptions.getDeploymentName());
327325

328326
return mergedAzureOptions;
329327
}
@@ -376,8 +374,8 @@ private ChatCompletionsOptions merge(AzureOpenAiChatOptions springAiOptions, Cha
376374
mergedAzureOptions.setUser(springAiOptions.getUser());
377375
}
378376

379-
if (springAiOptions.getModel() != null) {
380-
mergedAzureOptions.setModel(springAiOptions.getModel());
377+
if (springAiOptions.getDeploymentName() != null) {
378+
mergedAzureOptions.setModel(springAiOptions.getDeploymentName());
381379
}
382380

383381
return mergedAzureOptions;

models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,11 @@ public class AzureOpenAiChatOptions implements FunctionCallingOptions, ChatOptio
120120
private Double frequencyPenalty;
121121

122122
/**
123-
* The model name to provide as part of this completions request. Not applicable to
124-
* Azure OpenAI, where deployment information should be included in the Azure resource
125-
* URI that's connected to.
123+
* The deployment name as defined in Azure Open AI Studio when creating a deployment
124+
* backed by an Azure OpenAI base model.
126125
*/
127-
@JsonProperty(value = "model")
128-
private String model;
126+
@JsonProperty(value = "deployment_name")
127+
private String deploymentName;
129128

130129
/**
131130
* OpenAI Tool Function Callbacks to register with the ChatClient. For Prompt Options
@@ -169,8 +168,8 @@ public Builder(AzureOpenAiChatOptions options) {
169168
this.options = options;
170169
}
171170

172-
public Builder withModel(String model) {
173-
this.options.model = model;
171+
public Builder withDeploymentName(String deploymentName) {
172+
this.options.deploymentName = deploymentName;
174173
return this;
175174
}
176175

@@ -298,12 +297,12 @@ public void setFrequencyPenalty(Double frequencyPenalty) {
298297
this.frequencyPenalty = frequencyPenalty;
299298
}
300299

301-
public String getModel() {
302-
return this.model;
300+
public String getDeploymentName() {
301+
return this.deploymentName;
303302
}
304303

305-
public void setModel(String model) {
306-
this.model = model;
304+
public void setDeploymentName(String deploymentName) {
305+
this.deploymentName = deploymentName;
307306
}
308307

309308
@Override

models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingClient.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.springframework.ai.embedding.EmbeddingResponseMetadata;
3737
import org.springframework.ai.model.ModelOptionsUtils;
3838
import org.springframework.util.Assert;
39+
import org.springframework.util.StringUtils;
3940

4041
public class AzureOpenAiEmbeddingClient extends AbstractEmbeddingClient {
4142

@@ -53,7 +54,7 @@ public AzureOpenAiEmbeddingClient(OpenAIClient azureOpenAiClient) {
5354

5455
public AzureOpenAiEmbeddingClient(OpenAIClient azureOpenAiClient, MetadataMode metadataMode) {
5556
this(azureOpenAiClient, metadataMode,
56-
AzureOpenAiEmbeddingOptions.builder().withModel("text-embedding-ada-002").build());
57+
AzureOpenAiEmbeddingOptions.builder().withDeploymentName("text-embedding-ada-002").build());
5758
}
5859

5960
public AzureOpenAiEmbeddingClient(OpenAIClient azureOpenAiClient, MetadataMode metadataMode,
@@ -93,7 +94,7 @@ public EmbeddingResponse call(EmbeddingRequest embeddingRequest) {
9394
EmbeddingsOptions toEmbeddingOptions(EmbeddingRequest embeddingRequest) {
9495
var azureOptions = new EmbeddingsOptions(embeddingRequest.getInstructions());
9596
if (this.defaultOptions != null) {
96-
azureOptions.setModel(this.defaultOptions.getModel());
97+
azureOptions.setModel(this.defaultOptions.getDeploymentName());
9798
azureOptions.setUser(this.defaultOptions.getUser());
9899
}
99100
if (embeddingRequest.getOptions() != null && !EmbeddingOptions.EMPTY.equals(embeddingRequest.getOptions())) {

models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingOptions.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ public class AzureOpenAiEmbeddingOptions implements EmbeddingOptions {
3535
private String user;
3636

3737
/**
38-
* The model name to provide as part of this embeddings request. Not applicable to
39-
* Azure OpenAI, where deployment information should be included in the Azure resource
40-
* URI that's connected to.
38+
* The deployment name as defined in Azure Open AI Studio when creating a deployment
39+
* backed by an Azure OpenAI base model. If using Azure OpenAI library to communicate
40+
* with OpenAI (not Azure OpenAI) then this value will be used as the name of the
41+
* model. The json serialization of this field is 'model'.
4142
*/
4243
@JsonProperty(value = "model")
43-
private String model;
44+
private String deploymentName;
4445

4546
public static Builder builder() {
4647
return new Builder();
@@ -55,8 +56,8 @@ public Builder withUser(String user) {
5556
return this;
5657
}
5758

58-
public Builder withModel(String model) {
59-
this.options.setModel(model);
59+
public Builder withDeploymentName(String model) {
60+
this.options.setDeploymentName(model);
6061
return this;
6162
}
6263

@@ -74,12 +75,12 @@ public void setUser(String user) {
7475
this.user = user;
7576
}
7677

77-
public String getModel() {
78-
return this.model;
78+
public String getDeploymentName() {
79+
return this.deploymentName;
7980
}
8081

81-
public void setModel(String model) {
82-
this.model = model;
82+
public void setDeploymentName(String deploymentName) {
83+
this.deploymentName = deploymentName;
8384
}
8485

8586
}

models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureChatCompletionsOptionsTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public void createRequestWithChatOptions() {
3333

3434
OpenAIClient mockClient = Mockito.mock(OpenAIClient.class);
3535
var client = new AzureOpenAiChatClient(mockClient,
36-
AzureOpenAiChatOptions.builder().withModel("DEFAULT_MODEL").withTemperature(66.6f).build());
36+
AzureOpenAiChatOptions.builder().withDeploymentName("DEFAULT_MODEL").withTemperature(66.6f).build());
3737

3838
var requestOptions = client.toAzureChatCompletionsOptions(new Prompt("Test message content"));
3939

@@ -43,7 +43,7 @@ public void createRequestWithChatOptions() {
4343
assertThat(requestOptions.getTemperature()).isEqualTo(66.6f);
4444

4545
requestOptions = client.toAzureChatCompletionsOptions(new Prompt("Test message content",
46-
AzureOpenAiChatOptions.builder().withModel("PROMPT_MODEL").withTemperature(99.9f).build()));
46+
AzureOpenAiChatOptions.builder().withDeploymentName("PROMPT_MODEL").withTemperature(99.9f).build()));
4747

4848
assertThat(requestOptions.getMessages()).hasSize(1);
4949

models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureEmbeddingsOptionsTests.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ public void createRequestWithChatOptions() {
3737

3838
OpenAIClient mockClient = Mockito.mock(OpenAIClient.class);
3939
var client = new AzureOpenAiEmbeddingClient(mockClient, MetadataMode.EMBED,
40-
AzureOpenAiEmbeddingOptions.builder().withModel("DEFAULT_MODEL").withUser("USER_TEST").build());
40+
AzureOpenAiEmbeddingOptions.builder()
41+
.withDeploymentName("DEFAULT_MODEL")
42+
.withUser("USER_TEST")
43+
.build());
4144

4245
var requestOptions = client.toEmbeddingOptions(new EmbeddingRequest(List.of("Test message content"), null));
4346

@@ -47,7 +50,10 @@ public void createRequestWithChatOptions() {
4750
assertThat(requestOptions.getUser()).isEqualTo("USER_TEST");
4851

4952
requestOptions = client.toEmbeddingOptions(new EmbeddingRequest(List.of("Test message content"),
50-
AzureOpenAiEmbeddingOptions.builder().withModel("PROMPT_MODEL").withUser("PROMPT_USER").build()));
53+
AzureOpenAiEmbeddingOptions.builder()
54+
.withDeploymentName("PROMPT_MODEL")
55+
.withUser("PROMPT_USER")
56+
.build()));
5157

5258
assertThat(requestOptions.getInput()).hasSize(1);
5359

models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiChatClientIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ public OpenAIClient openAIClient() {
196196
@Bean
197197
public AzureOpenAiChatClient azureOpenAiChatClient(OpenAIClient openAIClient) {
198198
return new AzureOpenAiChatClient(openAIClient,
199-
AzureOpenAiChatOptions.builder().withModel("gpt-35-turbo").withMaxTokens(200).build());
199+
AzureOpenAiChatOptions.builder().withDeploymentName("gpt-35-turbo").withMaxTokens(200).build());
200200

201201
}
202202

models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/function/AzureOpenAiChatClientFunctionCallIT.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ void functionCallTest() {
5858
List<Message> messages = new ArrayList<>(List.of(userMessage));
5959

6060
var promptOptions = AzureOpenAiChatOptions.builder()
61-
.withModel("gpt-4-0125-preview")
61+
.withDeploymentName("gpt-4-0125-preview")
6262
.withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new MockWeatherService())
6363
.withName("getCurrentWeather")
6464
.withDescription("Get the current weather in a given location")
@@ -88,8 +88,10 @@ public OpenAIClient openAIClient() {
8888
@Bean
8989
public AzureOpenAiChatClient azureOpenAiChatClient(OpenAIClient openAIClient) {
9090
return new AzureOpenAiChatClient(openAIClient,
91-
AzureOpenAiChatOptions.builder().withModel("gpt-35-turbo-0613").withMaxTokens(500).build());
92-
91+
AzureOpenAiChatOptions.builder()
92+
.withDeploymentName("gpt-4-0125-preview")
93+
.withMaxTokens(500)
94+
.build());
9395
}
9496

9597
}

spring-ai-docs/src/main/antora/modules/ROOT/pages/api/clients/azure-openai-chat.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ The prefix `spring.ai.azure.openai.chat` is the property prefix that configures
9595
| Property | Description | Default
9696

9797
| spring.ai.azure.openai.chat.enabled | Enable Azure OpenAI chat client. | true
98-
| spring.ai.azure.openai.chat.options.model | * In use with Azure, this actually refers to the "Deployment Name" of your model, which you can find at https://oai.azure.com/portal. It's important to note that within an Azure OpenAI deployment, the "Deployment Name" is distinct from the model itself. The confusion around these terms stems from the intention to make the Azure OpenAI client library compatible with the original OpenAI endpoint. The deployment structures offered by Azure OpenAI and Sam Altman's OpenAI differ significantly. To clarify this distinction, we plan to rename this attribute to `deployment-name` in future updates.
98+
| spring.ai.azure.openai.chat.options.deployment-name | * In use with Azure, this refers to the "Deployment Name" of your model, which you can find at https://oai.azure.com/portal. It's important to note that within an Azure OpenAI deployment, the "Deployment Name" is distinct from the model itself. The confusion around these terms stems from the intention to make the Azure OpenAI client library compatible with the original OpenAI endpoint. The deployment structures offered by Azure OpenAI and Sam Altman's OpenAI differ significantly.
9999
Deployments model name to provide as part of this completions request.
100100
| gpt-35-turbo
101101
| spring.ai.azure.openai.chat.options.maxTokens | The maximum number of tokens to generate. | -

spring-ai-docs/src/main/antora/modules/ROOT/pages/api/embeddings/azure-openai-embeddings.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ The prefix `spring.ai.azure.openai.embeddings` is the property prefix that confi
7474

7575
| spring.ai.azure.openai.embedding.enabled | Enable Azure OpenAI embedding client. | true
7676
| spring.ai.azure.openai.embedding.metadata-mode | Document content extraction mode | EMBED
77-
| spring.ai.azure.openai.embedding.options.model | This is the value of the 'Deployment Name' as presented in the Azure AI Portal | text-embedding-ada-002
77+
| spring.ai.azure.openai.embedding.options.deployment-name | This is the value of the 'Deployment Name' as presented in the Azure AI Portal | text-embedding-ada-002
7878
| spring.ai.azure.openai.embedding.options.user | An identifier for the caller or end user of the operation. This may be used for tracking or rate-limiting purposes. | -
7979
|====
8080

0 commit comments

Comments
 (0)