Observação
Este tutorial usa a biblioteca C# do Semantic Kernel . Para obter um tutorial que usa a biblioteca Python, consulte Introdução à integração com o Python do Semantic Kernel.
Você pode integrar a Vector Search do MongoDB ao Microsoft Semantic Kernel para criar aplicativos de IA e implementar a geração aumentada de recuperação (RAG). Este tutorial demonstra como começar a usar o MongoDB Vector Search com o Semantic Kernel para realizar a pesquisa semântica em seus dados e criar uma implementação deRAG . Especificamente, você executa as seguintes ações:
Configure o ambiente.
Armazene dados personalizados no MongoDB.
Crie um índice do MongoDB Vector Search em seus dados.
Execute uma consulta de pesquisa semântica em seus dados.
Implemente o RAG usando o MongoDB Vector Search para responder a perguntas sobre seus dados.
Plano de fundo
O Semantic Kernel é um SDK de código aberto que permite combinar vários serviços e plug-ins de AI com seus aplicativos. Você pode usar o Semantic Kernel para uma variedade de casos de uso de AI , incluindo RAG.
Ao integrar o MongoDB Vector Search com o Semantic Kernel, você pode usar o MongoDB como um banco de dados vetorial e usar o MongoDB Vector Search para implementar RAG, recuperando documentos semanticamente semelhantes de seus dados. Para saber mais sobre RAG, consulte Geração Aumentada de Recuperação (RAG) com MongoDB.
Pré-requisitos
Para concluir este tutorial, você deve ter o seguinte:
Um dos seguintes tipos de cluster MongoDB :
Um cluster do Atlas executando a versão 6.0.11 do MongoDB, 7.0.2, ou posterior. Certifique-se de que seu endereço IP esteja incluído na lista de acesso do seu projeto Atlas.
Um sistema local do Atlas criado utilizando o Atlas CLI. Para saber mais, consulte Criar uma implantação de Atlas local.
Um cluster MongoDB Community ou Enterprise com Search e Vector Search instalados.
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.
Um terminal e editor de código para executar seu aplicativo .NET .
C#/ .NET instalado.
Configurar o ambiente
Você deve primeiro configurar o ambiente para este tutorial. Para configurar seu ambiente, conclua as etapas a seguir.
Instalar dependências.
Em seu terminal, execute os seguintes comandos para instalar os pacotes para este tutorial.
dotnet add package Microsoft.SemanticKernel dotnet add package Microsoft.SemanticKernel.Connectors.MongoDB --prerelease dotnet add package Microsoft.SemanticKernel.Connectors.OpenAI dotnet add package Microsoft.Extensions.AI dotnet add package Microsoft.Extensions.AI.OpenAI dotnet add package Microsoft.Extensions.AI.Abstractions dotnet add package Microsoft.Extensions.VectorData.Abstractions dotnet add package SemanticKernelPooling.Connectors.OpenAI
Defina as variáveis de ambiente.
Em seu terminal, execute os seguintes comandos para adicionar a string de conexão SRVdo MongoDB cluster e a chave de API OpenAI ao seu ambiente.
export OPENAI_API_KEY="<Your OpenAI API Key>" export MONGODB_URI="<Your MongoDB Atlas SRV Connection String>"
Observação
Substitua <connection-string> pela string de conexão do seu cluster do Atlas ou da implantação local do Atlas.
Sua string de conexão deve usar o seguinte formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Para saber mais, consulte Conectar a um cluster via drivers.
Sua string de conexão deve usar o seguinte formato:
mongodb://localhost:<port-number>/?directConnection=true
Para saber mais, consulte Connection strings.
Armazenar dados personalizados no MongoDB
Nesta seção, você inicializa o kernel, que é a interface principal usada para gerenciar os serviços e plug-ins do seu aplicativo. Por meio do kernel, você configura seus serviços de IA, instancia o MongoDB como um banco de dados vetorial (também chamado de armazenamento de memória) e carrega dados personalizados em seu cluster MongoDB .
Copie e cole o seguinte código no arquivo Program.cs de seu aplicativo.
Este código executa as seguintes ações:
Importa o Semantic Kernel e todos os pacotes necessários.
Conecta-se ao cluster do Atlas recuperando sua string de conexão SRV do ambiente.
Recupera sua chave de API OpenAI do ambiente e cria uma instância do modelo de incorporação
text-embedding-ada-002do OpenAI.Instancia o Atlas como um armazenamento de memória e especifica os seguintes parâmetros:
semantic_kernel_db.recordscomo a coleção para armazenar os documentos.vector_indexcomo o índice a ser usado para consultar o armazenamento de memória.
Preenche a coleção
semantic_kernel_db.recordscom documentos de amostra chamando o métodoCreateCollectionFromListAsync.Define uma variável
recordCollectioncontendo a coleçãosemantic_kernel_db.records.Cria dois métodos assistente para ajudar a armazenar e recuperar texto na memória:
CreateRecord: Uma fábrica para criar um novo objetoDataModel.CreateCollectionFromListAsync: Um método para pegar entradas de string, gerar incorporações para as strings, criar registros correspondentes e então fazer o upsert desses registros em uma collection no seu Atlas cluster.
Cria uma classe
DataModelque define a estrutura de documentos armazenados na coleção MongoDB .
using Microsoft.Extensions.AI; using Microsoft.Extensions.VectorData; using Microsoft.SemanticKernel.Connectors.MongoDB; using Microsoft.SemanticKernel.Data; using MongoDB.Bson; using MongoDB.Driver; using OpenAI; static class Program { static async Task Main(string[] args) { // Get connection string and OpenAI API Key var connectionString = Environment.GetEnvironmentVariable("MONGODB_URI"); if (connectionString == null) { Console.WriteLine("You must set your 'MONGODB_URI' environment variable."); Environment.Exit(0); } var openAIKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY"); if (openAIKey == null) { Console.WriteLine("You must set your 'OPENAPI_KEY' environment variable."); Environment.Exit(0); } // Create new OpenAI API Embedding Model var embeddingGenerator = new OpenAIClient(openAIKey) .GetEmbeddingClient("text-embedding-ada-002") .AsIEmbeddingGenerator(); // Instantiate MongoDB as a vector store var mongoClient = new MongoClient(connectionString); var options = new MongoVectorStoreOptions { EmbeddingGenerator = embeddingGenerator }; var vectorStore = new MongoVectorStore(mongoClient.GetDatabase("semantic_kernel_db"), options); // Sample data string[] lines = [ "I am a developer", "I started using MongoDB two years ago", "I'm using MongoDB Vector Search with Semantic Kernel to implement RAG", "I like coffee" ]; // Populate database with sample data await CreateCollectionFromListAsync<string, DataModel>(vectorStore, "records", lines, embeddingGenerator, CreateRecord); // Get the specific collection from the vector store var recordCollection = vectorStore.GetCollection<string, DataModel>("records"); } static DataModel CreateRecord(string text, ReadOnlyMemory<float> embedding) => new() { Key = ObjectId.GenerateNewId().ToString(), Text = text, Embedding = embedding }; static async Task CreateCollectionFromListAsync<TKey, TRecord>( this VectorStore vectorStore, string collectionName, string[] entries, IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator, Func<string, ReadOnlyMemory<float>, TRecord> createRecord) where TKey : notnull where TRecord : class { // Get and create collection if it doesn't exist var collection = vectorStore.GetCollection<TKey, TRecord>(collectionName); await collection.EnsureCollectionExistsAsync().ConfigureAwait(false); // Create records and generate embeddings for them var embeddings = await embeddingGenerator.GenerateAsync(entries); var records = entries.Zip(embeddings, (entry, embedding) => createRecord(entry, embedding.Vector)); // Add them to the database await collection.UpsertAsync(records).ConfigureAwait(false); } internal sealed class DataModel { [] [] public required String Key { get; init; } [] [] public required string Text { get; init; } [] public ReadOnlyMemory<float> Embedding { get; init; } } }
Salve o arquivo e execute o seguinte comando para carregar seus dados no MongoDB:
dotnet run
Dica
Depois de executar o código de amostra, se estiver usando o Atlas, poderá verificar suas incorporações vetoriais navegando até o namespace semantic_kernel_db.test na interface do usuário do Atlas.
Executar queries no Vector Search
Após criar suas incorporações vetoriais, você poderá executar consultas de pesquisa vetorial em seus dados.
No final da classe Program em seu arquivo Program.cs, adicione o seguinte código para executar uma pesquisa semântica básica para a string What is my job title?. Imprime o documento mais relevante .
1 // Create a text search instance using the InMemory vector store. 2 var textSearch = new VectorStoreTextSearch<DataModel>(recordCollection, embeddingGenerator); 3 4 // Search and return results as TextSearchResult items 5 var query = "What is my job title?"; 6 KernelSearchResults<TextSearchResult> textResults = await textSearch.GetTextSearchResultsAsync(query, new() { Top = 2, Skip = 0 }); 7 await foreach (TextSearchResult result in textResults.Results) 8 { 9 Console.WriteLine($"Answer: {result.Value}"); 10 } 11 Console.WriteLine("Search completed.");
Salve o arquivo e, em seguida, execute o seguinte comando para ver os resultados da pesquisa semântica:
dotnet run
Answer: I am a developer Search completed.
Responda a perguntas sobre seus dados
Esta seção mostra um exemplo de implementação de RAG com o MongoDB Vector Search e o semantic kernel. Agora que você usou o MongoDB Vector Search para recuperar documentos semanticamente semelhantes, cole o seguinte exemplo de código no final da classe Program em seu Program.cs para solicitar que o LLM responda a perguntas com base nesses documentos.
Este código executa as seguintes ações:
Cria um novo kernel utilizando o
gpt-4odo OpenAI como o modelo de chat para gerar respostas.Cria uma nova instância de pesquisa de texto utilizando o armazenamento de vetor.
Define uma pergunta a ser feita ao modelo de chat e inicializa a variável
retrievedContextpara manter o contexto do armazenamento de vetores.Executa uma pesquisa semântica no
recordCollectionpara a perguntaWhen did I start using MongoDB?e retorna o resultado de pesquisa mais relevante.Constrói um modelo de prompt que instrui o modelo de IA a responder à pergunta com base somente no contexto recuperado.
Cria uma função chamada
ragFunctiona partir do prompt de bate-papo usando a funçãoCreateFunctionFromPromptdo kernel.Prepara argumentos para o prompt RAG criando um novo objeto para manter a pergunta e o contexto.
Chama a função
InvokeAsyncdo kernel para gerar uma resposta do modelo de chat usando os seguintes parâmetros:O
ragFunctionque configura o modelo de prompt.O
ragArgumentsque contém a pergunta e o contexto.
Imprime a pergunta e gera a resposta.
// Create a kernel with OpenAI chat completion IKernelBuilder kernelBuilder = Kernel.CreateBuilder(); kernelBuilder.AddOpenAIChatCompletion( modelId: "gpt-4o", apiKey: openAIKey); Kernel kernel = kernelBuilder.Build(); // Create a text search instance using the vector store collection. var textSearch = new VectorStoreTextSearch<DataModel>(recordCollection, embeddingGenerator); // --- Modified RAG Section --- var userQuestion = "When did I start using MongoDB?"; string retrievedContext = "No relevant context found."; // Default // 1. Perform search to get context var searchResults = await textSearch.GetTextSearchResultsAsync(userQuestion, new() { Top = 1 }); // Get most relevant result await foreach (var result in searchResults.Results) { if (result.Value != null) { retrievedContext = result.Value; // Use the text from the search result as context break; // Take the most relevant result } } // 2. Define a prompt template that uses the retrieved context const string ragPromptTemplate = @" Context: {{$context}} Question: {{$question}} Based *only* on the context provided, answer the question. Answer: "; // 3. Create a function from the RAG prompt template var ragFunction = kernel.CreateFunctionFromPrompt(ragPromptTemplate); // 4. Prepare arguments for the RAG prompt var ragArguments = new KernelArguments { ["question"] = userQuestion, ["context"] = retrievedContext }; // 5. Invoke the RAG prompt var ragResult = await kernel.InvokeAsync(ragFunction, ragArguments); Console.WriteLine($"Question: {userQuestion}"); Console.WriteLine($"Retrieved Context: {retrievedContext}"); Console.WriteLine($"Answer: {ragResult.GetValue<string>()}"); // --- End of Modified RAG Section ---
Salve o arquivo e execute o seguinte comando para gerar uma resposta:
dotnet run
Question: When did I start using MongoDB? Retrieved Context: I started using MongoDB two years ago Answer: Two years ago.
Dica
Você pode adicionar seus próprios dados e substituir a seguinte parte do código para gerar respostas em uma pergunta diferente:
var userQuestion = "When did I start using MongoDB?"
Próximos passos
O MongoDB também fornece os seguintes recursos para desenvolvedores: