Microsoft Agent Framework 1.0 — Unified SDK for AI Agents on .NET 10
Posted on: 4/18/2026 9:16:10 AM
Table of contents
- 1. Why Unify?
- 2. Unification Timeline
- 3. The 5-Layer Architecture
- 4. The Five Built-in Orchestration Patterns
- 5. The Middleware Pipeline — Power Inherited from Semantic Kernel
- 6. Declarative Agents — Defining Agents with YAML
- 7. Tool Registration and MCP Integration
- 8. Observability with OpenTelemetry
- 9. Graph-based Workflows — Beyond Orchestration Patterns
- 10. Comparison with Other Agent Frameworks
- 11. Real-World Architecture: Interview Coach
- 12. Migrating from Semantic Kernel / AutoGen
- 13. Quick Start — From 0 to Your First Agent
- 14. Production Best Practices
- Conclusion
For years, the .NET ecosystem had two notable but completely separate AI agent frameworks: Semantic Kernel — enterprise-grade, type-safe, with a powerful middleware pipeline — and AutoGen — a breakthrough in conversation-centric multi-agent design, great for prototyping. Developers had to pick one or write glue code to bridge both. On April 3, 2026, Microsoft officially released Agent Framework 1.0 — a unified SDK that merges the best of Semantic Kernel and AutoGen into a single, production-ready framework with first-class support for both C#/.NET and Python.
This article dives deep into the architecture, orchestration patterns, middleware pipeline, declarative agents, observability, and MCP integration — all with concrete C# examples on .NET 10.
1. Why Unify?
Before Agent Framework 1.0, the .NET agent landscape was fairly fragmented:
| Criterion | Semantic Kernel | AutoGen |
|---|---|---|
| Philosophy | Enterprise — type safety, middleware, telemetry | Research — conversation-centric, fast prototyping |
| Multi-agent | Limited, mostly single-agent + plugins | Strong — group chat, Magentic-One |
| Orchestration | Sequential plugins | Conversation-based routing |
| Production readiness | High — session management, telemetry | Medium — lacking middleware, observability |
| Language | C# (primary), Python | Python (primary), C# |
This fragmentation caused real problems: enterprise teams wanted AutoGen's multi-agent patterns but needed Semantic Kernel's middleware pipeline. The result was bespoke glue code, non-standardized and hard to maintain. Agent Framework 1.0 solves this by taking the best of both:
Agent Framework 1.0 = ?
From AutoGen: Simple agent abstractions (Agent, ChatAgent), multi-agent patterns (group chat, Magentic-One), conversation flows.
From Semantic Kernel: Enterprise middleware pipeline, session-based state, type safety, OpenTelemetry integration, model connector ecosystem.
Brand new: Graph-based workflows, declarative YAML agents, MCP/A2A protocol support, and a DevUI debugger.
2. Unification Timeline
Microsoft.Agents.AI v1.1.0, PyPI package agent-framework.3. The 5-Layer Architecture
Agent Framework is designed with a clear layered architecture, each layer with its own responsibility:
graph TB
subgraph L1["🖥️ Client / Application Layer"]
A1[Web Apps / APIs]
A2[Console Apps]
A3[Teams Bots]
A4[Background Services]
end
subgraph L2["🤖 Agent Layer"]
B1[ChatClientAgent]
B2[Declarative Agent YAML]
B3[Custom Agent]
end
subgraph L3["⚙️ Runtime Layer"]
C1[Session Management]
C2[Middleware Pipeline]
C3[Memory / Context]
C4[Execution Loop]
end
subgraph L4["🔧 Tool / Integration Layer"]
D1[Function Tools]
D2[MCP Clients]
D3[External APIs]
D4[Databases]
end
subgraph L5["🧠 Model Provider Layer"]
E1[Azure OpenAI]
E2[OpenAI]
E3[Anthropic Claude]
E4[Google Gemini]
E5[Ollama]
end
L1 --> L2
L2 --> L3
L3 --> L4
L3 --> L5
style L1 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style L2 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style L3 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style L4 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style L5 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
A special feature: all model connectors implement the IChatClient interface from Microsoft.Extensions.AI — letting you write fully provider-agnostic code. You can swap from Azure OpenAI to Anthropic Claude or local Ollama without changing a single line of business logic.
4. The Five Built-in Orchestration Patterns
This is where Agent Framework truly shines compared to building your own. The framework ships 5 patterns out of the box, covering most multi-agent use cases in production:
graph LR
subgraph Sequential
S1[Agent A] --> S2[Agent B] --> S3[Agent C]
end
subgraph Concurrent
C0[Input] --> C1[Agent A]
C0 --> C2[Agent B]
C0 --> C3[Agent C]
C1 --> C4[Aggregator]
C2 --> C4
C3 --> C4
end
style S1 fill:#e94560,stroke:#fff,color:#fff
style S2 fill:#e94560,stroke:#fff,color:#fff
style S3 fill:#e94560,stroke:#fff,color:#fff
style C0 fill:#2c3e50,stroke:#fff,color:#fff
style C1 fill:#e94560,stroke:#fff,color:#fff
style C2 fill:#e94560,stroke:#fff,color:#fff
style C3 fill:#e94560,stroke:#fff,color:#fff
style C4 fill:#2c3e50,stroke:#fff,color:#fff
| Pattern | Topology | Typical Use Case |
|---|---|---|
| Sequential | Pipeline — A → B → C | Content pipeline: write → review → translate. Each agent's output is the next agent's input. |
| Concurrent | Fan-out/fan-in | Parallel analysis: sentiment + entity extraction + summarization → aggregate. |
| Handoff | Mesh — agents pass control | Customer support: triage → refund/order/return agent. Agents decide the handoff. |
| Group Chat | Shared conversation thread | Brainstorming: multiple agents with different expertise discussing in one thread. |
| Magentic-One | Manager dynamically coordinates | Complex task: a manager agent analyzes the task and delegates to the best-fit agent. |
4.1 Sequential — A Simple Pipeline
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Orchestrations;
// Create agents for a content pipeline
var writer = new ChatClientAgent(chatClient,
"You are a copywriter. Write a short, punchy marketing paragraph.",
name: "writer");
var reviewer = new ChatClientAgent(chatClient,
"You are an editor. Review and improve the draft, keep the tone.",
name: "reviewer");
var translator = new ChatClientAgent(chatClient,
"You are a translator. Translate the content into natural Vietnamese.",
name: "translator");
// Build a sequential workflow
var workflow = AgentWorkflowBuilder.BuildSequential([writer, reviewer, translator]);
// Execute
var messages = new List<ChatMessage>
{
new(ChatRole.User, "Write a tagline for a cloud-native .NET framework")
};
await using var run = await InProcessExecution.RunStreamingAsync(workflow, messages);
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
When to use Sequential?
Use it when the previous agent's output is a required input for the next agent. Don't use sequential if the agents can run independently — use Concurrent instead to save time.
4.2 Handoff — Mesh Topology with Control Transfer
Handoff is the most powerful pattern for customer-facing systems. Agents decide on their own when to pass a conversation to another agent:
// Define agents
var triageAgent = new ChatClientAgent(chatClient,
"You classify requests. ALWAYS hand off to the appropriate agent.",
name: "triage_agent", description: "Main router");
var refundAgent = new ChatClientAgent(chatClient,
"You handle refund requests. Verify order ID before processing.",
name: "refund_agent", description: "Refund handler");
var orderAgent = new ChatClientAgent(chatClient,
"You look up and update order status.",
name: "order_agent", description: "Order management");
var returnAgent = new ChatClientAgent(chatClient,
"You guide the return/exchange process.",
name: "return_agent", description: "Return handler");
// Build the handoff workflow with routing rules
var workflow = AgentWorkflowBuilder
.CreateHandoffBuilderWith(triageAgent)
.WithHandoffs(triageAgent, [refundAgent, orderAgent, returnAgent])
.WithHandoffs(returnAgent, [refundAgent])
.WithHandoffs(orderAgent, [triageAgent])
.WithHandoff(refundAgent, triageAgent)
.Build();
graph TD
T[Triage Agent] -->|"refund"| R[Refund Agent]
T -->|"order"| O[Order Agent]
T -->|"return"| RT[Return Agent]
RT -->|"needs refund"| R
O -->|"back"| T
R -->|"done"| T
style T fill:#e94560,stroke:#fff,color:#fff
style R fill:#2c3e50,stroke:#fff,color:#fff
style O fill:#2c3e50,stroke:#fff,color:#fff
style RT fill:#2c3e50,stroke:#fff,color:#fff
5. The Middleware Pipeline — Power Inherited from Semantic Kernel
One of the most important enterprise features inherited from Semantic Kernel is the middleware pipeline. It follows ASP.NET Core's middleware pattern exactly: ordered components, a context object, and a call_next() delegate.
Three Middleware Layers
graph LR
REQ[Request] --> ARM[Agent Run Middleware]
ARM --> FM[Function Middleware]
FM --> CM[Chat Middleware]
CM --> LLM[LLM Provider]
LLM --> CM2[Chat Middleware]
CM2 --> FM2[Function Middleware]
FM2 --> ARM2[Agent Run Middleware]
ARM2 --> RES[Response]
style REQ fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style ARM fill:#e94560,stroke:#fff,color:#fff
style FM fill:#16213e,stroke:#fff,color:#fff
style CM fill:#2c3e50,stroke:#fff,color:#fff
style LLM fill:#4CAF50,stroke:#fff,color:#fff
style CM2 fill:#2c3e50,stroke:#fff,color:#fff
style FM2 fill:#16213e,stroke:#fff,color:#fff
style ARM2 fill:#e94560,stroke:#fff,color:#fff
style RES fill:#f8f9fa,stroke:#e94560,color:#2c3e50
| Middleware Type | Intercepts | Use Case |
|---|---|---|
| Agent Run Middleware | The entire agent execution (input/output) | Logging, security checks, response override, audit trail |
| Function Middleware | Tool/function calls | Input validation, rate limiting, result transformation, caching |
| Chat (IChatClient) Middleware | Raw LLM requests/responses | Prompt injection detection, token tracking, content filtering |
Example: Security Middleware That Blocks Sensitive Data
// Middleware that blocks requests containing sensitive information
async Task<AgentResponse> SecurityMiddleware(
IEnumerable<ChatMessage> messages,
AgentSession? session,
AgentRunOptions? options,
AIAgent innerAgent,
CancellationToken ct)
{
var lastMessage = messages.LastOrDefault()?.Text ?? "";
// Check for PII patterns
if (Regex.IsMatch(lastMessage, @"\b\d{9,12}\b") ||
lastMessage.Contains("password", StringComparison.OrdinalIgnoreCase))
{
return new AgentResponse(new[]
{
new ChatMessage(ChatRole.Assistant,
"Request blocked: sensitive information detected.")
});
}
// Allow to proceed if safe
return await innerAgent.RunAsync(messages, session, options, ct);
}
// Middleware that logs every function call
async ValueTask<object?> AuditFunctionMiddleware(
AIAgent agent,
FunctionInvocationContext context,
Func<FunctionInvocationContext, CancellationToken, ValueTask<object?>> next,
CancellationToken ct)
{
var start = Stopwatch.GetTimestamp();
logger.LogInformation("Tool call: {Name}, Args: {Args}",
context.Function.Name, context.Arguments);
var result = await next(context, ct);
var elapsed = Stopwatch.GetElapsedTime(start);
logger.LogInformation("Tool {Name} completed in {Ms}ms",
context.Function.Name, elapsed.TotalMilliseconds);
return result;
}
// Register the middleware
var securedAgent = originalAgent
.AsBuilder()
.Use(runFunc: SecurityMiddleware)
.Use(AuditFunctionMiddleware)
.Build();
Middleware order matters!
Middleware runs in registration order (outermost → innermost). Security middleware should be registered first so it can block requests as early as possible — before they reach logging or business logic.
6. Declarative Agents — Defining Agents with YAML
Instead of hard-coding agents in C#, Agent Framework supports defining agents via YAML — version-controlled, easy to review, and accessible to non-developers (PMs, domain experts) participating in agent behavior design:
# agents/diagnostic-agent.yaml
kind: Prompt
name: DiagnosticAgent
displayName: System Diagnostic Assistant
description: Agent specialized in log analysis and fix suggestions
instructions: |
You are a DevOps expert. When receiving an error log:
1. Analyze the root cause
2. Suggest a specific fix with code
3. Rate severity (P0-P3)
Always reply in Vietnamese.
model:
id: gpt-4o
connection:
kind: azure_openai
endpoint: https://my-project.openai.azure.com/
options:
temperature: 0.3
topP: 0.9
outputSchema:
properties:
severity:
type: string
enum: [P0, P1, P2, P3]
root_cause:
type: string
fix_suggestion:
type: string
// Load the agent from YAML — just 3 lines
var factory = new ChatClientPromptAgentFactory(chatClient);
var agent = await factory.CreateFromYamlAsync(
File.ReadAllText("agents/diagnostic-agent.yaml"));
var response = await agent!.RunAsync("Error: Connection pool exhausted after 500 concurrent requests");
YAML Agents + GitOps
Declarative agents work great with a GitOps workflow: every agent behavior change goes through PR review, has history, and can be rolled back. QA teams can review instructions without reading C# code.
7. Tool Registration and MCP Integration
Agent Framework supports two tool registration approaches: inline function tools (simple and fast) and MCP servers (standardized and reusable).
7.1 Inline Function Tools
var tools = new[]
{
AIFunctionFactory.Create(
(string orderId) =>
{
// Query the database
var order = db.Orders.Find(orderId);
return order is null
? "Order not found"
: $"Order {orderId}: {order.Status}, shipped on {order.ShipDate:dd/MM/yyyy}";
},
name: "lookup_order",
description: "Look up order status by order ID"),
AIFunctionFactory.Create(
(string query, int limit = 5) =>
{
var results = searchService.Search(query, limit);
return JsonSerializer.Serialize(results);
},
name: "search_docs",
description: "Search the internal knowledge base")
};
var agent = chatClient.CreateAIAgent(
instructions: "You are a customer support assistant. Use lookup_order to check orders and search_docs to find guides.",
tools: tools);
7.2 MCP Server Integration
Agent Framework supports MCP (Model Context Protocol) — agents can dynamically discover and invoke tools from any MCP-compliant server:
// Connect to an MCP Server via Streamable HTTP
var mcpClient = new McpClient(new Uri("https://mcp.internal.company.com/tools"));
await mcpClient.InitializeAsync();
// The agent automatically discovers tools from the MCP server
var agent = chatClient.CreateAIAgent(
instructions: "You have access to database and monitoring tools via MCP.",
tools: mcpClient.GetAvailableTools());
MCP in Agent Framework vs Claude Code
Both Agent Framework and Claude Code implement an MCP client. The difference: Agent Framework uses MCP as an integration layer inside an application you build yourself, while Claude Code is a ready-to-use reference implementation. If you already know MCP from Claude Code, that knowledge transfers directly to Agent Framework.
8. Observability with OpenTelemetry
Agent Framework is deeply integrated with OpenTelemetry, emitting traces, logs, and metrics following the OpenTelemetry GenAI Semantic Conventions. This is a major differentiator vs other frameworks — instead of vendor-locked telemetry, you use an open standard.
Setting Up OpenTelemetry for an Agent
using OpenTelemetry;
using OpenTelemetry.Trace;
using OpenTelemetry.Metrics;
const string SourceName = "MyAgentApp";
// 1. Instrument the chat client
var instrumentedClient = chatClient
.AsBuilder()
.UseOpenTelemetry(
sourceName: SourceName,
configure: cfg => cfg.EnableSensitiveData = true)
.Build();
// 2. Instrument the agent
var agent = new ChatClientAgent(instrumentedClient,
name: "SupportAgent",
instructions: "You are a technical support assistant.")
.WithOpenTelemetry(
sourceName: SourceName,
configure: cfg => cfg.EnableSensitiveData = true);
// 3. Export via OTLP (Aspire Dashboard, Grafana, Jaeger...)
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("agent-app"))
.AddSource(SourceName)
.AddOtlpExporter(opt => opt.Endpoint = new Uri("http://localhost:4317"))
.Build();
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter(SourceName)
.AddOtlpExporter(opt => opt.Endpoint = new Uri("http://localhost:4317"))
.Build();
Automatic Metrics and Spans
| Name | Type | Meaning |
|---|---|---|
invoke_agent <name> | Span | Entire lifecycle of an agent call |
chat <model> | Span | Each LLM call (prompt + completion) |
execute_tool <func> | Span | Each tool/function execution |
gen_ai.client.operation.duration | Histogram | Latency of each LLM operation |
gen_ai.client.token.usage | Histogram | Token consumption (input + output) |
agent_framework.function.invocation.duration | Histogram | Tool execution latency |
graph LR
AF[Agent Framework] -->|OTLP| COL[OTel Collector]
COL --> TRACE[Tempo / Jaeger]
COL --> METRIC[Prometheus]
COL --> LOG[Loki]
TRACE --> GR[Grafana Dashboard]
METRIC --> GR
LOG --> GR
style AF fill:#e94560,stroke:#fff,color:#fff
style COL fill:#2c3e50,stroke:#fff,color:#fff
style TRACE fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style METRIC fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style LOG fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style GR fill:#4CAF50,stroke:#fff,color:#fff
DevUI — A visual debugger
Agent Framework ships with DevUI — a browser-based debugger that shows, in real time, message flows, tool calls, orchestration decisions, and agent transitions. Use it only in development (~15-30ms latency per step). Combined with OpenTelemetry, it provides complete observability from dev through production.
9. Graph-based Workflows — Beyond Orchestration Patterns
When the 5 built-in orchestration patterns aren't flexible enough, Agent Framework provides graph-based workflows — letting you design arbitrary complex processing flows as directed graphs:
// Core concepts:
// - Executor: processing unit (AI agent or custom logic)
// - Edge: connection between executors, supports conditional routing
// - Workflow: directed graph managing execution through supersteps
var classifier = new ChatClientAgent(chatClient,
"Classify input: 'technical' or 'business'. Reply with one word only.",
name: "classifier");
var techAgent = new ChatClientAgent(chatClient,
"You provide detailed technical answers.",
name: "tech_expert");
var bizAgent = new ChatClientAgent(chatClient,
"You provide business strategy advice.",
name: "biz_advisor");
var summarizer = new ChatClientAgent(chatClient,
"You summarize results into a concise report.",
name: "summarizer");
// Build the graph
var workflow = new AgentWorkflowBuilder()
.AddExecutor(classifier)
.AddExecutor(techAgent)
.AddExecutor(bizAgent)
.AddExecutor(summarizer)
.AddConditionalEdge(classifier, msg =>
msg.Contains("technical") ? techAgent.Name : bizAgent.Name)
.AddEdge(techAgent, summarizer)
.AddEdge(bizAgent, summarizer)
.SetEntryPoint(classifier)
.Build();
graph TD
CL[Classifier Agent] -->|"technical"| TE[Tech Expert]
CL -->|"business"| BA[Biz Advisor]
TE --> SU[Summarizer]
BA --> SU
style CL fill:#e94560,stroke:#fff,color:#fff
style TE fill:#2c3e50,stroke:#fff,color:#fff
style BA fill:#2c3e50,stroke:#fff,color:#fff
style SU fill:#4CAF50,stroke:#fff,color:#fff
10. Comparison with Other Agent Frameworks
| Feature | MS Agent Framework 1.0 | LangGraph | CrewAI |
|---|---|---|---|
| Language | C#/.NET + Python | Python, JS | Python |
| Architecture | Graph workflows + 5 orchestrations | Cyclical graph + shared state | Role-based agent teams |
| Enterprise features | Middleware, telemetry, sessions, type safety | State management, checkpointing | Task delegation |
| Protocol support | MCP + A2A | LangChain ecosystem | Limited |
| Observability | Native OpenTelemetry + Aspire | LangSmith | Limited |
| Declarative config | YAML agents + workflows | No | YAML crews |
| Human-in-the-loop | Built-in (tool approval, request info) | Yes | Limited |
| Memory | Pluggable (Redis, Neo4j, Mem0) | Built-in state | Limited |
| Strengths | Unified .NET+Python, enterprise pipeline | Fine-grained graph, LangChain | Simplest for role-based |
Which framework to choose?
Agent Framework 1.0 is the best choice if your team is on .NET, needs enterprise features (middleware, telemetry, type safety), and wants a framework with long-term Microsoft backing. LangGraph fits Python-first teams wanting fine-grained graph control. CrewAI is great for fast role-based multi-agent prototyping but lacks enterprise maturity.
11. Real-World Architecture: Interview Coach
Microsoft provides a full reference implementation — Interview Coach — showing how Agent Framework combines with Aspire, MCP, and Foundry in production:
graph TB
UI[Blazor WebUI] --> AS[Agent Service
Agent Framework 1.0]
AS --> MCP1[MarkItDown MCP Server
Python - Parse documents]
AS --> MCP2[InterviewData MCP Server
.NET - SQLite queries]
AS --> FD[Microsoft Foundry
LLM Provider]
subgraph Agents
TR[Triage Agent]
RC[Receptionist Agent]
BH[Behavioural Agent]
TC[Technical Agent]
SM[Summariser Agent]
end
AS --> Agents
TR --> RC
RC --> BH
BH --> TC
TC --> SM
SM --> TR
ASPIRE[.NET Aspire] -.->|orchestrate| UI
ASPIRE -.->|orchestrate| AS
ASPIRE -.->|orchestrate| MCP1
ASPIRE -.->|orchestrate| MCP2
style UI fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style AS fill:#e94560,stroke:#fff,color:#fff
style MCP1 fill:#2c3e50,stroke:#fff,color:#fff
style MCP2 fill:#2c3e50,stroke:#fff,color:#fff
style FD fill:#4CAF50,stroke:#fff,color:#fff
style ASPIRE fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style TR fill:#e94560,stroke:#fff,color:#fff
style RC fill:#16213e,stroke:#fff,color:#fff
style BH fill:#16213e,stroke:#fff,color:#fff
style TC fill:#16213e,stroke:#fff,color:#fff
style SM fill:#16213e,stroke:#fff,color:#fff
This architecture showcases the power of Agent Framework combined with the .NET ecosystem:
- .NET Aspire orchestrates all services — automatic service discovery, health checks, and distributed tracing.
- 5 agents use the Handoff pattern — triage routes to receptionist (info gathering), then behavioural interview, technical interview, and finally summariser aggregates feedback.
- 2 MCP Servers — one in Python (parse resumes/CVs) and one in .NET (query interview database).
- Microsoft Foundry — model routing, content safety, and managed hosting.
12. Migrating from Semantic Kernel / AutoGen
If your team is using Semantic Kernel or AutoGen, here's the basic mapping:
| Semantic Kernel | Agent Framework 1.0 |
|---|---|
Kernel + KernelPlugin | AIAgent + AIFunctionFactory |
KernelFunction | AIFunction (from M.E.AI) |
ChatCompletionService | IChatClient (from M.E.AI) |
KernelFilter | Middleware pipeline (3 layers) |
| AutoGen | Agent Framework 1.0 |
|---|---|
AssistantAgent | ChatClientAgent |
GroupChat | AgentWorkflowBuilder.BuildGroupChat() |
Magentic-One | AgentWorkflowBuilder.BuildMagenticOne() |
| Conversation routing | Handoff orchestration |
Migration notes
Semantic Kernel and AutoGen have entered maintenance mode — only bug fixes and security patches, no new features. Microsoft recommends migrating to Agent Framework for all new projects and gradually migrating existing ones. Official migration guide at learn.microsoft.com/en-us/agent-framework/migration-guide/.
13. Quick Start — From 0 to Your First Agent
# 1. Create a .NET 10 project
dotnet new console -n MyFirstAgent
cd MyFirstAgent
# 2. Add packages
dotnet add package Microsoft.Agents.AI
dotnet add package Microsoft.Agents.AI.OpenAI
# Or: Microsoft.Agents.AI.Foundry for Azure AI Foundry
// Program.cs — The simplest possible agent
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.OpenAI;
using OpenAI;
var openAiClient = new OpenAIClient(Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
var chatClient = openAiClient
.GetChatClient("gpt-4o")
.AsIChatClient();
var agent = chatClient.CreateAIAgent(
instructions: "You are a .NET programming assistant. Answer concisely with code examples.");
// Single turn
var response = await agent.RunAsync("Write an extension method to convert a string to a URL slug");
Console.WriteLine(response);
// Multi-turn with a session
var session = new AgentSession();
await agent.RunAsync("Add Unicode support to the method above", session: session);
Console.WriteLine(session.Messages.Last().Text);
Tip: Use Ollama for development
To avoid burning API credits during development, connect Agent Framework to Ollama running locally:
dotnet add package Microsoft.Extensions.AI.Ollama
var chatClient = new OllamaChatClient(new Uri("http://localhost:11434"), "llama3.1");
Business logic stays identical — just swap the chat client when you deploy to production.
14. Production Best Practices
- Start single-agent: 80% of use cases only need one agent with good tools. Only add more agents when you hit a clear expertise or parallelism bottleneck.
- Middleware for cross-cutting concerns: Logging, security, rate limiting — don't stuff these into agent instructions. Middleware is separable, testable, and reusable.
- YAML agents for behavior iteration: When agent behavior changes frequently, use declarative YAML instead of hard-coding. PMs and domain experts can review instructions in PRs.
- OpenTelemetry from day one: Don't wait for production to add telemetry. Set it up from development — near-zero cost but huge debug value.
- Handoff > Group Chat for customer-facing: Handoff yields clear, predictable conversation flow. Group Chat suits internal brainstorming but is harder to control for output quality.
- Function middleware for tool safety: Validate every tool input, especially when the tool accesses databases or external APIs. LLMs can hallucinate parameters.
Conclusion
Microsoft Agent Framework 1.0 marks a maturity milestone for the AI agent ecosystem on .NET. Instead of choosing between Semantic Kernel (enterprise) and AutoGen (multi-agent), you now have a unified SDK combining the best of both — plus graph workflows, declarative YAML agents, MCP integration, and standardized OpenTelemetry observability.
With 5 built-in orchestration patterns, a 3-layer middleware pipeline, support for 7+ model providers, and deep integration with .NET Aspire — Agent Framework 1.0 is the production-ready answer to "how do I build AI agents on .NET?"
If you're on Semantic Kernel or AutoGen, now is the time to plan your migration. If you're just getting started — Agent Framework 1.0 is the best possible starting point.
References
- Microsoft Agent Framework Version 1.0 — Official Announcement
- Agent Framework Overview — Microsoft Learn
- Agent Framework GitHub Repository (MIT License)
- Workflow Orchestrations — Microsoft Learn
- Agent Middleware — Microsoft Learn
- Declarative Agents — Microsoft Learn
- Observability — Microsoft Learn
- Golden Triangle: AG-UI, DevUI & OpenTelemetry Deep Dive
- Real-World Example with Agent Framework, Foundry, MCP and Aspire
- Visual Studio Magazine: Microsoft Ships Agent Framework 1.0
Grafana LGTM Stack — Build a Free Observability Platform for Production
API Gateway 2026 — Central Gateway Architecture for Microservices with YARP, Kong, and the BFF Pattern
Disclaimer: The opinions expressed in this blog are solely my own and do not reflect the views or opinions of my employer or any affiliated organizations. The content provided is for informational and educational purposes only and should not be taken as professional advice. While I strive to provide accurate and up-to-date information, I make no warranties or guarantees about the completeness, reliability, or accuracy of the content. Readers are encouraged to verify the information and seek independent advice as needed. I disclaim any liability for decisions or actions taken based on the content of this blog.