Back to Blog

Microsoft Ships Production-Ready Agent Framework 1.0 for .NET and Python

Microsoft just dropped Agent Framework 1.0. If you are suffering from AI-fatigue, I do not blame you. We survived the chaotic October 2025 previews where half the documentation resulted in 404s, the other half was hallucinated by Copilot, and breaking changes were pushed to main on Friday afternoons. We watched Microsoft ship fifteen overlapping AI SDKs in the span of two years, leaving architects paralyzed by choice. We endured Semantic Kernel’s ongoing identity crisis as it tried to figure out what it wanted to be, and we navigated AutoGen’s academic, impenetrable API surface that required a PhD to deploy a simple chat bot. But it is April 2026, and the dust has finally settled. Microsoft has stopped throwing spaghetti at the wall. Agent Framework 1.0 is here, it unifies the best parts of Semantic Kernel and AutoGen under a single cohesive umbrella, and shockingly, it is actually production-ready. This is not just another experimental wrapper around the OpenAI API. It is a fundamental rethinking of how intelligent applications should be built, deployed, and monitored at enterprise scale. Here is the comprehensive rundown of what they built, why the architecture makes sense, and how to use it without wanting to throw your laptop into the nearest body of water. ## The End of the Two-Language Cold War For the past three years, the AI ecosystem has been a bifurcated, frustrating mess. If you wanted to build data pipelines, train models, or write hacky prototypes, you used Python. If you had to maintain a monolithic enterprise backend, orchestrate microservices, or actually pay the bills with secure software, you used .NET. This created a massive friction point. The Python developers had all the cool new libraries, the latest LangChain updates, and native API clients on day one. The C# developers, on the other hand, had to wait six months for a community port that ultimately crashed on edge cases, or they were forced to deploy fragile Python sidecars just to communicate with a language model. Agent Framework 1.0 kills this dynamic permanently. It ships under the unified `Microsoft.Agents.AI` namespace for both .NET and Python simultaneously, guaranteeing feature parity from day one. The core single-agent abstraction is identical across both runtimes. An agent receives context, thinks using a connected LLM, calls tools, and returns a structured response. The abstraction is clean enough to swap providers without touching your business logic, and the serialization formats are identical. A state graph paused in a Python service can theoretically be resumed by a .NET worker. This is the interoperability the industry has been begging for. ## The Core Architecture: Goodbye, Spaghetti Prompts The problem with most LLM wrappers is they assume you want to write raw strings directly to an API endpoint. They treat the LLM as a text-in, text-out calculator. Agent Framework 1.0 treats agents as state machines. You define an agent, give it a system prompt, attach tools (which are just native functions mapped to JSON schemas), and wire it to a connector. The framework handles the JSON schema generation for tool calling, the retry logic for transient 503 errors, and the incredibly tedious task of context window management. When a conversation exceeds the model's maximum token limit, the framework automatically summarizes older turns or gracefully truncates the history based on the strategy you configure. Let's look at the initialization in both languages to see how seamless the developer experience is. ### Python Implementation Installation is standard, utilizing the modular architecture Microsoft adopted: ```bash pip install microsoft-agents-ai pip install microsoft-agents-connectors-openai The Python API is aggressively Pythonic. There are no weird Java-style builder patterns or forced object-oriented gymnastics. It utilizes decorators for elegant tool registration. ```python import os from microsoft.agents.ai import Agent, Tool from microsoft.agents.connectors.openai import OpenAIConnector # Define a native tool using a decorator @Tool(name="get_database_schema", description="Retrieves the schema for a given table to help answer user queries.") def get_schema(table_name: str) -> dict: # Real code would hit Postgres or SQL Server here # We return a dictionary, which the framework automatically serializes to JSON for the LLM return {"columns": ["id", "username", "password_hash", "last_login"]} # Initialize the connector with your credentials and model choice connector = OpenAIConnector( api_key=os.environ.get("OPENAI_API_KEY"), model="gpt-4o" ) # Build the agent, attaching the connector and the tools agent = Agent( name="DBAdmin", instructions="You are a senior database administrator. Use tools to inspect schemas and answer questions accurately. Never guess column names.", connector=connector, tools=[get_schema] ) # Execute the run loop. The framework handles the tool execution automatically. response = agent.run("What columns are in the users table?") print(response.content) ### .NET Implementation On the C# side, Microsoft leaned heavily into `Microsoft.Extensions.DependencyInjection`. If you know ASP.NET Core, this feels exactly like home. It hooks directly into the `ILogger` and `IConfiguration` systems you already use. ```bash dotnet add package Microsoft.Agents.AI dotnet add package Microsoft.Agents.Connectors.OpenAI ``` ```csharp using Microsoft.Agents.AI; using Microsoft.Agents.Connectors.OpenAI; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; var builder = Host.CreateDefaultBuilder(args); builder.ConfigureServices((context, services) => { // Register the connector using the options pattern services.AddOpenAIConnector(options => { options.ApiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY"); options.Model = "gpt-4o"; }); // Register tools as a class. The framework uses reflection to map methods to tools. services.AddAgentTool<DatabaseTools>(); // Register the agent and configure its behavior services.AddAgent("DBAdmin", options => { options.Instructions = "You are a senior database administrator. Use tools to inspect schemas and answer questions accurately."; options.Temperature = 0.2f; // Deterministic responses }); }); var app = builder.Build(); // Retrieve the agent from the DI container var agent = app.Services.GetRequiredService<IAgentProvider>().GetAgent("DBAdmin"); // Run the agent asynchronously var result = await agent.RunAsync("What columns are in the users table?"); Console.WriteLine(result.Content); ``` Notice the parity. You aren't learning two different mental models to deploy the same architecture across your microservices. The concepts map 1:1, drastically reducing the cognitive load on full-stack engineering teams. ## Provider Support: The "Bring Your Own Model" Reality Microsoft knows OpenAI is not the only game in town anymore, even with their massive investment in the company. Customers demand flexibility. They built first-party connectors for the heavy hitters. You do not have to write custom HTTP clients just because your security team suddenly mandated Anthropic over Azure, or because you want to use a highly specialized open-weight model for a specific task. ### Supported Connectors (v1.0 GA) | Provider | Connector Package | Best For | Status | | :--- | :--- | :--- | :--- | | **Azure OpenAI** | `connectors-azure-openai` | Enterprise compliance, VNET integration, Managed Identities | Tier 1 | | **OpenAI** | `connectors-openai` | Bleeding edge models (GPT-4.5, o3) and beta features | Tier 1 | | **Anthropic** | `connectors-anthropic` | Coding tasks, massive context windows (Claude 3.5 Sonnet) | Tier 1 | | **Amazon Bedrock** | `connectors-bedrock` | AWS multi-model architectures and existing AWS spend | Tier 2 | | **Google Gemini** | `connectors-gemini` | Native multimodal input, 1M+ token context windows | Tier 2 | | **Ollama** | `connectors-ollama` | Local development, CI/CD pipelines, air-gapped deployments | Tier 1 | | **Microsoft Foundry**| `connectors-foundry` | Internal MS models, Phi-4 edge deployments | Tier 1 | Swapping from OpenAI to a local Ollama instance for testing is literally a one-line dependency injection change. This alone saves weeks of refactoring when management decides API costs are too high. Furthermore, the framework introduces a `FallbackConnector` that automatically routes requests to a secondary provider (e.g., Anthropic) if the primary provider (e.g., OpenAI) rate-limits your application. ## Enterprise Security and Compliance Integration In the experimental era, developers hardcoded API keys and hoped for the best. Agent Framework 1.0 brings grown-up security primitives to the AI space. On the .NET side, the framework natively integrates with Azure Default Azure Credential and Managed Identities. You no longer need to pass API keys around. The agent running in your Azure Kubernetes Service (AKS) cluster automatically authenticates against Azure OpenAI using its underlying infrastructure identity. Furthermore, the framework implements an interception pipeline. You can register middleware that inspects every prompt before it leaves your network, and every response before it reaches the user. Need to redact Personally Identifiable Information (PII) like social security numbers or credit cards before sending context to Anthropic? You can write a 10-line `IPromptInterceptor` that scrubs the payload using a local regex or a lightweight local NLP model. This is how you pass a SOC2 audit while deploying generative AI. ## The Model Context Protocol (MCP) Integration This is where the framework goes from "nice to have" to "mandatory." Writing custom tools for every single internal API your company uses is tedious and brittle. If an API schema changes, your agent breaks. The Model Context Protocol (MCP) emerged late last year as the open standard for connecting AI models to data sources. Agent Framework 1.0 supports MCP out of the box. You do not write REST clients anymore. You point the framework at an MCP server, and the agent automatically discovers the available tools, prompts, and context resources. ```json // mcp-config.json { "servers": { "internal-wiki": { "command": "node", "args": ["/opt/mcp/confluence-server/build/index.js"] }, "github-repo": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"] }, "postgres-prod": { "command": "docker", "args": ["run", "-i", "--rm", "mcp/postgres", "postgres://user:pass@host/db"] } } } ``` Load that config into your Agent via `services.AddMcpClient("mcp-config.json")`, and it suddenly knows how to search your Confluence wiki, read your GitHub PRs, and query your production database without writing a single line of custom tool code. This is how you scale agents across an enterprise without hiring an army of integration engineers to maintain fragile API glue code. ## Step-by-Step: Building Your First Multi-Agent Support System To truly appreciate the framework, let's walk through building a practical multi-agent system: an automated Customer Support Triage team. We will use the Python SDK for brevity, but the steps are identical in C#. **Step 1: Define the Specialist Agents** You don't want one massive prompt trying to do everything. Break the problem down. We need a Triage Agent to classify the issue, a Technical Agent to solve bugs, and a Billing Agent to handle refunds. ```python from microsoft.agents.ai import Agent triage_agent = Agent( name="Triage", instructions="You read customer emails and decide if they need 'Technical' or 'Billing' help. Only output the department name.", connector=connector ) billing_agent = Agent( name="Billing", instructions="You handle refund requests. Use the `process_refund` tool to issue credits.", connector=connector, tools=[process_refund] ) tech_agent = Agent( name="Technical", instructions="You help users reset passwords and fix login errors. Use the `check_logs` tool.", connector=connector, tools=[check_logs] ) ``` **Step 2: Define the Routing Logic** Now, we need to wire them together. Agent Framework provides routing abstractions. ```python from microsoft.agents.ai.orchestration import HierarchicalRouter, GroupChat # The Triage agent acts as the manager. It reads the input and routes to the workers. router = HierarchicalRouter( manager=triage_agent, workers=[billing_agent, tech_agent], max_turns=3 # Prevent infinite loops ) support_chat = GroupChat(router=router) ``` **Step 3: Execute the Graph** Pass the user's email into the group chat. ```python result = support_chat.start(initial_message="I was charged twice for my subscription this month!") print(result.final_response) # The Billing agent will process this and respond. ``` In three simple steps, you have built an orchestrated, deterministic AI pipeline that routes tasks to specialized LLM instances. ## A2A: AutoGen Finally Grows Up Single agents are cute for chat interfaces, but production systems require multi-agent orchestration. You need a researcher agent gathering data, a coder agent writing the script, and a reviewer agent aggressively critiquing the code until the tests pass. Microsoft took the wild, academic chaos of the original AutoGen project and formalized it into the A2A (Agent-to-Agent) protocol. A2A defines standard communication patterns that are highly controllable: 1. **Sequential Chat:** Agent A finishes its work and hands the strict output to Agent B in an assembly-line fashion. 2. **Group Chat:** Multiple agents in a room, with a deterministic routing manager deciding who speaks next based on the current context. 3. **Hierarchical:** A manager agent delegates sub-tasks to worker agents, aggregates their responses, and delivers a final verdict. Instead of writing brittle while-loops to manage this, you define the topology and let the framework handle the state graph. The framework tracks the entire conversation history, manages token limits across the group, prevents infinite "you go first, no you go first" loops between agents, and halts when a consensus is reached or when the strict token budget evaporates. ## Advanced Memory Management and Persistence If your container restarts mid-thought, a default agent gets amnesia. To solve this, Agent Framework 1.0 introduces the `IMemoryStore` interface, fundamentally splitting memory into "Working Memory" (the current context window) and "Long-Term Memory" (vector databases). You can natively inject vector stores like Qdrant, Pinecone, or Azure AI Search directly into the agent's memory pipeline. ```csharp services.AddAgentMemory(options => { options.UseAzureAISearch(endpoint, indexName); options.ChunkingStrategy = ChunkingStrategy.Semantic; }); ``` When the agent is queried, the framework automatically embeds the user's prompt, queries the memory store, and injects relevant historical context into the prompt before hitting the LLM. It completely abstracts away the RAG (Retrieval-Augmented Generation) pipeline, turning complex semantic search into a background configuration. ## The Bad and The Ugly It is not all perfect. It is still a 1.0 release from Microsoft, and there are rough edges. * **Telemetry is deafeningly noisy:** By default, the OpenTelemetry integration spits out massive traces for every single LLM token chunk and tool call. You will blow out your Datadog or Application Insights budget in an hour if you do not aggressively filter the spans at the collector level. * **Python Typing Errors:** The Python SDK relies heavily on Pydantic under the hood for schema generation. The framework is strict. If you mess up a nested type hint on a tool parameter, the resulting error messages are deeply nested and completely incomprehensible to anyone who isn't a core contributor. * **State Persistence Documentation:** While `IMemoryStore` exists, wiring up Redis or Postgres manually to persist the actual *conversation state graph* (so a paused workflow can survive a server reboot) is tedious, and the documentation for this specific feature is currently very sparse. ## Actionable Takeaways If you are building AI features this year, stop writing raw `HttpClient` wrappers around the OpenAI REST API. You are building technical debt that you will have to rewrite by Christmas. 1. **Standardize on `Microsoft.Agents.AI`:** If you run a mixed .NET/Python environment, this is the only framework that treats both as first-class citizens. Stop making your C# devs use a Python sidecar just to run an agent. 2. **Adopt MCP immediately:** Stop writing custom tools for third-party SaaS apps. Find an open-source MCP server for the service, configure your JSON file, and plug it straight into the framework. 3. **Local Dev with Ollama:** Use the built-in Ollama connector to run your test suites against local models (like `llama3` or `phi-4`). It will save you thousands of dollars in CI/CD API costs and speed up your local test loops. 4. **Wrap the Telemetry:** Before pushing to production, configure your OpenTelemetry exporter to drop raw prompt payloads unless the log level is set to `Debug`. Your compliance officer and your cloud budget will thank you. ## Frequently Asked Questions (FAQ) **Q: Is Agent Framework 1.0 going to replace Semantic Kernel entirely?** A: Microsoft has stated that Agent Framework 1.0 is the evolution of Semantic Kernel. While existing SK packages will remain supported for bug fixes, all new feature development, including advanced A2A orchestration and MCP support, is happening inside the new `Microsoft.Agents.AI` namespace. Migration is highly recommended. **Q: Can I use open-source models hosted on my own infrastructure?** A: Absolutely. The framework is entirely model-agnostic. You can use the `connectors-ollama` package for local execution, or use the generic OpenAI-compatible connector to point the framework at standard vLLM or LM Studio servers running on your private hardware. **Q: How does the framework handle API rate limits and downtime?** A: The connectors implement robust resilience patterns using Polly (in .NET) and Tenacity (in Python). You can configure exponential backoff, jitter, and automatic failover. For example, you can instruct the framework to attempt a request with Azure OpenAI, and if it receives a 429 Too Many Requests error, automatically retry against standard OpenAI or Anthropic. **Q: Does it support streaming responses?** A: Yes, streaming is a first-class citizen. Both the Python and .NET SDKs support asynchronous generators and `IAsyncEnumerable`, allowing you to stream tokens directly to your frontend UI via WebSockets or Server-Sent Events (SSE) while the agent is still processing tool calls in the background. **Q: Are there licensing costs associated with the framework?** A: No. Agent Framework 1.0 is completely open-source and released under the MIT License. You only pay for the API calls you make to external providers like OpenAI or Anthropic, or the compute costs of hosting your own models. ## Conclusion The release of Microsoft Agent Framework 1.0 marks the end of the experimental phase of Generative AI development and the beginning of the engineering phase. By providing a unified, cross-language abstraction for tools, memory, routing, and telemetry, Microsoft has given developers the robust foundation needed to build reliable AI systems. While there are still minor growing pains regarding telemetry noise and documentation gaps, the architectural decisions here are universally sound. The integration of the Model Context Protocol (MCP) and the formalization of Agent-to-Agent (A2A) orchestration are massive leaps forward. Agent Framework 1.0 is boring, predictable, and heavily structured. In the chaotic, fast-moving AI space, "boring and predictable" is exactly what enterprise engineering teams need right now. Get to work.