Udostępnij za pośrednictwem


Co to są filtry?

Filtry zwiększają bezpieczeństwo, zapewniając kontrolę i widoczność sposobu i czasu działania funkcji. Jest to konieczne, aby wprowadzić zasady odpowiedzialnej sztucznej inteligencji do pracy, aby mieć pewność, że twoje rozwiązanie jest gotowe do użycia w przedsiębiorstwie.

Na przykład filtry są używane do sprawdzania poprawności uprawnień przed rozpoczęciem przepływu zatwierdzania. Polecenie IFunctionInvocationFilter jest uruchamiane, aby sprawdzić uprawnienia osoby, która chce przesłać zatwierdzenie. Oznacza to, że tylko wybrana grupa osób będzie mogła rozpocząć proces.

Dobry przykład filtrów znajduje się tutaj w naszym szczegółowym wpisie na blogu Semantic Kernel w temacie Filtry.   Filtry jądra semantycznego

Istnieją 3 typy filtrów:

  • Filtr wywołania funkcji — jest wykonywany za każdym razem, gdy KernelFunction jest wywoływany. Umożliwia uzyskanie informacji o funkcji, która ma zostać wykonana, jego argumenty, przechwycenie wyjątku podczas wykonywania funkcji, zastąpienie wyniku funkcji, ponawianie próby wykonania funkcji w przypadku awarii (może służyć do przełączania się do innego modelu sztucznej inteligencji).
  • Filtr renderowania monitu — jest wykonywany przed operacją renderowania monitu. Umożliwia sprawdzenie, jaki monit ma zostać wysłany do sztucznej inteligencji, zmodyfikować monit (np. rag, scenariusze redaction pii) i uniemożliwić wysłanie monitu do sztucznej inteligencji z zastąpieniem wyniku funkcji (można użyć do buforowania semantycznego).
  • Filtr wywołania funkcji automatycznej — podobny do filtru wywołania funkcji, ale jest wykonywany w zakresie automatic function calling operacji, dlatego zawiera więcej informacji dostępnych w kontekście, w tym historię czatów, listę wszystkich funkcji, które zostaną wykonane i zażądać liczników iteracji. Umożliwia również zakończenie procesu automatycznego wywoływania funkcji (np. istnieje 3 funkcje do wykonania, ale istnieje już żądany wynik z drugiej funkcji).

Każdy filtr zawiera context obiekt zawierający wszystkie informacje związane z wykonywaniem funkcji lub renderowaniem monitu. Wraz z kontekstem next istnieje również delegat/wywołanie zwrotne, który wykonuje następny filtr w potoku lub funkcji. Zapewnia to większą kontrolę i przydaje się w przypadku, gdy istnieje kilka powodów, aby uniknąć wykonywania funkcji (np. złośliwych monitów lub argumentów funkcji). Istnieje możliwość zarejestrowania wielu filtrów tego samego typu, w których każdy filtr będzie miał inną odpowiedzialność.

Przykład filtru wywołania funkcji do wykonywania rejestrowania przed wywołaniem funkcji i po nim:

public sealed class LoggingFilter(ILogger logger) : IFunctionInvocationFilter
{
    public async Task OnFunctionInvocationAsync(FunctionInvocationContext context, Func<FunctionInvocationContext, Task> next)
    {
        logger.LogInformation("FunctionInvoking - {PluginName}.{FunctionName}", context.Function.PluginName, context.Function.Name);

        await next(context);

        logger.LogInformation("FunctionInvoked - {PluginName}.{FunctionName}", context.Function.PluginName, context.Function.Name);
    }
}

Przykład filtru renderowania monitu, który zastępuje renderowany monit przed wysłaniem go do sztucznej inteligencji:

public class SafePromptFilter : IPromptRenderFilter
{
    public async Task OnPromptRenderAsync(PromptRenderContext context, Func<PromptRenderContext, Task> next)
    {
        // Example: get function information
        var functionName = context.Function.Name;

        await next(context);

        // Example: override rendered prompt before sending it to AI
        context.RenderedPrompt = "Safe prompt";
    }
}

Przykład filtru wywołania funkcji automatycznej, który kończy proces wywoływania funkcji natychmiast po osiągnięciu żądanego wyniku:

public sealed class EarlyTerminationFilter : IAutoFunctionInvocationFilter
{
    public async Task OnAutoFunctionInvocationAsync(AutoFunctionInvocationContext context, Func<AutoFunctionInvocationContext, Task> next)
    {
        await next(context);

        var result = context.Result.GetValue<string>();

        if (result == "desired result")
        {
            context.Terminate = true;
        }
    }
}

Więcej informacji

C#/.NET: