poniedziałek, 25 sierpnia 2025

AI Chatbot w Javie - RAG krok po kroku

Na bazie świetnego artykułu Baeldung o budowie chatbota w Javie z LangChain4j i MongoDB przygotowałem podobny, praktyczny przewodnik – ze wskazówkami, kodem i alternatywami. Oryginał znajdziesz tutaj: Building an AI Chatbot in Java With Langchain4j and MongoDB Atlas .



Dlaczego ten stack?

  • LangChain4j – wygodna warstwa do pracy z LLM w Javie (prompty, łańcuchy, pamięci, narzędzia).
  • MongoDB Atlas + Vector Search – trwałe przechowywanie embeddingów i szybkie zapytania semantyczne; idealne do RAG.

Efekt końcowy: prosty chatbot w stylu Q&A nad Twoimi dokumentami – z indeksem wektorowym w Atlasie, generacją embeddingów i łączeniem wyników z modelem językowym (RAG).

Wymagania wstępne

  • Java 17+
  • Konto w MongoDB Atlas i klaster (free tier wystarczy)
  • Klucz do dostawcy LLM/embeddingów (np. OpenAI) lub lokalny Ollama

Struktura projektu (Maven + Spring Boot)

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

  <dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-sync</artifactId>
    <version>5.1.0</version>
  </dependency>

  <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j</artifactId>
    <version>0.35.0</version>
  </dependency>

  <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-openai</artifactId>
    <version>0.35.0</version>
  </dependency>

  <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-mongodb</artifactId>
    <version>0.35.0</version>
  </dependency>
</dependencies>

Konfiguracja środowiska

server:
  port: 8080

app:
  mongo:
    uri: ${MONGODB_URI}
    db: ragdb
    collection: chunks
  openai:
    apiKey: ${OPENAI_API_KEY}
  rag:
    indexName: rag_vector_index
    dimensions: 1536

Definicja indeksu wektorowego

{
  "fields": [
    { "type": "vector", "path": "embedding", "numDimensions": 1536, "similarity": "cosine" },
    { "type": "string", "path": "source" },
    { "type": "string", "path": "text" }
  ]
}

Chunkowanie i embeddingi

Przykładowy kod Java generujący embeddingi i zapisujący do MongoDB:

float[] vec = embeddings.embed(chunk);
col.insertOne(new Document()
  .append("source", sourceName)
  .append("text", chunk)
  .append("embedding", toList(vec))
);

Retriever i RAG

Zapytanie semantyczne do Atlas Vector Search:

List<Bson> pipeline = List.of(
  Aggregates.vectorSearch("embedding", toList(qVec), indexName, 5, 200),
  Aggregates.project(Projections.include("text", "source"))
);

Łańcuch RAG z kontekstem i modelem czatu:

var messages = List.of(
  SystemMessage.from("Jesteś asystentem RAG..."),
  UserMessage.from("Kontekst:\n" + contextBlock + "\n\nPytanie: " + userQuestion)
);
return chat.generate(messages).content().text();

REST API

@PostMapping("/ingest")
public void ingest(@RequestBody IngestRequest req) {
  ing.ingest(req.source(), req.text());
}

@PostMapping
public ChatResponse chat(@RequestBody ChatRequest req) {
  return new ChatResponse(rag.ask(req.question()));
}

Alternatywy

Typowe pułapki

  1. Niedopasowany numDimensions w indeksie vs. model embeddingów.
  2. Brak overlapu przy chunkowaniu – tracony kontekst.
  3. Za duży kontekst – tnij do top-k i stosuj re-ranking.
  4. Sekrety w repo – używaj zmiennych środowiskowych.

Podsumowanie

W kilkudziesięciu linijkach kodu stworzyliśmy RAG chatbota – z MongoDB Atlas, LangChain4j i prostym REST API. Teraz możesz dodać streaming, cache embeddingów, czy personalizację dostępu.

Źródło, na którym bazowałem: Baeldung – Building an AI Chatbot in Java With Langchain4j and MongoDB Atlas

Dalsza lektura

Brak komentarzy:

Prześlij komentarz