Menu Docs
Página inicial do Docs
/
Atlas
/ /

Comece com a integração LangChain4j

Você pode integrar o MongoDB Vector Search ao LangChain4j para construir aplicativos LLM. Este tutorial demonstra como começar a usar o MongoDB Vector Search com o LangChain4j para realizar pesquisas semânticas em seus dados e criar uma implementação simples deRAG. Especificamente, você executa as seguintes ações:

  1. Configure o ambiente.

  2. Instancie o modelo de incorporação.

  3. Use o MongoDB como um armazenamento de incorporação.

  4. Armazene dados personalizados em seu cluster MongoDB .

  5. Execute as seguintes query de pesquisa vetorial:

    • Pesquisa semântica.

    • Pesquisa semântica com pré-filtragem de metadados.

  6. Implemente o RAG usando o MongoDB Vector Search para responder a perguntas sobre seus dados.

LangChain4j é um framework que simplifica a criação de aplicativos LLM em Java. LangChain4j combina conceitos e funcionalidades do LangChain, Haystack, LlamaIndex e outras fontes. Você pode usar este framework para uma variedade de casos de uso, incluindo pesquisa semântica e RAG.

Ao integrar o MongoDB Vector Search com o LangChain4j, você pode usar o MongoDB como um banco de dados vetorial e usar o MongoDB Vector Search para implementar RAG usando documentos semanticamente semelhantes para responder a queries. Para saber mais sobre RAG, consulte Geração Aumentada de Recuperação (RAG) com MongoDB.

Para concluir este tutorial, você deve ter o seguinte:

  • Um dos seguintes tipos de cluster MongoDB :

  • Uma chave de API da Voyage AI. Você deve ter uma conta com tokens disponíveis para solicitações de API. Para saber mais sobre como registrar uma conta Voyage AI, consulte o site da Voyage AI.

  • Uma chave de API da OpenAI. Você deve ter uma conta da OpenAI com créditos disponíveis para solicitações de API. Para aprender mais sobre como registrar uma conta OpenAI, consulte o website de API OpenAI.

  • Java Development Kit (JDK) versão 8 ou posterior.

  • Um ambiente para configurar e executar um aplicação Java . Recomendamos que você use um ambiente de desenvolvimento integrado (IDE) como IntelliJ IDEA ou Eclipse IDE para configurar Maven ou Gradle para construir e executar seu projeto.

Primeiro, você deve configurar o ambiente para este tutorial, o que inclui adicionar as dependências necessárias e definir as variáveis de ambiente.

1
  1. Abra seu IDE e crie um novo projeto Java, definindo as seguintes configurações:

    • Nome: LangChain4jSampleApp

    • Linguagem: Java

    • Sistema de construção: Maven

    • JDK: qualquer versão maior que 8

    Talvez você veja uma opção para incluir um código de exemplo. Selecionar esta opção pode ajudá-lo a verificar se o seu ambiente está funcionando e localizar o arquivo do aplicativo que você editará nas etapas seguintes.

2
  1. Adicione as seguintes dependências à array dependencies no arquivo pom.xml do seu projeto. Essas dependências adicionam as bibliotecas LangChain4j, Voyage AI API para LangChain4j e MongoDB Java Sync Driver ao seu aplicativo:

    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>
    <dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-sync</artifactId>
    <version>5.4.0</version>
    </dependency>
  2. Em seguida, adicione uma entrada dependencyManagement abaixo da sua lista de dependências para o Bill of Materials (BOM) do 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 aprender mais sobre o BOM do LangChain4j, veja a página Introdução na documentação do LangChain4j.

    Depois de terminar de editar o arquivo pom.xml, recarregue o projeto para garantir que as dependências estejam instaladas.

3

Localize o arquivo principal do aplicativo Main.java em seu projeto. Substitua quaisquer importações existentes pela seguinte lista de importações:

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.*;

Mais adiante neste tutorial, você usará essas classes e os métodos para criar incorporações vetoriais e consultar dados.

4

Dependendo do seu IDE, pode haver várias maneiras de definir variáveis de ambiente que o seu aplicativo pode recuperar. Para definir variáveis de ambiente no IntelliJ, você deve criar uma configuração de executar para seu aplicativo. Para aprender mais, consulte a seção Sistema Operacional da página Configuração de executar/depuração: aplicativo na documentação do IntelliJ.

Defina as seguintes variáveis de ambiente:

  • MONGODB_URI: Defina como para a string de conexão do MongoDB .

  • VOYAGE_AI_KEY: Defina a sua chave de API do Voyage AI.

Observação

Sua string de conexão deve usar o seguinte formato:

mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net/?<settings>

Para saber mais sobre como obter sua string de conexão, consulte o tutorial Introdução ao Atlas.

5

Recupere suas variáveis de ambiente adicionando o seguinte código dentro do método principal no arquivo Main.java do seu aplicativo:

String embeddingApiKey = System.getenv("VOYAGE_AI_KEY");
String uri = System.getenv("MONGODB_URI");

Nesta etapa, você instancia um modelo de incorporação que usa o Voyage AI para converter texto em dados de exemplo em embeddings vetoriais.

Adicione o seguinte código ao seu arquivo Main.java para instanciar o modelo de incorporação usando sua chave de API da Voyage AI e selecionando voyage-3-large como o modelo:

EmbeddingModel embeddingModel = VoyageAiEmbeddingModel.builder()
.apiKey(embeddingApiKey)
.modelName("voyage-3-large")
.build();

Para aprender mais sobre o modelo voyage-3-large, veja a publicação no blog sobre voyage-3 & voyage-3-lite no website da Voyage AI.

Nesta seção, você instancia o MongoDB como um banco de dados vetorial, também chamado de armazenamento vetorial ou de incorporação. Ao instanciar o armazenamento de incorporação, o LangChain4j cria automaticamente um índice do MongoDB Vector Search em seus dados.

Observação

Acesso necessário

Para criar um índice do MongoDB Vector Search, você deve ter acessoProject Data Access Admin ou superior ao projeto MongoDB.

Este código executa as seguintes ações:

  • Cria uma instância MongoClient que está conectada à sua implantação do Atlas.

  • Define o número de dimensões na definição do índice de pesquisa vetorial para a dimensão de incorporação do modelo de IA. O índice de pesquisa vetorial resultante tem a seguinte definição:

    {
    "fields": [
    {
    "type": "vector",
    "path": "embedding",
    "numDimensions": 1024,
    "similarity": "cosine"
    }
    ]
    }
  • Configura sua collection MongoDB especificando os seguintes parâmetros:

    • langchain4j_test.vector_store como a coleção MongoDB para armazenar os documentos.

    • vector_index como o índice a ser usado para consultar o armazenamento de incorporação.

Como o booleano createIndex está configurado para true, a instância do armazenamento de incorporação cria automaticamente o índice de pesquisa vetorial. O código inclui um atraso para possibilitar a criação bem-sucedida de índices.

Adicione o seguinte código ao seu arquivo 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 aprender mais sobre as classes e métodos usados no código anterior, consulte a documentação da API do pacote dev.langchain4j.store.embedding.mongodb.

Nesta seção, você cria documentos de exemplo, usa o modelo de incorporação para converter o texto em incorporações e persiste os dados no MongoDB.

Este código executa as seguintes ações:

  • Cria uma lista de documentos de amostra que inclui os campos text e metadata.

  • Converte o conteúdo do campo text em incorporações e persiste os dados no MongoDB. O código inclui um atraso para acomodar o tempo necessário para a conversão vetorial.

Adicione o seguinte código ao seu arquivo 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);
}

Esta seção demonstra como executar consultas em seus dados vetorizados.

1

Este código executa uma query de pesquisa semântica para a frase "Where do penguins live?" e retorna os três resultados mais relevantes. Ele também imprime uma pontuação que indica o quão bem cada resultado corresponde à query.

Adicione o seguinte código ao seu arquivo 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
2

Para realizar uma pesquisa com filtro de metadados, você pode usar classes do pacote dev.langchain4j.store.embedding.filter.comparison. Essas classes permitem que você crie filtros que comparem valores de metadados com valores especificados para restringir os resultados retornados pela pesquisa.

Este exemplo filtra documentos nos quais o valor do campo author é "B" ou "C". Em seguida, ele executa uma consulta de pesquisa semântica para a frase "Where do penguins live?".

Substitua o código que instancia uma instância EmbeddingSearchRequest na etapa anterior pelo seguinte 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 saber mais sobre a pré-filtragem de metadados, consulte Pré-filtro de Vector Search do MongoDB.

Dica

Para obter mais informações, consulte a referência da API.

Esta seção demonstra uma implementação de RAG que usa o framework LangChain4j e a Vector Search do MongoDB . Agora que você usou a Vector Search do MongoDB para recuperar documentos semanticamente semelhantes, use os exemplos de código a seguir para solicitar que o LLM responda às perguntas usando informações de documentos armazenados no MongoDB.

1
  1. Adicione as seguintes dependências à array dependencies no arquivo pom.xml do seu projeto, mas não remova nenhuma das dependências que você já adicionou. Essas dependências adicionam os serviços de AI LangChain4j e a API OpenAI para as bibliotecas LangChain4j ao seu aplicativo:

    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>

    Depois de terminar de editar o arquivo pom.xml, recarregue o projeto para garantir que as dependências estejam instaladas.

  2. Adicione as seguintes importações à sua lista de importações no seu arquivo 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;
  3. Defina a variável de ambiente OPENAI_KEY para a sua chave de API da OpenAI. Você utiliza esta chave para criar um modelo de chat que gera uma resposta à sua query.

2

Nesta etapa, você importa dados de uma fonte externa para o Atlas. Baixe o arquivo de dados de amostra rainforest-docs.json do repositório GitHub docs-code-examples. Os documentos neste arquivo contêm informações sobre plantas, animais e condições climáticas na floresta tropical.

Envie este arquivo para o diretório resources no seu projeto, que está no mesmo nível do diretório java que contém os arquivos do seu aplicativo.

Você deve processar os dados em um formato utilizável do qual possa criar embeddings e persistir no Atlas. Este código define o método loadJsonDocuments() que executa as seguintes ações:

  • Recupera os dados de amostra do seu diretório resources usando a classe ClassLoader.

  • Analisa os documentos JSON em uma List de instâncias do MongoDB Document utilizando a classe ObjectMapper

Adicione o seguinte código ao seu arquivo Main.java fora do 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;
}

Em seguida, adicione o seguinte código no corpo do método principal para chamar o método loadJsonDocuments() e carregar seus documentos:

System.out.println("Loading documents from file...");
String resourcePath = "rainforest-docs.json";
List<Document> documents = loadJsonDocuments(resourcePath);
3

Nesta etapa, você cria incorporações vetoriais a partir de seus documentos de amostra e as armazena no Atlas.

Este código converte o conteúdo dos campos text nos documentos de amostra em embeddings e persiste os dados no Atlas. O código inclui um atraso para acomodar o tempo necessário para a conversão de vetores.

Adicione o seguinte código ao seu arquivo 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);
}
4

Nesta etapa, você instancia um modelo de chat da OpenAI para dar resposta a perguntas com base em seus dados. Você também especifica um recuperador de conteúdo que apresenta documentos relevantes para informar a resposta elaborada pelo modelo de chat.

Este código executa as seguintes ações:

  • Instancia o modelo de chat usando sua chave de API OpenAI

  • Cria o recuperador de conteúdo com as seguintes especificações:

    • Recupere no máximo 3 documentos relevantes

    • Recupera documentos que possuem uma pontuação de relevância de no mínimo 0.75

Adicione o seguinte código ao seu arquivo Main.java no corpo do 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();

Dica

Filtragem de metadados

Você pode implementar a filtragem de metadados no seu ContentRetriever utilizando o método construtor filter() e passando uma instância de Filter. Veja o exemplo de filtragem de metadados na etapa anterior para aprender a construir um Filter.

5

Crie uma interface Assistant simples que implemente a API de Serviços de IA no seu aplicativo. Crie um arquivo de interface chamado Assistant.java no mesmo nível do seu arquivo Main.java.

Defina a interface Assistant:

package org.example;
public interface Assistant {
String answer(String question);
}

No seu arquivo Main.java, instancie o Assistant:

Assistant assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(chatModel)
.contentRetriever(contentRetriever)
.build();
6

Finalmente, execute uma query nos seus dados de amostra. Adicione o seguinte código ao seu arquivo Main.java para executar uma consulta e imprimir o 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.

O MongoDB também fornece os seguintes recursos para desenvolvedores:

Voltar

LangChainGo

Nesta página