Puede integrar MongoDB Vector Search con LangChain4j to build LLM applications. This tutorial demonstrates how to start using MongoDB Vector Search with LangChain4j to perform semantic searches on your data and build a simple Implementación deRAG. En concreto, se realizan las siguientes acciones:
Configura el entorno.
Instancia el modelo de embedding.
Utilice MongoDB como almacén de incrustaciones.
Almacene datos personalizados en su clúster MongoDB.
Ejecuta las siguientes consultas de búsqueda vectorial:
Búsqueda semántica.
Búsqueda semántica con prefiltrado de metadatos.
Implementa RAG usando la búsqueda vectorial de MongoDB para responder preguntas sobre tus datos.
Segundo plano
LangChain4j is a framework that simplifies the creation of LLM applications in Java. LangChain4j combines concepts and functionality from LangChain, Haystack, LlamaIndex, and other sources. You can use this framework for a variety of use cases, including semantic search and RAG.
By integrating MongoDB Vector Search with LangChain4j, you can use MongoDB as a vector database and use MongoDB Vector Search to implement RAG by using semantically similar documents to answer queries. To learn more about RAG, see Recuperación-Generación Aumentada (RAG) con MongoDB.
Requisitos previos
Para completar este tutorial, debes tener lo siguiente:
Uno de los siguientes tipos de clúster de MongoDB:
Un clúster de Atlas que ejecuta la versión 6.0.11, 7.0.2 o posterior de MongoDB. Asegúrese de que su dirección IP esté incluida en la lista de acceso de su proyecto Atlas.
Una implementación local de Atlas creada usando Atlas CLI. Para obtener más información, consulta Crear una Implementación local de Atlas.
Un clúster de MongoDB Community o Enterprise con Search y Vector Search instalados.
A Voyage AI API Key. You must have an account with tokens available for API requests. To learn more about registering a Voyage AI account, see Model API Keys.
Una llave de API de OpenAI. Debes tener una cuenta de OpenAI con créditos disponibles para las solicitudes de API. Para obtener más información sobre cómo registrar una cuenta de OpenAI, consulta el sitio web de la API de OpenAI.
Java Development Kit (JDK) versión 8 o posterior.
Un entorno para configurar y ejecutar una aplicación Java. Recomendamos utilizar un entorno de desarrollo integrado (IDE) como IntelliJ IDEA o Eclipse IDE para configurar Maven o Gradle para compilar y ejecutar el proyecto.
Configurar el entorno
Primero debe configurar el entorno para este tutorial, lo que incluye agregar las dependencias necesarias y configurar las variables de entorno.
Crea una nueva aplicación Java.
Abra su IDE y cree un nuevo proyecto Java y configure las siguientes configuraciones:
Nombre: LangChain4jSampleApp
Lenguaje: Java
Sistema de compilación: Maven
JDK: Any version greater than
8
Es posible que vea una opción para incluir código de ejemplo. Seleccionar esta opción podría ayudarle a comprobar el funcionamiento de su entorno y a localizar el archivo de la aplicación que edite en los siguientes pasos.
Agrega dependencias.
Agregue las siguientes dependencias a la matriz
dependenciesen el archivopom.xmlde su proyecto. Estas dependencias agregan las bibliotecas LangChain4j, Voyage AI API for LangChain4j y MongoDB Java Sync Driver a su aplicación:pom.xml<dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-mongodb-atlas</artifactId> <version>1.1.0</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-voyage-ai</artifactId> <version>1.1.0-beta7</version> </dependency> A continuación, agregue una entrada
dependencyManagementdebajo de su lista de dependencias para la lista de materiales (BOM) de LangChain4j:pom.xml<dependencyManagement> <dependencies> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-bom</artifactId> <version>1.1.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> Para obtener más información sobre la lista de materiales de LangChain4j, consulte la página Comenzar en la 4documentación de LangChain j.
Después de terminar de editar el archivo
pom.xml, vuelva a cargar su proyecto para asegurarse de que sus dependencias estén instaladas.
Importar clases y métodos.
Localice el archivo de aplicación principal Main.java en su proyecto. Reemplace las importaciones existentes con la siguiente lista:
import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import dev.langchain4j.data.document.Metadata; import dev.langchain4j.data.embedding.Embedding; import dev.langchain4j.data.segment.TextSegment; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.voyageai.VoyageAiEmbeddingModel; import dev.langchain4j.store.embedding.EmbeddingMatch; import dev.langchain4j.store.embedding.EmbeddingSearchRequest; import dev.langchain4j.store.embedding.EmbeddingSearchResult; import dev.langchain4j.store.embedding.filter.comparison.*; import dev.langchain4j.store.embedding.mongodb.IndexMapping; import dev.langchain4j.store.embedding.mongodb.MongoDbEmbeddingStore; import org.bson.Document; import java.io.*; import java.util.*;
Más adelante en este tutorial, utilizará estas clases y métodos para crear incrustaciones vectoriales y consultar datos.
Establecer variables de entorno.
Dependiendo de su IDE, puede haber varias maneras de configurar variables de entorno que su aplicación pueda recuperar. Para configurar variables de entorno en IntelliJ, debe crear una configuración de ejecución para su aplicación. Para obtener más información, consulte la sección "Sistema operativo" de la página "Configuración de ejecución/depuración: Aplicación" en la documentación de IntelliJ.
Establezca las siguientes variables de entorno:
MONGODB_URI: Set to your MongoDB connection string.VOYAGE_AI_KEY: Set to your Voyage AI API key.
Nota
Su cadena de conexión debe usar el siguiente formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net/?<settings>
Para obtener más información sobre cómo recuperar su cadena de conexión, consulte el tutorial Introducción a Atlas.
Crear una instancia del modelo de incrustación
En este paso, se crea una instancia de un modelo de incrustación que utiliza Voyage AI para convertir el texto de los datos de muestra en incrustaciones vectoriales.
Agregue el siguiente código a su archivo Main.java para crear una instancia del modelo de inserción utilizando su clave API de Voyage AI y seleccionando voyage-3-large como modelo:
EmbeddingModel embeddingModel = VoyageAiEmbeddingModel.builder() .apiKey(embeddingApiKey) .modelName("voyage-3-large") .build();
Para obtener más información sobre el voyage-3-large modelo, consulte la publicación del blog sobre voyage-3 y voyage-3-lite en el sitio web de Voyage AI.
Utilice MongoDB como almacén de incrustaciones
En esta sección, se instancia MongoDB como una base de datos vectorial, también llamada almacén vectorial o de incrustación. Al instanciar el almacén de incrustación, LangChain4j crea automáticamente un índice de búsqueda vectorial de MongoDB en los datos.
Nota
Acceso requerido
Para crear un índice de búsqueda vectorial Project Data Access Admin de MongoDB, debe tener o acceso superior al proyecto MongoDB.
Este código realiza las siguientes acciones:
Crea una instancia
MongoClientque está conectada a su implementación de Atlas.Establece el número de dimensiones en la definición del índice de búsqueda vectorial según la dimensión de incrustación del modelo de IA. El índice de búsqueda vectorial resultante tiene la siguiente definición:
{ "fields": [ { "type": "vector", "path": "embedding", "numDimensions": 1024, "similarity": "cosine" } ] } Configura su colección MongoDB especificando los siguientes parámetros:
langchain4j_test.vector_storecomo la colección MongoDB para almacenar los documentos.vector_indexas the index to use for querying the embedding store.
Dado que el booleano createIndex está establecido en true, al instanciar el almacén de incrustaciones se crea automáticamente el índice de búsqueda vectorial. El código incluye un retardo para permitir la creación correcta del índice.
Añade el siguiente código en tu archivo Main.java:
MongoClient mongoClient = MongoClients.create(uri); System.out.println("Instantiating the embedding store..."); // Set to false if the vector index already exists Boolean createIndex = true; IndexMapping indexMapping = IndexMapping.builder() .dimension(embeddingModel.dimension()) .metadataFieldNames(new HashSet<>()) .build(); MongoDbEmbeddingStore embeddingStore = MongoDbEmbeddingStore.builder() .databaseName("search") .collectionName("langchaintest") .createIndex(createIndex) .indexName("vector_index") .indexMapping(indexMapping) .fromClient(mongoClient) .build(); if (createIndex) { // Creating a vector search index can take up to a minute, // so this delay allows the index to become queryable try { Thread.sleep(15000); } catch (InterruptedException e) { throw new RuntimeException(e); } }
Para obtener más información sobre las clases y los métodos utilizados en el código anterior, consulte la documentación de la API del paquete dev.langchain j.store.embedding.mongodb.4
Almacenar datos personalizados
En esta sección, creará documentos de muestra, utilizará el modelo de incrustación para convertir el texto en incrustaciones y conservará los datos en MongoDB.
Este código realiza las siguientes acciones:
Crea una lista de documentos de muestra que incluye los campos
textymetadata.Convierte el contenido del campo
texten incrustaciones y conserva los datos en MongoDB. El código incluye un retardo para adaptar el tiempo necesario para la conversión vectorial.
Añade el siguiente código en tu archivo Main.java:
ArrayList<Document> docs = new ArrayList<>(); docs.add(new Document() .append("text", "In Zadie Smith's new novel, the true story of a heated nineteenth-century criminal trial connects to the unrest of current times.") .append("metadata", new Metadata(Map.of("author", "A")))); docs.add(new Document() .append("text", "Emperor penguins are the tallest and heaviest of all penguin species, standing up to 4 feet.") .append("metadata", new Metadata(Map.of("author", "D")))); docs.add(new Document() .append("text", "Penguins are flightless seabirds that live almost exclusively below the equator. Some island-dwellers can be found in warmer climates.") .append("metadata", new Metadata(Map.of("author", "C")))); docs.add(new Document() .append("text", "Patagonia is home to five penguin species - Magellanic, Humboldt, Gentoo, Southern Rockhopper and King.") .append("metadata", new Metadata(Map.of("author", "B")))); System.out.println("Persisting document embeddings..."); for (Document doc : docs) { TextSegment segment = TextSegment.from( doc.getString("text"), doc.get("metadata", Metadata.class) ); Embedding embedding = embeddingModel.embed(segment).content(); embeddingStore.add(embedding, segment); } // Delay for persisting data try { Thread.sleep(5000); } catch (InterruptedException e) { throw new RuntimeException(e); }
Ejecución de consultas de búsqueda vectorial
Esta sección demuestra cómo ejecutar consultas en sus datos vectorizados.
Realizar una búsqueda semántica.
Este código realiza una búsqueda semántica de la frase "Where do penguins live?" y devuelve los tres resultados más relevantes. También imprime una puntuación que captura la coincidencia de cada resultado con la consulta.
Añade el siguiente código a tu archivo Main.java:
String query = "Where do penguins live?"; Embedding queryEmbedding = embeddingModel.embed(query).content(); EmbeddingSearchRequest searchRequest = EmbeddingSearchRequest.builder() .queryEmbedding(queryEmbedding) .maxResults(3) .build(); System.out.println("Performing the query..."); EmbeddingSearchResult<TextSegment> searchResult = embeddingStore.search(searchRequest); List<EmbeddingMatch<TextSegment>> matches = searchResult.matches(); for (EmbeddingMatch<TextSegment> embeddingMatch : matches) { System.out.println("Response: " + embeddingMatch.embedded().text()); System.out.println("Author: " + embeddingMatch.embedded().metadata().getString("author")); System.out.println("Score: " + embeddingMatch.score()); }
Response: Penguins are flightless seabirds that live almost exclusively below the equator. Some island-dwellers can be found in warmer climates. Author: C Score: 0.829620897769928 Response: Patagonia is home to five penguin species - Magellanic, Humboldt, Gentoo, Southern Rockhopper and King. Author: B Score: 0.7459062337875366 Response: Emperor penguins are the tallest and heaviest of all penguin species, standing up to 4 feet. Author: D Score: 0.6908764839172363
(Opcional) Realice una búsqueda semántica con filtrado de metadatos.
Para realizar una búsqueda con filtrado de metadatos, puede usar clases del paquete dev.langchain4j.store.embedding.filter.comparison. Estas clases permiten crear filtros que comparan los valores de los metadatos con valores específicos para restringir los resultados de la búsqueda.
Este ejemplo filtra los documentos cuyo valor del campo author sea "B" o "C". A continuación, realiza una búsqueda semántica de la frase "Where do penguins live?".
Reemplace el código que crea una instancia EmbeddingSearchRequest en el paso anterior con el siguiente código:
EmbeddingSearchRequest searchRequest = EmbeddingSearchRequest.builder() .queryEmbedding(queryEmbedding) .filter(new IsIn("author", List.of("B", "C"))) .maxResults(3) .build();
Response: Penguins are flightless seabirds that live almost exclusively below the equator. Some island-dwellers can be found in warmer climates. Author: C Score: 0.8520907163619995 Response: Patagonia is home to five penguin species - Magellanic, Humboldt, Gentoo, Southern Rockhopper and King. Author: B Score: 0.7666836977005005
Para obtener más información sobre el prefiltrado de metadatos, consulte Prefiltrado de búsqueda vectorial de MongoDB.
Tip
Para obtener más información, consulte la referencia de API.
Utilice sus datos para responder preguntas
This section demonstrates a RAG implementation that uses the LangChain4j framework and MongoDB Vector Search. Now that you've used MongoDB Vector Search to retrieve semantically similar documents, use the following code examples to prompt the LLM to answer questions by using information from documents stored in MongoDB.
Set up your project for RAG.
Agregue las siguientes dependencias a la
dependenciesmatriz en el archivo de supom.xmlproyecto, pero no elimine ninguna de las dependencias ya agregadas. Estas dependencias agregan los4servicios de IA de LangChain j y la API de OpenAI para las bibliotecas de LangChain4j a su aplicación:pom.xml<dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> <version>1.1.0</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j</artifactId> <version>1.1.0</version> </dependency> Después de terminar de editar el archivo
pom.xml, vuelva a cargar su proyecto para asegurarse de que sus dependencias estén instaladas.Agregue las siguientes importaciones a su lista de importaciones en su archivo
Main.java:import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import dev.langchain4j.service.AiServices; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.openai.OpenAiChatModel; import dev.langchain4j.rag.content.retriever.ContentRetriever; import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever; Establezca la
OPENAI_KEYvariable de entorno en su clave API de OpenAI. Esta clave se utiliza para crear un modelo de chat que genere una respuesta a su consulta.
Cargue los datos de muestra.
En este paso se ingresan datos externos en Atlas. Descarga el archivo de datos de muestra rainforest-docs.json desde el docs-code-examples repositorio de GitHub. Los documentos de este archivo contienen información sobre las plantas, animales y clima de la selva tropical.
Cargue este archivo en el directorio resources de su proyecto, que está en el mismo nivel que el directorio java que contiene los archivos de su aplicación.
Debe procesar los datos en un formato utilizable que permita crear incrustaciones y conservarlas en Atlas. Este código define el método loadJsonDocuments(), que realiza las siguientes acciones:
Recupera los datos de muestra de su directorio
resourcesutilizando la claseClassLoaderAnaliza los documentos JSON en un
Listde instancias de MongoDBDocumentmediante la claseObjectMapper
Agregue el siguiente código a su Main.java archivo fuera de su método principal:
private static List<Document> loadJsonDocuments(String resourcePath) throws IOException { // Loads file from resources directory using the ClassLoader InputStream inputStream = Main.class.getClassLoader().getResourceAsStream(resourcePath); if (inputStream == null) { throw new FileNotFoundException("Resource not found: " + resourcePath); } // Parses JSON file to List of MongoDB Documents ObjectMapper objectMapper = new ObjectMapper(); List<Document> documents = objectMapper.readValue(inputStream, new TypeReference<>() {}); return documents; }
Luego, agregue el siguiente código en el cuerpo del método principal para llamar al método loadJsonDocuments() y cargar sus documentos:
System.out.println("Loading documents from file..."); String resourcePath = "rainforest-docs.json"; List<Document> documents = loadJsonDocuments(resourcePath);
Almacenar incrustaciones vectoriales en Atlas.
En este paso, creará incrustaciones vectoriales a partir de sus documentos de muestra y las conservará en Atlas.
Este código convierte el contenido de los campos text de los documentos de ejemplo en incrustaciones y conserva los datos en Atlas. El código incluye un retardo para adaptar el tiempo necesario para la conversión vectorial.
Añade el siguiente código en tu archivo Main.java:
System.out.println("Persisting document embeddings..."); for (Document doc : documents) { TextSegment segment = TextSegment.from( doc.getString("text"), new Metadata(doc.get("metadata", Map.class))); Embedding embedding = embeddingModel.embed(segment).content(); embeddingStore.add(embedding, segment); } try { Thread.sleep(5000); } catch (InterruptedException e) { throw new RuntimeException(e); }
Cree una instancia del modelo de chat y especifique el recuperador de contenido.
En este paso, se instancia un modelo de chat de OpenAI para poder responder preguntas basadas en los datos. También se especifica un recuperador de contenido que muestra los documentos relevantes para fundamentar la respuesta generada por el modelo de chat.
Este código realiza las siguientes acciones:
Crea una instancia del modelo de chat utilizando su clave API de OpenAI
Crea el recuperador de contenido con las siguientes especificaciones:
Recupera como máximo
3documentos relevantesRetrieves documents that have a relevance score of at least
0.75
Agregue el siguiente código a su archivo Main.java en el cuerpo del método principal:
String chatApiKey = System.getenv("OPENAI_KEY"); ChatLanguageModel chatModel = OpenAiChatModel.builder() .apiKey(chatApiKey) .modelName("gpt-4") .build(); ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder() .embeddingStore(embeddingStore) .embeddingModel(embeddingModel) .maxResults(3) .minScore(0.75) .build();
Tip
Filtrado de metadatos
Puede implementar el filtrado de metadatos en su ContentRetriever usando el filter() método de construcción y pasando una instancia de Filter un. Consulte el ejemplo de filtrado de metadatos del paso anterior para aprender a construir Filter un.
Crear el asistente de chat.
Cree una interfaz Assistant simple que implemente la API de servicios de IA en su aplicación. Cree un archivo de interfaz llamado Assistant.java en el mismo nivel que su archivo Main.java.
Define la interfaz Assistant:
package org.example; public interface Assistant { String answer(String question); }
En su archivo Main.java, cree una instancia de Assistant:
Assistant assistant = AiServices.builder(Assistant.class) .chatLanguageModel(chatModel) .contentRetriever(contentRetriever) .build();
Realizar consultas sobre sus datos.
Finalmente, realice una consulta con los datos de muestra. Agregue el siguiente código al archivo Main.java para ejecutar una consulta e imprimir el resultado:
String ragQuery = "What types of insects live in the rainforest?"; String output = assistant.answer(ragQuery); System.out.println("Response:\n" + output);
Response: In the rainforest, there are numerous species of insects such as beetles, butterflies, moths, wasps, bees, flies, and ants. Of the many insects that live in the rainforest, ants are particularly important as they play a crucial role in nutrient recycling and aeration of the soil. Moreover, many of these insects are involved in the processes of pollination and decomposition. The adaptations these insects have developed enable their survival in the rainforest's specific conditions, characterized by heavy rainfall.
Próximos pasos
MongoDB también proporciona los siguientes recursos para desarrolladores:
Cómo crear una aplicación RAG con LangChain4j tutorial en el sitio web de la comunidad DEV