$npx -y skills add managedcode/dotnet-skills --skill semantic-kernelBuild AI-enabled .NET applications with Semantic Kernel using services, plugins, prompts, and function-calling patterns that remain testable and maintainable. USE FOR: adding AI-driven prompts, plugins, or orchestration to a .NET app; reviewing kernel construction, service regist
| 1 | # Semantic Kernel for .NET |
| 2 | |
| 3 | ## Trigger On |
| 4 | |
| 5 | - adding AI-driven prompts, plugins, or orchestration to a .NET app |
| 6 | - reviewing kernel construction, service registration, or plugin usage |
| 7 | - building function-calling patterns with LLMs |
| 8 | - migrating older Semantic Kernel code to current APIs |
| 9 | |
| 10 | ## Documentation |
| 11 | |
| 12 | - [Semantic Kernel Overview](https://learn.microsoft.com/en-us/semantic-kernel/overview/) |
| 13 | - [Plugins and Functions](https://learn.microsoft.com/en-us/semantic-kernel/concepts/plugins/) |
| 14 | - [Agent Functions](https://learn.microsoft.com/en-us/semantic-kernel/frameworks/agent/agent-functions) |
| 15 | - [GitHub Repository](https://github.com/microsoft/semantic-kernel) |
| 16 | - [Microsoft Agent Framework](https://learn.microsoft.com/en-us/semantic-kernel/frameworks/agent/) |
| 17 | |
| 18 | ### References |
| 19 | |
| 20 | - [patterns.md](references/patterns.md) - Plugin patterns, function calling patterns, multi-agent patterns, prompt templates, and RAG patterns |
| 21 | - [anti-patterns.md](references/anti-patterns.md) - Common Semantic Kernel mistakes and how to avoid them |
| 22 | |
| 23 | ## Core Concepts |
| 24 | |
| 25 | | Concept | Description | |
| 26 | |---------|-------------| |
| 27 | | **Kernel** | Central orchestrator for AI services and plugins | |
| 28 | | **Plugin** | Collection of functions exposed to the LLM | |
| 29 | | **Function** | Native C# method or prompt template | |
| 30 | | **Chat Completion** | LLM service for generating responses | |
| 31 | | **Memory** | Vector storage for semantic search | |
| 32 | |
| 33 | ## Workflow |
| 34 | |
| 35 | 1. **Build the Kernel** with required services |
| 36 | 2. **Create Plugins** with well-described functions |
| 37 | 3. **Configure Function Calling** for automatic tool use |
| 38 | 4. **Handle Responses** and manage conversation state |
| 39 | 5. **Test and Observe** AI behavior with logging |
| 40 | 6. For Semantic Kernel `dotnet-1.78.0` and later, keep OpenAPI plugin server URL validation enabled, do not re-enable automatic redirects on the default `HttpPlugin` or `WebFileDownloadPlugin` clients without an explicit trusted-host policy, and use the current Microsoft Agent Framework-compatible migration samples when moving SK agent code to Agent Framework. |
| 41 | 7. Re-test custom file, document, and web plugin paths after upgrading to `1.78.0`; the release hardens path validation and updates vulnerable transitive dependencies, so local workarounds that weakened validation should be removed rather than carried forward. |
| 42 | |
| 43 | ## Kernel Setup |
| 44 | |
| 45 | ### Basic Configuration |
| 46 | ```csharp |
| 47 | var builder = Kernel.CreateBuilder(); |
| 48 | |
| 49 | builder.AddAzureOpenAIChatCompletion( |
| 50 | deploymentName: "gpt-4", |
| 51 | endpoint: config["AzureOpenAI:Endpoint"]!, |
| 52 | apiKey: config["AzureOpenAI:ApiKey"]!); |
| 53 | |
| 54 | // Or OpenAI |
| 55 | builder.AddOpenAIChatCompletion( |
| 56 | modelId: "gpt-4", |
| 57 | apiKey: config["OpenAI:ApiKey"]!); |
| 58 | |
| 59 | var kernel = builder.Build(); |
| 60 | ``` |
| 61 | |
| 62 | ### With Dependency Injection |
| 63 | ```csharp |
| 64 | builder.Services.AddKernel() |
| 65 | .AddAzureOpenAIChatCompletion( |
| 66 | deploymentName: "gpt-4", |
| 67 | endpoint: config["AzureOpenAI:Endpoint"]!, |
| 68 | apiKey: config["AzureOpenAI:ApiKey"]!); |
| 69 | |
| 70 | // Register plugins |
| 71 | builder.Services.AddSingleton<WeatherPlugin>(); |
| 72 | builder.Services.AddSingleton<OrderPlugin>(); |
| 73 | |
| 74 | // In your service |
| 75 | public class AiService(Kernel kernel) |
| 76 | { |
| 77 | public async Task<string> ChatAsync(string message) |
| 78 | { |
| 79 | var response = await kernel.InvokePromptAsync(message); |
| 80 | return response.ToString(); |
| 81 | } |
| 82 | } |
| 83 | ``` |
| 84 | |
| 85 | ## Plugin Patterns |
| 86 | |
| 87 | ### Creating a Plugin |
| 88 | ```csharp |
| 89 | public class WeatherPlugin |
| 90 | { |
| 91 | [KernelFunction] |
| 92 | [Description("Gets the current weather for a specified city")] |
| 93 | public async Task<string> GetWeather( |
| 94 | [Description("The city name, e.g., 'Seattle'")] string city, |
| 95 | [Description("Temperature unit: 'celsius' or 'fahrenheit'")] string unit = "celsius") |
| 96 | { |
| 97 | // Call actual weather API |
| 98 | var weather = await _weatherService.GetCurrentAsync(city); |
| 99 | return $"Weather in {city}: {weather.Temperature}° {unit}, {weather.Condition}"; |
| 100 | } |
| 101 | |
| 102 | [KernelFunction] |
| 103 | [Description("Gets the weather forecast for the next N days")] |
| 104 | public async Task<string> GetForecast( |
| 105 | [Description("The city name")] string city, |
| 106 | [Description("Number of days (1-7)")] int days = 3) |
| 107 | { |
| 108 | var forecast = await _weatherService.GetForecastAsync(city, days); |
| 109 | return FormatForecast(forecast); |
| 110 | } |
| 111 | } |
| 112 | ``` |
| 113 | |
| 114 | ### Plugin Best Practices |
| 115 | |
| 116 | | Practice | Why It Matters | |
| 117 | |----------|----------------| |
| 118 | | Clear `[De |