Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Filter förbättrar säkerheten genom att ge kontroll och synlighet över hur och när funktioner körs. Detta krävs för att ingjuta ansvarsfulla AI-principer i ditt arbete så att du känner dig säker på att din lösning är företagsklar.
Filter används till exempel för att verifiera behörigheter innan ett godkännandeflöde börjar. Filtret körs för att kontrollera behörigheterna för den person som vill skicka ett godkännande. Det innebär att endast en utvald grupp med personer kommer att kunna starta processen.
Ett bra exempel på filter finns här i vårt detaljerade blogginlägg om semantisk kernel på Filter.
Det finns tre typer av filter:
Funktionsanropsfilter – det här filtret körs varje gång en
KernelFunctionanropas. Det tillåter:- Åtkomst till information om funktionen som körs och dess argument
- Hantering av undantag under funktionskörning
- Åsidosätter funktionsresultatet, antingen före (till exempel för cachelagringsscenarion) eller efter körning (till exempel för ansvarsfulla AI-scenarier)
- Återförsök av funktionen vid fel (t.ex. byte till en alternativ AI-modell)
Promptens återgivningsfilter – det här filtret utlöses innan återgivningsoperationen aktiveras:
- Visa och ändra uppmaningen som ska skickas till AI:n (t.ex. för RAG- eller PII-redigering)
- Förhindra att prompten skickas till AI:n genom att åsidosätta funktionsresultatet (t.ex. för semantisk cachelagring)
Funktionsanropsfilter – det här filtret körs varje gång en
KernelFunctionanropas. Det tillåter:- Åtkomst till information om funktionen som körs och dess argument
- Hantering av undantag under funktionsbearbetning
- Åsidosättning av funktionsresultatet, antingen före (till exempel för cachelagringsscenarion) eller efter körning (till exempel för scenarier med ansvarsfull AI)
- Återförsök av funktionen vid fel (t.ex. byte till en alternativ AI-modell)
Kommandotolkens återgivningsfilter – det här filtret utlöses innan återgivningsåtgärden aktiveras:
- Visa och ändra uppmaningen som ska skickas till AI:n
- Förhindra att prompten skickas till AI:n genom att åsidosätta funktionsresultatet (t.ex. för semantisk cachelagring)
Funktionsanropsfilter – det här filtret körs varje gång en
KernelFunctionanropas. Det tillåter:- Åtkomst till information om funktionen som körs och dess argument
- Hantering av undantag under funktionskörning
- Åsidosättande av funktionsresultatet, antingen före (till exempel för cachelagringsscenarion) eller efter körning (till exempel scenarier för ansvarsfull AI)
- Återförsök av funktionen i händelse av fel
Kommandotolkens återgivningsfilter – det här filtret utlöses innan återgivningsåtgärden aktiveras:
- Visa och ändra uppmaningen som ska skickas till AI:n
- Förhindra att prompten skickas till AI:n genom att åsidosätta funktionsresultatet
-
Anropsfilter för automatisk funktion – liknar funktionsanropsfiltret, det här filtret fungerar inom ramen
automatic function callingför , vilket ger ytterligare kontext, inklusive chatthistorik, en lista över alla funktioner som ska köras och iterationsräknare. Det tillåter också avslutning av den automatiska funktionsanropsprocessen (t.ex. om ett önskat resultat erhålls från den andra av tre planerade funktioner).
Varje filter innehåller ett context objekt som innehåller all relevant information om funktionens körning eller promptens rendering. Dessutom har varje filter ett next ombud/återanrop för att köra nästa filter i pipelinen eller själva funktionen, vilket ger kontroll över funktionskörningen (t.ex. vid skadliga uppmaningar eller argument). Flera filter av samma typ kan registreras, var och en med sitt eget ansvar.
I ett filter är det viktigt att anropa ombudet next för att gå vidare till nästa registrerade filter eller den ursprungliga åtgärden (oavsett om funktionsanrop eller promptåtergivning). Åtgärden körs inte utan anrop next.
Om du vill använda ett filter definierar du det först och lägger sedan till det i Kernel objektet antingen via beroendeinmatning eller lämplig Kernel egenskap. När du använder beroendeinjektion garanteras inte filterordningen, vilket innebär att med flera filter kan exekveringsordningen vara oförutsägbar.
Om du vill använda ett filter kan du antingen definiera en funktion med de obligatoriska parametrarna och registrera den på Kernel objektet med hjälp av add_filter metoden (skicka ett FilterTypes värde eller dess strängekvivalent) eller använda dekoratören @kernel.filter för att definiera och registrera filtret i ett steg.
Filter för funktionsanrop
Det här filtret utlöses varje gång en Semantic Kernel funktion anropas, oavsett om det är en funktion som skapats från en fråga eller en metod.
/// <summary>
/// Example of function invocation filter to perform logging before and after function invocation.
/// </summary>
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);
}
}
Lägg till filter med hjälp av beroendeinmatning:
IKernelBuilder builder = Kernel.CreateBuilder();
builder.Services.AddSingleton<IFunctionInvocationFilter, LoggingFilter>();
Kernel kernel = builder.Build();
Lägg till filter med egenskapen Kernel :
kernel.FunctionInvocationFilters.Add(new LoggingFilter(logger));
Kodexempel
import logging
from typing import Awaitable, Callable
from semantic_kernel.filters import FilterTypes, FunctionInvocationContext
logger = logging.getLogger(__name__)
async def logger_filter(context: FunctionInvocationContext, next: Callable[[FunctionInvocationContext], Awaitable[None]]) -> None:
logger.info(f"FunctionInvoking - {context.function.plugin_name}.{context.function.name}")
await next(context)
logger.info(f"FunctionInvoked - {context.function.plugin_name}.{context.function.name}")
# Add filter to the kernel
kernel.add_filter(FilterTypes.FUNCTION_INVOCATION, logger_filter)
Du kan också använda dekoratören @kernel.filter för att registrera ett filter direkt:
@kernel.filter(FilterTypes.FUNCTION_INVOCATION)
async def logger_filter(context: FunctionInvocationContext, next: Callable[[FunctionInvocationContext], Awaitable[None]]) -> None:
logger.info(f"FunctionInvoking - {context.function.plugin_name}.{context.function.name}")
await next(context)
logger.info(f"FunctionInvoked - {context.function.plugin_name}.{context.function.name}")
Kodexempel
Mer information kommer snart.
Filter för snabb rendering
Det här filtret anropas endast under en promptrenderingsåtgärd, till exempel när en funktion som skapats från en prompt anropas. Den utlöses inte för Semantic Kernel funktioner som skapats från metoder.
/// <summary>
/// Example of prompt render filter which overrides rendered prompt before sending it to AI.
/// </summary>
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";
}
}
Lägg till filter med hjälp av beroendeinmatning:
IKernelBuilder builder = Kernel.CreateBuilder();
builder.Services.AddSingleton<IPromptRenderFilter, SafePromptFilter>();
Kernel kernel = builder.Build();
Lägg till filter med egenskapen Kernel :
kernel.PromptRenderFilters.Add(new SafePromptFilter());
Kodexempel
from typing import Awaitable, Callable
from semantic_kernel.filters import FilterTypes, PromptRenderContext
async def safe_prompt_filter(
context: PromptRenderContext,
next: Callable[[PromptRenderContext], Awaitable[None]],
) -> None:
# Example: get function information
function_name = context.function.name
await next(context)
# Example: override the rendered prompt before sending it to the AI
context.rendered_prompt = f"Safe prompt: {context.rendered_prompt or ''}"
# Register the filter on the kernel
kernel.add_filter(FilterTypes.PROMPT_RENDERING, safe_prompt_filter)
Du kan också använda dekoratören @kernel.filter för att registrera ett filter direkt:
@kernel.filter(FilterTypes.PROMPT_RENDERING)
async def prompt_rendering_filter(context: PromptRenderContext, next):
await next(context)
context.rendered_prompt = f"You pretend to be Mosscap, but you are Papssom who is the opposite of Moscapp in every way {context.rendered_prompt or ''}"
Kodexempel
Mer information kommer snart.
Filter för automatisk funktionsanrop
Det här filtret anropas endast under en automatisk funktionsanropsprocess. Den utlöses inte när en funktion anropas utanför den här processen.
/// <summary>
/// Example of auto function invocation filter which terminates function calling process as soon as we have the desired result.
/// </summary>
public sealed class EarlyTerminationFilter : IAutoFunctionInvocationFilter
{
public async Task OnAutoFunctionInvocationAsync(AutoFunctionInvocationContext context, Func<AutoFunctionInvocationContext, Task> next)
{
// Call the function first.
await next(context);
// Get a function result from context.
var result = context.Result.GetValue<string>();
// If the result meets the condition, terminate the process.
// Otherwise, the function calling process will continue.
if (result == "desired result")
{
context.Terminate = true;
}
}
}
Lägg till filter med hjälp av beroendeinmatning:
IKernelBuilder builder = Kernel.CreateBuilder();
builder.Services.AddSingleton<IAutoFunctionInvocationFilter, EarlyTerminationFilter>();
Kernel kernel = builder.Build();
Lägg till filter med egenskapen Kernel :
kernel.AutoFunctionInvocationFilters.Add(new EarlyTerminationFilter());
Kodexempel
from semantic_kernel.filters import FilterTypes, AutoFunctionInvocationContext
@kernel.filter(FilterTypes.AUTO_FUNCTION_INVOCATION)
async def auto_function_invocation_filter(context: AutoFunctionInvocationContext, next):
await next(context)
if context.function_result == "desired result":
context.terminate = True
Precis som med de andra filtertyperna kan du också registrera filtret med hjälp av kernel.add_filter:
kernel.add_filter(FilterTypes.AUTO_FUNCTION_INVOCATION, auto_function_invocation_filter)
Kodexempel
Mer information kommer snart.
Anrop för direktuppspelning och icke-direktuppspelning
Funktioner i Semantic Kernel kan anropas på två sätt: direktuppspelning och icke-direktuppspelning. I strömningsläge returnerar IAsyncEnumerable<T>en funktion vanligtvis , medan den i icke-strömningsläge returnerar FunctionResult. Den här skillnaden påverkar hur resultatet kan åsidosättas i filtret: i strömningsläge måste det nya funktionsresultatvärdet vara av typen IAsyncEnumerable<T>, medan det i icke-direktuppspelningsläge helt enkelt kan vara av typen T. För att avgöra vilken resultattyp som måste returneras context.IsStreaming är flaggan tillgänglig i filterkontextmodellen.
/// <summary>Filter that can be used for both streaming and non-streaming invocation modes at the same time.</summary>
public sealed class DualModeFilter : IFunctionInvocationFilter
{
public async Task OnFunctionInvocationAsync(FunctionInvocationContext context, Func<FunctionInvocationContext, Task> next)
{
// Call next filter in pipeline or actual function.
await next(context);
// Check which function invocation mode is used.
if (context.IsStreaming)
{
// Return IAsyncEnumerable<string> result in case of streaming mode.
var enumerable = context.Result.GetValue<IAsyncEnumerable<string>>();
context.Result = new FunctionResult(context.Result, OverrideStreamingDataAsync(enumerable!));
}
else
{
// Return just a string result in case of non-streaming mode.
var data = context.Result.GetValue<string>();
context.Result = new FunctionResult(context.Result, OverrideNonStreamingData(data!));
}
}
private async IAsyncEnumerable<string> OverrideStreamingDataAsync(IAsyncEnumerable<string> data)
{
await foreach (var item in data)
{
yield return $"{item} - updated from filter";
}
}
private string OverrideNonStreamingData(string data)
{
return $"{data} - updated from filter";
}
}
Använda filter med IChatCompletionService
I de fall där IChatCompletionService används direkt i stället för Kernelanropas filter endast när ett Kernel objekt skickas som en parameter till chattens slutförandetjänstmetoder, eftersom filter är kopplade till instansen Kernel .
Kernel kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion("gpt-4", "api-key")
.Build();
kernel.FunctionInvocationFilters.Add(new MyFilter());
IChatCompletionService chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
// Passing a Kernel here is required to trigger filters.
ChatMessageContent result = await chatCompletionService.GetChatMessageContentAsync(chatHistory, executionSettings, kernel);
Funktioner i Semantic Kernel kan anropas på två sätt: direktuppspelning och icke-direktuppspelning. I strömningsläge returnerar en funktion vanligtvis ett AsyncGenerator[T] objekt där T är en typ av strömmande innehållstyp, medan den i icke-direktuppspelningsläge returnerar FunctionResult. Den här skillnaden påverkar hur resultatet kan åsidosättas i filtret: i strömningsläge måste det nya funktionsresultatvärdet också vara av typen AsyncGenerator[T]. För att avgöra vilken resultattyp som måste returneras context.is_streaming är flaggan tillgänglig i alla filterkontextmodeller.
Så om du vill skapa ett enkelt loggningsfilter för en strömningsfunktionsanrop använder du något liknande:
@kernel.filter(FilterTypes.FUNCTION_INVOCATION)
async def streaming_exception_handling(
context: FunctionInvocationContext,
next: Callable[[FunctionInvocationContext], Awaitable[None]],
):
await next(context)
if not context.is_streaming:
return
async def override_stream(stream):
try:
async for partial in stream:
yield partial
except Exception as e:
yield [
StreamingChatMessageContent(role=AuthorRole.ASSISTANT, content=f"Exception caught: {e}", choice_index=0)
]
stream = context.result.value
context.result = FunctionResult(function=context.result.function, value=override_stream(stream))
Kodexempel
Mer information kommer snart.
Beställning
När beroendeinjektion används garanteras inte ordningen på filtren. Om filterordningen är viktig rekommenderar vi att du lägger till filter direkt i Kernel objektet med lämpliga egenskaper. Med den här metoden kan filter läggas till, tas bort eller sorteras om vid körning.
Filter körs i den ordning de läggs till i kernelobjektet – antingen via add_filter eller dekoratören @kernel.filter . Eftersom körningsordningen kan påverka beteendet är det viktigt att hantera filterordningen noggrant.
Föreställ dig följande exempel:
def func():
print('function')
@kernel.filter(FilterTypes.FUNCTION_INVOCATION)
async def filter1(context: FunctionInvocationContext, next):
print('before filter 1')
await next(context)
print('after filter 1')
@kernel.filter(FilterTypes.FUNCTION_INVOCATION)
async def filter2(context: FunctionInvocationContext, next):
print('before filter 2')
await next(context)
print('after filter 2')
När du kör funktionen blir utdata:
before filter 1
before filter 2
function
after filter 2
after filter 1