LangChain4j mit Qdrant – Schritt-für-Schritt Tutorial für Einsteiger

Willkommen zum Tutorial zur Integration von Qdrant mit LangChain4j! In diesem Blog-Post lernst du, wie du einen leistungsstarken Vektor-Datenbank-Store für deine KI-Anwendungen einrichtest und nutzt.

Was du am Ende dieses Tutorials gelernt hast

Nach diesem Tutorial wirst du wissen:

  • Wie man Qdrant als Embedding-Speicher mit LangChain4j integriert
  • Wie man Dokumente in Qdrant speichert und abfragt
  • Wie man Embeddings mit OpenAI erstellt und in Qdrant speichert
  • Wie man Suchoperationen durchführt, um relevante Informationen zu finden

Voraussetzungen für das Tutorial

Bevor du mit dem Tutorial beginnst, benötigst du folgende Voraussetzungen:

  1. Java Development Kit (JDK) 11 oder höher
  2. Gradle Build-Tool (Version 7.x oder höher)
  3. Docker (für die Qdrant Server-Installation)
  4. Ein OpenAI API-Schlüssel (openai.com)
  5. Grundlegende Kenntnisse in Java und Gradle
  6. Ein Code-Editor wie IntelliJ IDEA, VS Code oder Eclipse

Schritt-für-Schritt-Anleitung

Schritt 1: Projektstruktur und Abhängigkeiten einrichten

Zuerst erstellen wir ein neues Gradle-Projekt und fügen die notwendigen Abhängigkeiten hinzu.

build.gradle

plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    // LangChain4j core
    implementation 'dev.langchain4j:langchain4j:0.28.0'

    // Qdrant integration
    implementation 'dev.langchain4j:langchain4j-qdrant:0.28.0'

    // OpenAI integration (für Embeddings)
    implementation 'dev.langchain4j:langchain4j-open-ai:0.28.0'

    // Logging
    implementation 'org.slf4j:slf4j-simple:2.0.9'

    testImplementation 'junit:junit:4.13.2'
}

Warum diese Abhängigkeiten?

  • langchain4j: Die Hauptbibliothek für KI-Anwendungen
  • langchain4j-qdrant: Spezielle Integration für Qdrant Vektor-Datenbank
  • langchain4j-open-ai: Für das Erstellen von Embeddings mit OpenAI
  • slf4j-simple: Einfache Logging-Lösung für Entwicklungszwecke

Schritt 2: Qdrant Server starten

Bevor wir mit der Programmierung beginnen, müssen wir den Qdrant-Server starten:

docker run -p 6333:6333 -p 6334:6334 \
  --name qdrant \
  --restart=always \
  qdrant/qdrant

Warum Docker?
Docker ermöglicht es uns, Qdrant schnell und ohne Komplikationen zu installieren. Es ist eine vollständig isolierte Umgebung, in der alle Abhängigkeiten korrekt geladen werden.

Schritt 3: Grundlegende Implementierung

Erstelle die Hauptklasse für unsere Qdrant-Integration:

import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.splitter.RecursiveCharacterTextSplitter;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.qdrant.QdrantEmbeddingStore;

public class QdrantExample {

    public static void main(String[] args) {
        // Embedding-Modell initialisieren
        EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
                .apiKey("your-openai-api-key")
                .modelName("text-embedding-3-small")
                .build();

        // Qdrant Speicher initialisieren
        EmbeddingStore<TextSegment> embeddingStore = QdrantEmbeddingStore.builder()
                .host("localhost")  
                .port(6334)         
                .collectionName("my_collection")
                .build();

        // Dokumente aufteilen
        RecursiveCharacterTextSplitter splitter = new RecursiveCharacterTextSplitter(
                1000,  // chunk size
                200    // chunk overlap
        );

        // Dokumente hinzufügen
        String documentContent = "Dein langer Textinhalt hier...";
        Document document = Document.from(documentContent);
        List<TextSegment> segments = splitter.split(document);

        // Embeddings erstellen und in Qdrant speichern
        List<Embedding> embeddings = embeddingModel.embedAll(segments).content();
        embeddingStore.addAll(embeddings, segments);

        System.out.println("Dokumente erfolgreich gespeichert!");
    }
}

Schritt 4: Vollständiges Suchbeispiel

Erstelle eine umfassende Implementierung mit Suchfunktion:

import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.splitter.RecursiveCharacterTextSplitter;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.qdrant.QdrantEmbeddingStore;

public class QdrantSearchExample {

    public static void main(String[] args) {
        // Embedding-Modell konfigurieren
        EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("text-embedding-3-small")
                .build();

        // Qdrant Speicher erstellen
        EmbeddingStore<TextSegment> embeddingStore = QdrantEmbeddingStore.builder()
                .host("localhost")
                .port(6333)
                .collectionName("documents")
                .build();

        // Beispiel-Dokumente hinzufügen
        addDocument(embeddingStore, embeddingModel, "Künstliche Intelligenz ist eine Technologie...");
        addDocument(embeddingStore, embeddingModel, "Machine Learning ist ein Teilbereich der KI...");

        // Suche durchführen
        searchDocuments(embeddingStore, embeddingModel, "Was ist Machine Learning?");
    }

    private static void addDocument(EmbeddingStore<TextSegment> store, 
                                   EmbeddingModel model, String content) {
        // Dokument aufteilen
        RecursiveCharacterTextSplitter splitter = new RecursiveCharacterTextSplitter(1000, 200);
        List<TextSegment> segments = splitter.split(Document.from(content));

        // Embeddings erstellen und speichern
        List<Embedding> embeddings = model.embedAll(segments).content();
        store.addAll(embeddings, segments);
    }

    private static void searchDocuments(EmbeddingStore<TextSegment> store,
                                      EmbeddingModel model, String query) {
        // Query-Embedding erstellen
        Embedding queryEmbedding = model.embed(query).content();

        // Ähnliche Dokumente finden
        List<TextSegment> relevantSegments = store.findRelevant(queryEmbedding, 3);

        // Ergebnisse anzeigen
        System.out.println("Suchergebnisse für: " + query);
        for (TextSegment segment : relevantSegments) {
            System.out.println("- " + segment.text());
        }
    }
}

Häufige Fehler und wie man sie behebt

Fehler 1: Verbindung zum Qdrant-Server nicht möglich

Problem: Die Anwendung meldet „Connection refused“ oder ähnliche Verbindungsfehler.

Lösung:

  1. Überprüfe, ob Docker installiert ist und läuft:
   docker ps
  1. Starte den Qdrant-Container neu:
   docker stop qdrant && docker rm qdrant
   docker run -p 6333:6333 -p 6334:6334 --name qdrant --restart=always qdrant/qdrant
  1. Stelle sicher, dass Port 6333 und 6334 nicht bereits von anderen Anwendungen verwendet werden.

Fehler 2: OpenAI API-Schlüssel nicht gefunden

Problem: Die Anwendung wirft eine Fehlermeldung wegen fehlenden API-Schlüssels.

Lösung:

  1. Erstelle einen API-Schlüssel auf platform.openai.com
  2. Setze den Schlüssel als Umgebungsvariable:
   export OPENAI_API_KEY="dein_sehr_geheimer_schlüssel"
  1. Oder füge ihn direkt in den Code ein (nur für Entwicklung):
   .apiKey("dein_sehr_geheimer_schlüssel")

Fehler 3: Gradle-Kompilierungsfehler

Problem: Kompilierungsfehler wie „package not found“ oder „version conflict“.

Lösung:

  1. Synchronisiere deine Gradle-Abhängigkeiten:
   ./gradlew clean build --refresh-dependencies
  1. Überprüfe, ob du die richtige Java-Version verwendest:
   java -version
  1. Stelle sicher, dass alle Abhängigkeiten in der build.gradle korrekt sind.

Zusammenfassung und nächste Schritte

In diesem Tutorial hast du gelernt, wie man Qdrant als leistungsstarken Vektor-Datenbank-Speicher für LangChain4j einrichtet. Du hast gesehen, wie man Dokumente in Qdrant speichert, Embeddings generiert und Suchoperationen durchführt.

Wichtige Punkte, die du gelernt hast:

  • Die Integration von Qdrant mit LangChain4j ist einfach und effizient
  • Embeddings sind der Schlüssel für semantische Suche in KI-Anwendungen
  • Qdrant ermöglicht schnelle und skalierbare Suchoperationen
  • Die Kombination mit OpenAI bietet hochwertige Embeddings

Nächste Schritte für dich:

  1. Erweitere deine Anwendung: Füge eine Web-Oberfläche hinzu, um die Suchfunktion grafisch darzustellen
  2. Verwende verschiedene Embedding-Modelle: Teste andere Modelle wie BERT oder Sentence Transformers
  3. Implementiere fortgeschrittene Suchoperationen: Wie ReRanking, Filterung und mehr
  4. Skaliere deine Lösung: Erweitere die Anwendung für große Datensätze und mehrere Benutzer