Nota
Este tutorial utiliza el núcleo semántico Biblioteca de C#Para ver un tutorial que utiliza la biblioteca de Python, consulte Comienza con la integración de Semantic Kernel en Python.
Puede integrar MongoDB Vector Search con Microsoft Semantic Kernel para crear aplicaciones de IA e implementar la generación aumentada por recuperación (RAG). Este tutorial muestra cómo empezar a usar MongoDB Vector Search con Semantic Kernel para realizar búsquedas semánticas en sus datos y crear una Implementación deRAG. En concreto, se realizan las siguientes acciones:
Configura el entorno.
Almacenar datos personalizados en MongoDB.
Cree un índice de búsqueda vectorial MongoDB en sus datos.
Ejecute una consulta de búsqueda semántica en sus datos.
Implemente RAG utilizando MongoDB Vector Search para responder preguntas sobre sus datos.
Segundo plano
Semantic Kernel es un SDK de código abierto que permite combinar diversos servicios y complementos de IA con las aplicaciones. Se puede usar Semantic Kernel para diversos casos de uso de IA, incluyendo 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 editor de código y terminal para ejecutar su aplicación .NET.
C#/.NET instalado.
Configurar el entorno
Primero debe configurar el entorno para este tutorial. Para ello, siga estos pasos.
Instalar 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
Definir 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,consulte Conectarse a un clúster a través de bibliotecas de cliente.
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.
Almacenar 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.
Copie y pegue el siguiente código en el archivo Program.cs de su aplicación.
Este código realiza las siguientes acciones:
Importa el kernel semántico y todos los paquetes necesarios.
Se conecta a su clúster Atlas recuperando su cadena de conexión SRVdel entorno.
Recupera su clave API de OpenAI del entorno y crea una instancia del modelo de incorporación
text-embedding-ada-002de OpenAI.Crea una instancia de Atlas como 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 memoria.
Rellena la colección
semantic_kernel_db.recordscon documentos de muestra llamando al métodoCreateCollectionFromListAsync.Define una variable
recordCollectionque contiene la colecciónsemantic_kernel_db.records.Crea dos métodos auxiliares para ayudar a almacenar y recuperar texto en la 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; } } }
Guarde el archivo y luego ejecute el siguiente comando para cargar sus 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 haya creado sus incrustaciones vectoriales, puede ejecutar consultas de búsqueda vectoriales en sus datos.
Al final de la clase Program en el 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?. 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.");
Guarde el archivo y luego ejecute el siguiente comando para ver los resultados de la búsqueda semántica:
dotnet run
Answer: I am a developer Search completed.
Responda preguntas sobre sus 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 Program clase en su Program.cs para solicitar al LLM que responda preguntas basadas en esos documentos.
Este código realiza las siguientes acciones:
Crea un nuevo kernel utilizando
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 hacerle al modelo de chat e inicializa la variable
retrievedContextpara contener el contexto del almacén de vectores.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.Crea una plantilla de solicitud que indica al modelo de IA que responda 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 argumentos para la solicitud 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 luego ejecute el siguiente comando para generar 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
Puede agregar sus propios datos y reemplazar la siguiente parte del código para generar respuestas a una pregunta diferente:
var userQuestion = "When did I start using MongoDB?"
Próximos pasos
MongoDB también proporciona los siguientes recursos para desarrolladores: