Testen Sie Elasticsearch: Sehen Sie sich unsere Beispiel-Notebooks an, starten Sie eine kostenlose Cloud-Testversion oder testen Sie Elastic jetzt auf Ihrem lokalem Gerät.
Im vorherigen Beitrag haben wir herausgefunden, was LangChain4j ist und wie es funktioniert:
- Führen Sie eine Diskussion mit LLMs, indem Sie ein
ChatLanguageModelund einChatMemory - Die Chat-Historie wird im Speicher gehalten, um den Kontext einer früheren Diskussion mit einem LLM wieder abrufen zu können.
Dieser Blogbeitrag erklärt, wie man:
- Vektor-Einbettungen aus Textbeispielen erstellen
- Vektoreinbettungen im Elasticsearch-Einbettungsspeicher speichern
- Suche nach ähnlichen Vektoren
Einbettungen erstellen
Um Einbettungen zu erstellen, müssen wir ein EmbeddingModel definieren, das verwendet werden soll. Wir können beispielsweise dasselbe Mistral-Modell verwenden, das wir im vorherigen Beitrag verwendet haben. Es lief mit ollama:
Ein Modell ist in der Lage, aus Text Vektoren zu generieren. Hier können wir die Anzahl der vom Modell generierten Dimensionen überprüfen:
Um Vektoren aus einem Text zu generieren, können wir Folgendes verwenden:
Oder wenn wir auch Metadaten bereitstellen möchten, um nach Dingen wie Text, Preis, Veröffentlichungsdatum oder Ähnlichem filtern zu können, können wir Metadata.from() verwenden. Zum Beispiel fügen wir hier den Spielnamen als Metadatenfeld hinzu:
Wenn Sie diesen Code ausführen möchten, sehen Sie sich bitte die Klasse Step5EmbedddingsTest.java an.
Elasticsearch hinzufügen, um unsere Vektoren zu speichern
LangChain4j bietet einen In-Memory-Embedding-Speicher. Dies ist nützlich, um einfache Tests durchzuführen:
Bei deutlich größeren Datensätzen funktioniert das natürlich nicht, da dieser Datenspeicher alles im Arbeitsspeicher ablegt und wir auf unseren Servern nicht über unbegrenzten Speicherplatz verfügen. Wir könnten unsere Einbettungen also stattdessen in Elasticsearch speichern, das per Definition "elastisch" ist und mit Ihren Daten skalieren kann. Dazu fügen wir Elasticsearch zu unserem Projekt hinzu:
Wie Sie bemerkt haben, haben wir dem Projekt auch das Elasticsearch TestContainers-Modul hinzugefügt, sodass wir eine Elasticsearch-Instanz aus unseren Tests heraus starten können:
Um Elasticsearch als Einbettungsspeicher zu verwenden, müssen Sie „nur“ vom LangChain4j-In-Memory-Datenspeicher zum Elasticsearch-Datenspeicher wechseln:
Dadurch werden Ihre Vektoren in Elasticsearch in einem default -Index gespeichert. Sie können den Indexnamen auch in einen aussagekräftigeren Namen ändern:
Wenn Sie diesen Code ausführen möchten, sehen Sie sich bitte die Klasse Step6ElasticsearchEmbedddingsTest.java an.
Suche nach ähnlichen Vektoren
Um nach ähnlichen Vektoren zu suchen, müssen wir zunächst unsere Frage mithilfe des gleichen Modells, das wir zuvor verwendet haben, in eine Vektordarstellung umwandeln. Das haben wir schon gemacht, also ist es nicht schwer, das noch einmal zu tun. Beachten Sie, dass wir in diesem Fall die Metadaten nicht benötigen:
Wir können mit dieser Repräsentation unserer Frage eine Suchanfrage erstellen und den Embedding-Speicher bitten, die ersten Top-Vektoren zu finden:
Wir können die Ergebnisse nun durchlaufen und einige Informationen ausgeben, wie zum Beispiel den Spielnamen, der aus den Metadaten stammt, und die Punktzahl:
Wie zu erwarten, ist „Out Run“ der erste Treffer:

Wenn Sie diesen Code ausführen möchten, sehen Sie sich bitte die Klasse Step7SearchForVectorsTest.java an.
Hinter den Kulissen
Die Standardkonfiguration für den Elasticsearch Embedding Store verwendet im Hintergrund die approximative kNN-Abfrage .
Dies könnte jedoch geändert werden, indem dem Embedding-Speicher eine andere Konfiguration (ElasticsearchConfigurationScript) als die Standardkonfiguration (ElasticsearchConfigurationKnn) bereitgestellt wird:
Die ElasticsearchConfigurationScript -Implementierung führt im Hintergrund eine script_score -Abfrage mit einer cosineSimilarity -Funktion aus.
Grundsätzlich gilt beim Aufruf:
Dies nennt man nun:
In diesem Fall ändert sich das Ergebnis hinsichtlich der "Ordnung" nicht, sondern nur die Punktzahl wird angepasst, da der cosineSimilarity -Aufruf keine Näherung verwendet, sondern den Kosinus für jeden der übereinstimmenden Vektoren berechnet:
Wenn Sie diesen Code ausführen möchten, sehen Sie sich bitte die Klasse Step7SearchForVectorsTest.java an.
Fazit
Wir haben behandelt, wie einfach Sie Einbettungen aus Ihrem Text generieren können und wie Sie die nächsten Nachbarn in Elasticsearch speichern und suchen können, und zwar mit zwei verschiedenen Ansätzen:
- Verwendung der approximativen und schnellen
knn-Abfrage mit der StandardoptionElasticsearchConfigurationKnn - Verwendung der exakten, aber langsameren
script_score-Abfrage mit derElasticsearchConfigurationScript-Option
Im nächsten Schritt geht es darum, eine vollständige RAG-Anwendung zu entwickeln, basierend auf dem, was wir hier gelernt haben.




