Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Microsoft Semantic kernel IFunctionInvocationFilter

From Leeroopedia
Knowledge Sources
Domains AI_Orchestration, Observability, Middleware
Last Updated 2026-02-11 19:00 GMT

Overview

Concrete tool for implementing middleware-style interceptors that observe, modify, or short-circuit function invocations and prompt rendering in Microsoft Semantic Kernel.

Description

IFunctionInvocationFilter and IPromptRenderFilter are interfaces that define the contract for observability filters in the Semantic Kernel pipeline. By implementing these interfaces and registering the implementations with the kernel's service collection, developers can intercept every function invocation and every prompt rendering operation.

IFunctionInvocationFilter defines a single method, OnFunctionInvocationAsync, which is called for every function invocation (native plugin functions and prompt functions alike). The method receives a FunctionInvocationContext containing:

  • Kernel: The kernel instance.
  • Function: The KernelFunction being invoked.
  • Arguments: The KernelArguments passed to the function.
  • Result: The FunctionResult (available after next is called).
  • IsStreaming: Whether the invocation is in streaming mode.
  • CancellationToken: For cooperative cancellation.

IPromptRenderFilter defines OnPromptRenderAsync, which is called before a rendered prompt is sent to the AI model. Its PromptRenderContext includes:

  • Kernel: The kernel instance.
  • Function: The KernelFunction associated with the prompt.
  • Arguments: The KernelArguments for the invocation.
  • RenderedPrompt: The rendered prompt text (can be read and modified).
  • ExecutionSettings: The PromptExecutionSettings in effect.
  • Result: Can be set to short-circuit function invocation entirely.

Additionally, IAutoFunctionInvocationFilter targets specifically the automatic function invocations triggered by AI model tool-call requests during the auto-invoke loop.

All filters follow the delegate-based middleware pattern: call next to proceed through the pipeline, or skip it to short-circuit.

Usage

Use IFunctionInvocationFilter for cross-cutting concerns around function execution (logging, timing, error handling, caching). Use IPromptRenderFilter for prompt-level concerns (content filtering, PII redaction, prompt logging). Use IAutoFunctionInvocationFilter for concerns specific to AI-initiated function calls.

Code Reference

Source Location

  • Repository: semantic-kernel
  • File (IFunctionInvocationFilter): dotnet/src/SemanticKernel.Abstractions/Filters/Function/IFunctionInvocationFilter.cs:L13-21
  • File (IPromptRenderFilter): dotnet/src/SemanticKernel.Abstractions/Filters/Prompt/IPromptRenderFilter.cs:L13-21
  • File (IAutoFunctionInvocationFilter): dotnet/src/SemanticKernel.Abstractions/Filters/AutoFunctionInvocation/IAutoFunctionInvocationFilter.cs:L13-21

Signature (IFunctionInvocationFilter)

public interface IFunctionInvocationFilter
{
    Task OnFunctionInvocationAsync(
        FunctionInvocationContext context,
        Func<FunctionInvocationContext, Task> next);
}

Signature (IPromptRenderFilter)

public interface IPromptRenderFilter
{
    Task OnPromptRenderAsync(
        PromptRenderContext context,
        Func<PromptRenderContext, Task> next);
}

Signature (IAutoFunctionInvocationFilter)

public interface IAutoFunctionInvocationFilter
{
    Task OnAutoFunctionInvocationAsync(
        AutoFunctionInvocationContext context,
        Func<AutoFunctionInvocationContext, Task> next);
}

Import

using Microsoft.SemanticKernel;

I/O Contract

Inputs (IFunctionInvocationFilter.OnFunctionInvocationAsync)

Name Type Required Description
context FunctionInvocationContext Yes Contains the Kernel, Function, Arguments, Result, IsStreaming flag, and CancellationToken for the current invocation.
next Func<FunctionInvocationContext, Task> Yes Delegate to the next filter in the pipeline or the function itself. Must be called to proceed; omit to short-circuit.

Inputs (IPromptRenderFilter.OnPromptRenderAsync)

Name Type Required Description
context PromptRenderContext Yes Contains the Kernel, Function, Arguments, RenderedPrompt, ExecutionSettings, and Result for the current rendering.
next Func<PromptRenderContext, Task> Yes Delegate to the next filter in the pipeline or the rendering operation itself.

Outputs

Name Type Description
return Task Both methods return Task (void async). Side effects are applied by modifying the context object or by calling/not calling next.

Usage Examples

Logging Filter for Function Invocations

using Microsoft.SemanticKernel;

public class LoggingFilter : IFunctionInvocationFilter
{
    public async Task OnFunctionInvocationAsync(
        FunctionInvocationContext context,
        Func<FunctionInvocationContext, Task> next)
    {
        Console.WriteLine($"Invoking: {context.Function.Name}");
        var stopwatch = System.Diagnostics.Stopwatch.StartNew();

        // Proceed with the function invocation
        await next(context);

        stopwatch.Stop();
        Console.WriteLine($"Completed: {context.Function.Name} in {stopwatch.ElapsedMilliseconds}ms");
        Console.WriteLine($"Result: {context.Result}");
    }
}

Prompt Redaction Filter

using Microsoft.SemanticKernel;

public class PiiRedactionFilter : IPromptRenderFilter
{
    public async Task OnPromptRenderAsync(
        PromptRenderContext context,
        Func<PromptRenderContext, Task> next)
    {
        // Proceed with prompt rendering first
        await next(context);

        // Redact sensitive patterns from the rendered prompt
        if (context.RenderedPrompt is not null)
        {
            context.RenderedPrompt = RedactPii(context.RenderedPrompt);
        }
    }

    private static string RedactPii(string text)
    {
        // Replace email patterns, SSNs, etc.
        return System.Text.RegularExpressions.Regex.Replace(
            text, @"\b[\w.-]+@[\w.-]+\.\w+\b", "[REDACTED_EMAIL]");
    }
}

Registering Filters with the Kernel

using Microsoft.SemanticKernel;

IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.AddOpenAIChatClient(modelId: "gpt-4o", apiKey: "your-api-key");
kernelBuilder.Plugins.AddFromType<TimeInformation>();

// Register filters via the service collection
kernelBuilder.Services.AddSingleton<IFunctionInvocationFilter, LoggingFilter>();
kernelBuilder.Services.AddSingleton<IPromptRenderFilter, PiiRedactionFilter>();

Kernel kernel = kernelBuilder.Build();

// Filters are now active for all invocations
OpenAIPromptExecutionSettings settings = new()
{
    FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};
Console.WriteLine(await kernel.InvokePromptAsync("What time is it?", new(settings)));

Short-Circuiting with a Cached Result

using Microsoft.SemanticKernel;

public class CachingFilter : IFunctionInvocationFilter
{
    private readonly Dictionary<string, FunctionResult> _cache = new();

    public async Task OnFunctionInvocationAsync(
        FunctionInvocationContext context,
        Func<FunctionInvocationContext, Task> next)
    {
        var cacheKey = $"{context.Function.Name}:{string.Join(",", context.Arguments)}";

        if (_cache.TryGetValue(cacheKey, out var cachedResult))
        {
            // Short-circuit: return cached result without calling the function
            context.Result = cachedResult;
            return;
        }

        // Proceed with function invocation
        await next(context);

        // Cache the result for future calls
        _cache[cacheKey] = context.Result;
    }
}

Related Pages

Implements Principle

Uses Heuristic

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment