@@ -14,67 +14,153 @@ This filter runs every time a function is executed, whether it originates from a
14
14
15
15
Here's an example of a function invocation filter that logs the invoked plugin function:
16
16
17
- ``` c#
18
- public sealed class LoggingFilter ( ILogger logger ) : IFunctionInvocationFilter
19
- {
20
- public async Task OnFunctionInvocationAsync ( FunctionInvocationContext context , Func < FunctionInvocationContext , Task > next )
17
+ ::: zone pivot="csharp"
18
+
19
+ ```c#
20
+ public sealed class LoggingFilter(ILogger logger) : IFunctionInvocationFilter
21
21
{
22
- logger .LogInformation (" Invoking: {PluginName}.{FunctionName}" , context .Function .PluginName , context .Function .Name );
22
+ public async Task OnFunctionInvocationAsync(FunctionInvocationContext context, Func<FunctionInvocationContext, Task> next)
23
+ {
24
+ logger.LogInformation("Invoking: {PluginName}.{FunctionName}", context.Function.PluginName, context.Function.Name);
23
25
24
- await next (context );
26
+ await next(context);
25
27
26
- logger .LogInformation (" Executed: {PluginName}.{FunctionName}" , context .Function .PluginName , context .Function .Name );
28
+ logger.LogInformation("Executed: {PluginName}.{FunctionName}", context.Function.PluginName, context.Function.Name);
29
+ }
27
30
}
28
- }
29
- ```
31
+ ```
32
+
33
+ ::: zone-end
34
+
35
+ ::: zone pivot="python"
36
+
37
+ ````python
38
+ # Python example: Function invocation filter using a decorator
39
+
40
+ from semantic_kernel.functions.kernel_function_decorator import kernel_function
41
+
42
+ def logging_filter(func):
43
+ def wrapper(*args, **kwargs):
44
+ print(f"Invoking: {func.__qualname__}")
45
+ result = func(*args, **kwargs)
46
+ print(f"Executed: {func.__qualname__}")
47
+ return result
48
+ return wrapper
49
+
50
+ class WeatherForecastUtils:
51
+ @kernel_function(name="GetWeatherForCity", description="Gets the weather for a given city.")
52
+ @logging_filter
53
+ def get_weather_for_city(self, city: str) -> str:
54
+ return "Sunny"
55
+ ````
56
+
57
+ ::: zone-end
30
58
31
59
### Prompt Render Filter
32
60
33
61
Triggered during prompt rendering, this filter provides control over how prompts are formatted and submitted to AI. It's ideal for tasks like modifying prompts for sensitive information (e.g., PII redaction) or enabling semantic caching.
34
62
35
63
Here's an example of a prompt render filter:
36
64
37
- ``` c#
38
- public class SafePromptFilter : IPromptRenderFilter
39
- {
40
- public async Task OnPromptRenderAsync ( PromptRenderContext context , Func < PromptRenderContext , Task > next )
65
+ ::: zone pivot="csharp"
66
+
67
+ ```c#
68
+ public class SafePromptFilter : IPromptRenderFilter
41
69
{
42
- await next (context );
70
+ public async Task OnPromptRenderAsync(PromptRenderContext context, Func<PromptRenderContext, Task> next)
71
+ {
72
+ await next(context);
43
73
44
- // Modify prompt before submission
45
- context .RenderedPrompt = " Safe and sanitized prompt." ;
74
+ // Modify prompt before submission
75
+ context.RenderedPrompt = "Safe and sanitized prompt.";
76
+ }
46
77
}
47
- }
48
- ```
78
+ ```
79
+
80
+ ::: zone-end
81
+
82
+ ::: zone pivot="python"
83
+
84
+ ````python
85
+ # Python example: Prompt render filter using a decorator
86
+
87
+ def safe_prompt_filter(render_func):
88
+ def wrapper(*args, **kwargs):
89
+ prompt = render_func(*args, **kwargs)
90
+ # Modify prompt before submission
91
+ return "Safe and sanitized prompt."
92
+ return wrapper
93
+
94
+ @safe_prompt_filter
95
+ def render_prompt(user_input):
96
+ return f"User prompt: {user_input}"
97
+
98
+ # Example usage
99
+ print(render_prompt("Sensitive information here"))
100
+ ````
101
+
102
+ ::: zone-end
49
103
50
104
### Auto Function Invocation Filter
51
105
52
106
This filter is invoked only during the automatic function calling process. It can adjust or even terminate workflows based on intermediate results.
53
107
54
108
Here's an example of a function invocation filter that terminates the function calling process:
55
109
56
- ``` c#
57
- public sealed class EarlyTerminationFilter : IAutoFunctionInvocationFilter
58
- {
59
- public async Task OnAutoFunctionInvocationAsync (AutoFunctionInvocationContext context , Func <AutoFunctionInvocationContext , Task > next )
60
- {
61
- await next (context );
110
+ ::: zone pivot="csharp"
62
111
63
- var result = context .Result .GetValue <string >();
64
- if (result == " desired result" )
112
+ ```c#
113
+ public sealed class EarlyTerminationFilter : IAutoFunctionInvocationFilter
114
+ {
115
+ public async Task OnAutoFunctionInvocationAsync(AutoFunctionInvocationContext context, Func<AutoFunctionInvocationContext, Task> next)
65
116
{
66
- context .Terminate = true ;
117
+ await next(context);
118
+
119
+ var result = context.Result.GetValue<string>();
120
+ if (result == "desired result")
121
+ {
122
+ context.Terminate = true;
123
+ }
67
124
}
68
125
}
69
- }
70
- ```
126
+ ```
127
+
128
+ ::: zone-end
129
+
130
+ ::: zone pivot="python"
131
+
132
+ ````python
133
+ # Python example: Auto function invocation filter using a decorator
134
+
135
+ def early_termination_filter(func):
136
+ def wrapper(*args, **kwargs):
137
+ result = func(*args, **kwargs)
138
+ # Simulate checking the result and terminating if needed
139
+ if result == "desired result":
140
+ print("Terminating workflow early.")
141
+ return result
142
+ return result
143
+ return wrapper
144
+
145
+ @early_termination_filter
146
+ def auto_function():
147
+ # Simulate function logic
148
+ return "desired result"
149
+
150
+ # Example usage
151
+ auto_function()
152
+ ````
153
+
154
+ ::: zone-end
71
155
72
156
### Integrate function filters
73
157
158
+ ::: zone pivot="csharp"
159
+
74
160
To integrate any of the function filters, you can use the following methods:
75
161
76
162
- ** Dependency Injection** :
77
-
163
+
78
164
Add the function to the KernelBuilder services:
79
165
80
166
``` c#
@@ -89,6 +175,21 @@ To integrate any of the function filters, you can use the following methods:
89
175
kernel .FunctionInvocationFilters .Add (new LoggingFilter (logger ));
90
176
```
91
177
178
+ ::: zone - end
179
+
180
+ ::: zone pivot = " python"
181
+
182
+ To integrate filters in Python , apply decorators to your plugin methods or prompt rendering functions as shown above .
183
+ Register your plugin class with the kernel as usual:
184
+
185
+ ```
186
+ kernel .add_plugin (WeatherForecastUtils (), "WeatherForecastUtils ")
187
+ ```
188
+
189
+ The decorated methods will have the filter logic applied automatically .
190
+
191
+ ::: zone -end
192
+
92
193
Always invoke the `next ` delegate in your function filter to allow subsequent filters or the primary operation to execute . Skipping this step blocks the operation .
93
194
94
- By integrating these filters thoughtfully , you can enhance both the functionality and security of your Semantic Kernel implementations , aligning with best practices for responsible AI development .
195
+ By integrating prompt render filters , you make your Semantic Kernel solutions safer and more reliable . Prompt filters let you sanitize prompts before they reach the AI . Auto - invocation filters let you control function execution , enabling early termination or custom logic based on results .
0 commit comments