Geração aumentada de recuperação (RAG) com Atlas Vector Search
Nesta página
A geração aumentada de recuperação (RAG) é uma arquitetura usada para aumentar grandes modelos de linguagem (LLMs) com dados adicionais para que possam gerar respostas mais precisas. Você pode implementar a RAG nos seus aplicativos de IA generativa combinando um LLM com um sistema de recuperação com tecnologia Atlas Vector Search.
Por que usar a RAG?
Ao usar LLMs, você pode encontrar as seguintes limitações:
Dados obsoletos: os LLMs são treinados em um conjunto de dados estático até um determinado momento. Isso significa que eles têm uma base de conhecimento limitada e podem usar dados desatualizados.
Sem acesso aos dados locais: os LLMsnão têm acesso aos dados locais ou personalizados. Portanto, eles podem não ter conhecimento sobre domínios específicos.
Alucinações: quando os dados de treinamento estão incompletos ou desatualizados, os LLMs podem gerar informações imprecisas.
Você pode resolver essas limitações seguindo as seguintes etapas para implementar o RAG:
Ingestão: Armazene seus dados personalizados como incorporações vetoriais em um banco de dados de dados vetorial , como o MongoDB Atlas. Isso permite que você crie uma base de conhecimento com dados atualizados e personalizados.
Recuperação: recupere documentos semanticamente semelhantes do banco de dados com base na pergunta do usuário usando uma solução de pesquisa, como o Atlas Vector Search. Esses documentos complementam o LLM com dados adicionais relevantes.
Geração: solicite o LLM. O LLM usa os documentos recuperados como contexto para gerar uma resposta mais precisa e relevante, reduzindo as alucinações.
Como a RAG permite tarefas como resposta a perguntas e geração de texto, é uma arquitetura eficaz para criar chatbots de AI que fornecem respostas personalizadas e específicas do domínio. Para criar chatbots prontos para produção, você deve configurar um servidor para rotear solicitações e criar uma interface de usuário com base na implementação da RAG.
RAG com Atlas Vector Search
Para implementar a RAG com o Atlas Vector Search, você ingere dados no Atlas, recupera documentos com o Atlas Vector Search e gera respostas usando um LLM. Esta seção descreve os componentes de uma implementação RAG básica ou ingênua com o Atlas Vector Search. Para obter instruções passo a passo, consulte Iniciar.
Ingestão
A ingestão de dados para RAG envolve o processamento de seus dados personalizados e o armazenamento deles em um banco de dados vetorial para prepará-los para recuperação. Para criar um pipeline de ingestão básico com o Atlas como banco de dados vetorial, faça o seguinte:
Carregar os dados.
Use ferramentas como carregadores de documento para carregar dados de diferentes formatos e locais de dados.
Divida os dados em partes.
Processe ou particione seus dados. O particionamento envolve a divisão de seus dados em partes menores para melhorar o desempenho.
Converta os dados em incorporações vetoriais.
Converta seus dados em incorporações vetoriais usando um modelo de incorporação. Para saber mais, consulte Como criar incorporações vetoriais.
Armazene os dados e incorporações no Atlas.
Armazene essas incorporações no Atlas. Você armazena incorporações como um campo junto com outros dados em sua coleção.
Carregar os dados.
Use ferramentas como carregadores de documentos ou conectores de dados para carregar dados de diferentes formatos e locais.
Divida os dados em partes.
Processe ou particione seus dados. O particionamento envolve a divisão de seus dados em partes menores para melhorar o desempenho.
Converta os dados em incorporações vetoriais.
Converta seus dados em incorporações vetoriais usando um modelo de incorporação. Para saber mais, consulte Como criar incorporações vetoriais.
Armazene os dados e incorporações no Atlas.
Armazene essas incorporações no Atlas. Você armazena incorporações como um campo junto com outros dados em sua coleção.
Carregar os dados.
Use ferramentas como carregadores de documentos ou conectores de dados para carregar dados de diferentes formatos e locais.
Divida os dados em partes.
Processe ou particione seus dados. O particionamento envolve a divisão de seus dados em partes menores para melhorar o desempenho.
Converta os dados em incorporações vetoriais.
Converta seus dados em incorporações vetoriais usando um modelo de incorporação. Para saber mais, consulte Como criar incorporações vetoriais.
Armazene os dados e incorporações no Atlas.
Armazene essas incorporações no Atlas. Você armazena incorporações como um campo junto com outros dados em sua coleção.
Retrieval
Construir um sistema de recuperação envolve pesquisar e retornar os documentos mais relevantes do seu banco de dados vetoriais para aumentar o LLM com. Para recuperar documentos relevantes com o Atlas Vector Search, você converte a pergunta do usuário em incorporações vetoriais e executa uma consulta de pesquisa vetorial em seus dados no Atlas para encontrar documentos com as incorporações mais semelhantes.
Para executar a recuperação básica com o Atlas Vector Search, faça o seguinte:
Defina um índice do Atlas Vector Search na coleção que contém suas incorporações vetoriais.
Escolha um dos seguintes métodos para recuperar documentos com base na pergunta do usuário:
Use uma integração do Atlas Vector Search com um framework ou serviço popular. Essas integrações incluem bibliotecas e ferramentas integradas que permitem que você crie facilmente sistemas de recuperação com o Atlas Vector Search.
Crie seu próprio sistema de recuperação. Você pode definir suas próprias funções e pipelines para executar queries do Atlas Vector Search específicas para o seu caso de uso.
Para aprender como construir um sistema básico de recuperação com o Atlas Vector Search, consulte Iniciar.
Geração
Para gerar respostas, combine seu sistema de recuperação com um LLM. Depois de realizar uma pesquisa vetorial para recuperar documentos relevantes, você fornece a pergunta do usuário junto com os documentos relevantes como contexto para o LLM para que ele possa gerar uma resposta mais precisa.
Escolha um dos seguintes métodos para se conectar a um LLM:
Use uma integração do Atlas Vector Search com um framework ou serviço popular. Essas integrações incluem bibliotecas e ferramentas integradas para ajudá-lo a se conectar aos LLMs com configuração mínima.
Chame a API do LLM. A maioria dos provedores de IA oferece APIs para seus modelos generativos que você pode usar para gerar respostas.
Carregue um LLM de código aberto . Se você não tiver chaves de API ou créditos, pode usar um LLM de código aberto carregando-o localmente a partir de seu aplicativo.
Começar
O exemplo a seguir demonstra como implementar o RAG com um sistema de recuperação baseado no Atlas Vector Search e modelos open-source da Hugging Face.
Pré-requisitos
➤ Use o menu suspenso Selecione sua linguagem para definir o idioma dos exemplos nesta página.
Para concluir este exemplo, você deve ter o seguinte:
Uma conta do Atlas com um cluster executando o MongoDB versão 6.0.11 ou 7.0.2 e posterior. Para saber mais, consulte Criar um cluster.
Um token de acesso do Hugging Face com acesso de leitura.
Um terminal e um editor de código para executar seu projeto Go.
Go instalado.
Uma conta do Atlas com um cluster executando o MongoDB versão 6.0.11 ou 7.0.2 e posterior. Para saber mais, consulte Criar um cluster.
Um token de acesso do Hugging Face com acesso de leitura.
Um editor de terminal e código para executar seu projeto Node.js.
npm e Node.js instalado.
Uma conta do Atlas com um cluster executando o MongoDB versão 6.0.11 ou 7.0.2 e posterior. Para saber mais, consulte Criar um cluster.
Um token de acesso do Hugging Face com acesso de leitura.
Um ambiente para executar notebooks Python interativos, como o Colab.
Observação
Se estiver usando o Colab, certifique-se de que o endereço IP da sessão do notebook esteja incluído na lista de acesso do projeto Atlas.
Procedimento
Configure o ambiente.
Inicialize seu projeto Go .
Execute os seguintes comandos no seu terminal para criar um novo diretório denominado
rag-mongodb
e inicializar seu projeto:mkdir rag-mongodb cd rag-mongodb go mod init rag-mongodb Instalar e importar dependências.
Execute os seguintes comandos:
go get github.com/joho/godotenv go get go.mongodb.org/mongo-driver/mongo go get github.com/tmc/langchaingo/llms go get github.com/tmc/langchaingo/documentloaders go get github.com/tmc/langchaingo/embeddings/huggingface go get github.com/tmc/langchaingo/llms/huggingface go get github.com/tmc/langchaingo/prompts Crie um arquivo
.env
.Em seu projeto, crie um arquivo
.env
para armazenar sua string de conexão do Atlas e o token de acesso do Hugging Face..envHUGGINGFACEHUB_API_TOKEN = "<access-token>" ATLAS_CONNECTION_STRING = "<connection-string>" Substitua os valores de placeholder
<access-token>
e<connection-string>
pelo token de acesso do Hugging Face e pela string de conexão SRV do cluster do Atlas. Sua string de conexão deve usar o seguinte formato:mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Crie uma função para gerar embeddings de vetores.
Nesta seção, você cria uma função que:
Carrega o mxbai-embed-large-v1 modelo incorporado do centro de modelos do Abraçando a face.
Cria incorporações vetoriais a partir dos dados inseridos.
Execute o comando a seguir para criar um diretório que armazena funções comuns, incluindo uma que você reutilizará para criar incorporações.
mkdir common && cd common Crie um arquivo chamado
get-embeddings.go
no diretóriocommon
e cole o seguinte código nele:get-embeddings.gopackage common import ( "context" "log" "github.com/tmc/langchaingo/embeddings/huggingface" ) func GetEmbeddings(documents []string) [][]float32 { hf, err := huggingface.NewHuggingface( huggingface.WithModel("mixedbread-ai/mxbai-embed-large-v1"), huggingface.WithTask("feature-extraction")) if err != nil { log.Fatalf("failed to connect to Hugging Face: %v", err) } embs, err := hf.EmbedDocuments(context.Background(), documents) if err != nil { log.Fatalf("failed to generate embeddings: %v", err) } return embs }
Ingerir dados no Atlas.
Nesta seção, você ingere dados de amostra no Atlas aos quais os LLM s não têm acesso. O código a seguir usa a biblioteca Go para LangChain e driver Go para fazer o seguinte:
Crie um arquivo HTML que contenha um relatório de rendimentos do MongoDB .
Divida os dados em partes, especificando o tamanho da parte (número de caracteres) e a sobreposição da parte (número de caracteres sobrepostos entre partes consecutivas).
Crie incorporações vetoriais a partir dos dados fragmentados usando a função
GetEmbeddings
que você definiu.Armazene essas incorporações junto com os dados em partes na coleção
rag_db.test
no cluster do Atlas.
Navegue até a raiz do diretório de projeto do
rag-mongodb
.Crie um arquivo chamado
ingest-data.go
em seu projeto e cole o seguinte código nele:ingest-data.gopackage main import ( "context" "fmt" "io" "log" "net/http" "os" "rag-mongodb/common" // Module that contains the embedding function "github.com/joho/godotenv" "github.com/tmc/langchaingo/documentloaders" "github.com/tmc/langchaingo/textsplitter" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type DocumentToInsert struct { PageContent string `bson:"pageContent"` Embedding []float32 `bson:"embedding"` } func downloadReport(filename string) { _, err := os.Stat(filename) if err == nil { return } url := "https://investors.mongodb.com/node/12236" fmt.Println("Downloading ", url, " to ", filename) resp, err := http.Get(url) if err != nil { log.Fatalf("failed to connect to download the report: %v", err) } defer func() { _ = resp.Body.Close() }() f, err := os.Create(filename) if err != nil { return } defer func() { _ = f.Close() }() _, err = io.Copy(f, resp.Body) if err != nil { log.Fatalf("failed to copy the report: %v", err) } } func main() { ctx := context.Background() filename := "investor-report.html" downloadReport(filename) f, err := os.Open(filename) if err != nil { defer func() { _ = f.Close() }() log.Fatalf("failed to open the report: %v", err) } defer func() { _ = f.Close() }() html := documentloaders.NewHTML(f) split := textsplitter.NewRecursiveCharacter() split.ChunkSize = 400 split.ChunkOverlap = 20 docs, err := html.LoadAndSplit(context.Background(), split) if err != nil { log.Fatalf("failed to chunk the HTML into documents: %v", err) } fmt.Printf("Successfully chunked the HTML into %v documents.\n", len(docs)) if err := godotenv.Load(); err != nil { log.Fatal("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Set the namespace coll := client.Database("rag_db").Collection("test") fmt.Println("Generating embeddings.") var pageContents []string for i := range docs { pageContents = append(pageContents, docs[i].PageContent) } embeddings := common.GetEmbeddings(pageContents) docsToInsert := make([]interface{}, len(embeddings)) for i := range embeddings { docsToInsert[i] = DocumentToInsert{ PageContent: pageContents[i], Embedding: embeddings[i], } } result, err := coll.InsertMany(ctx, docsToInsert) if err != nil { log.Fatalf("failed to insert documents: %v", err) } fmt.Printf("Successfully inserted %v documents into Atlas\n", len(result.InsertedIDs)) } Execute o seguinte comando para executar o código:
go run ingest-data.go Successfully chunked the HTML into 163 documents. Generating embeddings. Successfully inserted document with id: &{ObjectID("66faffcd60da3f6d4f990fa4")} Successfully inserted document with id: &{ObjectID("66faffce60da3f6d4f990fa5")} ...
Use o Atlas Vector Search para recuperar documentos.
Nesta seção, você configura o Atlas Vector Search para recuperar documentos do seu banco de dados de vetores. Conclua as seguintes etapas:
Crie um índice do Atlas Vector Search em suas incorporações vetoriais.
Crie um novo arquivo chamado
rag-vector-index.go
e cole o código a seguir. Este código se conecta ao seu cluster Atlas e cria um índice do tipo vectorSearch na coleçãorag_db.test
.Rag-vector-index.gopackage main import ( "context" "log" "os" "time" "go.mongodb.org/mongo-driver/bson" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) func main() { ctx := context.Background() if err := godotenv.Load(); err != nil { log.Fatal("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Specify the database and collection coll := client.Database("rag_db").Collection("test") indexName := "vector_index" opts := options.SearchIndexes().SetName(indexName).SetType("vectorSearch") type vectorDefinitionField struct { Type string `bson:"type"` Path string `bson:"path"` NumDimensions int `bson:"numDimensions"` Similarity string `bson:"similarity"` } type filterField struct { Type string `bson:"type"` Path string `bson:"path"` } type vectorDefinition struct { Fields []vectorDefinitionField `bson:"fields"` } indexModel := mongo.SearchIndexModel{ Definition: vectorDefinition{ Fields: []vectorDefinitionField{{ Type: "vector", Path: "embedding", NumDimensions: 1024, Similarity: "cosine"}}, }, Options: opts, } log.Println("Creating the index.") searchIndexName, err := coll.SearchIndexes().CreateOne(ctx, indexModel) if err != nil { log.Fatalf("failed to create the search index: %v", err) } // Await the creation of the index. log.Println("Polling to confirm successful index creation.") log.Println("NOTE: This may take up to a minute.") searchIndexes := coll.SearchIndexes() var doc bson.Raw for doc == nil { cursor, err := searchIndexes.List(ctx, options.SearchIndexes().SetName(searchIndexName)) if err != nil { log.Printf("failed to list search indexes: %w", err) } if !cursor.Next(ctx) { break } name := cursor.Current.Lookup("name").StringValue() queryable := cursor.Current.Lookup("queryable").Boolean() if name == searchIndexName && queryable { doc = cursor.Current } else { time.Sleep(5 * time.Second) } } log.Println("Name of Index Created: " + searchIndexName) } Execute o seguinte comando para criar o índice:
go run rag-vector-index.go Defina uma função para recuperar dados relevantes.
Nesta etapa, você cria uma função de recuperação chamada
GetQueryResults
que executa uma query para recuperar documentos relevantes. Ele usa a funçãoGetEmbeddings
para criar incorporações a partir da query de pesquisa. Em seguida, ele executa a query para retornar documentos semanticamente semelhantes.Para saber mais, consulte Executar queries no Vector Search.
No diretório
common
, crie um novo arquivo chamadoget-query-results.go
e cole o seguinte código nele:get-query-results.gopackage common import ( "context" "log" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type TextWithScore struct { PageContent string `bson:"pageContent"` Score float64 `bson:"score"` } func GetQueryResults(query string) []TextWithScore { ctx := context.Background() if err := godotenv.Load(); err != nil { log.Fatal("no .env file found") } // Connect to your Atlas cluster uri := os.Getenv("ATLAS_CONNECTION_STRING") if uri == "" { log.Fatal("set your 'ATLAS_CONNECTION_STRING' environment variable.") } clientOptions := options.Client().ApplyURI(uri) client, err := mongo.Connect(ctx, clientOptions) if err != nil { log.Fatalf("failed to connect to the server: %v", err) } defer func() { _ = client.Disconnect(ctx) }() // Specify the database and collection coll := client.Database("rag_db").Collection("test") queryEmbedding := GetEmbeddings([]string{query}) vectorSearchStage := bson.D{ {"$vectorSearch", bson.D{ {"index", "vector_index"}, {"path", "embedding"}, {"queryVector", queryEmbedding[0]}, {"exact", true}, {"limit", 5}, }}} projectStage := bson.D{ {"$project", bson.D{ {"_id", 0}, {"pageContent", 1}, {"score", bson.D{{"$meta", "vectorSearchScore"}}}, }}} cursor, err := coll.Aggregate(ctx, mongo.Pipeline{vectorSearchStage, projectStage}) if err != nil { log.Fatalf("failed to execute the aggregation pipeline: %v", err) } var results []TextWithScore if err = cursor.All(context.TODO(), &results); err != nil { log.Fatalf("failed to connect unmarshal retrieved documents: %v", err) } return results } Teste a recuperação dos dados.
No diretório de projeto
rag-mongodb
, crie um novo arquivo chamadoretrieve-documents-test.go
. Nesta etapa, você verifica se a função que acabou de definir retorna resultados relevantes.Cole este código no seu arquivo:
retrieve-documents-test.gopackage main import ( "fmt" "rag-mongodb/common" // Module that contains the GetQueryResults function ) func main() { query := "AI Technology" documents := common.GetQueryResults(query) for _, doc := range documents { fmt.Printf("Text: %s \nScore: %v \n\n", doc.PageContent, doc.Score) } } Execute o seguinte comando para executar o código:
go run retrieve-documents-test.go Text: for the variety and scale of data required by AI-powered applications. We are confident MongoDB will be a substantial beneficiary of this next wave of application development." Score: 0.835033655166626 Text: "As we look ahead, we continue to be incredibly excited by our large market opportunity, the potential to increase share, and become a standard within more of our customers. We also see a tremendous opportunity to win more legacy workloads, as AI has now become a catalyst to modernize these applications. MongoDB's document-based architecture is particularly well-suited for the variety and Score: 0.8280757665634155 Text: to the use of new and evolving technologies, such as artificial intelligence, in our offerings or partnerships; the growth and expansion of the market for database products and our ability to penetrate that market; our ability to integrate acquired businesses and technologies successfully or achieve the expected benefits of such acquisitions; our ability to maintain the security of our software Score: 0.8165900111198425 Text: MongoDB continues to expand its AI ecosystem with the announcement of the MongoDB AI Applications Program (MAAP), which provides customers with reference architectures, pre-built partner integrations, and professional services to help them quickly build AI-powered applications. Accenture will establish a center of excellence focused on MongoDB projects, and is the first global systems Score: 0.8023912906646729 Text: Bendigo and Adelaide Bank partnered with MongoDB to modernize their core banking technology. With the help of MongoDB Relational Migrator and generative AI-powered modernization tools, Bendigo and Adelaide Bank decomposed an outdated consumer-servicing application into microservices and migrated off its underlying legacy relational database technology significantly faster and more easily than Score: 0.7959681749343872
Gere respostas com o LLM.
Nesta seção, você gera respostas solicitando que um LLM use os documentos recuperados como contexto. Este exemplo usa a função que você acabou de definir para recuperar documentos correspondentes do banco de dados e, além disso:
Acessa o modelo Mistral 7B Instruct do hub de modelos da Hugging Face.
Instrui o LLM a incluir a pergunta do usuário e os documentos recuperados no prompt.
Informa o LLM sobre os últimos anúncios de AI do MongoDB.
Crie um novo arquivo chamado
generate-responses.go
e cole o seguinte código nele:gerar-respostas.gopackage main import ( "context" "fmt" "log" "rag-mongodb/common" // Module that contains the GetQueryResults function "strings" "github.com/tmc/langchaingo/llms" "github.com/tmc/langchaingo/llms/huggingface" "github.com/tmc/langchaingo/prompts" ) func main() { ctx := context.Background() query := "AI Technology" documents := common.GetQueryResults(query) var textDocuments strings.Builder for _, doc := range documents { textDocuments.WriteString(doc.PageContent) } question := "In a few sentences, what are MongoDB's latest AI announcements?" template := prompts.NewPromptTemplate( `Answer the following question based on the given context. Question: {{.question}} Context: {{.context}}`, []string{"question", "context"}, ) prompt, err := template.Format(map[string]any{ "question": question, "context": textDocuments.String(), }) opts := llms.CallOptions{ Model: "mistralai/Mistral-7B-Instruct-v0.3", MaxTokens: 150, Temperature: 0.1, } llm, err := huggingface.New(huggingface.WithModel("mistralai/Mistral-7B-Instruct-v0.3")) if err != nil { log.Fatalf("failed to initialize a Hugging Face LLM: %v", err) } completion, err := llms.GenerateFromSinglePrompt(ctx, llm, prompt, llms.WithOptions(opts)) if err != nil { log.Fatalf("failed to generate a response from the prompt: %v", err) } response := strings.Split(completion, "\n\n") if len(response) == 2 { fmt.Printf("Prompt: %v\n\n", response[0]) fmt.Printf("Response: %v\n", response[1]) } } Execute este comando para executar o código. A resposta gerada pode variar.
go run generate-responses.go Prompt: Answer the following question based on the given context. Question: In a few sentences, what are MongoDB's latest AI announcements? Context: for the variety and scale of data required by AI-powered applications. We are confident MongoDB will be a substantial beneficiary of this next wave of application development.""As we look ahead, we continue to be incredibly excited by our large market opportunity, the potential to increase share, and become a standard within more of our customers. We also see a tremendous opportunity to win more legacy workloads, as AI has now become a catalyst to modernize these applications. MongoDB's document-based architecture is particularly well-suited for the variety andto the use of new and evolving technologies, such as artificial intelligence, in our offerings or partnerships; the growth and expansion of the market for database products and our ability to penetrate that market; our ability to integrate acquired businesses and technologies successfully or achieve the expected benefits of such acquisitions; our ability to maintain the security of our softwareMongoDB continues to expand its AI ecosystem with the announcement of the MongoDB AI Applications Program (MAAP), which provides customers with reference architectures, pre-built partner integrations, and professional services to help them quickly build AI-powered applications. Accenture will establish a center of excellence focused on MongoDB projects, and is the first global systemsBendigo and Adelaide Bank partnered with MongoDB to modernize their core banking technology. With the help of MongoDB Relational Migrator and generative AI-powered modernization tools, Bendigo and Adelaide Bank decomposed an outdated consumer-servicing application into microservices and migrated off its underlying legacy relational database technology significantly faster and more easily than expected. Response: MongoDB's latest AI announcements include the launch of the MongoDB AI Applications Program (MAAP) and a partnership with Accenture to establish a center of excellence focused on MongoDB projects. Additionally, Bendigo and Adelaide Bank have partnered with MongoDB to modernize their core banking technology using MongoDB's AI-powered modernization tools.
Configure o ambiente.
Inicialize seu projeto Node.js.
Execute os seguintes comandos em seu terminal para criar um novo diretório chamado
rag-mongodb
e inicializar seu projeto:mkdir rag-mongodb cd rag-mongodb npm init -y Instalar e importar dependências.
Execute o seguinte comando:
npm install mongodb langchain @langchain/community @xenova/transformers @huggingface/inference pdf-parse Atualize seu arquivo
package.json
.No arquivo
package.json
do seu projeto, especifique o campotype
como mostrado no exemplo a seguir e salve o arquivo.{ "name": "rag-mongodb", "type": "module", ... Crie um arquivo
.env
.Em seu projeto, crie um arquivo
.env
para armazenar sua string de conexão do Atlas e o token de acesso do Hugging Face.HUGGING_FACE_ACCESS_TOKEN = "<access-token>" ATLAS_CONNECTION_STRING = "<connection-string>" Substitua os valores de placeholder
<access-token>
e<connection-string>
pelo token de acesso do Hugging Face e pela string de conexão SRV do cluster do Atlas. Sua string de conexão deve usar o seguinte formato:mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net Observação
Requisitos mínimos de versão do Node.js
O Node.js v20.x introduziu a opção
--env-file
. Se você estiver usando uma versão mais antiga do Node.js, adicione o pacotedotenv
ao seu projeto ou use um método diferente para gerenciar suas variáveis de ambiente.
Crie uma função para gerar embeddings de vetores.
Nesta seção, você cria uma função que:
Carrega o modelo de incorporação nomic-embed-text-v1 do hub de modelos da Hugging Face.
Cria incorporações vetoriais a partir dos dados inseridos.
Crie um arquivo chamado get-embeddings.js
no seu projeto e cole o seguinte código:
import { pipeline } from '@xenova/transformers'; // Function to generate embeddings for a given data source export async function getEmbedding(data) { const embedder = await pipeline( 'feature-extraction', 'Xenova/nomic-embed-text-v1'); const results = await embedder(data, { pooling: 'mean', normalize: true }); return Array.from(results.data); }
Ingerir dados no Atlas.
Nesta seção, você ingere dados de amostra no Atlas aos quais os LLMs não têm acesso. O código a seguir usa a integração LangChain e o driver Node.js para fazer o seguinte:
Carregue um PDF que contenha um relatório de ganhos do MongoDB.
Divida os dados em partes, especificando o tamanho da parte (número de caracteres) e a sobreposição da parte (número de caracteres sobrepostos entre partes consecutivas).
Crie incorporações vetoriais a partir dos dados fragmentados usando a função
getEmbeddings
que você definiu.Armazene essas incorporações junto com os dados em partes na coleção
rag_db.test
no cluster do Atlas.
Crie um arquivo chamado ingest-data.js
no seu projeto e cole o seguinte código:
import { PDFLoader } from "@langchain/community/document_loaders/fs/pdf"; import { RecursiveCharacterTextSplitter } from "langchain/text_splitter"; import { MongoClient } from 'mongodb'; import { getEmbeddings } from './get-embeddings.js'; import * as fs from 'fs'; async function run() { const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); try { // Save online PDF as a file const rawData = await fetch("https://investors.mongodb.com/node/12236/pdf"); const pdfBuffer = await rawData.arrayBuffer(); const pdfData = Buffer.from(pdfBuffer); fs.writeFileSync("investor-report.pdf", pdfData); const loader = new PDFLoader(`investor-report.pdf`); const data = await loader.load(); // Chunk the text from the PDF const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 400, chunkOverlap: 20, }); const docs = await textSplitter.splitDocuments(data); console.log(`Successfully chunked the PDF into ${docs.length} documents.`); // Connect to your Atlas cluster await client.connect(); const db = client.db("rag_db"); const collection = db.collection("test"); console.log("Generating embeddings and inserting documents."); let docCount = 0; await Promise.all(docs.map(async doc => { const embeddings = await getEmbeddings(doc.pageContent); // Insert the embeddings and the chunked PDF data into Atlas await collection.insertOne({ document: doc, embedding: embeddings, }); docCount += 1; })) console.log(`Successfully inserted ${docCount} documents.`); } catch (err) { console.log(err.stack); } finally { await client.close(); } } run().catch(console.dir);
Em seguida, execute o seguinte comando para executar o código:
node --env-file=.env ingest-data.js
Dica
Este código demora algum tempo para ser executado. Você pode visualizar seus embeddings vetoriais conforme eles são inseridos navegando até a coleção rag_db.test
na interface do Atlas.
Use o Atlas Vector Search para recuperar documentos.
Nesta seção, você configura o Atlas Vector Search para recuperar documentos do seu banco de dados de vetores. Conclua as seguintes etapas:
Crie um índice do Atlas Vector Search em suas incorporações vetoriais.
Crie um novo arquivo chamado
rag-vector-index.js
e cole o código a seguir. Este código se conecta ao seu cluster Atlas e cria um índice do tipo vectorSearch na coleçãorag_db.test
.import { MongoClient } from 'mongodb'; // Connect to your Atlas cluster const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); async function run() { try { const database = client.db("rag_db"); const collection = database.collection("test"); // Define your Atlas Vector Search index const index = { name: "vector_index", type: "vectorSearch", definition: { "fields": [ { "type": "vector", "numDimensions": 768, "path": "embedding", "similarity": "cosine" } ] } } // Call the method to create the index const result = await collection.createSearchIndex(index); console.log(result); } finally { await client.close(); } } run().catch(console.dir); Em seguida, execute o seguinte comando para executar o código:
node --env-file=.env rag-vector-index.js Defina uma função para recuperar dados relevantes.
Crie um novo arquivo chamado
retrieve-documents.js
.Nesta etapa, você cria uma função de recuperação chamada
getQueryResults
que executa uma query para recuperar documentos relevantes. Ele usa a funçãogetEmbeddings
para criar incorporações a partir da query de pesquisa. Em seguida, ele executa a query para retornar documentos semanticamente semelhantes.Para saber mais, consulte Executar queries no Vector Search.
Cole este código no seu arquivo:
import { MongoClient } from 'mongodb'; import { getEmbeddings } from './get-embeddings.js'; // Function to get the results of a vector query export async function getQueryResults(query) { // Connect to your Atlas cluster const client = new MongoClient(process.env.ATLAS_CONNECTION_STRING); try { // Get embeddings for a query const queryEmbeddings = await getEmbeddings(query); await client.connect(); const db = client.db("rag_db"); const collection = db.collection("test"); const pipeline = [ { $vectorSearch: { index: "vector_index", queryVector: queryEmbeddings, path: "embedding", exact: true, limit: 5 } }, { $project: { _id: 0, document: 1, } } ]; // Retrieve documents from Atlas using this Vector Search query const result = collection.aggregate(pipeline); const arrayOfQueryDocs = []; for await (const doc of result) { arrayOfQueryDocs.push(doc); } return arrayOfQueryDocs; } catch (err) { console.log(err.stack); } finally { await client.close(); } } Teste a recuperação dos dados.
Crie um novo arquivo chamado
retrieve-documents-test.js
. Nesta etapa, você verifica se a função que você acabou de definir retorna resultados relevantes.Cole este código no seu arquivo:
import { getQueryResults } from './retrieve-documents.js'; async function run() { try { const query = "AI Technology"; const documents = await getQueryResults(query); documents.forEach( doc => { console.log(doc); }); } catch (err) { console.log(err.stack); } } run().catch(console.dir); Em seguida, execute o seguinte comando para executar o código:
node --env-file=.env retrieve-documents-test.js { document: { pageContent: 'MongoDB continues to expand its AI ecosystem with the announcement of the MongoDB AI Applications Program (MAAP),', metadata: { source: 'investor-report.pdf', pdf: [Object], loc: [Object] }, id: null } } { document: { pageContent: 'artificial intelligence, in our offerings or partnerships; the growth and expansion of the market for database products and our ability to penetrate that\n' + 'market; our ability to integrate acquired businesses and technologies successfully or achieve the expected benefits of such acquisitions; our ability to', metadata: { source: 'investor-report.pdf', pdf: [Object], loc: [Object] }, id: null } } { document: { pageContent: 'more of our customers. We also see a tremendous opportunity to win more legacy workloads, as AI has now become a catalyst to modernize these\n' + "applications. MongoDB's document-based architecture is particularly well-suited for the variety and scale of data required by AI-powered applications. \n" + 'We are confident MongoDB will be a substantial beneficiary of this next wave of application development."', metadata: { source: 'investor-report.pdf', pdf: [Object], loc: [Object] }, id: null } } { document: { pageContent: 'which provides customers with reference architectures, pre-built partner integrations, and professional services to help\n' + 'them quickly build AI-powered applications. Accenture will establish a center of excellence focused on MongoDB projects,\n' + 'and is the first global systems integrator to join MAAP.', metadata: { source: 'investor-report.pdf', pdf: [Object], loc: [Object] }, id: null } } { document: { pageContent: 'Bendigo and Adelaide Bank partnered with MongoDB to modernize their core banking technology. With the help of\n' + 'MongoDB Relational Migrator and generative AI-powered modernization tools, Bendigo and Adelaide Bank decomposed an\n' + 'outdated consumer-servicing application into microservices and migrated off its underlying legacy relational database', metadata: { source: 'investor-report.pdf', pdf: [Object], loc: [Object] }, id: null } }
Gere respostas com o LLM.
Nesta seção, você gera respostas solicitando que um LLM use os documentos recuperados como contexto. Este exemplo usa a função que você acabou de definir para recuperar documentos correspondentes do banco de dados e, além disso:
Acessa o modelo Mistral 7B Instruct do hub de modelos da Hugging Face.
Instrui o LLM a incluir a pergunta do usuário e os documentos recuperados no prompt.
Informa o LLM sobre os últimos anúncios de AI do MongoDB.
Crie um novo arquivo chamado generate-responses.js
e cole o seguinte código nele:
import { getQueryResults } from './retrieve-documents.js'; import { HfInference } from '@huggingface/inference' async function run() { try { // Specify search query and retrieve relevant documents const query = "AI Technology"; const documents = await getQueryResults(query); // Build a string representation of the retrieved documents to use in the prompt let textDocuments = ""; documents.forEach(doc => { textDocuments += doc.document.pageContent; }); const question = "In a few sentences, what are MongoDB's latest AI announcements?"; // Create a prompt consisting of the question and context to pass to the LLM const prompt = `Answer the following question based on the given context. Question: {${question}} Context: {${textDocuments}} `; // Connect to Hugging Face, using the access token from the environment file const hf = new HfInference(process.env.HUGGING_FACE_ACCESS_TOKEN); const llm = hf.endpoint( "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.3" ); // Prompt the LLM to answer the question using the // retrieved documents as the context const output = await llm.chatCompletion({ model: "mistralai/Mistral-7B-Instruct-v0.2", messages: [{ role: "user", content: prompt }], max_tokens: 150, }); // Output the LLM's response as text. console.log(output.choices[0].message.content); } catch (err) { console.log(err.stack); } } run().catch(console.dir);
Em seguida, execute este comando para executar o código. A resposta gerada pode variar.
node --env-file=.env generate-responses.js
MongoDB's latest AI announcements include the launch of the MongoDB AI Applications Program (MAAP), which provides customers with reference architectures, pre-built partner integrations, and professional services to help them build AI-powered applications quickly. Accenture has joined MAAP as the first global systems integrator, establishing a center of excellence focused on MongoDB projects. Additionally, Bendigo and Adelaide Bank have partnered with MongoDB to modernize their core banking technology using MongoDB's Relational Migrator and generative AI-powered modernization tools.
Configure o ambiente.
Crie um bloco de anotações Python interativo salvando um arquivo com a extensão .ipynb
. Este bloco de anotações permite que você execute trechos de código Python individualmente. No seu bloco de anotações, execute o seguinte código para instalar as dependências deste tutorial:
pip install --quiet pymongo sentence_transformers einops langchain langchain_community pypdf huggingface_hub
Ingerir dados no Atlas.
Nesta seção, você ingere dados de amostra no Atlas aos quais os LLMs não têm acesso. Cole e execute cada um dos seguintes trechos de código em seu bloco de anotações:
Defina uma função para gerar incorporações vetoriais.
Execute este código para criar uma função que gera incorporações vetoriais usando um modelo de incorporação de código aberto. Especificamente, este código faz o seguinte:
Carrega o nomic-embed-text-v1 modelo de incorporação do Sentence Transformers.
Cria uma função chamada
get_embedding
que usa o modelo para gerar uma incorporação para uma determinada entrada de texto.
from sentence_transformers import SentenceTransformer # Load the embedding model (https://huggingface.co/nomic-ai/nomic-embed-text-v1") model = SentenceTransformer("nomic-ai/nomic-embed-text-v1", trust_remote_code=True) # Define a function to generate embeddings def get_embedding(data): """Generates vector embeddings for the given data.""" embedding = model.encode(data) return embedding.tolist() Carregue e divisão os dados.
Execute este código para carregar e divisão dados de exemplo usando a integração LangChain. Especificamente, este código faz o seguinte:
Carrega um PDF que contém um relatório de rendimentos do MongoDB .
Divide os dados em chunks, especificando o tamanho do chunk (número de caracteres) e a sobreposição do chunk (número de caracteres sobrepostos entre chunks consecutivos).
from langchain_community.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter # Load the PDF loader = PyPDFLoader("https://investors.mongodb.com/node/12236/pdf") data = loader.load() # Split the data into chunks text_splitter = RecursiveCharacterTextSplitter(chunk_size=400, chunk_overlap=20) documents = text_splitter.split_documents(data) Converta os dados em incorporações vetoriais.
Execute este código para preparar os documentos em partes para ingestão, criando uma lista de documentos com suas incorporações vetoriais correspondentes. Gere estas incorporações utilizando a função
get_embedding
que acabou de definir.# Prepare documents for insertion docs_to_insert = [{ "text": doc.page_content, "embedding": get_embedding(doc.page_content) } for doc in documents] Armazene os dados e incorporações no Atlas
Execute este código para inserir os documentos que contêm as incorporações na coleção
rag_db.test
no seu Atlas cluster. Antes de executar o código, substitua<connection-string>
por sua string de conexãodo Atlas .from pymongo import MongoClient # Connect to your Atlas cluster client = MongoClient("<connection-string>") collection = client["rag_db"]["test"] # Insert documents into the collection result = collection.insert_many(docs_to_insert) Dica
Depois de executar o código, você pode visualizar suas incorporações vetoriais na UI do Atlas navegando até a coleção
rag_db.test
em seu cluster.
Use o Atlas Vector Search para recuperar documentos.
Nesta seção, você cria um sistema de recuperação utilizando o Atlas Vector Search para obter documentos relevantes do seu banco de banco de dados vetorial. Cole e execute cada um dos seguintes trechos de código em seu bloco de anotações:
Crie um índice do Atlas Vector Search em suas incorporações vetoriais.
Execute o seguinte código para criar o índice diretamente do seu aplicação com o Driver PyMongo. Este código também inclui um mecanismo de pesquisa para verificar se o índice está pronto para ser usado.
Para saber mais, consulte Como indexar campos do Vector Search.
from pymongo.operations import SearchIndexModel import time # Create your index model, then create the search index index_name="vector_index" search_index_model = SearchIndexModel( definition = { "fields": [ { "type": "vector", "numDimensions": 768, "path": "embedding", "similarity": "cosine" } ] }, name = index_name, type = "vectorSearch" ) collection.create_search_index(model=search_index_model) # Wait for initial sync to complete print("Polling to check if the index is ready. This may take up to a minute.") predicate=None if predicate is None: predicate = lambda index: index.get("queryable") is True while True: indices = list(collection.list_search_indexes(index_name)) if len(indices) and predicate(indices[0]): break time.sleep(5) print(index_name + " is ready for querying.") Defina uma função para executar queries de pesquisa vetorial.
Execute este código para criar uma função de recuperação chamada
get_query_results
que executa uma query de pesquisa vetorial básica. Utiliza a funçãoget_embedding
para criar incorporações a partir da query de pesquisa. Em seguida, ele executa a query para retornar documentos semanticamente semelhantes.Para saber mais, consulte Executar queries de pesquisa vetorial.
# Define a function to run vector search queries def get_query_results(query): """Gets results from a vector search query.""" query_embedding = get_embedding(query) pipeline = [ { "$vectorSearch": { "index": "vector_index", "queryVector": query_embedding, "path": "embedding", "exact": True, "limit": 5 } }, { "$project": { "_id": 0, "text": 1 } } ] results = collection.aggregate(pipeline) array_of_results = [] for doc in results: array_of_results.append(doc) return array_of_results # Test the function with a sample query import pprint pprint.pprint(get_query_results("AI technology")) [{'text': 'more of our customers. We also see a tremendous opportunity to win ' 'more legacy workloads, as AI has now become a catalyst to modernize ' 'these\n' "applications. MongoDB's document-based architecture is " 'particularly well-suited for the variety and scale of data required ' 'by AI-powered applications.'}, {'text': 'artificial intelligence, in our offerings or partnerships; the ' 'growth and expansion of the market for database products and our ' 'ability to penetrate that\n' 'market; our ability to integrate acquired businesses and ' 'technologies successfully or achieve the expected benefits of such ' 'acquisitions; our ability to'}, {'text': 'MongoDB continues to expand its AI ecosystem with the announcement ' 'of the MongoDB AI Applications Program (MAAP),'}, {'text': 'which provides customers with reference architectures, pre-built ' 'partner integrations, and professional services to help\n' 'them quickly build AI-powered applications. Accenture will ' 'establish a center of excellence focused on MongoDB projects,\n' 'and is the first global systems integrator to join MAAP.'}, {'text': 'Bendigo and Adelaide Bank partnered with MongoDB to modernize ' 'their core banking technology. With the help of\n' 'MongoDB Relational Migrator and generative AI-powered modernization ' 'tools, Bendigo and Adelaide Bank decomposed an\n' 'outdated consumer-servicing application into microservices and ' 'migrated off its underlying legacy relational database'}]
Gere respostas com o LLM.
Nesta seção, você gera respostas solicitando a um LLM que use os documentos recuperados como contexto.
Substitua <token>
no código a seguir pelo token de acesso do Abraçando a Face e, em seguida, execute o código no bloco de anotações. Este código faz o seguinte:
Utiliza a função
get_query_results
que você definiu para recuperar documentos relevantes do Atlas.Cria um prompt usando a pergunta do usuário e os documentos recuperados como contexto.
Acessa o modelo Mistral 7B Instruct do hub de modelos da Hugging Face.
Informa o LLM sobre os últimos anúncios de IA do MongoDB. A resposta gerada pode variar.
import os from huggingface_hub import InferenceClient # Specify search query, retrieve relevant documents, and convert to string query = "What are MongoDB's latest AI announcements?" context_docs = get_query_results(query) context_string = " ".join([doc["text"] for doc in context_docs]) # Construct prompt for the LLM using the retrieved documents as the context prompt = f"""Use the following pieces of context to answer the question at the end. {context_string} Question: {query} """ # Authenticate to Hugging Face and access the model os.environ["HF_TOKEN"] = "<token>" llm = InferenceClient( "mistralai/Mistral-7B-Instruct-v0.3", token = os.getenv("HF_TOKEN")) # Prompt the LLM (this code varies depending on the model you use) output = llm.chat_completion( messages=[{"role": "user", "content": prompt}], max_tokens=150 ) print(output.choices[0].message.content)
MongoDB's latest AI announcements include the MongoDB AI Applications Program (MAAP), a program designed to help customers build AI-powered applications more efficiently. Additionally, they have announced significant performance improvements in MongoDB 8.0, featuring faster reads, updates, bulk inserts, and time series queries. Another announcement is the general availability of Atlas Stream Processing to build sophisticated, event-driven applications with real-time data.
Próximos passos
Para tutoriais RAG mais detalhados, use os seguintes recursos:
Para saber como implementar a RAG com estruturas de LLM e serviços de IA populares, consulte Integrar o Vector Search com tecnologias de IA.
Para saber como implementar a RAG usando uma implantação do Atlas local e modelos locais, consulte Criar uma implementação da RAG local com o Atlas Vector Search.
Para tutoriais baseados em casos de uso e notebooks interativos do Python, consulte Repositório de casos de uso de IA generativa .
Para começar a criar chatbots prontos para produção com o Atlas Vector Search, você pode usar o MongoDB Chatbot Framework. Esse framework fornece um conjunto de bibliotecas que permitem criar rapidamente aplicativos de chatbot de IA.
Ajuste fino
Para otimizar e ajustar seus aplicativos de RAG, você pode experimentar diferentes modelos de incorporação, estratégias de fragmentação e LLMs. Para saber mais, consulte os seguintes recursos:
Como escolher o modelo de incorporação correto para seu aplicativo LLM
Como escolher a estratégia de chunking certa para seu aplicativo LLM
Além disso, o Atlas Vector Search suporta sistemas avançados de recuperação. Como pode indexar perfeitamente dados vetoriais junto com seus outros dados no Atlas, você pode ajustar seus resultados de recuperação por pré-filtragem em outros campos em sua coleção ou realizando pesquisa híbrida para combinar pesquisa semântica com resultados de pesquisa de texto completo.