Spring AI - openAi Error extracting response of type OpenAiApi$EmbeddingList<......OpenAiApi$Embedding>

145 Views Asked by At

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>
2

There are 2 best solutions below

2
Sagar On

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.

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/vector_store
    username: postgres
    password: postgres
  ai:
    openai:
      api-key: ${SPRING_AI_OPENAI_API_KEY}
      embedding-api-key: ${SPRING_AI_OPENAI_API_KEY}
      embedding:
        options:
          model: text-embedding-ada-002
      base-url: https://api.openai.com/
      chat:
        options:
          temperature: 0.2
          model: gpt-3.5-turbo
2
Swarup Saha On

Please add the following dependency and it will resolve the issue.

<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.2.1</version>
</dependency>