Partilhar 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 do Kernel Semântico sobre Filtros.   Filtros semânticos do 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 vai ser executada, seus argumentos, pegar uma exceção durante a execução da função, substituir o resultado da função, repetir a execução da função em caso de falha (pode ser usado para mudar 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 IA, modificar prompt (por exemplo, RAG, cenários de edição PII) e impedir que o prompt seja enviado para IA com substituição de resultado de função (pode ser usado para cache semântico).
  • Filtro de invocação de função automática - 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. Ele também permite encerrar o processo de chamada de função automática (por exemplo, existem 3 funções para executar, mas já há 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 de prompts. Juntamente com o contexto, há também um delegado/retorno de next chamada, que executa o próximo filtro no pipeline ou na própria função. Isso fornece mais controle, e é útil no caso de haver algumas razões para evitar a execução de funções (por exemplo, prompt malicioso ou argumentos de função). É possível registar vários filtros do mesmo tipo, onde cada filtro terá responsabilidades diferentes.

Exemplo de filtro de invocação de função para executar o registro em log antes e depois da chamada de 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 de função automática que encerra o processo de chamada de função assim que temos 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: