Passez à la pratique avec Elasticsearch : explorez nos notebooks d’exemples, lancez un essai gratuit sur le cloud ou testez Elastic dès maintenant sur votre machine locale.
Dans l'article précédent, nous avons découvert ce qu'est LangChain4j et comment l'utiliser :
- Discutez avec les LLM en mettant en place un
ChatLanguageModelet unChatMemory - Conserver l'historique du chat en mémoire pour se rappeler le contexte d'une discussion précédente avec un LLM
Cet article de blog traite de la manière de procéder :
- Création d'encastrements vectoriels à partir d'exemples de textes
- Stocker les embeddings vectoriels dans le magasin d'embedding d'Elasticsearch
- Recherche de vecteurs similaires
Créer des embeddings
Pour créer des embeddings, nous devons définir un EmbeddingModel à utiliser. Par exemple, nous pouvons utiliser le même modèle de mistral que celui utilisé dans le billet précédent. Il s'agissait de courir avec l'ollama :
Un modèle est capable de générer des vecteurs à partir d'un texte. Nous pouvons ici vérifier le nombre de dimensions générées par le modèle :
Pour générer des vecteurs à partir d'un texte, nous pouvons utiliser :
Si nous voulons également fournir des métadonnées pour nous permettre de filtrer des éléments tels que le texte, le prix, la date de sortie ou autre, nous pouvons utiliser Metadata.from(). Par exemple, nous ajoutons ici le nom du jeu comme champ de métadonnées :
Si vous souhaitez exécuter ce code, veuillez consulter la classe Step5EmbedddingsTest.java.
Ajouter Elasticsearch pour stocker nos vecteurs
LangChain4j fournit un magasin d'intégration en mémoire. Cette fonction est utile pour exécuter des tests simples :
Mais il est évident que cela ne pourrait pas fonctionner avec un ensemble de données beaucoup plus important car ce datastore stocke tout en mémoire et nous ne disposons pas d'une mémoire infinie sur nos serveurs. Ainsi, nous pourrions plutôt stocker nos enregistrements dans Elasticsearch, qui est par définition "élastique" et peut évoluer avec vos données. Pour cela, ajoutons Elasticsearch à notre projet :
Comme vous l'avez remarqué, nous avons également ajouté le module Elasticsearch TestContainers au projet, afin de pouvoir démarrer une instance Elasticsearch à partir de nos tests :
Pour utiliser Elasticsearch comme magasin d'intégration, il suffit de "" passer du datastore LangChain4j en mémoire au datastore Elasticsearch :
Cela permettra de stocker vos vecteurs dans Elasticsearch dans un index default. Vous pouvez également changer le nom de l'index en quelque chose de plus significatif :
Si vous souhaitez exécuter ce code, veuillez consulter la classe Step6ElasticsearchEmbedddingsTest.java.
Recherche de vecteurs similaires
Pour rechercher des vecteurs similaires, nous devons d'abord transformer notre question en une représentation vectorielle en utilisant le même modèle que celui utilisé précédemment. Nous l'avons déjà fait, il n'est donc pas difficile de le faire à nouveau. Notez que nous n'avons pas besoin des métadonnées dans ce cas :
Nous pouvons construire une requête de recherche avec cette représentation de notre question et demander au magasin d'intégration de trouver les premiers vecteurs :
Nous pouvons maintenant itérer sur les résultats et imprimer certaines informations, comme le nom du jeu qui provient des métadonnées et le score :
Comme on pouvait s'y attendre, cela nous donne "Out Run" comme premier résultat :

Si vous souhaitez exécuter ce code, consultez la classe Step7SearchForVectorsTest.java.
L'envers du décor
La configuration par défaut du magasin Elasticsearch Embedding utilise la requête kNN approximative en arrière-plan.
Mais cela peut être modifié en fournissant une autre configuration (ElasticsearchConfigurationScript) que celle par défaut (ElasticsearchConfigurationKnn) au magasin d'intégration :
L'implémentation de ElasticsearchConfigurationScript exécute en coulisse une requête script_score à l'aide d'une fonction cosineSimilarity.
En principe, lors d'un appel :
Il s'agit maintenant d'un appel :
Dans ce cas, le résultat ne change pas en termes d'ordre "" mais le score est simplement ajusté parce que l'appel cosineSimilarity n'utilise pas d'approximation mais calcule le cosinus pour chacun des vecteurs correspondants :
Si vous souhaitez exécuter ce code, consultez la classe Step7SearchForVectorsTest.java.
Conclusion
Nous avons vu comment vous pouvez facilement générer des embeddings à partir de votre texte et comment vous pouvez stocker et rechercher les voisins les plus proches dans Elasticsearch en utilisant deux approches différentes :
- Utilisation de la requête approximative et rapide
knnavec l'option par défautElasticsearchConfigurationKnn - Utilisation de la requête exacte mais plus lente
script_scoreavec l'optionElasticsearchConfigurationScript
La prochaine étape consistera à créer une application RAG complète, sur la base de ce que nous avons appris ici.




