I am trying my hands on spring ai. I am trying to read a pdf and save the data into a vector store. Then I am calling aiclient to respond to prompts. This is what it looks like
@Component
class Chatbot {
private final String template = """
You're assisting with questions about a given pdf
Use the information from the DOCUMENTS section to provide accurate answers but act as if you knew this information innately.
If unsure, simply state that you don't know.
DOCUMENTS:
{documents}
""";
private final ChatClient aiClient;
private final VectorStore vectorStore;
Chatbot(ChatClient aiClient, VectorStore vectorStore) {
this.aiClient = aiClient;
this.vectorStore = vectorStore;
}
public String chat(String message) {
var listOfSimilarDocuments = this.vectorStore.similaritySearch(message);
var documents = listOfSimilarDocuments
.stream()
.map(Document::getContent)
.collect(Collectors.joining(System.lineSeparator()));
var systemMessage = new SystemPromptTemplate(this.template)
.createMessage(Map.of("documents", documents));
var userMessage = new UserMessage(message);
var prompt = new Prompt(List.of(systemMessage, userMessage));
var aiResponse = aiClient.call(prompt);
return aiResponse.getResult().getOutput().getContent();
}
}
I have a api key setup on openAi.
When I start my application, I see that even before the above piece of code is called, a rest call is made to openai which is resulting in the following error
org.springframework.web.client.RestClientException: Error while extracting response for type [org.springframework.ai.openai.api.OpenAiApi$EmbeddingList<org.springframework.ai.openai.api.OpenAiApi$Embedding>] and content type [application/json;charset=utf-8]
at org.springframework.web.client.DefaultRestClient.readWithMessageConverters(DefaultRestClient.java:231) ~[spring-web-6.1.2.jar:6.1.2]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.readBody(DefaultRestClient.java:659) ~[spring-web-6.1.2.jar:6.1.2]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.toEntityInternal(DefaultRestClient.java:629) ~[spring-web-6.1.2.jar:6.1.2]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.toEntity(DefaultRestClient.java:625) ~[spring-web-6.1.2.jar:6.1.2]
at org.springframework.ai.openai.api.OpenAiApi.embeddings(OpenAiApi.java:795) ~[spring-ai-openai-0.8.0-20240223.153858-200.jar:0.8.0-SNAPSHOT]
at org.springframework.ai.openai.OpenAiEmbeddingClient.lambda$call$1(OpenAiEmbeddingClient.java:114) ~[spring-ai-openai-0.8.0-20240223.153858-200.jar:0.8.0-SNAPSHOT]
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:335) ~[spring-retry-2.0.5.jar:na]
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:211) ~[spring-retry-2.0.5.jar:na]
at org.springframework.ai.openai.OpenAiEmbeddingClient.call(OpenAiEmbeddingClient.java:100) ~[spring-ai-openai-0.8.0-20240223.153858-200.jar:0.8.0-SNAPSHOT]
at org.springframework.ai.embedding.EmbeddingClient.embed(EmbeddingClient.java:56) ~[spring-ai-core-0.8.0-20240223.153858-209.jar:0.8.0-SNAPSHOT]
at org.springframework.ai.embedding.EmbeddingClient.embed(EmbeddingClient.java:39) ~[spring-ai-core-0.8.0-20240223.153858-209.jar:0.8.0-SNAPSHOT]
at org.springframework.ai.embedding.AbstractEmbeddingClient.dimensions(AbstractEmbeddingClient.java:57) ~[spring-ai-core-0.8.0-20240223.153858-209.jar:0.8.0-SNAPSHOT]
at org.springframework.ai.embedding.AbstractEmbeddingClient.dimensions(AbstractEmbeddingClient.java:79) ~[spring-ai-core-0.8.0-20240223.153858-209.jar:0.8.0-SNAPSHOT]
at org.springframework.ai.vectorstore.PgVectorStore.embeddingDimensions(PgVectorStore.java:363) ~[spring-ai-pgvector-store-0.8.0-20240223.153858-191.jar:0.8.0-SNAPSHOT]
at org.springframework.ai.vectorstore.PgVectorStore.afterPropertiesSet(PgVectorStore.java:347) ~[spring-ai-pgvector-store-0.8.0-20240223.153858-191.jar:0.8.0-SNAPSHOT]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1820) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1769) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:911) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:241) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[spring-beans-6.1.2.jar:6.1.2]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:960) ~[spring-context-6.1.2.jar:6.1.2]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) ~[spring-context-6.1.2.jar:6.1.2]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.1.jar:3.2.1]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762) ~[spring-boot-3.2.1.jar:3.2.1]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:464) ~[spring-boot-3.2.1.jar:3.2.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) ~[spring-boot-3.2.1.jar:3.2.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1358) ~[spring-boot-3.2.1.jar:3.2.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1347) ~[spring-boot-3.2.1.jar:3.2.1]
at bootiful.service.ServiceApplication.main(ServiceApplication.java:33) ~[classes/:na]
Caused by: java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1796) ~[na:na]
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1599) ~[na:na]
at java.base/sun.net.www.protocol.http.HttpURLConnection.getHeaderFieldKey(HttpURLConnection.java:3288) ~[na:na]
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getHeaderFieldKey(HttpsURLConnectionImpl.java:276) ~[na:na]
at org.springframework.http.client.SimpleClientHttpResponse.getHeaders(SimpleClientHttpResponse.java:69) ~[spring-web-6.1.2.jar:6.1.2]
at org.springframework.web.client.DefaultRestClient$DefaultConvertibleClientHttpResponse.getHeaders(DefaultRestClient.java:715) ~[spring-web-6.1.2.jar:6.1.2]
at org.springframework.web.client.DefaultRestClient.getContentType(DefaultRestClient.java:236) ~[spring-web-6.1.2.jar:6.1.2]
at org.springframework.web.client.DefaultRestClient.readWithMessageConverters(DefaultRestClient.java:192) ~[spring-web-6.1.2.jar:6.1.2]
... 46 common frames omitted
I am not sure why is this happening or how to fix this. Any help is much appreciated.
When I tried debugging, I see that OpenAiEmbeddingClient::call method is called where a Hello World request is sent with model text-embedding-ada-002. This call is failing
EmbeddingList<OpenAiApi.Embedding> apiEmbeddingResponse = this.openAiApi.embeddings(apiRequest).getBody();
I have the following dependencies in the pom.
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pdf-document-reader</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
You need to provide the Open AI API Key and the embedding model API key and the model name in your application.properties (or YAML) file.
Something like this. In this sample example, the SPRING_AI_OPENAI_API_KEY is an environment variable.