Nota
Este tutorial utiliza la librería de C# de Semantic Kernel. Para un tutorial que utilice la librería de Python, consulta Comienza con Semantic Kernel Python Integration.
Puedes integrar MongoDB Vector Search con Semantic Kernel de Microsoft para crear aplicaciones de IA e implementar la generación de recuperación aumentada (RAG). Este tutorial demuestra cómo empezar a utilizar la búsqueda vectorial de MongoDB con Semantic Kernel para realizar una búsqueda semántica en tus datos y compilar una implementación de RAG. Específicamente, realizas las siguientes acciones:
Configura el entorno.
Almacene datos personalizados en MongoDB.
Cree un índice de Búsqueda Vectorial de MongoDB en sus datos.
Ejecutar una búsqueda semántica query en tus datos.
Implementa RAG utilizando MongoDB Vector Search para responder preguntas sobre tus datos.
Segundo plano
Semantic Kernel es un SDK de código abierto que permite combinar distintos servicios de IA y plugins con tus aplicaciones. Puedes utilizar Semantic Kernel para una variedad de casos de uso de IA, incluyendo RAG.
Al integrar la búsqueda vectorial de MongoDB con Semantic Kernel, puedes utilizar MongoDB como una base de datos vectorial y utilizar la búsqueda vectorial de MongoDB para implementar RAG recuperando documentos semánticamente similares de tus datos. Para obtener más información sobre RAG, consulte Generación de recuperación aumentada (RAG) con MongoDB.
Requisitos previos
Para completar este tutorial, debes tener lo siguiente:
Uno de los siguientes tipos de clúster de MongoDB:
Se requiere un clúster de Atlas que ejecute MongoDB 6.0.11 versión, 7.0.2 o posterior. Asegúrese de que su dirección IP esté incluida en la lista de acceso de su proyecto de Atlas.
Una implementación local de Atlas creada usando Atlas CLI. Para obtener más información, consulta Crear una Implementación local de Atlas.
Un clúster de MongoDB Community o Enterprise con Search y Vector Search instalados.
Una llave de API de OpenAI. Debes tener una cuenta de OpenAI con créditos disponibles para las solicitudes de API. Para obtener más información sobre cómo registrar una cuenta de OpenAI, consulta el sitio web de la API de OpenAI.
Un terminal y editor de código para ejecutar tu aplicación en .NET.
C#/.NET instalado.
Configurar el entorno
Primero debes configurar el entorno para este tutorial. Para configurar su entorno, complete los siguientes pasos.
Instalar las dependencias.
En tu terminal, ejecuta los siguientes comandos para instalar los paquetes 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 variables de entorno.
En tu terminal, ejecuta los siguientes comandos para añadir el SRV de tu clúster de MongoDB cadena de conexión y la clave API de OpenAI a tu entorno.
export OPENAI_API_KEY="<Your OpenAI API Key>" export MONGODB_URI="<Your MongoDB Atlas SRV Connection String>"
Nota
Se debe sustituir <connection-string> por la cadena de conexión del clúster Atlas o de la implementación local de Atlas.
Su cadena de conexión debe usar el siguiente formato:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
Para obtener más información, consulta Conectar a un clúster a través de bibliotecas de clientes.
Su cadena de conexión debe usar el siguiente formato:
mongodb://localhost:<port-number>/?directConnection=true
Para obtener más información, consulta Cadenas de conexión.
Almacene datos personalizados en MongoDB
En esta sección, inicias el kernel, que es la interfaz principal utilizada para gestionar los servicios y plugins de la aplicación. Mediante el kernel, configuras tus servicios de IA, instancias MongoDB como una base de datos vectorial (también llamada almacén de memoria) y cargas datos personalizados en tu clúster de MongoDB.
Copia y pega el siguiente código en el Program.cs archivo de tu aplicación.
Este código realiza las siguientes acciones:
Importa Semantic Kernel y todos los paquetes necesarios.
Se conecta a su clúster Atlas recuperando su SRV de cadena de conexión desde el entorno.
Recupera tu clave de API de OpenAI desde el entorno y crea una instancia del modelo de incrustaciones
text-embedding-ada-002de OpenAI.Instancia Atlas como un almacén de memoria y especifica los siguientes parámetros:
semantic_kernel_db.recordscomo la colección para almacenar los documentos.vector_indexcomo el índice a utilizar para consultar el almacén de la memoria.
La colección
semantic_kernel_db.recordsse llena con documentos de ejemplo llamando al métodoCreateCollectionFromListAsync.Define una variable
recordCollectionque contiene la colecciónsemantic_kernel_db.records.Crea dos métodos asistentes para ayudar a almacenar y recuperar texto en memoria:
CreateRecordUna fábrica para crear un nuevo objetoDataModel.CreateCollectionFromListAsync: Un método para tomar entradas de string, generar incrustaciones para las strings, crear registros correspondientes y luego insertar esos registros en una colección de tu clúster de Atlas.
Crea una clase
DataModelque define la estructura de los documentos almacenados en la colección de 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; } } }
Guarda el archivo y luego ejecuta el siguiente comando para cargar tus datos en MongoDB:
dotnet run
Tip
Después de ejecutar el código de ejemplo, si usas Atlas, puedes verificar tus incrustaciones vectoriales navegando al namespace semantic_kernel_db.test en la Interfaz de Usuario de Atlas.
Ejecución de consultas de búsqueda vectorial
Una vez que hayas creado tus embeddings vectoriales, puedes ejecutar consultas de búsqueda vectorial en tus datos.
Al final de la clase Program en su archivo Program.cs, agregue el siguiente código para realizar una búsqueda semántica básica de la cadena What is my job title?. El sistema imprime el documento más 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.");
Guarda el archivo y luego ejecuta el siguiente comando para ver los resultados de la búsqueda semántica:
dotnet run
Answer: I am a developer Search completed.
Responde preguntas sobre tus datos
Esta sección muestra una implementación de ejemplo RAG con MongoDB Vector Search y Semantic Kernel. Ahora que usaste MongoDB Vector Search para recuperar documentos semánticamente similares, pega el siguiente ejemplo de código al final de la clase Program en tu Program.cs para que el LLM pueda responder preguntas basadas en esos documentos.
Este código realiza las siguientes acciones:
Crea un nuevo kernel utilizando el
gpt-4ode OpenAI como modelo de chat para generar respuestas.Crea una nueva instancia de búsqueda de texto usando el almacén de vectores.
Define una pregunta para hacer al modelo de chat e inicializa la variable
retrievedContextpara almacenar el contexto del almacén vectorial.Realiza una búsqueda semántica en
recordCollectionpara la preguntaWhen did I start using MongoDB?y devuelve el resultado de búsqueda más relevante.Compila una plantilla de mensaje que instruye al modelo de IA a responder la pregunta basándose únicamente en el contexto recuperado.
Crea una función llamada
ragFunctiondesde el prompt de chat utilizando la funciónCreateFunctionFromPromptdel kernel.Prepara los argumentos para el prompt RAG creando un nuevo objeto para contener la pregunta y el contexto.
Llama a la función
InvokeAsyncdel kernel para generar una respuesta del modelo de chat utilizando los siguientes parámetros:El
ragFunctionque configura la plantilla del prompt.El
ragArgumentsque contiene la pregunta y el contexto.
Imprime la pregunta y la respuesta generada.
// 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 ---
Guarde el archivo y ejecute el siguiente comando para obtener una respuesta:
dotnet run
Question: When did I start using MongoDB? Retrieved Context: I started using MongoDB two years ago Answer: Two years ago.
Tip
Puedes agregar tus propios datos y reemplazar la siguiente parte del código para generar respuestas sobre una pregunta diferente:
var userQuestion = "When did I start using MongoDB?"
Próximos pasos
MongoDB también proporciona los siguientes recursos para desarrolladores: