Kihagyás

Spring AI - Rag

pom.xml

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

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-vector-store-pgvector</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-vector-store-advisor</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>

Config

@Bean
CommandLineRunner ingest(VectorStore vectorStore) {
    return args -> {
        var doc1 = new Document("On my Chuwi server, NPM handles HTTPS on DuckDNS ...");
        var doc2 = new Document("The wol-bridge is a Rust based HTTP server with wake-on-LAN ...");
        vectorStore.add(List.of(doc1, doc2));
    };
}

@Bean
ChatClient chatClient(Builder builder, VectorStore vectorStore) {
    var customTemplate = new PromptTemplate("""
        Answer the question based solely on the context below.
        If there is no relevant information in the context, say: "I have no information about..."

        Context:
        {question_answer_context}

        Question: {query}
        """);
    return builder.defaultAdvisors(QuestionAnswerAdvisor.builder(vectorStore).promptTemplate(customTemplate)
        .build());
}

application.yaml

spring:
  ai:
    openai:
      base-url: https://example.com/
      api-key: shhh
      chat:
        options:
          model: Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf
      embedding:
        options:
          model: nomic-embed-text
    vectorstore:
      pgvector:
        dimensions: 768
        initialize-schema: true
  datasource:
    username: ragadmin
    password: localdev
    url: jdbc:postgresql://localhost:5432/ragdb
    driverClassName: org.postgresql.Driver

ChatController

@RestController
public class ChatController {

    private final ChatClient chatClient;

    public ChatController(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    @GetMapping("/chat")
    public String chat(@RequestParam String message) {
        return chatClient.prompt().user(message).call().content();
    }
}

Curl

curl --get --data-urlencode "message=What protocol does NPM handle on chuwin?" localhost:8080/chat