这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
1 change: 1 addition & 0 deletions spring-ai-modules/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<modules>
<module>spring-ai-mcp</module>
<module>spring-ai-text-to-sql</module>
<module>spring-ai-vector-stores</module>
</modules>

</project>
23 changes: 23 additions & 0 deletions spring-ai-modules/spring-ai-vector-stores/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.baeldung</groupId>
<artifactId>spring-ai-modules</artifactId>
<version>0.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>spring-ai-vector-stores</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
<name>spring-ai-vector-stores</name>

<modules>
<module>spring-ai-oracle</module>
</modules>

</project>
79 changes: 79 additions & 0 deletions spring-ai-modules/spring-ai-vector-stores/spring-ai-oracle/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.baeldung</groupId>
<artifactId>spring-ai-vector-stores</artifactId>
<version>0.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

<groupId>com.baeldung</groupId>
<artifactId>spring-ai-oracle</artifactId>
<version>0.0.1</version>
<name>spring-ai-oracle</name>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-oracle</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-advisors-vector-store</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>oracle-free</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<properties>
<java.version>21</java.version>
<spring-ai.version>1.0.0</spring-ai.version>
<spring-boot.version>3.5.4</spring-boot.version>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.baeldung.springai.vectorstore.oracle;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.baeldung.springai.vectorstore.oracle;

record Quote(String quote, String author) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.baeldung.springai.vectorstore.oracle;

import org.springframework.core.ParameterizedTypeReference;
import org.springframework.web.client.RestClient;

import java.net.URI;
import java.util.List;

class QuoteFetcher {

private static final String BASE_URL = "https://api.breakingbadquotes.xyz/v1/quotes/";
private static final int DEFAULT_COUNT = 150;

static List<Quote> fetch() {
return fetch(DEFAULT_COUNT);
}

static List<Quote> fetch(int count) {
return RestClient
.create()
.get()
.uri(URI.create(BASE_URL + count))
.retrieve()
.body(new ParameterizedTypeReference<>() {});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.baeldung.springai.vectorstore.oracle;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.template.st.StTemplateRenderer;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

@Configuration
class RAGChatbotConfiguration {

private static final int MAX_RESULTS = 10;

@Bean
PromptTemplate promptTemplate(
@Value("classpath:prompt-template.st") Resource promptTemplate
) throws IOException {
String template = promptTemplate.getContentAsString(StandardCharsets.UTF_8);
return PromptTemplate
.builder()
.renderer(StTemplateRenderer
.builder()
.startDelimiterToken('<')
.endDelimiterToken('>')
.build())
.template(template)
.build();
}

@Bean
ChatClient chatClient(
ChatModel chatModel,
VectorStore vectorStore,
PromptTemplate promptTemplate
) {
return ChatClient
.builder(chatModel)
.defaultAdvisors(
QuestionAnswerAdvisor
.builder(vectorStore)
.promptTemplate(promptTemplate)
.searchRequest(SearchRequest
.builder()
.topK(MAX_RESULTS)
.build())
.build()
)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.baeldung.springai.vectorstore.oracle;

import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Component
class VectorStoreInitializer implements ApplicationRunner {

private final VectorStore vectorStore;

VectorStoreInitializer(VectorStore vectorStore) {
this.vectorStore = vectorStore;
}

@Override
public void run(ApplicationArguments args) {
List<Document> documents = QuoteFetcher
.fetch()
.stream()
.map(quote -> {
Map<String, Object> metadata = Map.of("author", quote.author());
return new Document(quote.quote(), metadata);
})
.toList();
vectorStore.add(documents);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
spring:
ai:
vectorstore:
oracle:
initialize-schema: true
openai:
api-key: ${OPENAI_API_KEY}
embedding:
options:
model: text-embedding-3-large
chat:
options:
model: gpt-4o
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%p] [%c{1}] - %m%n</pattern>
</encoder>
</appender>

<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>

<logger name="org.springframework" level="INFO" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
</configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
You are a chatbot built for analyzing quotes from the 'Breaking Bad' television series.
Given the quotes in the CONTEXT section, answer the query in the USER_QUESTION section.
The response should follow the guidelines listed in the GUIDELINES section.

CONTEXT:
<question_answer_context>

USER_QUESTION:
<query>

GUIDELINES:
- Base your answer solely on the information found in the provided quotes.
- Provide concise, direct answers without mentioning "based on the context" or similar phrases.
- When referencing specific quotes, mention the character who said them.
- If the question cannot be answered using the context, respond with "The provided quotes do not contain information to answer this question."
- If the question is unrelated to the Breaking Bad show or the quotes provided, respond with "This question is outside the scope of the available Breaking Bad quotes."
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.baeldung.springai.vectorstore.oracle;

import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource;
import org.testcontainers.oracle.OracleContainer;

class OracleDatabaseContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<OracleContainer, JdbcConnectionDetails> {

@Override
protected JdbcConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<OracleContainer> source) {
return new OracleDatabaseContainerConnectionDetails(source);
}

private static final class OracleDatabaseContainerConnectionDetails
extends ContainerConnectionDetails<OracleContainer> implements JdbcConnectionDetails {

OracleDatabaseContainerConnectionDetails(ContainerConnectionSource<OracleContainer> source) {
super(source);
}

@Override
public String getUsername() {
return getContainer().getUsername();
}

@Override
public String getPassword() {
return getContainer().getPassword();
}

@Override
public String getJdbcUrl() {
return getContainer().getJdbcUrl();
}

}

}
Loading