Výběr kontextové funkce pomocí agentů

Důležité

Tato funkce je v experimentální fázi. Funkce v této fázi se aktivně vyvíjí a před přechodem do fáze Preview nebo verze Candidate se můžou výrazně změnit.

Přehled

Výběr kontextové funkce je pokročilá funkce v sémantickém rozhraní agenta jádra, která umožňuje agentům dynamicky vybírat a inzerovat pouze ty nejrelevantní funkce na základě aktuálního kontextu konverzace. Místo zveřejnění všech dostupných funkcí pro model AI tato funkce používá k filtrování a prezentování pouze těch funkcí, které jsou pro požadavek uživatele relevantní, Retrieval-Augmented Generation (RAG).

Tento přístup řeší výzvu výběru funkcí při práci s velkým počtem dostupných funkcí, kdy se modely AI mohou jinak potýkat s výběrem příslušné funkce, což vede k nejasnostem a neoptimálnímu výkonu.

Výstraha

Při použití ContextualFunctionProvider musí být nastavení na agentovi UseImmutableKernel nastaveno na true, protože funkce vyžaduje klonování jádra při vyvolávání agenta. Všimněte si, že nastavení UseImmutableKernel na true znamená, že jakékoli úpravy dat jádra provedené během vyvolání agenta, například prostřednictvím pluginů, nebudou po dokončení tohoto vyvolání zachovány.

Jak funguje výběr kontextové funkce

Když je agent nakonfigurovaný s výběrem kontextové funkce, využívá úložiště vektorů a generátor vkládání k sémanticky spárování kontextu aktuální konverzace (včetně předchozích zpráv a uživatelských vstupů) s popisy a názvy dostupných funkcí. Nejrelevantnější funkce, až do zadaného limitu, se pak představují modelu AI pro aktivaci.

Tento mechanismus je užitečný zejména pro agenty, kteří mají přístup k široké sadě modulů plug-in nebo nástrojů a zajišťují, aby se v každém kroku zvažovaly pouze kontextově vhodné akce.

Příklad použití

Následující příklad ukazuje, jak lze agent nakonfigurovat tak, aby používal výběr kontextové funkce. Agent je nastavený tak, aby shrnoval recenze zákazníků, ale pro každé vyvolání se inzerují do modelu AI pouze nejdůležitější funkce. Metoda GetAvailableFunctions záměrně zahrnuje relevantní i i irelevantní funkce, které zvýrazňují výhody kontextového výběru.

// Create an embedding generator for function vectorization
var embeddingGenerator = new AzureOpenAIClient(new Uri("<endpoint>"), new ApiKeyCredential("<api-key>"))
    .GetEmbeddingClient("<deployment-name>")
    .AsIEmbeddingGenerator();

// Create kernel and register AzureOpenAI chat completion service
var kernel = Kernel.CreateBuilder()
    .AddAzureOpenAIChatCompletion("<deployment-name>", "<endpoint>", "<api-key>");
    .Build();

// Create a chat completion agent
ChatCompletionAgent agent = new()
{
    Name = "ReviewGuru",
    Instructions = "You are a friendly assistant that summarizes key points and sentiments from customer reviews. For each response, list available functions.",
    Kernel = kernel,
    Arguments = new(new PromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(options: new FunctionChoiceBehaviorOptions { RetainArgumentTypes = true }) }),
    // This setting must be set to true when using the ContextualFunctionProvider
    UseImmutableKernel = true
};

// Create the agent thread and register the contextual function provider
ChatHistoryAgentThread agentThread = new();

agentThread.AIContextProviders.Add(
    new ContextualFunctionProvider(
        vectorStore: new InMemoryVectorStore(new InMemoryVectorStoreOptions() { EmbeddingGenerator = embeddingGenerator }),
        vectorDimensions: 1536,
        functions: AvailableFunctions(),
        maxNumberOfFunctions: 3, // Only the top 3 relevant functions are advertised
        loggerFactory: LoggerFactory
    )
);


// Invoke the agent
ChatMessageContent message = await agent.InvokeAsync("Get and summarize customer review.", agentThread).FirstAsync();
Console.WriteLine(message.Content);

// Output
/*
    Customer Reviews:
    -----------------
    1. John D. - ★★★★★
       Comment: Great product and fast shipping!
       Date: 2023-10-01

    Summary:
    --------
    The reviews indicate high customer satisfaction,
    highlighting product quality and shipping speed.

    Available functions:
    --------------------
    - Tools-GetCustomerReviews
    - Tools-Summarize
    - Tools-CollectSentiments
*/

IReadOnlyList<AIFunction> GetAvailableFunctions()
{
    // Only a few functions are directly related to the prompt; the majority are unrelated to demonstrate the benefits of contextual filtering.
    return new List<AIFunction>
    {
        // Relevant functions
        AIFunctionFactory.Create(() => "[ { 'reviewer': 'John D.', 'date': '2023-10-01', 'rating': 5, 'comment': 'Great product and fast shipping!' } ]", "GetCustomerReviews"),
        AIFunctionFactory.Create((string text) => "Summary generated based on input data: key points include customer satisfaction.", "Summarize"),
        AIFunctionFactory.Create((string text) => "The collected sentiment is mostly positive.", "CollectSentiments"),

        // Irrelevant functions
        AIFunctionFactory.Create(() => "Current weather is sunny.", "GetWeather"),
        AIFunctionFactory.Create(() => "Email sent.", "SendEmail"),
        AIFunctionFactory.Create(() => "The current stock price is $123.45.", "GetStockPrice"),
        AIFunctionFactory.Create(() => "The time is 12:00 PM.", "GetCurrentTime")
    };
}

Vektorové úložiště

Poskytovatel je primárně navržený pro práci s úložišti vektorů v paměti, které nabízejí jednoduchost. Pokud se ale používají jiné typy úložišť vektorů, je důležité si uvědomit, že odpovědnost za zpracování synchronizace dat a konzistence spadá do hostitelské aplikace.

Synchronizace je nutná vždy, když se změní seznam funkcí nebo když se změní zdroj vkládání funkcí. Pokud má například agent zpočátku tři funkce (f1, f2, f3), které jsou vektorizované a uložené v cloudovém vektorovém úložišti, a později f3 se odeberou ze seznamu funkcí agenta, musí být úložiště vektorů aktualizováno tak, aby odráželo pouze aktuální funkce, které agent má (f1 a f2). Nepodaření aktualizace úložiště vektorů může vést k tomu, že se jako výsledky vrátí irelevantní funkce. Podobně platí, že pokud se změní data použitá pro vektorizaci, jako jsou názvy funkcí, popisy atd. úložiště vektorů by se mělo vyprázdnit a znovu ho na základě aktualizovaných informací vkládat.

Správa synchronizace dat v externích nebo distribuovaných úložištích vektorů může být složitá a náchylná k chybám, zejména v distribuovaných aplikacích, kde mohou různé služby nebo instance fungovat nezávisle a vyžadují konzistentní přístup ke stejným datům. Použití úložiště v paměti naopak zjednodušuje tento proces: když se změní seznam funkcí nebo vektorizace, úložiště v paměti se dá snadno znovu vytvořit s novou sadou funkcí a jejich vkládáním a zajistit tak konzistenci s minimálním úsilím.

Určení funkcí

Zprostředkovatel kontextové funkce musí být dodán se seznamem funkcí, ze kterých může vybrat ty nejrelevantní na základě aktuálního kontextu. Toho lze dosáhnout poskytnutím seznamu funkcí functions parametru konstruktoru ContextualFunctionProvider .

Kromě funkcí musíte také zadat maximální počet relevantních funkcí, které se mají vrátit pomocí parametru maxNumberOfFunctions . Tento parametr určuje, kolik funkcí bude poskytovatel při výběru nejrelevavantnějších funkcí pro aktuální kontext zvážit. Zadané číslo není určeno jako přesné; slouží spíše jako horní limit, který závisí na konkrétním scénáři.

Nastavení příliš nízké hodnoty může zabránit agentům v přístupu ke všem nezbytným funkcím pro scénář, což může vést k selhání scénáře. Nastavení příliš vysoké může naopak zahltit agenta příliš mnoha funkcemi, což může vést k halucinacím, nadměrné spotřebě vstupních tokenů a neoptimálnímu výkonu.

// Create the provider with a list of functions and a maximum number of functions to return
ContextualFunctionProvider provider = new (
    vectorStore: new InMemoryVectorStore(new InMemoryVectorStoreOptions { EmbeddingGenerator = embeddingGenerator }),
    vectorDimensions: 1536,
    functions: [AIFunctionFactory.Create((string text) => $"Echo: {text}", "Echo"), <other functions>]
    maxNumberOfFunctions: 3 // Only the top 3 relevant functions are advertised
);

Možnosti zprostředkovatele kontextových funkcí

Zprostředkovatel lze nakonfigurovat pomocí ContextualFunctionProviderOptions třídy, která umožňuje přizpůsobit různé aspekty fungování poskytovatele:

// Create options for the contextual function provider
ContextualFunctionProviderOptions options = new ()
{
    ...
};

// Create the provider with options
ContextualFunctionProvider provider = new (
    ...
    options: options // Pass the options
);

Velikost kontextu

Velikost kontextu určuje, kolik posledních zpráv z předchozích vyvolání agentů se zahrne při vytváření kontextu pro nové vyvolání. Poskytovatel shromažďuje všechny zprávy z předchozích spuštění, až do zadaného počtu, a připojí je k novým zprávám, aby vytvořil kontext.

Použití nedávných zpráv spolu s novými zprávami je užitečné hlavně pro úkoly, které vyžadují informace z dřívějších kroků v konverzaci. Pokud například agent zřídí prostředek v jednom vyvolání a nasadí ho v dalším vyvolání, může krok nasazení získat přístup k podrobnostem z kroku zřizování a získat informace o zřízeném prostředku pro nasazení.

Výchozí hodnota pro počet posledních zpráv v kontextu je 2, ale to lze nakonfigurovat podle potřeby zadáním NumberOfRecentMessagesInContext vlastnosti v :ContextualFunctionProviderOptions

ContextualFunctionProviderOptions options = new ()
{
    NumberOfRecentMessagesInContext = 1 // Only the last message will be included in the context
};

Kontextová vložená zdrojová hodnota

Aby bylo možné provést výběr kontextové funkce, musí zprostředkovatel vektorizovat aktuální kontext, aby bylo možné jej porovnat s dostupnými funkcemi v úložišti vektorů. Ve výchozím nastavení zprostředkovatel vytvoří tento kontext vkládání tím, že zřetězí všechny neprázdné poslední a nové zprávy do jednoho řetězce, který se pak vektorizuje a používá k vyhledávání relevantních funkcí.

V některých scénářích můžete chtít toto chování přizpůsobit takto:

  • Zaměřte se na konkrétní typy zpráv (např. pouze uživatelské zprávy).
  • Vyloučení určitých informací z kontextu
  • Předběžné zpracování nebo shrnutí kontextu před vektorizací (např. použití přeformulování výzvy)

K tomu můžete přiřadit vlastního delegáta ContextEmbeddingValueProvider. Tento delegát obdrží poslední a nové zprávy a vrátí řetězcovou hodnotu, která se použije jako zdroj pro vkládání kontextu:

ContextualFunctionProviderOptions options = new()
{
    ContextEmbeddingValueProvider = async (recentMessages, newMessages, cancellationToken) =>
    {
        // Example: Only include user messages in the embedding
        var allUserMessages = recentMessages.Concat(newMessages)
            .Where(m => m.Role == "user")
            .Select(m => m.Content)
            .Where(content => !string.IsNullOrWhiteSpace(content));
        return string.Join("\n", allUserMessages);
    }
};

Přizpůsobení vkládání kontextu může zlepšit význam výběru funkcí, zejména ve složitých nebo vysoce specializovaných scénářích agentů.

Vložená zdrojová hodnota funkce

Zprostředkovatel musí vektorizovat každou dostupnou funkci, aby ji mohli porovnat s kontextem a vybrat ty nejrelevavantnější. Ve výchozím nastavení zprostředkovatel vytvoří funkci vloženou tak, že zřetězí název a popis funkce do jednoho řetězce, který se pak vektorizuje a uloží v úložišti vektorů.

Toto chování můžete přizpůsobit pomocí EmbeddingValueProvider vlastnosti ContextualFunctionProviderOptions. Tato vlastnost umožňuje zadat zpětné volání (callback), které přijme funkci a token zrušení a vrátí řetězec, jenž se použije jako zdroj pro vložení funkce. To je užitečné, pokud chcete:

  • Přidání dalších metadat funkce do vkládacího zdroje
  • Předběžné zpracování, filtrování nebo přeformátování informací o funkci před vektorizací
ContextualFunctionProviderOptions options = new()
{
    EmbeddingValueProvider = async (function, cancellationToken) =>
    {
        // Example: Use only the function name for embedding
        return function.Name;
    }
};

Přizpůsobením zdrojové hodnoty pro vložení funkce můžete zlepšit přesnost výběru funkce, zejména pokud mají vaše funkce bohaté metadata relevantní pro kontext nebo když se chcete zaměřit na vyhledávání na konkrétní aspekty jednotlivých funkcí.

Další kroky

Prozkoumání ukázek výběru kontextových funkcí

Již brzy

Další informace budou brzy k dispozici.

Již brzy

Další informace budou brzy k dispozici.