Introdução à integração do LangChain JS/TS
Nesta página
Observação
Este tutorial usa a biblioteca JavaScript do LangChain. Para obter um tutorial que usa a biblioteca Python, consulte Você pode integrar o Atlas Vector Search com o LangChain.
Você pode integrar o Atlas Vector Search com o LangChain para construir aplicativosLLM e implementar a geração aumentada de recuperação (RAG). Este tutorial demonstra como começar a usar o Atlas Vector Search com o LangChain para executar a Atlas Search semântica em seus dados e criar uma implementação de RAG . Especificamente, você executa as seguintes ações:
Configure o ambiente.
Armazene dados personalizados no Atlas.
Crie um índice de pesquisa do Atlas Vector Search em seus dados.
Execute as seguintes query de pesquisa vetorial:
Pesquisa semântica.
Pesquisa semântica com pré-filtragem de metadados.
Atlas Search de máxima relevância secundária (MMR).
Implemente o RAG usando o Atlas Vector Search para responder a perguntas sobre seus dados.
Plano de fundo
LangChain é uma estrutura de código aberto que simplifica a criação de aplicativos LLM por meio do uso de "cadeias". As cadeias são componentes específicos do LangChain que podem ser combinados para uma variedade de casos de uso de AI , incluindo RAG.
Ao integrar o Atlas Vector Search com o LangChain, você pode usar o Atlas como um banco de dados vetorial e usar o Atlas Vector Search para implementar o RAG recuperando documentos semanticamente semelhantes dos seus dados. Para saber mais sobre RAG, consulte Geração Aumentada de Recuperação (RAG) com Atlas Vector Search.
Pré-requisitos
Para concluir este tutorial, você deve ter o seguinte:
Um cluster do Atlas executando MongoDB versão 6.0.11, 7.0.2 ou posterior (incluindo RCs).
Uma chave de API OpenAI. Você deve ter uma conta OpenAI paga com créditos disponíveis para solicitações de API.
Um editor de terminal e código para executar seu projeto Node.js.
npm e Node.js instalado.
Configurar o ambiente
Configure o ambiente para este tutorial. Para configurar seu ambiente, conclua as etapas a seguir.
Atualize seu arquivo package.json
.
Configure seu projeto para usar módulos ES adicionando "type": "module"
ao seu arquivo package.json
e salvando-o.
{ "type": "module", // other fields... }
Crie um arquivo chamado get-started.js
e cole o código a seguir.
Em seu projeto, crie um arquivo chamado get-started.js
e, em seguida, copie e cole o seguinte código no arquivo. Você adicionará código a esse arquivo durante o tutorial.
Este trecho de código inicial importa os pacotes necessários para este tutorial, define variáveis ambientais e estabelece uma conexão com seu cluster do Atlas.
import { formatDocumentsAsString } from "langchain/util/document"; import { MongoClient } from "mongodb"; import { MongoDBAtlasVectorSearch } from "@langchain/mongodb"; import { OpenAIEmbeddings, ChatOpenAI } from "@langchain/openai"; import { PDFLoader } from "@langchain/community/document_loaders/fs/pdf"; import { PromptTemplate } from "@langchain/core/prompts"; import { RecursiveCharacterTextSplitter } from "langchain/text_splitter"; import { RunnableSequence, RunnablePassthrough } from "@langchain/core/runnables"; import { StringOutputParser } from "@langchain/core/output_parsers"; import * as fs from 'fs'; process.env.OPENAI_API_KEY = "<api-key>"; process.env.ATLAS_CONNECTION_STRING = "<connection-string>"; const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING);
Substitua os valores do espaço reservado.
Para concluir a configuração do ambiente, substitua <api-key>
os <connection-string>
valores de espaço reservado get-started.js
e em por sua chave de API OpenAI e a connection string SRVpara seu cluster Atlas. Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Use o Atlas como um Vector Store
Nesta seção, você define uma função assíncrona para carregar dados personalizados no Atlas e instanciar o Atlas como um banco de dados vetorial, também chamado de armazenamento de vetores . Adicione o seguinte código ao seu arquivo get-started.js
.
Observação
Para este tutorial, você usa um documento PDF acessível ao público intitulado Melhores práticas do MongoDB Atlas como fonte de dados para seu armazenamento de vetores. Este documento descreve várias recomendações e conceitos principais para gerenciar seus sistemas Atlas.
Este código executa as seguintes ações:
Configura sua coleção do Atlas especificando os seguintes parâmetros:
langchain_db.test
como a coleção Atlas para armazenar os documentos.vector_index
como o índice a ser usado para consultar o armazenamento de vetores.text
como o nome do campo que contém o conteúdo de texto bruto.embedding
como o nome do campo que contém as incorporações do vetor.
Prepara seus dados personalizados fazendo o seguinte:
Recupera dados brutos da URL especificada e os salva como PDF.
Usa um divisor de texto para dividir os dados em documentos menores.
Especifica os parâmetros de parte, que determinam o número de caracteres em cada documento e o número de caracteres que devem se sobrepor entre dois documentos consecutivos.
Cria um armazenamento de vetor a partir dos documentos de amostra chamando o método
MongoDBAtlasVectorSearch.fromDocuments
. Este método especifica os seguintes parâmetros:O documento de amostra a serem armazenados no reconhecimento de data center vetorial.
Modelo de incorporação do OpenAI como o modelo usado para converter texto em incorporações vetoriais para o campo
embedding
.Sua configuração do Atlas.
async function run() { try { // Configure your Atlas collection const database = client.db("langchain_db"); const collection = database.collection("test"); const dbConfig = { collection: collection, indexName: "vector_index", // The name of the Atlas search index to use. textKey: "text", // Field name for the raw text content. Defaults to "text". embeddingKey: "embedding", // Field name for the vector embeddings. Defaults to "embedding". }; // Ensure that the collection is empty const count = await collection.countDocuments(); if (count > 0) { await collection.deleteMany({}); } // Save online PDF as a file const rawData = await fetch("https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE4HkJP"); const pdfBuffer = await rawData.arrayBuffer(); const pdfData = Buffer.from(pdfBuffer); fs.writeFileSync("atlas_best_practices.pdf", pdfData); // Load and split the sample data const loader = new PDFLoader(`atlas_best_practices.pdf`); const data = await loader.load(); const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 200, chunkOverlap: 20, }); const docs = await textSplitter.splitDocuments(data); // Instantiate Atlas as a vector store const vectorStore = await MongoDBAtlasVectorSearch.fromDocuments(docs, new OpenAIEmbeddings(), dbConfig); } finally { // Ensure that the client will close when you finish/error await client.close(); } } run().catch(console.dir);
Salve o arquivo e então execute o seguinte comando para carregar seus dados no Atlas.
node get-started.js
Dica
Depois de executar get-started.js
, você pode visualizar suas incorporações vetoriais na interface do Atlas navegando até a coleção langchain_db.test
no seu cluster.
Criar o índice Atlas Vector Search Index
Observação
Para criar um Atlas Vector Search índice de pesquisa, você deve ter acesso Project Data Access Admin
ou superior ao Atlas projeto.
Para habilitar consultas de pesquisa de vetor no seu armazenamento de vetor, crie um índice do Atlas Vector Search na coleção langchain_db.test
.
Adicione o seguinte código à função assíncrona que você definiu no seu arquivo get-started.js
. Este código cria um índice do tipo vectorSearch que especifica a indexação dos seguintes campos:
embedding
campo como o tipo de vetor . O campoembedding
contém as incorporações criadas utilizando o modelo de incorporaçãotext-embedding-ada-002
do OpenAI. A definição de índice especifica1536
dimensões vetoriais e mede a similaridade usandocosine
.loc.pageNumber
campo como o tipo de filtro para pré-filtrar dados pelo número da página no PDF.
Este código também usa uma função await para garantir que seu índice de pesquisa tenha sido sincronizado com seus dados antes de ser usado.
1 // Ensure index does not already exist, then create your Atlas Vector Search index 2 const indexes = await collection.listSearchIndexes("vector_index").toArray(); 3 if(indexes.length === 0){ 4 5 // Define your Atlas Vector Search Index 6 const index = { 7 name: "vector_index", 8 type: "vectorSearch", 9 definition: { 10 "fields": [ 11 { 12 "type": "vector", 13 "numDimensions": 1536, 14 "path": "embedding", 15 "similarity": "cosine" 16 }, 17 { 18 "type": "filter", 19 "path": "loc.pageNumber" 20 } 21 ] 22 } 23 } 24 25 // Run the helper method 26 const result = await collection.createSearchIndex(index); 27 console.log(result); 28 29 // Wait for Atlas to sync index 30 console.log("Waiting for initial sync..."); 31 await new Promise(resolve => setTimeout(() => { 32 resolve(); 33 }, 10000)); 34 }
Salve o arquivo e execute o seguinte comando para criar seu índice do Atlas Vector Search.
node get-started.js
Executar queries no Vector Search
Esta seção demonstra várias queries que você pode executar em seus dados vetorizados. Agora que você criou o índice, adicione o seguinte código à sua função assíncrona para executar queries do Atlas Search vetorial em seus dados.
Observação
Se você tiver resultados imprecisos ao consultar seus dados, seu índice pode estar demorando mais do que o esperado para sincronizar. Aumente o número na função setTimeout
para permitir mais tempo para a sincronização inicial.
Adicione o seguinte código à sua função assíncrona e salve o arquivo.
O código a seguir usa o método similaritySearch
para executar uma pesquisa semântica básica para a string MongoDB Atlas security
. Ele retorna uma lista de documentos classificados por relevância com apenas os campos pageContent
e pageNumber
.
// Basic semantic search const basicOutput = await vectorStore.similaritySearch("MongoDB Atlas security"); const basicResults = basicOutput.map((results => ({ pageContent: results.pageContent, pageNumber: results.metadata.loc.pageNumber, }))) console.log("Semantic Search Results:") console.log(basicResults)
Execute o seguinte comando para executar a query.
node get-started.js
... Semantic Search Results: [ { pageContent: 'MongoDB Atlas features extensive capabilities to defend,\n' + 'detect, and control access to MongoDB, offering among\n' + 'the most complete security controls of any modern\n' + 'database:', pageNumber: 18 }, { pageContent: 'Atlas provides encryption of data at rest with encrypted\n' + 'storage volumes.\n' + 'Optionally, Atlas users can configure an additional layer of\n' + 'encryption on their data at rest using the MongoDB', pageNumber: 19 }, { pageContent: 'automatically enabled.\n' + 'Review thesecurity section of the MongoDB Atlas\n' + 'documentationto learn more about each of the security\n' + 'features discussed below.\n' + 'IP Whitelisting', pageNumber: 18 }, { pageContent: '16Security\n' + '17Business Intelligence with MongoDB Atlas\n' + '18Considerations for Proofs of Concept\n' + '18MongoDB Stitch: Serverless Platform from MongoDB\n' + '19We Can Help\n' + '19Resources', pageNumber: 2 } ]
Você pode pré-filtrar seus dados usando uma expressão de correspondência MQL que compara o campo indexado com valores booleanos, numéricos ou de string. Você deve indexar todos os campos de metadados pelos quais deseja filtrar como o tipo filter
. Para saber mais, consulte Como indexar campos do Vector Search.
Observação
Você especificou o campo loc.pageNumber
como um filtro quando criou o índice para este tutorial.
Adicione o seguinte código à sua função assíncrona e salve o arquivo.
O código a seguir usa o método similaritySearch
para executar uma pesquisa semântica para a string MongoDB Atlas security
. Ele especifica os seguintes parâmetros:
O número de documentos a retornar como
3
.Um pré-filtro no campo
loc.pageNumber
que usa o operador$eq
para corresponder aos documentos que aparecem somente na página 17 .
Ele retorna uma lista de documentos classificados por relevância com apenas os campos pageContent
e pageNumber
.
// Semantic search with metadata filter const filteredOutput = await vectorStore.similaritySearch("MongoDB Atlas security", 3, { preFilter: { "loc.pageNumber": {"$eq": 17 }, } }); const filteredResults = filteredOutput.map((results => ({ pageContent: results.pageContent, pageNumber: results.metadata.loc.pageNumber, }))) console.log("Semantic Search with Filtering Results:") console.log(filteredResults)
Execute o seguinte comando para executar a query.
node get-started.js
... Semantic Search with Filter Results: [ { pageContent: 'BSON database dumps produced bymongodump.\n' + 'In the vast majority of cases, MongoDB Atlas backups\n' + 'delivers the simplest, safest, and most efficient backup', pageNumber: 17 }, { pageContent: 'Monitoring Solutions\n' + 'The MongoDB Atlas API provides integration with external\n' + 'management frameworks through programmatic access to\n' + 'automation features and alerts.\n' + 'APM Integration', pageNumber: 17 }, { pageContent: 'MongoDB Atlas backups are maintained continuously, just\n' + 'a few seconds behind the operational system. If the\n' + 'MongoDB cluster experiences a failure, the most recent', pageNumber: 17 } ]
Você também pode realizar pesquisas semânticas com base na Relevância Marginal Máxima (MMR), uma medida de relevância semântica otimizada para a diversidade.
Adicione o seguinte código à sua função assíncrona e salve o arquivo.
O código a seguir usa o método maxMarginalRelevanceSearch
para pesquisar a string MongoDB Atlas security
. Ele também especifica um objeto que define os seguintes parâmetros opcionais:
k
para limitar o número de documentos retornados a3
.fetchK
para buscar apenas10
documentos antes de passá-los para o algoritmo MMR .
Ele retorna uma lista de documentos classificados por relevância com apenas os campos pageContent
e pageNumber
.
// Max Marginal Relevance search const mmrOutput = await vectorStore.maxMarginalRelevanceSearch("MongoDB Atlas security", { k: 3, fetchK: 10, }); const mmrResults = mmrOutput.map((results => ({ pageContent: results.pageContent, pageNumber: results.metadata.loc.pageNumber, }))) console.log("Max Marginal Relevance Search Results:") console.log(mmrResults)
Execute o seguinte comando para executar a query.
node get-started.js
... Max Marginal Relevance Search Results: [ { pageContent: 'MongoDB Atlas features extensive capabilities to defend,\n' + 'detect, and control access to MongoDB, offering among\n' + 'the most complete security controls of any modern\n' + 'database:', pageNumber: 18 }, { pageContent: 'automatically enabled.\n' + 'Review thesecurity section of the MongoDB Atlas\n' + 'documentationto learn more about each of the security\n' + 'features discussed below.\n' + 'IP Whitelisting', pageNumber: 18 }, { pageContent: '16Security\n' + '17Business Intelligence with MongoDB Atlas\n' + '18Considerations for Proofs of Concept\n' + '18MongoDB Stitch: Serverless Platform from MongoDB\n' + '19We Can Help\n' + '19Resources', pageNumber: 2 } ]
Responda a perguntas sobre seus dados
Esta seção demonstra duas implementações diferentes de RAG usando Atlas Vector Search e LangChain. Agora que você usou o Atlas Vector Search para recuperar documentos semanticamente semelhantes, use os seguintes exemplos de código para solicitar que o LLM responda às perguntas dos documentos retornados pelo Atlas Vector Search.
Adicione o seguinte código à sua função assíncrona e salve o arquivo.
Este código faz o seguinte:
Instancia o Atlas Vector Search como um recuperador para fazer query de documentos semanticamente semelhantes.
Define um modelo de prompt LangChain para instruir o LLM a usar esses documentos como contexto para sua query. O LangChain passa esses documentos para a variável de entrada
{context}
e sua query para a variável{question}
.Constrói uma cadeia que usa o modelo de chat da OpenAI para gerar respostas sensíveis ao contexto com base em sua solicitação.
Solicita a cadeia com uma query de amostra sobre as recomendações de segurança do Atlas .
Retorna a resposta do LLM e os documentos usados como contexto.
// Implement RAG to answer questions on your data const retriever = vectorStore.asRetriever(); const prompt = PromptTemplate.fromTemplate(`Answer the question based on the following context: {context} Question: {question}`); const model = new ChatOpenAI({}); const chain = RunnableSequence.from([ { context: retriever.pipe(formatDocumentsAsString), question: new RunnablePassthrough(), }, prompt, model, new StringOutputParser(), ]); // Prompt the LLM const question = "How can I secure my MongoDB Atlas cluster?"; const answer = await chain.invoke(question); console.log("Question: " + question); console.log("Answer: " + answer); // Return source documents const retrievedResults = await retriever.getRelevantDocuments(question) const documents = retrievedResults.map((documents => ({ pageContent: documents.pageContent, pageNumber: documents.metadata.loc.pageNumber, }))) console.log("\nSource documents:\n" + JSON.stringify(documents, 1, 2))
Execute o seguinte comando para executar seu arquivo.
Depois de salvar o arquivo, execute o seguinte comando. A resposta gerada pode variar.
node get-started.js
... Question: How can I secure my MongoDB Atlas cluster? Answer: You can secure your MongoDB Atlas cluster by taking advantage of extensive capabilities to defend, detect, and control access to MongoDB. You can also enable encryption of data at rest with encrypted storage volumes and configure an additional layer of encryption on your data. Additionally, you can set up global clusters on Amazon Web Services, Microsoft Azure, and Google Cloud Platform with just a few clicks in the MongoDB Atlas UI. Source documents: [ { "pageContent": "MongoDB Atlas features extensive capabilities to defend,\ndetect, and control access to MongoDB, offering among\nthe most complete security controls of any modern\ndatabase:", "pageNumber": 18 }, { "pageContent": "throughput is required, it is recommended to either\nupgrade the Atlas cluster or take advantage of MongoDB's\nauto-shardingto distribute read operations across multiple\nprimary members.", "pageNumber": 14 }, { "pageContent": "Atlas provides encryption of data at rest with encrypted\nstorage volumes.\nOptionally, Atlas users can configure an additional layer of\nencryption on their data at rest using the MongoDB", "pageNumber": 19 }, { "pageContent": "You can set up global clusters — available on Amazon Web\nServices, Microsoft Azure, and Google Cloud Platform —\nwith just a few clicks in the MongoDB Atlas UI. MongoDB", "pageNumber": 13 } ]
Adicione o seguinte código à sua função assíncrona e salve o arquivo.
Este código faz o seguinte:
Instancia o Atlas Vector Search como um recuperador para fazer query de documentos semanticamente semelhantes. Ela também especifica os seguintes parâmetros opcionais:
searchType
comommr
, que especifica que o Atlas Vector Search recupere documentos com base na Relevância Marginal Maxima (MMR).filter
para adicionar um pré-filtro no campolog.pageNumbers
para incluir documentos que aparecem apenas na página 17.Os seguintes parâmetros específicos do MMR:
fetchK
para buscar apenas20
documentos antes de passá-los para o algoritmo MMR .lambda
, um valor entre0
e1
para determinar o grau de diversidade entre os resultados, com0
representando a diversidade máxima e1
representando a diversidade mínima.
Define um modelo de prompt LangChain para instruir o LLM a usar esses documentos como contexto para sua query. O LangChain passa esses documentos para a variável de entrada
{context}
e sua query para a variável{question}
.Constrói uma cadeia que usa o modelo de chat da OpenAI para gerar respostas sensíveis ao contexto com base em sua solicitação.
Solicita a cadeia com uma query de amostra sobre as recomendações de segurança do Atlas .
Retorna a resposta do LLM e os documentos usados como contexto.
// Implement RAG to answer questions on your data const retriever = await vectorStore.asRetriever({ searchType: "mmr", // Defaults to "similarity filter: { preFilter: { "loc.pageNumber": { "$eq": 17 } } }, searchKwargs: { fetchK: 20, lambda: 0.1, }, }); const prompt = PromptTemplate.fromTemplate(`Answer the question based on the following context: {context} Question: {question}`); const model = new ChatOpenAI({}); const chain = RunnableSequence.from([ { context: retriever.pipe(formatDocumentsAsString), question: new RunnablePassthrough(), }, prompt, model, new StringOutputParser(), ]); // Prompt the LLM const question = "How can I secure my MongoDB Atlas cluster?"; const answer = await chain.invoke(question); console.log("Question: " + question); console.log("Answer: " + answer); // Return source documents const retrievedResults = await retriever.getRelevantDocuments(question) const documents = retrievedResults.map((documents => ({ pageContent: documents.pageContent, pageNumber: documents.metadata.loc.pageNumber, }))) console.log("\nSource documents:\n" + JSON.stringify(documents, 1, 2))
Execute o seguinte comando para executar seu arquivo.
Depois de salvar o arquivo, execute o seguinte comando. A resposta gerada pode variar.
node get-started.js
... Question: How can I secure my MongoDB Atlas cluster? Answer: To secure your MongoDB Atlas cluster, you can take the following measures: 1. Enable authentication and use strong, unique passwords for all users. 2. Utilize encryption in transit and at rest to protect data both while in motion and at rest. 3. Configure network security by whitelisting IP addresses that can access your cluster. 4. Enable role-based access control to limit what actions users can perform within the cluster. 5. Monitor and audit your cluster for suspicious activity using logging and alerting features. 6. Keep your cluster up to date with the latest patches and updates to prevent vulnerabilities. 7. Implement backups and disaster recovery plans to ensure you can recover your data in case of data loss. Source documents: [ { "pageContent": "BSON database dumps produced bymongodump.\nIn the vast majority of cases, MongoDB Atlas backups\ndelivers the simplest, safest, and most efficient backup", "pageNumber": 17 }, { "pageContent": "APM Integration\nMany operations teams use Application Performance\nMonitoring (APM) platforms to gain global oversight of\n15", "pageNumber": 17 }, { "pageContent": "performance SLA.\nIf in the course of a deployment it is determined that a new\nshard key should be used, it will be necessary to reload the\ndata with a new shard key because designation and values", "pageNumber": 17 }, { "pageContent": "to the database.\nReplication Lag\nReplication lag is the amount of time it takes a write\noperation on the primary replica set member to replicate to", "pageNumber": 17 } ]
Próximos passos
O MongoDB também fornece os seguintes recursos para desenvolvedores: