Sdílet prostřednictvím


Přístup k datům ve funkcích AI

Při vytváření funkcí AI může být potřeba získat přístup k kontextovým datům nad rámec parametrů poskytovaných modelem AI. Knihovna Microsoft.Extensions.AI poskytuje několik mechanismů pro předávání dat delegátům funkcí.

Třída AIFunction

Typ AIFunction představuje funkci, kterou lze popsat službě AI a vyvolat ji. Objekty můžete vytvořit AIFunction voláním jednoho z AIFunctionFactory.Create přetížení. Je ale AIFunction také základní třídou a můžete z ní odvodit a implementovat vlastní typ funkce AI. DelegatingAIFunction poskytuje snadný způsob, jak zabalit existující AIFunction a přidat další funkce, včetně zachytávání dalších dat pro použití.

Předání dat

Data můžete k funkci přidružit v okamžiku jeho vytvoření, a to buď prostřednictvím uzavření, nebo prostřednictvím AdditionalProperties. Pokud vytváříte vlastní funkci, můžete ji naplnit AdditionalProperties jakýmkoli způsobem. Pokud použijete AIFunctionFactory k vytvoření funkce, můžete data naplnit pomocí AIFunctionFactoryOptions.AdditionalProperties.

Můžete také zaznamenat jakékoli odkazy na data jako součást poskytovaného delegáta AIFunctionFactory. To znamená, že můžete integrovat cokoliv, na co chcete odkazovat jako součást samotného AIFunction.

Přístup k datům ve funkčních delegátech

Můžete volat AIFunction přímo, nebo můžete volat nepřímo pomocí FunctionInvokingChatClient. Následující části popisují, jak přistupovat k datům argumentů pomocí některého z přístupů.

Ruční vyvolání funkce

Pokud ručně vyvoláte AIFunction voláním AIFunction.InvokeAsync(AIFunctionArguments, CancellationToken), předáváte AIFunctionArguments. Typ AIFunctionArguments zahrnuje:

Pokud chcete získat přístup buď k AIFunctionArguments, nebo k IServiceProvider ze svého delegáta AIFunctionFactory.Create, vytvořte parametr typu IServiceProvider nebo AIFunctionArguments. Tento parametr bude vázán na relevantní data z předaného AIFunctionArguments do AIFunction.InvokeAsync().

Následující kód ukazuje příklad:

Delegate getWeatherDelegate = (AIFunctionArguments args) =>
{
    // Access named parameters from the arguments dictionary.
    string? location = args.TryGetValue("location", out object? loc) ? loc.ToString() : "Unknown";
    string? units = args.TryGetValue("units", out object? u) ? u.ToString() : "celsius";

    return $"Weather in {location}: 35°{units}";
};

// Create the AIFunction.
AIFunction getWeather = AIFunctionFactory.Create(getWeatherDelegate);

// Call the function manually.
var result = await getWeather.InvokeAsync(new AIFunctionArguments
{
    { "location", "Seattle" },
    { "units", "F" }
});
Console.WriteLine($"Function result: {result}");

CancellationToken je také zvláštním případem: pokud delegát nebo lambda ve AIFunctionFactory.Create má parametr CancellationToken, bude svázán s CancellationToken, který byl předán do AIFunction.InvokeAsync().

Vyvolání prostřednictvím FunctionInvokingChatClient

FunctionInvokingChatClient publikuje stav o aktuálním vyvolání FunctionInvokingChatClient.CurrentContext, včetně nejen argumentů, ale všech vstupních ChatMessage objektů, a podrobností o tom, ChatOptionskterá funkce je vyvolána (z kolika). Můžete přidat libovolná data do ChatOptions.AdditionalProperties a extrahovat je uvnitř vašeho AIFunction z FunctionInvokingChatClient.CurrentContext.Options.AdditionalProperties.

Následující kód ukazuje příklad:

FunctionInvokingChatClient client = new FunctionInvokingChatClient(
    new AzureOpenAIClient(new Uri(endpoint), new AzureKeyCredential(apiKey))
    .GetChatClient(model).AsIChatClient());

AIFunction getWeather = AIFunctionFactory.Create(() =>
    {
        // Access named parameters from the arguments dictionary.
        AdditionalPropertiesDictionary props =
            FunctionInvokingChatClient.CurrentContext.Options.AdditionalProperties;

        string location = props["location"].ToString();
        string units = props["units"].ToString();

        return $"Weather in {location}: 35°{units}";
    });

var chatOptions = new ChatOptions
{
    Tools = [getWeather],
    AdditionalProperties = new AdditionalPropertiesDictionary {
        ["location"] = "Seattle",
        ["units"] = "F"
    },
};

List<ChatMessage> chatHistory = [
    new(ChatRole.System, "You're a helpful weather assistant.")
];
chatHistory.Add(new ChatMessage(ChatRole.User, "What's the weather like?"));

ChatResponse response = await client.GetResponseAsync(chatHistory, chatOptions);
Console.WriteLine($"Response: {response.Text}");

Injekce závislostí

Pokud používáte FunctionInvokingChatClient k automatickému vyvolání funkcí, klient nakonfiguruje AIFunctionArguments objekt, který předává do objektu AIFunction. Protože AIFunctionArguments zahrnuje IServiceProvider, který byl FunctionInvokingChatClient sám poskytnut, pokud vytváříte klienta pomocí standardních prostředků DI, je IServiceProvider plně předán do vašeho AIFunction. V tomto okamžiku ho můžete dotazovat na cokoli, co chcete, z DI.

Pokročilé techniky

Pokud chcete jemněji odstupňovanou kontrolu nad tím, jak jsou parametry vázané, můžete použít AIFunctionFactoryOptions.ConfigureParameterBinding, což vám dává kontrolu nad tím, jak se jednotlivé parametry naplní. Například sada MCP C# SDK používá tuto techniku k automatickému svázání parametrů z DI.

Pokud použijete AIFunctionFactory.Create(MethodInfo, Func<AIFunctionArguments,Object>, AIFunctionFactoryOptions) přetížení, můžete také spustit vlastní libovolnou logiku, kdykoli vytvoříte cílový objekt, na který bude volána metoda instance. Můžete udělat cokoli potřebného k nakonfigurování této instance.