Claude
Skills
Sign in
Back

dotnet-semantic-kernel

Included with Lifetime
$97 forever

Building AI/LLM features. Semantic Kernel setup, plugins, prompt templates, memory stores, agents.

AI Agents

What this skill does


# dotnet-semantic-kernel

Microsoft Semantic Kernel for AI and LLM orchestration in .NET applications. Covers kernel setup and configuration, plugin/function calling, prompt templates with Handlebars and Liquid syntax, memory and vector store integration, planners, the agents framework, and integration with Azure OpenAI, OpenAI, and local models.

**Out of scope:** General async/await patterns and cancellation token propagation -- see [skill:dotnet-csharp-async-patterns]. DI container mechanics and service lifetime management -- see [skill:dotnet-csharp-dependency-injection]. HTTP client resilience and retry policies -- see [skill:dotnet-resilience]. Configuration binding (options pattern, secrets) -- see [skill:dotnet-csharp-configuration].

Cross-references: [skill:dotnet-csharp-async-patterns] for async streaming patterns used with chat completions, [skill:dotnet-csharp-dependency-injection] for kernel service registration in ASP.NET Core, [skill:dotnet-resilience] for retry policies on AI service calls, [skill:dotnet-csharp-configuration] for managing API keys and model configuration.

---

## Kernel Setup

The `Kernel` is the central object in Semantic Kernel. It manages AI service connections, plugins, and function invocation.

### Package Landscape

| Package | Purpose |
|---------|---------|
| `Microsoft.SemanticKernel` | Core kernel, function calling, prompt templates |
| `Microsoft.SemanticKernel.Connectors.AzureOpenAI` | Azure OpenAI chat/embedding/image services |
| `Microsoft.SemanticKernel.Connectors.OpenAI` | OpenAI chat/embedding/image services |
| `Microsoft.SemanticKernel.Connectors.Ollama` | Ollama local model integration |
| `Microsoft.SemanticKernel.Plugins.Core` | Built-in plugins (time, math, text) |
| `Microsoft.SemanticKernel.Agents.Core` | Agent framework (chat agents, group chat) |
| `Microsoft.Extensions.VectorData.Abstractions` | Vector store abstraction layer |
| `Microsoft.SemanticKernel.Connectors.Qdrant` | Qdrant vector store connector |
| `Microsoft.SemanticKernel.Connectors.AzureAISearch` | Azure AI Search vector store connector |

### Basic Kernel Configuration

```csharp
using Microsoft.SemanticKernel;

var builder = Kernel.CreateBuilder();

// Azure OpenAI
builder.AddAzureOpenAIChatCompletion(
    deploymentName: "gpt-4o",
    endpoint: Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!,
    apiKey: Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!);

var kernel = builder.Build();
```

### DI Integration with ASP.NET Core

```csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddKernel();

builder.Services.AddAzureOpenAIChatCompletion(
    deploymentName: builder.Configuration["AI:DeploymentName"]!,
    endpoint: builder.Configuration["AI:Endpoint"]!,
    apiKey: builder.Configuration["AI:ApiKey"]!);

// Register plugins
builder.Services.AddSingleton<OrderPlugin>();
builder.Services.AddSingleton(sp =>
{
    var kernel = sp.GetRequiredService<Kernel>();
    kernel.Plugins.AddFromObject(sp.GetRequiredService<OrderPlugin>());
    return kernel;
});
```

### Multiple AI Services

Register multiple AI services and select by service ID:

```csharp
var builder = Kernel.CreateBuilder();

builder.AddAzureOpenAIChatCompletion(
    deploymentName: "gpt-4o",
    endpoint: endpoint,
    apiKey: apiKey,
    serviceId: "gpt4o");

builder.AddAzureOpenAIChatCompletion(
    deploymentName: "gpt-4o-mini",
    endpoint: endpoint,
    apiKey: apiKey,
    serviceId: "gpt4o-mini");

var kernel = builder.Build();

// Select service at invocation time
var settings = new PromptExecutionSettings { ServiceId = "gpt4o-mini" };
var result = await kernel.InvokePromptAsync("Summarize: {{$input}}", new(settings)
{
    ["input"] = longDocument
});
```

### Local Models with Ollama

```csharp
#pragma warning disable SKEXP0070  // Ollama connector is experimental

var builder = Kernel.CreateBuilder();

builder.AddOllamaChatCompletion(
    modelId: "llama3.2",
    endpoint: new Uri("http://localhost:11434"));

var kernel = builder.Build();
```

---

## Plugins and Function Calling

Plugins expose .NET methods as functions that the AI model can invoke. This is the primary mechanism for grounding LLM responses in real data and actions.

### Defining a Plugin

```csharp
using Microsoft.SemanticKernel;
using System.ComponentModel;

public sealed class OrderPlugin
{
    private readonly IOrderRepository _repository;

    public OrderPlugin(IOrderRepository repository) => _repository = repository;

    [KernelFunction("get_order")]
    [Description("Retrieves an order by its ID")]
    public async Task<OrderSummary?> GetOrderAsync(
        [Description("The unique order identifier")] string orderId,
        CancellationToken ct = default)
    {
        var order = await _repository.GetByIdAsync(orderId, ct);
        return order is null ? null : new OrderSummary(order);
    }

    [KernelFunction("list_recent_orders")]
    [Description("Lists the most recent orders for a customer")]
    public async Task<IReadOnlyList<OrderSummary>> ListRecentOrdersAsync(
        [Description("The customer ID")] string customerId,
        [Description("Maximum number of orders to return")] int limit = 10,
        CancellationToken ct = default)
    {
        var orders = await _repository.GetRecentAsync(customerId, limit, ct);
        return orders.Select(o => new OrderSummary(o)).ToList();
    }
}
```

### Registering Plugins

```csharp
var kernel = builder.Build();

// From an object instance (DI-friendly)
kernel.Plugins.AddFromObject(new OrderPlugin(orderRepo), "Orders");

// From a type (kernel creates the instance)
kernel.Plugins.AddFromType<TimePlugin>("Time");

// From functions directly
kernel.Plugins.AddFromFunctions("Math",
[
    KernelFunctionFactory.CreateFromMethod(
        ([Description("First number")] double a, [Description("Second number")] double b) => a + b,
        "Add",
        "Adds two numbers")
]);
```

### Automatic Function Calling

Enable the model to call functions automatically during chat:

```csharp
var settings = new AzureOpenAIPromptExecutionSettings
{
    FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};

var chatHistory = new ChatHistory();
chatHistory.AddUserMessage("What's the status of order ORD-12345?");

var result = await kernel.GetRequiredService<IChatCompletionService>()
    .GetChatMessageContentAsync(chatHistory, settings, kernel);

// The model calls get_order("ORD-12345") automatically and responds with the result
Console.WriteLine(result.Content);
```

### Function Filters

Intercept function calls for logging, authorization, or modification:

```csharp
public sealed class AuthorizationFilter : IFunctionInvocationFilter
{
    public async Task OnFunctionInvocationAsync(
        FunctionInvocationContext context,
        Func<FunctionInvocationContext, Task> next)
    {
        // Check authorization before function execution
        if (context.Function.Name == "get_order")
        {
            var orderId = context.Arguments["orderId"]?.ToString();
            // Validate access...
        }

        await next(context);

        // Post-execution: log or modify result
    }
}

// Register the filter
builder.Services.AddSingleton<IFunctionInvocationFilter, AuthorizationFilter>();
```

---

## Prompt Templates

Prompt templates support variable substitution and function calling within structured prompts.

### Inline Prompts

```csharp
var result = await kernel.InvokePromptAsync(
    "Summarize the following text in {{$style}} style:\n\n{{$input}}",
    new KernelArguments
    {
        ["input"] = articleText,
        ["style"] = "concise bullet points"
    });
```

### Handlebars Templates

Handlebars templates support conditionals, loops, and function calls:

```csharp
var templateString = """
    <message role="system">
    You are a helpful customer service agent.
    {{#if isVip}}You are speaking with a VIP customer. Be extra attentive.{{/if}}
    </message>
    <

Related in AI Agents