Nota
Este tutorial utiliza el Kernel Semántico librería de C#. Para un tutorial que utilice la librería de Python, consulta Comienza con la integración de Semantic Kernel en Python.
Puede integrar MongoDB Vector Search con Microsoft Semantic Kernel para compilar aplicaciones de IA e implementar la generación de recuperación aumentada (RAG). Este tutorial demuestra cómo empezar a usar MongoDB Vector Search con Semantic Kernel para realizar búsquedas semánticas en tus datos y compilar un RAG implementation. 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.
Ejecute una consulta de búsqueda semántica en sus datos.
Implementa RAG utilizando MongoDB Vector Search para responder preguntas sobre tus datos.
Segundo plano
Semantic Kernel es un kit de desarrollo (SDK) de código abierto que permite combinar varios servicios y plugins de IA con sus aplicaciones. Puede usar Semantic Kernel para una variedad de casos de uso de IA, incluido RAG.
Al integrar Búsqueda Vectorial de MongoDB con Semantic Kernel, se puede utilizar MongoDB como una base de datos vectorial y así aprovechar Búsqueda Vectorial de MongoDB para implementar RAG al recuperar documentos semánticamente similares de sus 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:
Un clúster de Atlas que ejecuta la versión 6.0.11, 7.0.2 o posterior de MongoDB. Asegúrese de que su dirección IP esté incluida en la lista de acceso de su proyecto 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 su terminal, ejecute los siguientes comandos para instalar los paquetes de 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 su terminal, ejecute los siguientes comandos para agregar la cadena de conexión SRVde su clúster MongoDB y la clave API de OpenAI a su 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, se inicializa el kernel, la interfaz principal para administrar los servicios y complementos de la aplicación. A través del kernel, se configuran los servicios de IA, se instancia MongoDB como base de datos vectorial (también denominada almacén de memoria) y se cargan datos personalizados en el 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 el kernel semántico y todos los paquetes necesarios.
Se conecta a tu clúster de Atlas recuperando tu SRV 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:
CreateRecord:Una 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 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 un ejemplo de implementación de RAG con MongoDB Vector Search y Semantic Kernel. Ahora que ha utilizado MongoDB Vector Search para recuperar documentos semánticamente similares, pegue el siguiente ejemplo de código al final de la clase Program en su Program.cs para que el LLM responda 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: