I built the same one-tool weather agent in Pydantic AI 2.54.0 and Microsoft Agent Framework (MAF) 1.19.0 and ran each five times against a local qwen3.5:4b model on an 8 GB MacBook Air M1. Both called the tool correctly in 5 of 5 runs, and the median agent latency (8.14 s against 9.98 s) mostly measured the model, not the framework. The differences that showed up were install weight and API churn: MAF pulled in 205 packages and 496 MB against Pydantic AI's 97 packages and 118 MB, and a MAF script written from older examples failed on its first import.

So Pydantic AI vs Microsoft Agent Framework is a choice between portability and an enterprise platform, not between a framework that works and one that does not. Pick Pydantic AI if you want a typed Python agent service that can move between model providers. Pick Microsoft Agent Framework if you deploy on Azure and want Microsoft's supported successor to AutoGen and Semantic Kernel. Pydantic AI is the typed, provider-portable Python option. Microsoft Agent Framework 1.0 is the production-ready .NET and Python framework that unifies the AutoGen and Semantic Kernel foundations, with multi-provider model support, MCP, A2A, and Azure or Foundry deployment paths. The deciding question is whether Microsoft deployment and migration support matter more to you than staying portable.

The short version of the tradeoff: Pydantic AI bets on typing and validation first, while MAF bets on Azure-native breadth and enterprise tooling.

Pydantic AI vs Microsoft Agent Framework at a glance

DimensionPydantic AIMicrosoft Agent Framework
Typing and validationType-safe by design, Pydantic models validate every input and outputTyped via .NET and Python SDKs, validation is opt-in per component
Model accessModel-agnostic (OpenAI, Anthropic, Gemini, others)Multi-provider but Azure OpenAI-first; also OpenAI, Anthropic, Bedrock, Gemini, Ollama
MCP supportYes, documented on PyPIYes, native since 1.0
A2A supportCommunity pattern, not a first-party primitiveYes, native protocol support since 1.0
Multi-agent orchestrationLightweight, code-first compositionNamed patterns: sequential, concurrent, handoff, group chat, Magentic-One
Migration path from AutoGenRewrite (different design philosophy)Official first-party migration guide
Version policyPin and test the Pydantic AI package before comparing behaviorMAF 1.0 has stable APIs, but review preview connectors before production

The rows come from the two MAF announcements and the Pydantic AI package page. The sections below explain each one.

What is Pydantic AI?

Pydantic AI is a Python agent framework built by the team behind the Pydantic validation library. It treats every agent input and output as a typed, validated object rather than a loosely structured string, which is why teams choose it when correctness matters more than flexibility. Its package page describes it as model-agnostic and MIT-licensed, and it requires Python 3.10 or newer.

Pydantic AI does not sit still. Version 2.13.0 shipped July 18, 2026, continuing a near-weekly cadence that started with the 1.0.0 release on September 5, 2025. It integrates with Pydantic Logfire for observability and documents Model Context Protocol (MCP) support directly on its package page, so an agent can call external tools and data sources through the same protocol MAF uses.

The core idea is simple: define an agent's expected output as a Pydantic model, and the framework rejects or retries any response that does not match the schema. That makes Pydantic AI a natural fit for teams already using Pydantic elsewhere in a Python codebase, since agent outputs get the same validation guarantees as any other typed data structure in the app.

What is Microsoft Agent Framework?

Microsoft Agent Framework, usually shortened to MAF, is Microsoft's unified agent SDK for .NET and Python. It reached 1.0 general availability on April 3, 2026, unifying the foundations of two earlier Microsoft projects: AutoGen, the research-oriented multi-agent framework, and Semantic Kernel, the enterprise orchestration SDK. Microsoft ships migration guides for teams coming from either one. As Shawn Henry, Principal Group Product Manager on Microsoft Agent Framework, put it in the 1.0 announcement, the framework "gives you enterprise-grade multi-agent orchestration, multi-provider model support, and cross-runtime interoperability".

At Build 2026, Microsoft added three production features to MAF: Agent Harness (shell access, human-in-the-loop approvals, automatic context compaction), Foundry Hosted Agents (scale-to-zero deployment with VM-isolated sessions), and CodeAct, where the model writes one short Python program instead of chaining individual tool calls. Microsoft's own benchmark on multi-step workloads showed CodeAct running 52.4% faster (27.81 seconds to 13.23 seconds) and using 63.9% fewer tokens (6,890 to 2,489) than the sequential-call pattern it replaces.

Two more pieces reached 1.0 in the same release: GitHub Copilot SDK integration for coding-oriented agents, and a dedicated handoff orchestration pattern for multi-agent routing, where one agent hands a task to another with full context. A browser-based DevUI debugger also ships in preview, giving teams a visual trace of agent decisions during development.

Typing and model access: where the two diverge

Pydantic AI's whole design starts from validation. Every tool call and every structured output gets validated against a Pydantic model before your code ever sees it, and the framework does not care which model provider generated the response. That model-agnostic stance is deliberate: you can swap Anthropic for OpenAI or Gemini without rewriting your agent logic.

MAF takes the opposite default. It defaults to Azure OpenAI but is not locked to Azure: per the 1.0 announcement, it also connects to OpenAI, Anthropic, Amazon Bedrock, Google Gemini, and Ollama, six model providers in all. Its tooling, hosting, and support story still assume an Azure-centric deployment. This is also where MAF succeeds Semantic Kernel specifically. Teams that once compared "pydantic ai vs semantic kernel" for enterprise orchestration are now comparing Pydantic AI against MAF, because Semantic Kernel's enterprise features folded into the unified framework.

Both frameworks are typed in the sense that they ship SDKs with type hints, but only Pydantic AI enforces validation as a first-class runtime behavior. MAF's .NET and Python SDKs give you compile-time or IDE-level typing on the plumbing. Whether a given agent output gets validated against a schema is still something you configure per component, not a default the framework imposes on every response.

MCP, A2A, and multi-agent orchestration

Both frameworks now speak the Model Context Protocol (MCP), the open standard for connecting an agent to external tools and data sources, and the Agent-to-Agent (A2A) protocol, which lets independently built agents interoperate across runtimes. The A2A support differs in kind, though: MAF has had native protocol support since 1.0, while in Pydantic AI it is a community pattern rather than a first-party primitive. Even so, the overlap closes a gap that existed through most of 2025, so tool and cross-agent interoperability is no longer the differentiator it was. Keep in mind that MCP connects tools and data; it does not replace document retrieval, which is a separate decision covered in the MCP vs RAG comparison.

Where the two still differ is orchestration maturity. MAF ships named, first-class patterns: sequential, concurrent, handoff, group chat, and Magentic-One (a research-derived pattern where a lead agent plans and delegates subtasks to specialist agents), plus a graph-based workflow engine with checkpointing so a long-running workflow can resume after a failure. Pydantic AI leans lighter, composing multi-agent behavior in code rather than through named topology primitives. That means more control, but more boilerplate for complex handoffs.

CodeAct is MAF's clearest orchestration-efficiency argument. Letting the model write one program instead of looping through individual tool calls cut both latency and token spend by more than half in Microsoft's own test, and the generated code runs inside Hyperlight micro-VM isolation so it cannot touch the host directly.

Migrating from AutoGen into each framework

If your team is already on AutoGen, the paths diverge sharply. MAF's migration guide exists because MAF is architecturally AutoGen's successor: your agent definitions and orchestration patterns carry over with documented API mappings. AutoGen remains available, but new feature investment now flows into MAF.

Moving AutoGen code to Pydantic AI is a different kind of project. There is no official migration guide because the two frameworks do not share a design lineage. You are rewriting agent logic around Pydantic models and validated tool signatures, not porting orchestration graphs. Teams choose this path when the destination, type safety and provider independence, matters more than migration speed.

The same asymmetry applies to Semantic Kernel. MAF absorbed SK's enterprise orchestration concepts directly, so an SK migration is closer to an upgrade than a rewrite. Pydantic AI has no equivalent lineage with either legacy framework, so any move from AutoGen or SK into Pydantic AI should be budgeted as new development, not a port.

Which should you pick

Decision rule: if your organization already standardizes on Azure and wants a vendor-supported successor to AutoGen or Semantic Kernel, pick Microsoft Agent Framework. If you want a framework-agnostic Python stack with validation baked into every agent boundary, and you are willing to trade a slower migration for long-term portability, pick Pydantic AI. Neither is objectively better; the decision follows your existing stack and how much you value portability against managed enterprise tooling.

My hands-on run did not change that rule, but it sharpened two parts of it. First, the basic agent loop is not a differentiator: both frameworks reached a local Ollama model through its OpenAI-compatible endpoint and called the tool correctly every time, and the latency gap sat inside the run-to-run spread. Second, the cost of MAF's breadth shows up before you write any code. The agent-framework meta-package installed 205 packages and 496 MB of site-packages, including 29 agent-framework-* subpackages, against 97 packages and 118 MB for Pydantic AI. Its Python API has also moved since the examples many tutorials still show, so I would pin the exact MAF version and read the current docs rather than copy older snippets. If you are a small Python team with no Azure commitment, those two points tip me further toward Pydantic AI. If you are on Azure, the footprint is a one-time cost and MAF's migration and hosting story still wins.

Observability follows the same split. Pydantic AI hands off to Pydantic Logfire, a smaller, framework-native tracing tool documented on its PyPI listing. According to the Build 2026 announcement, MAF wires into Application Insights and OpenTelemetry by default, which is heavier to set up but sits inside a monitoring stack an Azure team likely already runs. Team size matters too: a solo builder or small Python team gets moving faster with Pydantic AI's four-line quickstart, while a platform team standardizing agent deployment across an org gets more out of MAF's Foundry Hosted Agents and scale-to-zero pricing.

The same one-tool agent in both frameworks

To see how the two feel in practice, I wrote the smallest agent that still exercises tool calling: one tool, get_weather(city), that returns a fixed result ({"city": city, "temp_c": 18, "condition": "cloudy"}), and one question, "What is the weather in Paris right now?". Both agents talk to Ollama through its OpenAI-compatible /v1 endpoint, so the model, prompt, and tool are identical and only the framework changes. The listings below are exactly what ran, and the Pydantic AI script and MAF script are published unedited.

Pydantic AI (agent_pydantic.py):

import json, os, time

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.openai import OpenAIProvider

CALLS = []
model = OpenAIChatModel(
    os.environ.get("MODEL", "qwen3.5:4b"),
    provider=OpenAIProvider(base_url="http://localhost:11434/v1", api_key="ollama"),
)
agent = Agent(model, instructions="Use the get_weather tool to answer weather questions.")


@agent.tool_plain
def get_weather(city: str) -> dict:
    """Return the current weather for a city."""
    CALLS.append(city)
    return {"city": city, "temp_c": 18, "condition": "cloudy"}


t0 = time.time()
result = agent.run_sync("What is the weather in Paris right now?")
print(json.dumps({"calls": CALLS, "answer": result.output, "latency_s": round(time.time() - t0, 2)}))

Microsoft Agent Framework (agent_maf.py):

import asyncio, json, os, time

from agent_framework import Agent
from agent_framework.openai import OpenAIChatCompletionClient

CALLS = []


def get_weather(city: str) -> dict:
    """Return the current weather for a city."""
    CALLS.append(city)
    return {"city": city, "temp_c": 18, "condition": "cloudy"}


async def main():
    client = OpenAIChatCompletionClient(model=os.environ.get("MODEL", "qwen3.5:4b"),
                                        base_url="http://localhost:11434/v1", api_key="ollama")
    agent = Agent(client, instructions="Use the get_weather tool to answer weather questions.",
                  tools=[get_weather])
    t0 = time.time()
    result = await agent.run("What is the weather in Paris right now?")
    print(json.dumps({"calls": CALLS, "answer": result.text, "latency_s": round(time.time() - t0, 2)}))


asyncio.run(main())

The shapes differ in small ways. Pydantic AI registers the tool with a decorator on the agent and offers a synchronous run_sync, while MAF takes plain functions in a tools=[...] list and runs async. In code size they came out even: 18 non-blank, non-comment lines for Pydantic AI and 17 for MAF, counting the tool, prints, and timing.

MeasurePydantic AIMicrosoft Agent Framework
Install commanduv pip install pydantic-aiuv pip install agent-framework
Version installed2.54.01.19.0
Packages installed into a fresh venv97205
site-packages size118 MB496 MB
Tool-call success5 of 55 of 5
Median agent run latency (min to max)8.14 s (7.89 to 11.65)9.98 s (6.85 to 12.41)
Median whole-process wall time10.18 s10.95 s
Median import time, 3 runs1.47 s0.52 s
Banner printed to stderr5 of 5 runsnone

A run counted as a success only when the process exited 0, get_weather was called exactly once with "Paris", and the answer contained 18. Every run of both agents met that bar. The latency ranges overlap heavily, so I read the gap between the medians as noise from a small local model, not as one framework being faster. Pydantic AI took longer to import (1.47 s against 0.52 s), which matters for short-lived CLI tools or cold-started functions more than for a long-running service.

Two hurdles came up, and both are worth knowing before you start.

  • MAF's API has moved: my first MAF script followed older examples that use ChatAgent and OpenAIChatClient(model_id=...). On 1.19.0 it failed immediately with ImportError: cannot import name 'ChatAgent' from 'agent_framework' ... Did you mean: 'RawAgent'?. The working version uses Agent(client, instructions=..., tools=[...]) with OpenAIChatCompletionClient(model=...). PyPI already listed 1.20.0 the same day while uv resolved 1.19.0, so pin the version you test against.
  • Pydantic AI prints an observability banner: every Pydantic AI run wrote a multi-line Logfire banner to stderr, advertising tracing setup. It is harmless, but it clutters logs and CLI output. The banner itself says it goes away once observability is on or when you set PYDANTIC_AI_NO_BANNER=1.

This run covers only the simplest piece of a real evaluation. Before you commit, build the same three things in each framework: one typed tool call that hits a validation failure, one handoff or multi-agent step, and one trace export. Record how each framework recovers from the failure, which model and provider combinations work, and how the workflow fits your existing Azure or Python stack. A broad framework roundup, this one included, cannot answer those integration questions for your team.

How I tested this

  • Machine: MacBook Air with an Apple M1 and 8 GB of unified memory, with desktop apps open during the runs.
  • Date: October 4, 2026.
  • Model server: Ollama 0.35.1 serving qwen3.5:4b through its OpenAI-compatible /v1 chat completions endpoint on localhost.
  • Frameworks: two fresh uv virtual environments on Python 3.12. uv pip install pydantic-ai resolved pydantic-ai 2.54.0; uv pip install agent-framework resolved agent-framework 1.19.0 with agent-framework-core 1.19.0. Both pulled in the openai SDK 3.24.0.
  • Protocol: each agent ran 5 times, one Python process per run, with the model already warm. Latency is the wall time of the agent run call; process wall time includes imports. Import time is the median of 3 runs of python -c importing the agent and OpenAI client classes. Package counts come from uv's "Installed N packages" line, and sizes from du on site-packages. The two installs ran at the same time, so I did not compare install times.
  • Not tested: MCP servers, A2A, multi-agent workflows and handoffs, structured output with validation failures, tracing through Logfire or Application Insights, the .NET SDK, Foundry hosting, and cloud models such as Azure OpenAI. Five runs on one small local model is enough to show that the basic tool loop works in both, not to rank their speed.
  • Raw record: the per-metric results are published at https://www.agenticwire.news/benchmarks/pydantic-ai-vs-microsoft-agent-framework/results.json.

References