Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
{"short-description":".NET skill guidance for foundation tasks"}
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.
Scope
Kernel setup and DI integration for AI services (Azure OpenAI, OpenAI, Ollama)
Plugin/function calling with automatic invocation and filters
Prompt templates (inline, Handlebars, YAML)
Vector store abstractions and RAG patterns
Agents framework (ChatCompletionAgent, group chat, OpenAI Assistant)
Streaming responses
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
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();
```text
### 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;
});
```text
### Multiple AI Services
Register multiple AI services andselectby 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 timevar settings = new PromptExecutionSettings { ServiceId = "gpt4o-mini" };
var result = await kernel.InvokePromptAsync("Summarize: {{$input}}", (settings)
{
[] = longDocument
});
```text
```csharp
builder = Kernel.CreateBuilder();
builder.AddOllamaChatCompletion(
modelId: ,
endpoint: Uri());
kernel = builder.Build();
```text
---
Plugins expose .NET methods functions that the AI model can invoke. This the primary mechanism grounding LLM responses real data actions.
```csharp
Microsoft.SemanticKernel;
System.ComponentModel;
{
IOrderRepository _repository;
=> _repository = repository;
[]
[]
Task<OrderSummary?> GetOrderAsync(
[] orderId,
CancellationToken ct = )
{
order = _repository.GetByIdAsync(orderId, ct);
order ? : OrderSummary(order);
}
[]
[]
Task<IReadOnlyList<OrderSummary>> ListRecentOrdersAsync(
[] customerId,
[] limit = ,
CancellationToken ct = )
{
orders = _repository.GetRecentAsync(customerId, limit, ct);
orders.Select(o => OrderSummary(o)).ToList();
}
}
```text
```csharp
kernel = builder.Build();
kernel.Plugins.AddFromObject( OrderPlugin(orderRepo), );
kernel.Plugins.AddFromType<TimePlugin>();
kernel.Plugins.AddFromFunctions(,
[
KernelFunctionFactory.CreateFromMethod(
([Description()] a, [Description()] b) => a + b,
,
)
]);
```text
Enable the model to call functions automatically during chat:
```csharp
settings = AzureOpenAIPromptExecutionSettings
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};
chatHistory = ChatHistory();
chatHistory.AddUserMessage();
result = kernel.GetRequiredService<IChatCompletionService>()
.GetChatMessageContentAsync(chatHistory, settings, kernel);
Console.WriteLine(result.Content);
```text
Intercept function calls logging, authorization, modification:
```csharp
:
{
{
(context.Function.Name == )
{
orderId = context.Arguments[]?.ToString();
}
next(context);
}
}
builder.Services.AddSingleton<IFunctionInvocationFilter, AuthorizationFilter>();
```text
---
Prompt templates support variable substitution function calling within structured prompts.
```csharp
result = kernel.InvokePromptAsync(
,
KernelArguments
{
[] = articleText,
[] =
});
```text
Handlebars templates support conditionals, loops, function calls:
```csharp
templateString = ;
factory = HandlebarsPromptTemplateFactory();
template = factory.Create( PromptTemplateConfig(templateString)
{
TemplateFormat = HandlebarsPromptTemplateFactory.HandlebarsTemplateFormat
});
result = template.RenderAsync(kernel, KernelArguments
{
[] = ,
[] = ,
[] = ,
[] = recentOrders
});
```text
Define prompts YAML files separation of concerns:
```yaml
name: Summarize
description: Summarizes text to a specified length
template_format: handlebars
template: |
<message role=>
Summarize the following text approximately {{maxWords}} words.
Focus key facts actionable items.
</message>
<message role=>{{input}}</message>
input_variables:
- name: input
description: The text to summarize
is_required:
- name: maxWords
description: Target word count
:
execution_settings:
:
temperature:
max_tokens:
```text
```csharp
yamlContent = File.ReadAllText();
function = kernel.CreateFunctionFromPromptYaml(yamlContent);
result = kernel.InvokeAsync(function, KernelArguments
{
[] = longText,
[] =
});
```text
---
Semantic Kernel provides abstractions vector storage, enabling retrieval-;
{
[]
Id { ; ; } = .Empty;
[]
Source { ; ; } = .Empty;
[]
Content { ; ; } = .Empty;
[]
ReadOnlyMemory<> Embedding { ; ; }
}
```text
```csharp
Microsoft.SemanticKernel.Connectors.Qdrant;
builder = Kernel.CreateBuilder();
builder.AddAzureOpenAITextEmbeddingGeneration(
deploymentName: ,
endpoint: endpoint,
apiKey: apiKey);
builder.Services.AddQdrantVectorStore(, );
```text
```csharp
{
IVectorStoreRecordCollection<, DocumentRecord> _collection;
ITextEmbeddingGenerationService _embeddingService;
IChatCompletionService _chatService;
{
_collection = vectorStore.GetCollection<, DocumentRecord>();
_embeddingService = embeddingService;
_chatService = chatService;
}
{
questionEmbedding = _embeddingService
.GenerateEmbeddingAsync(question, cancellationToken: ct);
searchResults = _collection.VectorizedSearchAsync(
questionEmbedding,
VectorSearchOptions { Top = },
ct);
contextBuilder = StringBuilder();
( result searchResults)
{
contextBuilder.AppendLine(result.Record.Content);
contextBuilder.AppendLine();
}
chatHistory = ChatHistory();
chatHistory.AddSystemMessage(
);
chatHistory.AddUserMessage(question);
response = _chatService
.GetChatMessageContentAsync(chatHistory, cancellationToken: ct);
response.Content ?? .Empty;
}
}
```text
```
{
_collection.CreateCollectionIfNotExistsAsync(ct);
embedding = _embeddingService
.GenerateEmbeddingAsync(content, cancellationToken: ct);
_collection.UpsertAsync( DocumentRecord
{
Id = documentId,
Content = content,
Source = source,
Embedding = embedding
}, cancellationToken: ct);
}
```text
---
The Semantic Kernel agents framework enables building multi-agent systems specialized agents collaborate tasks.
```csharp
Microsoft.SemanticKernel.Agents;
agent = ChatCompletionAgent
{
Name = ,
Instructions = ,
Kernel = kernel,
Arguments = KernelArguments( AzureOpenAIPromptExecutionSettings
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
})
};
thread = ChatHistoryAgentThread();
( message agent.InvokeAsync(
, thread))
{
Console.WriteLine(message.Content);
}
```text
Multiple agents can collaborate a chat termination conditions:
```csharp
analyst = ChatCompletionAgent
{
Name = ,
Instructions = ,
Kernel = kernel
};
writer = ChatCompletionAgent
{
Name = ,
Instructions = ,
Kernel = kernel
};
chat = AgentGroupChat(analyst, writer)
{
ExecutionSettings = AgentGroupChatSettings
{
TerminationStrategy = ApprovalTerminationStrategy
{
MaximumIterations =
}
}
};
chat.AddChatMessage(
ChatMessageContent(AuthorRole.User, ));
( message chat.InvokeAsync())
{
Console.WriteLine();
}
```text
For stateful conversations built- = OpenAIAssistantAgent.CreateAsync(
kernel,
OpenAIAssistantDefinition()
{
Name = ,
Instructions = ,
EnableCodeInterpreter =
});
{
thread = agent.CreateThreadAsync();
( message agent.InvokeAsync(
, thread))
{
Console.WriteLine(message.Content);
}
}
{
agent.DeleteAsync();
}
```text
Note: = kernel.GetRequiredService<IChatCompletionService>();
chatHistory = ChatHistory();
chatHistory.AddUserMessage(userInput);
settings = AzureOpenAIPromptExecutionSettings
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};
( chunk chatService.GetStreamingChatMessageContentsAsync(
chatHistory, settings, kernel))
{
Console.Write(chunk.Content);
}
```text
---
- **Use function calling over prompt stuffing** -- the model call plugins to retrieve real-time data rather than injecting everything the prompt
- **Keep plugins focused** -- each plugin should represent a single domain; use `[Description]` attributes functions parameters so the model knows how to call them
- **Use YAML prompts production** -- separate prompt content code easier iteration non-developer editing
- **Do store API keys code** -- use environment variables, Azure Key Vault, the .
new
"input"
### Local Models with Ollama
#pragmawarning disable SKEXP0070 // Ollama connector is experimental
var
"llama3.2"
new
"http://localhost:11434"
var
## Plugins and Function Calling
as
is
for
in
and
### Defining a Plugin
using
using
public
sealed
class
OrderPlugin
private
readonly
publicOrderPlugin(IOrderRepository repository)
KernelFunction("get_order")
Description("Retrieves an order by its ID")
public
async
Description("The unique order identifier")
string
default
var
await
return
is
null
null
new
KernelFunction("list_recent_orders")
Description("Lists the most recent orders for a customer")
public
async
Description("The customer ID")
string
Description("Maximum number of orders to return")
int
10
default
var
await
return
new
### Registering Plugins
var
// From an object instance (DI-friendly)
new
"Orders"
// From a type (kernel creates the instance)
"Time"
// From functions directly
"Math"
"First number"
double
"Second number"
double
"Add"
"Adds two numbers"
### Automatic Function Calling
var
new
var
new
"What's the status of order ORD-12345?"
var
await
// The model calls get_order("ORD-12345") automatically and responds with the result
"Summarize the following text in {{$style}} style:\n\n{{$input}}"
new
"input"
"style"
"concise bullet points"
### Handlebars Templates
and
var
"""
<message role="system">
You are a helpful customer service agent.
{{#if isVip}}You are speaking with a VIP customer. Be extra attentive.{{/if}}
</message>
<message role="user">
Customer: {{customerName}}
Query: {{query}}
Recent orders:
{{#each orders}}
- Order {{this.Id}}: {{this.Status}} ({{this.Date}})
{{/each}}
</message>
"""
var
new
var
new
var
await
new
"customerName"
"Alice"
"query"
"Where is my order?"
"isVip"
true
"orders"
### YAML Prompt Configuration
as
for
# prompts/summarize.yaml
"system"
in
on
and
"user"
true
default
"100"
default
0.3
500
var
"prompts/summarize.yaml"
var
var
await
new
"input"
"maxWords"
"50"
## Memory and Vector Stores
for
augmented generation (RAG) patterns.
### Vector Store Abstractions
```csharp
using Microsoft.Extensions.VectorData
#pragmawarning disable SKEXP0110 // Agents framework is experimental
using
var
new
"OrderAssistant"
"""
You are an order management assistant. Help customers check order status,
process returns, and answer questions about their orders.
Always verify the customer's identity before sharing order details.
"""
new
new
// Invoke via a thread (required -- agents do not accept bare strings)
var
new
await
foreach
var
in
"What's the status of my order ORD-12345?"
### Agent Group Chat
in
group
with
var
new
"DataAnalyst"
"You analyze data and provide insights. Present findings clearly."
var
new
"ReportWriter"
"You take analytical findings and write clear, actionable reports."
var
new
new
new
6
new
"Analyze Q4 sales trends and write a summary report."
await
foreach
var
in
$"[{message.AuthorName}]: {message.Content}"
### OpenAI Assistant Agent
with
intools (code interpreter, file search):
```csharp
#pragma warning disable SKEXP0110
// Create the assistant via the builder pattern
OpenAIAssistantAgent agent
await
new
"gpt-4o"
"DataProcessor"
"You process CSV data and generate insights."
true
try
// Assistant agents use threads for stateful conversations
var
await
await
foreach
var
in
"Analyze the attached sales data."
finally
await
The agents framework isexperimental (`SKEXP0110`). APIs change frequently between Semantic Kernel releases. Verify method signatures against the [latest samples](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/samples) when adopting.
---
## Streaming Responses
For chat applications, stream responses token-by-token:
```csharp
var chatService
var
new
"You are a helpful assistant."
var
new
await
foreach
var
in
## Key Principles
let
into
on
and
when
and
for
from
for
and
not
in
or
NET secrets manager (see [skill:dotnet-csharp-configuration])
- **Prefer vector store abstractions** -- code against `IVectorStore` to allow switching between Qdrant, Azure AI Search, and other providers
- **Handle experimental APIs explicitly** -- suppress `SKEXP*` warnings per-call, not globally, so you notice when APIs graduate to stable
---
## Agent Gotchas
1. **Do not hardcode API keys or endpoints in Kernel builder calls** -- use `builder.Configuration` or environment variables. Hardcoded secrets leak into source control and prevent environment-specific configuration.
2. **Do not suppress all `SKEXP*` warnings globally** -- experimental APIs change frequently. Suppress per-usage (`#pragma warning disable SKEXP0110`) so new experimental usage sites are flagged by the compiler.
3. **Do not create a new `Kernel` instance per request in ASP.NET Core** -- register the kernel in DI as a singleton (it is thread-safe) and clone with `kernel.Clone()` if per-request state is needed.
4. **Do not ignore `CancellationToken` in plugin functions** -- AI function calls can be cancelled by the user or timeout policies. Always propagate `CancellationToken` through plugin method signatures.
5. **Do notreturn large objects from plugin functions** -- the model receives the serialized result as context. Return summary DTOs, not full entity graphs, to avoid exceeding token limits.
6. **Do not mix `AddAzureOpenAIChatCompletion` and `AddOpenAIChatCompletion` without `serviceId`** -- without a service ID, the last registration wins. Use explicit `serviceId` when registering multiple AI services.
---
## Prerequisites
- `Microsoft.SemanticKernel` NuGet package (1.x stable)
- An AI service endpoint (Azure OpenAI, OpenAI API key, or Ollama for local models)
- For vector stores: a running instance of the chosen provider (Qdrant, Azure AI Search, etc.)
---
## References
- [Semantic Kernel documentation](https://learn.microsoft.com/en-us/semantic-kernel/)
- [Semantic Kernel .NET SDK](https://github.com/microsoft/semantic-kernel)
- [Semantic Kernel plugins](https://learn.microsoft.com/en-us/semantic-kernel/concepts/plugins/)
- [Semantic Kernel agents](https://learn.microsoft.com/en-us/semantic-kernel/frameworks/agent/)
- [Vector store connectors](https://learn.microsoft.com/en-us/semantic-kernel/concepts/vector-store-connectors/)
- [Semantic Kernel samples](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/samples)