Uso de complementos para la generación aumentada de recuperación (RAG)
A menudo, los agentes de inteligencia artificial deben recuperar datos de orígenes externos para generar respuestas en tierra. Sin este contexto adicional, los agentes de IA pueden alucinar o proporcionar información incorrecta. Para solucionar esto, puede usar complementos para recuperar datos de orígenes externos.
Al considerar los complementos para la generación aumentada de recuperación (RAG), debe plantearse dos preguntas:
- ¿Cómo buscará (o su agente de IA) los datos necesarios? ¿Necesita búsqueda semántica o búsqueda clásica?
- ¿Ya conoce los datos que necesita el agente de IA con antelación (datos capturados previamente) o el agente de IA necesita recuperar los datos de forma dinámica?
- ¿Cómo protegerá los datos y evitará el uso compartido excesivo de información confidencial?
Búsqueda semántica frente a clásica
Al desarrollar complementos para la generación aumentada de recuperación (RAG), puede usar dos tipos de búsqueda: búsqueda semántica y búsqueda clásica.
Búsqueda semántica
La búsqueda semántica utiliza bases de datos vectoriales para comprender y recuperar información basada en el significado y el contexto de la consulta, en lugar de simplemente hacer coincidir palabras clave. Este método permite al motor de búsqueda comprender los matices del lenguaje, como sinónimos, conceptos relacionados y la intención general detrás de una consulta.
La búsqueda semántica se destaca en entornos en los que las consultas de usuario son complejas, abiertas o requieren una comprensión más profunda del contenido. Por ejemplo, la búsqueda de "mejores smartphones para fotografía" produciría resultados que consideran el contexto de las características de fotografía en smartphones, en lugar de simplemente coincidir con las palabras "mejor", "smartphones" y "fotografía".
Al proporcionar un LLM con una función de búsqueda semántica, normalmente solo es necesario definir una función con una sola consulta de búsqueda. A continuación, LLM usará esta función para recuperar la información necesaria. A continuación se muestra un ejemplo de una función de búsqueda semántica que usa Azure AI Search para buscar documentos similares a una consulta determinada.
using System.ComponentModel;
using System.Text.Json.Serialization;
using Azure;
using Azure.Search.Documents;
using Azure.Search.Documents.Indexes;
using Azure.Search.Documents.Models;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Embeddings;
public class InternalDocumentsPlugin
{
private readonly ITextEmbeddingGenerationService _textEmbeddingGenerationService;
private readonly SearchIndexClient _indexClient;
public AzureAISearchPlugin(ITextEmbeddingGenerationService textEmbeddingGenerationService, SearchIndexClient indexClient)
{
_textEmbeddingGenerationService = textEmbeddingGenerationService;
_indexClient = indexClient;
}
[KernelFunction("Search")]
[Description("Search for a document similar to the given query.")]
public async Task<string> SearchAsync(string query)
{
// Convert string query to vector
ReadOnlyMemory<float> embedding = await _textEmbeddingGenerationService.GenerateEmbeddingAsync(query);
// Get client for search operations
SearchClient searchClient = _indexClient.GetSearchClient("default-collection");
// Configure request parameters
VectorizedQuery vectorQuery = new(embedding);
vectorQuery.Fields.Add("vector");
SearchOptions searchOptions = new() { VectorSearch = new() { Queries = { vectorQuery } } };
// Perform search request
Response<SearchResults<IndexSchema>> response = await searchClient.SearchAsync<IndexSchema>(searchOptions);
// Collect search results
await foreach (SearchResult<IndexSchema> result in response.Value.GetResultsAsync())
{
return result.Document.Chunk; // Return text from first result
}
return string.Empty;
}
private sealed class IndexSchema
{
[JsonPropertyName("chunk")]
public string Chunk { get; set; }
[JsonPropertyName("vector")]
public ReadOnlyMemory<float> Vector { get; set; }
}
}
Búsqueda clásica
La búsqueda clásica, también conocida como búsqueda basada en atributos o criterios, se basa en el filtrado y la coincidencia de términos o valores exactos dentro de un conjunto de datos. Resulta especialmente eficaz para las consultas de base de datos, las búsquedas de inventario y cualquier situación en la que sea necesario filtrar por atributos específicos.
Por ejemplo, si un usuario quiere buscar todos los pedidos realizados por un identificador de cliente determinado o recuperar productos dentro de un intervalo de precios y una categoría específicos, la búsqueda clásica proporciona resultados precisos y confiables. Sin embargo, la búsqueda clásica está limitada por su incapacidad para comprender el contexto o las variaciones en el lenguaje.
Sugerencia
En la mayoría de los casos, los servicios existentes ya admiten la búsqueda clásica. Antes de implementar una búsqueda semántica, considere si los servicios existentes pueden proporcionar el contexto necesario para los agentes de IA.
Por ejemplo, un complemento que recupera la información del cliente de un sistema CRM mediante la búsqueda clásica. Aquí, la inteligencia artificial simplemente necesita llamar a la GetCustomerInfoAsync
función con un identificador de cliente para recuperar la información necesaria.
using System.ComponentModel;
using Microsoft.SemanticKernel;
public class CRMPlugin
{
private readonly CRMService _crmService;
public CRMPlugin(CRMService crmService)
{
_crmService = crmService;
}
[KernelFunction("GetCustomerInfo")]
[Description("Retrieve customer information based on the given customer ID.")]
public async Task<Customer> GetCustomerInfoAsync(string customerId)
{
return await _crmService.GetCustomerInfoAsync(customerId);
}
}
Lograr la misma funcionalidad de búsqueda con la búsqueda semántica probablemente sería imposible o poco práctico debido a la naturaleza no determinista de las consultas semánticas.
Cuándo usar cada uno
Elegir entre la búsqueda semántica y clásica depende de la naturaleza de la consulta. Es ideal para entornos pesados de contenido, como bases de conocimiento y soporte técnico al cliente, donde los usuarios pueden formular preguntas o buscar productos con lenguaje natural. La búsqueda clásica, por otro lado, debe emplearse cuando la precisión y las coincidencias exactas son importantes.
En algunos escenarios, es posible que tenga que combinar ambos enfoques para proporcionar funcionalidades de búsqueda completas. Por ejemplo, un bot de chat que ayuda a los clientes en un almacén de comercio electrónico puede usar la búsqueda semántica para comprender las consultas de usuario y la búsqueda clásica para filtrar productos en función de atributos específicos, como el precio, la marca o la disponibilidad.
A continuación se muestra un ejemplo de un complemento que combina la búsqueda semántica y clásica para recuperar la información del producto de una base de datos de comercio electrónico.
using System.ComponentModel;
using Microsoft.SemanticKernel;
public class ECommercePlugin
{
[KernelFunction("search_products")]
[Description("Search for products based on the given query.")]
public async Task<IEnumerable<Product>> SearchProductsAsync(string query, ProductCategories category = null, decimal? minPrice = null, decimal? maxPrice = null)
{
// Perform semantic and classic search with the given parameters
}
}
Recuperación de datos dinámica frente a captura previa
Al desarrollar complementos para la generación aumentada de recuperación (RAG), también debe tener en cuenta si el proceso de recuperación de datos es estático o dinámico. Esto le permite optimizar el rendimiento de los agentes de inteligencia artificial mediante la recuperación de datos solo cuando sea necesario.
Recuperación dinámica de datos
En la mayoría de los casos, la consulta del usuario determinará los datos que el agente de IA necesita recuperar. Por ejemplo, un usuario podría pedir la diferencia entre dos productos diferentes. Después, el agente de IA tendría que recuperar dinámicamente la información del producto de una base de datos o API para generar una respuesta mediante una llamada a función. Sería poco práctico capturar previamente toda la información de producto posible con antelación y darle al agente de IA.
A continuación se muestra un ejemplo de un chat de ida y vuelta entre un usuario y un agente de IA en el que es necesario recuperar datos dinámicos.
Role | Mensaje |
---|---|
🔵User | ¿Puedes decirme sobre los mejores colchones? |
🔴Asistente (llamada de función) | Products.Search("mattresses") |
🟢Herramienta | [{"id": 25323, "name": "Cloud Nine"},{"id": 63633, "name": "Best Sleep"}] |
🔴Asistente | Por supuesto. Tenemos nueve en la nube y el mejor sueño |
🔵User | ¿Cuál es la diferencia entre ellos? |
🔴Asistente (llamada de función) | Products.GetDetails(25323) Products.GetDetails(63633) |
🟢Herramienta | { "id": 25323, "name": "Cloud Nine", "price": 1000, "material": "Memory foam" } |
🟢Herramienta | { "id": 63633, "name": "Best Sleep", "price": 1200, "material": "Latex" } |
🔴Asistente | Cloud Nine está hecho de espuma de memoria y cuesta $1000. El mejor sueño está hecho de látex y cuesta $1200. |
Recuperación de datos capturadas previamente
La recuperación de datos estáticos implica capturar datos de orígenes externos y proporcionarlos siempre al agente de IA. Esto resulta útil cuando los datos son necesarios para cada solicitud o cuando los datos son relativamente estables y no cambian con frecuencia.
Por ejemplo, un agente que siempre responde a preguntas sobre el tiempo local. Suponiendo que tiene un WeatherPlugin
, puede capturar previamente los datos meteorológicos de una API meteorológica y proporcionarlos en el historial de chat. Esto permite al agente generar respuestas sobre el tiempo sin perder tiempo solicitando los datos de la API.
using System.Text.Json;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(deploymentName, endpoint, apiKey);
builder.Plugins.AddFromType<WeatherPlugin>();
Kernel kernel = builder.Build();
// Get the weather
var weather = await kernel.Plugins.GetFunction("WeatherPlugin", "get_weather").InvokeAsync(kernel);
// Initialize the chat history with the weather
ChatHistory chatHistory = new ChatHistory("The weather is:\n" + JsonSerializer.Serialize(weather));
// Simulate a user message
chatHistory.AddUserMessage("What is the weather like today?");
// Get the answer from the AI agent
IChatCompletionService chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
var result = await chatCompletionService.GetChatMessageContentAsync(chatHistory);
Mantener los datos seguros
Al recuperar datos de orígenes externos, es importante asegurarse de que los datos son seguros y que la información confidencial no se expone. Para evitar el uso compartido excesivo de información confidencial, puede usar las siguientes estrategias:
Estrategia | Descripción |
---|---|
Uso del token de autenticación del usuario | Evite crear entidades de servicio usadas por el agente de IA para recuperar información de los usuarios. Al hacerlo, resulta difícil comprobar que un usuario tiene acceso a la información recuperada. |
Evitar volver a crear servicios de búsqueda | Antes de crear un nuevo servicio de búsqueda con una base de datos vectorial, compruebe si ya existe uno para el servicio que tiene los datos necesarios. Al reutilizar los servicios existentes, puede evitar duplicar contenido confidencial, aprovechar los controles de acceso existentes y usar mecanismos de filtrado existentes que solo devuelvan datos a los que el usuario tiene acceso. |
Almacenar referencia en bases de datos vectoriales en lugar de contenido | En lugar de duplicar contenido confidencial en bases de datos vectoriales, puede almacenar referencias a los datos reales. Para que un usuario acceda a esta información, primero se debe usar su token de autenticación para recuperar los datos reales. |
Pasos siguientes
Ahora que ahora aprenderá a poner en tierra los agentes de inteligencia artificial con datos de orígenes externos, ahora puede aprender a usar agentes de inteligencia artificial para automatizar los procesos empresariales. Para más información, consulte Uso de funciones de automatización de tareas.