Allow the openai embedding client to use different model, key and url from the completion one

This commit is contained in:
Christian Tzolov
2023-10-19 16:25:41 +02:00
parent 90117fe504
commit 8f1826aef6
2 changed files with 66 additions and 46 deletions

View File

@@ -16,10 +16,11 @@
package org.springframework.ai.autoconfigure.openai;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.theokanning.openai.OpenAiApi;
import com.theokanning.openai.service.OpenAiService;
import java.time.Duration;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.theokanning.openai.client.OpenAiApi;
import com.theokanning.openai.service.OpenAiService;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
@@ -27,10 +28,11 @@ import retrofit2.converter.jackson.JacksonConverterFactory;
import org.springframework.ai.autoconfigure.NativeHints;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.openai.embedding.OpenAiEmbeddingClient;
import org.springframework.ai.openai.client.OpenAiClient;
import org.springframework.ai.openai.embedding.OpenAiEmbeddingClient;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ImportRuntimeHints;
@@ -44,27 +46,37 @@ import static org.springframework.ai.autoconfigure.openai.OpenAiProperties.CONFI
@ImportRuntimeHints(NativeHints.class)
public class OpenAiAutoConfiguration {
private final OpenAiProperties openAiProperties;
public OpenAiAutoConfiguration(OpenAiProperties openAiProperties) {
this.openAiProperties = openAiProperties;
@Bean
@ConditionalOnMissingBean
public OpenAiClient openAiClient(OpenAiProperties openAiProperties) {
OpenAiClient openAiClient = new OpenAiClient(theoOpenAiService(openAiProperties.getBaseUrl(),
openAiProperties.getApiKey(), openAiProperties.getDuration()));
openAiClient.setTemperature(openAiProperties.getTemperature());
openAiClient.setModel(openAiProperties.getModel());
return openAiClient;
}
@Bean
public OpenAiService theoOpenAiService(OpenAiProperties openAiProperties) {
if ("https://api.openai.com".equals(openAiProperties.getBaseUrl())) {
if (!StringUtils.hasText(openAiProperties.getApiKey())) {
throw new IllegalArgumentException(
"You must provide an API key with the property name " + CONFIG_PREFIX + ".api-key");
}
@ConditionalOnMissingBean
public EmbeddingClient openAiEmbeddingClient(OpenAiProperties openAiProperties) {
return new OpenAiEmbeddingClient(theoOpenAiService(openAiProperties.getEmbeddingBaseUrl(),
openAiProperties.getEmbeddingApiKey(), openAiProperties.getDuration()),
openAiProperties.getEmbeddingModel());
}
private OpenAiService theoOpenAiService(String baseUrl, String apiKey, Duration duration) {
if ("https://api.openai.com".equals(baseUrl) && !StringUtils.hasText(apiKey)) {
throw new IllegalArgumentException(
"You must provide an API key with the property name " + CONFIG_PREFIX + ".api-key");
}
ObjectMapper mapper = OpenAiService.defaultObjectMapper();
OkHttpClient client = OpenAiService.defaultClient(openAiProperties.getApiKey(), openAiProperties.getDuration());
OkHttpClient client = OpenAiService.defaultClient(apiKey, duration);
// Waiting for https://github.com/TheoKanning/openai-java/issues/249 to be
// resolved.
Retrofit retrofit = new Retrofit.Builder().baseUrl(openAiProperties.getBaseUrl())
Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl)
.client(client)
.addConverterFactory(JacksonConverterFactory.create(mapper))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
@@ -75,17 +87,4 @@ public class OpenAiAutoConfiguration {
return new OpenAiService(api);
}
@Bean
public OpenAiClient openAiClient(OpenAiProperties openAiProperties, OpenAiService theoOpenAiService) {
OpenAiClient openAiClient = new OpenAiClient(theoOpenAiService);
openAiClient.setTemperature(openAiProperties.getTemperature());
openAiClient.setModel(openAiProperties.getModel());
return openAiClient;
}
@Bean
public EmbeddingClient openAiEmbeddingClient(OpenAiService theoOpenAiService) {
return new OpenAiEmbeddingClient(theoOpenAiService, openAiProperties.getEmbeddingModel());
}
}

View File

@@ -17,6 +17,7 @@
package org.springframework.ai.autoconfigure.openai;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.StringUtils;
import java.time.Duration;
@@ -27,20 +28,24 @@ public class OpenAiProperties {
public static final String CONFIG_PREFIX = "spring.ai.openai";
private String apiKey;
private Double temperature = 0.7;
private Duration duration = Duration.ofSeconds(60);
private String model = "gpt-3.5-turbo";
private String apiKey;
private String embeddingModel = "text-embedding-ada-002";
private String model = "gpt-3.5-turbo";
private String baseUrl = "https://api.openai.com";
private String embeddingModel = "text-embedding-ada-002";
private String embeddingBaseUrl;
private String embeddingApiKey;
public String getApiKey() {
return apiKey;
return this.apiKey;
}
public void setApiKey(String apiKey) {
@@ -48,23 +53,15 @@ public class OpenAiProperties {
}
public String getModel() {
return model;
return this.model;
}
public void setModel(String model) {
this.model = model;
}
public String getEmbeddingModel() {
return embeddingModel;
}
public void setEmbeddingModel(String embeddingModel) {
this.embeddingModel = embeddingModel;
}
public Double getTemperature() {
return temperature;
return this.temperature;
}
public void setTemperature(Double temperature) {
@@ -72,7 +69,7 @@ public class OpenAiProperties {
}
public Duration getDuration() {
return duration;
return this.duration;
}
public void setDuration(Duration duration) {
@@ -80,11 +77,35 @@ public class OpenAiProperties {
}
public String getBaseUrl() {
return baseUrl;
return this.baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
public String getEmbeddingModel() {
return this.embeddingModel;
}
public void setEmbeddingModel(String embeddingModel) {
this.embeddingModel = embeddingModel;
}
public void setEmbeddingBaseUrl(String embeddingBaseUrl) {
this.embeddingBaseUrl = embeddingBaseUrl;
}
public String getEmbeddingBaseUrl() {
return StringUtils.hasText(this.embeddingBaseUrl) ? this.embeddingBaseUrl : this.baseUrl;
}
public String getEmbeddingApiKey() {
return StringUtils.hasText(this.embeddingApiKey) ? this.embeddingApiKey : this.apiKey;
}
public void setEmbeddingApiKey(String embeddingApiKey) {
this.embeddingApiKey = embeddingApiKey;
}
}