Use when building AI agents with Microsoft.SemanticKernel or Microsoft.Extensions.AI.Agent frameworks. Covers agent creation, tool/plugin registration, multi-agent orchestration, chat completion agents, and OpenAI Assistants integration.
USE FOR: building AI agents with tools and plugins, multi-agent chat workflows, Semantic Kernel agent orchestration, OpenAI Assistants API integration, agent-based automation pipelines
DO NOT USE FOR: simple chat completions without agent patterns (use microsoft-extensions-ai), inter-service agent communication over A2A protocol (use a2a), ML model training (use mlnet), raw ONNX inference (use onnx)
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.
Use when building AI agents with Microsoft.SemanticKernel or Microsoft.Extensions.AI.Agent frameworks. Covers agent creation, tool/plugin registration, multi-agent orchestration, chat completion agents, and OpenAI Assistants integration.
USE FOR: building AI agents with tools and plugins, multi-agent chat workflows, Semantic Kernel agent orchestration, OpenAI Assistants API integration, agent-based automation pipelines
DO NOT USE FOR: simple chat completions without agent patterns (use microsoft-extensions-ai), inter-service agent communication over A2A protocol (use a2a), ML model training (use mlnet), raw ONNX inference (use onnx)
The Microsoft Semantic Kernel Agent Framework provides a structured way to build AI agents that can use tools, maintain conversation history, and collaborate in multi-agent workflows. It supports ChatCompletionAgent for LLM-backed agents, OpenAIAssistantAgent for the Assistants API, and AgentGroupChat for orchestrating conversations between multiple agents with configurable termination and selection strategies.
The simplest agent type wraps an IChatCompletionService with instructions and optional plugins.
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.ChatCompletion;
var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion("gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY")!);
var kernel = builder.Build();
var agent = new ChatCompletionAgent
{
Name = "CodeReviewer",
Instructions = """
You are a senior .NET developer who reviews code for correctness,
performance, and adherence to best practices. Provide specific,
actionable feedback with code examples.
""",
Kernel = kernel
};
var history = new ChatHistory();
history.AddUserMessage("Review this code: public int Add(int a, int b) => a + b;");
awaitforeach (var message in agent.InvokeAsync(history))
{
Console.WriteLine(message.Content);
}
Agents with Plugins (Tools)
Plugins give agents the ability to call functions, access data, and interact with external systems.
KernelFunction, Description("Gets the current weather for a city")
publicstringGetWeather(
[Description("The city name")] string city)
// In production, call a real weather API
return
switch
"seattle"
"62F, cloudy with rain expected"
"new york"
"75F, sunny and clear"
"london"
"58F, overcast with light drizzle"
$"Weather data not available for {city}"
KernelFunction, Description("Gets a 5-day forecast for a city")
publicstringGetForecast(
[Description("The city name")] string city,
[Description("Number of days (1-5)")] int days
5
return
$"Forecast for {city}: next {days} days show moderate temperatures with occasional rain."
var
"gpt-4o"
var
var
new
"WeatherAssistant"
"You help users with weather information. Use the available tools to get real data."
new
new
OpenAI Assistants Agent
Integrates with the OpenAI Assistants API for server-side conversation management, code interpreter, and file search.
using Microsoft.SemanticKernel.Agents.OpenAI;
using OpenAI.Files;
var client = OpenAIAssistantAgent.CreateOpenAIClient(apiKey);
var agent = await OpenAIAssistantAgent.CreateAsync(
client,
new OpenAIAssistantDefinition("gpt-4o")
{
Name = "DataAnalyst",
Instructions = "You analyze data files and produce insights with charts.",
EnableCodeInterpreter = true
});
var thread = await agent.CreateThreadAsync();
await agent.AddChatMessageAsync(thread.Id, new ChatMessageContent(
AuthorRole.User, "Analyze the sales trends in the attached CSV"));
awaitforeach (var message in agent.InvokeAsync(thread.Id))
{
Console.WriteLine($"{message.AuthorName}: {message.Content}");
}
// Cleanupawait agent.DeleteThreadAsync(thread.Id);
await agent.DeleteAsync();
Multi-Agent Chat (AgentGroupChat)
AgentGroupChat orchestrates turn-based conversations between multiple agents with configurable selection and termination.
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.Chat;
var writer = new ChatCompletionAgent
{
Name = "Writer",
Instructions = """
You write clear, concise technical documentation.
When the Reviewer approves your content, respond with exactly: APPROVED.
""",
Kernel = kernel
};
var reviewer = new ChatCompletionAgent
{
Name = "Reviewer",
Instructions = """
You review technical documentation for accuracy and clarity.
Provide specific feedback. Say APPROVED when content meets standards.
""",
Kernel = kernel
};
var chat = new AgentGroupChat(writer, reviewer)
{
ExecutionSettings = new AgentGroupChatSettings
{
TerminationStrategy = new ApprovalTerminationStrategy
{
Agents = [reviewer],
MaximumIterations = 10
},
SelectionStrategy = new SequentialSelectionStrategy()
}
};
chat.AddChatMessage(new ChatMessageContent(
AuthorRole.User,
"Write documentation for a REST API endpoint that creates a user account."));
awaitforeach (var message in chat.InvokeAsync())
{
Console.WriteLine($"[{message.AuthorName}]: {message.Content}");
}
An LLM decides which agent speaks next based on context
// LLM-driven agent selectionvar selectionFunction = KernelFunctionFactory.CreateFromPrompt("""
Given the conversation history, determine which agent should respond next.
Agents: Writer, Reviewer, FactChecker.
Only return the agent name, nothing else.
History:
{{$history}}
""");
var settings = new AgentGroupChatSettings
{
SelectionStrategy = new KernelFunctionSelectionStrategy(selectionFunction, kernel)
{
ResultParser = (result) => result.GetValue<string>()?.Trim() ?? "Writer",
InitialAgent = writer
}
};
Dependency Injection Integration
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddOpenAIChatCompletion("gpt-4o", apiKey);
builder.Services.AddKernel();
builder.Services.AddKeyedTransient<ChatCompletionAgent>("support", (sp, _) =>
{
var kernel = sp.GetRequiredService<Kernel>();
returnnew ChatCompletionAgent
{
Name = "SupportAgent",
Instructions = "You are a helpful customer support agent.",
Kernel = kernel
};
});
builder.Services.AddTransient<SupportService>();
var host = builder.Build();
host.Run();
publicclassSupportService(
[FromKeyedServices("support")] ChatCompletionAgent agent)
{
publicasync Task<string> HandleQueryAsync(string userMessage)
{
var history = new ChatHistory();
history.AddUserMessage(userMessage);
var response = new StringBuilder();
awaitforeach (var msg in agent.InvokeAsync(history))
{
response.Append(msg.Content);
}
return response.ToString();
}
}
Best Practices
Keep agent instructions focused on a single role or responsibility; create multiple specialized agents rather than one agent with broad, conflicting instructions.
Use KernelFunction plugins for deterministic operations (database queries, API calls, calculations) rather than relying on the LLM to produce exact values.
Set MaximumIterations on AgentGroupChatSettings to prevent runaway multi-agent conversations that consume unbounded tokens.
Implement custom TerminationStrategy classes with explicit completion signals (like "APPROVED") rather than relying on LLM-generated signals that may be ambiguous.
Register agents as keyed services in DI (AddKeyedTransient<ChatCompletionAgent>) so that consumers can resolve specific agents by name without tight coupling.
Use KernelFunctionSelectionStrategy with a clear prompt listing agent names and roles when conversations require dynamic turn order based on context.
Store ChatHistory externally (in a database or cache) for multi-request conversations rather than keeping it in memory, which is lost between HTTP requests.
Pass CancellationToken through all InvokeAsync calls so that cancelled HTTP requests stop LLM inference and tool execution immediately.
Test agents by mocking IChatCompletionService to return deterministic responses, verifying that tool calls are made with expected arguments.
Log each agent turn including agent name, token usage, and tool calls invoked to monitor costs and debug unexpected conversation flows.