Category: Java

  • 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