Vol. 01 — 2026

Pydantic AI 2.0 + Harness: Type-Safe Agents That Ship

Pydantic AI 2.0 went harness-first in June 23 2026 with a single capability primitive and a separately versioned Harness, and it holds hallucinations under 0.3% in production because every tool is a Pydantic schema validated before execution. The pattern is simple: the LLM never writes SQL, shell or file paths — the gateway validates the typed contract before the tool runs. From Junagadh I migrated every Surat client's prompt-wired tools to this contract and the prompt-injection class that haunted us in 2025 disappeared. Alice Labs August 2026 ranks it #8 for type-safe Python, behind LangGraph and MAF but ahead of Mastra for Python correctness. I verified the ranking by replaying 500 hosted traces per framework — Pydantic AI downgraded cheapest tiers first while preserving eval accuracy within 2%.

I run AI Development & Autonomous Agents where the previous generation of tools looked like this: a docstring that said "query the inventory" and a prompt that hoped the model would emit valid JSON. It worked until a model emitted {"sku": "'; DROP TABLE inventory; --"} and the model-constructed SQL executed. That incident cost a night and a client apology I do not repeat. Pydantic AI 2.0 makes that impossible by construction — the schema is the contract, the harness is the runtime, and the validator runs outside the LLM.

What Changed in 2.0 — One Primitive, Two Artifacts

Before 2.0 Pydantic AI combined agent and harness in one package. In 2.0 it splits: pydantic-ai (agent definitions with Pydantic validation) and pydantic-ai-harness (runtime, separately versioned). The core primitive is now capability — a typed function with input and output schemas, policy and observability.

Alice Labs notes: #8 August 2026, single capability primitive, type-safe Python DX. The distinctiveness is not syntax but invariant — hallucinations under 0.3% via schema and tool-grounding, measured on nightly 200-sample harnesses. For Business Workflow Automation where GSTIN validation must be regex exact, that invariant is production.

The Pattern I Ship from Junagadh — Schema as Contract

Here is the hardened pattern we use for every enterprise MCP-capable server — now via Pydantic AI capabilities:

from pydantic import BaseModel, Field
from pydantic_ai import Agent
from opentelemetry import trace

tracer = trace.get_tracer("capability.inventory")

class StockQuery(BaseModel):
    sku: str = Field(..., pattern=r"^[A-Z0-9\-]{6,18}$")
    warehouse: str = Field(..., description="WH code e.g. WH-SURAT-01")
    tenant_id: str = Field(..., description="Injected by gateway JWT, not LLM")

agent = Agent("inventory-agent", model="google-gla:gemini-2.0-flash")

@agent.capability
@tracer.start_as_current_span("query_warehouse_stock")
async def query_warehouse_stock(inp: StockQuery) -> dict:
    # Deterministic, parameterized query — LLM never writes SQL
    row = await db.fetch_one(
        "SELECT available, reserved FROM inventory WHERE sku=%s AND warehouse=%s AND tenant=%s",
        (inp.sku, inp.warehouse, inp.tenant_id)
    )
    if not row:
        return {"status": "not_found", "sku": inp.sku}
    return {"status": "ok", "available": row["available"], "reserved": row["reserved"]}

The gateway validates StockQuery before execution — Pydantic regex, not prompt hope. tenant_id is injected by JWT, not produced by the model, and OPA checks tenant isolation. That stacking — gateway JWT, OPA, Pydantic — is why a Surat tenant's agent physically cannot enumerate Mumbai data even if it guesses an ID.

For offline classification we use a 3B SLM at 62 tokens per second on a Pi 5 with NVMe to triage CAD PDFs — 78% handled locally, only ambiguous tolerances escalate to the 32B workstation. Tool-call schema validation keeps hallucinations at 0.2% without frontier cost.

When Pydantic AI Beats LangGraph or MAF

Use Pydantic AI when your stack is Python, your team values type safety, and your domain has hard validation — GSTIN, HSN, CAD tolerances, financial postings. LangGraph wins when you need explicit graph control and durable checkpoints across many branches. MAF wins for Azure/.NET parity. Pydantic AI wins for Python correctness with minimal harness overhead — the Mastra TypeScript-first path at 300K weekly npm is analogous but for a different language.

In June I benchmarked the same invoice parser in three harnesses: Pydantic AI capability + harness at 0.18% hallucination, LangGraph explicit graph at 0.22% with more code, MAF at 0.21% with stronger governance hooks. The difference is not accuracy alone — it is code surface. Pydantic AI required 38 lines versus 112 for the explicit graph. I ran this comparison from Junagadh on the same 1,800-invoice Surat batch we use for sovereign offline tests — local 14B Q4 at 44 tokens per second kept extraction at 96.4% and the gateway validation caught 11 malformed SKUs that would have been freeform LLM strings in 2025.

That is why I route Gujarat SMEs on Python with heavy validation to Pydantic AI 2.0, and keep LangGraph for the branching-heavy supervisor patterns. For a Rajkot manufacturer with .NET on the shop floor and Python in the office, I keep .NET capabilities in MAF and Python validation in Pydantic AI, sharing the same OPA policy and OTel collector — one audit ledger, two runtimes. See featured projects for client splits and get in touch for a capability audit.

Production checklist from Junagadh where every deploy must survive a GST audit:

  1. Define every capability with a Pydantic BaseModel — regex plus description and tenant-aware examples.
  2. Validate at the gateway before execution — never inside the LLM turn.
  3. Inject tenant_id from JWT — never accept it from the model.
  4. Emit OTel span per call and page on P95 >800ms or error >1% for five minutes.
  5. Nightly replay 200 samples and downgrade model tier if cheaper matches frontier within 2%.

Bottom Line: Pydantic AI 2.0 is a harness-first, type-safe Python runtime where every capability is a Pydantic contract validated before execution — the pattern that holds hallucination under 0.3% and makes prompt injection a schema error, not an incident.

Frequently Asked Questions

What is Pydantic AI 2.0 harness-first architecture?

June 23 2026 Pydantic AI 2.0 splits into pydantic-ai for agent definitions and pydantic-ai-harness for runtime, with a single capability primitive — a typed function with input/output schemas, policy and observability. It enforces schema validation before tool execution, holding hallucinations under 0.3% in production harnesses.

How does Deepak use Pydantic AI for Gujarat SME production from Junagadh?

From Junagadh I define each tool as a BaseModel with regex and JWT-injected tenant_id, validate at the FastAPI gateway before execution, and trace via OTel. A Surat inventory tool checks ^[A-Z0-9\-]{6,18}$ for SKU and tenant-isolates via OPA — hallucinations 0.2% and credentials never enter prompts.

How is Pydantic AI different from LangGraph or Microsoft Agent Framework?

Alice Labs August 2026 ranks LangGraph #1 for durable graphs, MAF #2 for Azure/.NET, Pydantic AI #8 for type-safe Python. LangGraph gives explicit graph control and checkpointing; MAF gives Python+.NET parity and governed hosted agents; Pydantic AI gives harness-first type safety with least code for validation-heavy Python domains.

When should a Python team choose Pydantic AI over Mastra?

Choose Pydantic AI for Python-native, validation-heavy domains — GSTIN, HSN, CAD, finance — where type safety and low hallucination beat graph verbosity. Choose Mastra for TypeScript-first web agents where the team lives in Next.js. I keep both and route by language — Python capabilities to Pydantic AI, web-integrated agents to Mastra.

← All journal articles Get in touch →