2 min read
Semantic Kernel Filters: Intercepting and Modifying AI Operations
Semantic Kernel filters provide a middleware pattern for intercepting AI operations. Use them to add logging, modify prompts, validate outputs, or implement custom business logic around your AI calls.
Understanding Filter Types
Semantic Kernel supports several filter types: function invocation filters, prompt render filters, and auto function invocation filters. Each intercepts different stages of the AI pipeline.
Implementing a Function Invocation Filter
using Microsoft.SemanticKernel;
public class LoggingFilter : IFunctionInvocationFilter
{
private readonly ILogger<LoggingFilter> _logger;
public LoggingFilter(ILogger<LoggingFilter> logger)
{
_logger = logger;
}
public async Task OnFunctionInvocationAsync(
FunctionInvocationContext context,
Func<FunctionInvocationContext, Task> next)
{
var startTime = DateTime.UtcNow;
_logger.LogInformation(
"Invoking function {PluginName}.{FunctionName}",
context.Function.PluginName,
context.Function.Name);
try
{
await next(context);
var duration = DateTime.UtcNow - startTime;
_logger.LogInformation(
"Function {FunctionName} completed in {Duration}ms",
context.Function.Name,
duration.TotalMilliseconds);
}
catch (Exception ex)
{
_logger.LogError(ex,
"Function {FunctionName} failed",
context.Function.Name);
throw;
}
}
}
Prompt Render Filter for Modification
public class PromptEnhancementFilter : IPromptRenderFilter
{
public async Task OnPromptRenderAsync(
PromptRenderContext context,
Func<PromptRenderContext, Task> next)
{
// Add context before rendering
if (context.Arguments.TryGetValue("user_context", out var userContext))
{
context.Arguments["enhanced_prompt"] =
$"User Context: {userContext}\n\n{context.Arguments["prompt"]}";
}
await next(context);
// Log the final rendered prompt
Console.WriteLine($"Rendered prompt: {context.RenderedPrompt}");
}
}
Registering Filters
var builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(deploymentName, endpoint, apiKey);
// Add filters
builder.Services.AddSingleton<IFunctionInvocationFilter, LoggingFilter>();
builder.Services.AddSingleton<IPromptRenderFilter, PromptEnhancementFilter>();
var kernel = builder.Build();
Filters enable clean separation of cross-cutting concerns from your core AI logic, making applications more maintainable and testable.