Compartilhar via


O que são filtros?

Os filtros aumentam a segurança, fornecendo controle e visibilidade sobre como e quando as funções são executadas. Isso é necessário para incutir princípios de IA responsáveis em seu trabalho, para que você se sinta confiante de que sua solução está pronta para a empresa.

Por exemplo, os filtros são aproveitados para validar permissões antes do início de um fluxo de aprovação. O IFunctionInvocationFilter é executado para verificar as permissões da pessoa que deseja enviar uma aprovação. Isso significa que apenas um grupo seleto de pessoas poderá iniciar o processo.

Um bom exemplo de filtros é fornecido aqui em nossa postagem detalhada do blog Semantic Kernel sobre Filtros.   Filtros semânticos de kernel

Existem 3 tipos de filtros:

  • Filtro de invocação de função - é executado sempre que KernelFunction é invocado. Permite obter informações sobre a função que será executada, seus argumentos, capturar uma exceção durante a execução da função, substituir o resultado da função, tentar novamente a execução da função em caso de falha (pode ser usado para alternar para outro modelo de IA).
  • Filtro de renderização de prompt - é executado antes da operação de renderização de prompt. Permite ver qual prompt será enviado para a IA, modificar o prompt (por exemplo, RAG, cenários de redação de PII) e impedir que o prompt seja enviado para a IA com substituição de resultado de função (pode ser usado para cache semântico).
  • Filtro de invocação automática de função - semelhante ao filtro de invocação de função, mas é executado em um escopo de automatic function calling operação, portanto, tem mais informações disponíveis em um contexto, incluindo histórico de bate-papo, lista de todas as funções que serão executadas e contadores de iteração de solicitação. Também permite encerrar o processo de chamada automática de função (por exemplo, existem 3 funções a serem executadas, mas já existe o resultado desejado da segunda função).

Cada filtro tem context um objeto que contém todas as informações relacionadas à execução da função ou à renderização do prompt. Junto com o contexto, há também um next delegado/retorno de chamada, que executa o próximo filtro no pipeline ou na própria função. Isso fornece mais controle e é útil caso haja alguns motivos para evitar a execução da função (por exemplo, prompt malicioso ou argumentos de função). É possível cadastrar vários filtros do mesmo tipo, onde cada filtro terá responsabilidade diferente.

Exemplo de filtro de invocação de função para executar o registro antes e depois da invocação da função:

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

Exemplo de filtro de renderização de prompt que substitui o prompt renderizado antes de enviá-lo para a IA:

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

Exemplo de filtro de invocação automática de função que encerra o processo de chamada de função assim que tivermos o resultado desejado:

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

Mais informações

C#/.NET: