Sdílet prostřednictvím


Použití modulů plug-in pro načítání rozšířené generace (RAG)

Agenti umělé inteligence často musí načítat data z externích zdrojů, aby vygenerovali uzemněné odpovědi. Bez tohoto dalšího kontextu můžou agenti umělé inteligence halucinovat nebo poskytovat nesprávné informace. K vyřešení tohoto řešení můžete použít moduly plug-in k načtení dat z externích zdrojů.

Při zvažování modulů plug-in pro načítání rozšířené generace (RAG) byste se měli zeptat na dvě otázky:

  1. Jak vy (nebo agent AI) vyhledáte požadovaná data? Potřebujete sémantické vyhledávání nebo klasické vyhledávání?
  2. Už víte, jaká data agent AI potřebuje předem (předem načtená data), nebo potřebuje agent umělé inteligence data dynamicky načíst?
  3. Jak zajistíte zabezpečení dat a zabráníte nadměrnému sdílení citlivých informací?

Při vývoji modulů plug-in pro načítání rozšířené generace (RAG) můžete použít dva typy vyhledávání: sémantické vyhledávání a klasické vyhledávání.

Sémantické vyhledávání využívá vektorové databáze k pochopení a načítání informací na základě významu a kontextu dotazu, nikoli pouze shodných klíčových slov. Tato metoda umožňuje vyhledávacímu webu pochopit drobné odlišnosti jazyka, jako jsou synonyma, související koncepty a celkový záměr za dotazem.

Sémantické vyhledávání exceluje v prostředích, kde jsou uživatelské dotazy složité, otevřené nebo vyžadují hlubší porozumění obsahu. Například hledání "nejlepších smartphonů pro fotografii" by přineslo výsledky, které berou v úvahu kontext funkcí fotografie ve smartphonech, a ne jen párování slov "nejlepší", "smartphony" a "fotografie".

Při poskytování LLM sémantickou vyhledávací funkcí obvykle stačí definovat funkci pouze s jedním vyhledávacím dotazem. LLM pak použije tuto funkci k načtení potřebných informací. Níže je příklad sémantické vyhledávací funkce, která k vyhledání dokumentů podobných danému dotazu používá Azure AI Search.

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; }
    }
}

Klasické vyhledávání, označované také jako vyhledávání založené na atributech nebo kritériích, spoléhá na filtrování a porovnávání přesných termínů nebo hodnot v datové sadě. Je zvlášť efektivní pro databázové dotazy, vyhledávání inventáře a jakoukoli situaci, kdy je nutné filtrovat podle konkrétních atributů.

Pokud například chce uživatel najít všechny objednávky zadané konkrétním ID zákazníka nebo načíst produkty v rámci konkrétního cenového rozsahu a kategorie, klasické vyhledávání poskytuje přesné a spolehlivé výsledky. Klasické vyhledávání je ale omezené nemožností pochopit kontext nebo varianty jazyka.

Tip

Ve většině případů vaše stávající služby již podporují klasické vyhledávání. Před implementací sémantického vyhledávání zvažte, jestli vaše stávající služby mohou poskytovat potřebný kontext pro agenty AI.

Například modul plug-in, který načítá informace o zákaznících ze systému CRM pomocí klasického vyhledávání. V této části potřebuje AI jednoduše volat GetCustomerInfoAsync funkci s ID zákazníka, aby načetla potřebné informace.

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);
    }
}

Dosažení stejné funkce vyhledávání pomocí sémantického vyhledávání by pravděpodobně nebylo možné nebo nepraktické z důvodu ne deterministické povahy sémantických dotazů.

Kdy použít jednotlivé

Volba mezi sémantickým a klasickým vyhledáváním závisí na povaze dotazu. Je ideální pro prostředí náročné na obsah, jako jsou znalostní báze a zákaznická podpora, kde se uživatelé můžou ptát nebo hledat produkty používající přirozený jazyk. Klasické vyhledávání by mělo být naopak použito, když jsou důležité přesné a přesné shody.

V některých scénářích možná budete muset zkombinovat oba přístupy, abyste mohli poskytovat komplexní možnosti vyhledávání. Například chatovací robot, který pomáhá zákazníkům v obchodě elektronického obchodování, může použít sémantické vyhledávání k pochopení uživatelských dotazů a klasického vyhledávání k filtrování produktů na základě konkrétních atributů, jako je cena, značka nebo dostupnost.

Níže je příklad modulu plug-in, který kombinuje sémantické a klasické vyhledávání a načítá informace o produktech z databáze elektronického obchodování.

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
    }
}

Dynamické a předem načtené načítání dat

Při vývoji modulů plug-in pro načítání rozšířené generace (RAG) musíte také zvážit, jestli je proces načítání dat statický nebo dynamický. To vám umožní optimalizovat výkon agentů AI načtením dat pouze v případě potřeby.

Dynamické načítání dat

Ve většině případů uživatelský dotaz určí data, která agent AI potřebuje načíst. Uživatel může například požádat o rozdíl mezi dvěma různými produkty. Agent AI by pak potřeboval dynamicky načíst informace o produktu z databáze nebo rozhraní API, aby vygeneroval odpověď pomocí volání funkce. Předem by bylo nepraktické předem načíst všechny možné informace o produktu a dát je agentovi AI.

Níže je příklad zpětného chatu mezi uživatelem a agentem umělé inteligence, kde je potřeba dynamické načítání dat.

Role Zpráva
🔵Uživatel Můžeš mi říct o nejlepších matracích?
🔴Asistent (volání funkce) Products.Search("mattresses")
🟢Nástroj [{"id": 25323, "name": "Cloud Nine"},{"id": 63633, "name": "Best Sleep"}]
🔴Asistent Jasně! Máme cloud nine i nejlepší spánek.
🔵Uživatel Jaký je mezi nimi rozdíl?
🔴Asistent (volání funkce) Products.GetDetails(25323) Products.GetDetails(63633)
🟢Nástroj { "id": 25323, "name": "Cloud Nine", "price": 1000, "material": "Memory foam" }
🟢Nástroj { "id": 63633, "name": "Best Sleep", "price": 1200, "material": "Latex" }
🔴Asistent Cloud Nine je vyroben z paměťové pěny a stojí $1000. Nejlepší spánek je vyroben z latexu a stojí $1200.

Načtení předem načtených dat

Načtení statických dat zahrnuje načtení dat z externích zdrojů a jejich poskytování agentovi AI. To je užitečné, když se data vyžadují pro každou žádost nebo když jsou data relativně stabilní a často se nemění.

Vezměte například agenta, který vždy odpovídá na otázky týkající se místního počasí. Za předpokladu WeatherPlugin, že máte , můžete předem načíst data o počasí z rozhraní API pro počasí a poskytnout je v historii chatu. To umožňuje agentu generovat odpovědi o počasí, aniž by museli vyžadovat čas vyžádání dat z rozhraní 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);

Zajištění zabezpečení dat

Při načítání dat z externích zdrojů je důležité zajistit, aby byla data zabezpečená a že citlivé informace nejsou vystavené. Pokud chcete zabránit nadměrnému sdílení citlivých informací, můžete použít následující strategie:

Strategie Popis
Použití ověřovacího tokenu uživatele Vyhněte se vytváření instančních objektů používaných agentem AI k načtení informací pro uživatele. Díky tomu je obtížné ověřit, jestli má uživatel přístup k načteným informacím.
Vyhněte se opětovnému vytváření vyhledávacích služeb Před vytvořením nové vyhledávací služby s vektorovou databází zkontrolujte, jestli už existuje pro službu s požadovanými daty. Opětovným použitím stávajících služeb se můžete vyhnout duplikování citlivého obsahu, využívat stávající řízení přístupu a používat existující mechanismy filtrování, ke kterým má přístup pouze uživatel.
Ukládat odkazy do vektorových databází místo obsahu Místo duplikování citlivého obsahu na vektorové databáze můžete ukládat odkazy na skutečná data. Aby měl uživatel přístup k tomuto informacím, musí se nejprve použít ověřovací token k načtení skutečných dat.

Další kroky

Teď, když teď zjistíte, jak uzemnění agentů AI s daty z externích zdrojů, teď se naučíte používat agenty AI k automatizaci obchodních procesů. Další informace najdete v tématu Použití funkcí automatizace úloh.