Artificial intelligence news.
Straight from the original announcements.

Pydantic: Graph Libraries Are a Mistake, Because Code Is the Graph

October 13, 2026, 11:00Source: Pydantic
Pydantic: Graph Libraries Are a Mistake, Because Code Is the Graph
Image: Pydantic

Pydantic argues that graph libraries for AI agents are a mistake and that the only workable graph is code itself. In an article titled "The code is the graph", the company says plain async Python gives type safety, parallel execution and durability without a separate graph abstraction.

Key points
  • Pydantic argues graph libraries for agents are a mistake and that code itself is the graph.
  • Fan-out, join and branch map directly onto asyncio.gather, if and for in typed Python.
  • The author claims graphs cannot offer type safety, parallelism and snapshots together, because merging parallel state is a semantic step no type system checks.
  • Pydantic built Monty, a sandboxed Python interpreter that can snapshot and resume at every external function call.
  • Durable execution comes from Temporal outside the sandbox and Monty inside it, according to Pydantic.

Plain Python instead of nodes and edges

The article responds to a recent debate over whether agents should be driven by prompting or by graphs and loops. According to Pydantic, some argue that prompting is over and that graph engineering will become the default architecture for serious agentic systems within six months. The author says he agrees with half of that: humans writing code is going away, and developers will instead formulate the problem, choosing the metrics an agent should optimize and the constraints it must respect.

The other half, he writes, is wrong. Graphs as most people know them, meaning nodes and edges handed to a library that walks them, are in his view a mistake. He says this as someone who built a graph library, pydantic-graph, and he notes he first wondered whether his view was just a reaction to his dislike of LangGraph and its disregard for type safety. He now says he is convinced it is not.

The example in the article is a function, review_comments, that fans out sub-agents with asyncio.gather, collects their issues, and branches to a summarizer if any were found. Pydantic describes this as a graph and also a Python function: the type checker ty verifies that the summarizer accepts the issues, the call stack is the run state, and a model can write it in one tool call.

Why graph libraries fight the call stack

The core argument is that a program already has state: variable values, the point execution has reached, and the calls waiting to return. A graph library adds a second representation of that state which must be kept consistent with the code. Pydantic maps the constructs one to one: if is a branch, for is a loop, a function call is an edge, and await asyncio.gather(...) is a fan-out and a join. The call stack, stack traces, debugger, profiler and type checker already exist for this, and, in the author's words, every programmer and every model already knows it.

To illustrate, the article compares a fan-out example from the pydantic-graph docs with the same program in plain Python. The graph version uses GraphBuilder, a state dataclass, decorated steps, a join with a reducer and explicit edges. The plain version is a short square function and one asyncio.gather call. According to Pydantic, the second is typed with nothing added, can take a breakpoint, and is readable in seconds by a human or a model.

The author keeps a role for diagrams: they are useful as something drawn about the code, which is why pydantic-graph renders Mermaid. The mistake, he says, is making the drawing the thing that executes. He adds that the control flow an agent needs is rarely known before a run, and that a fixed graph wired up by a human in advance is "a prompt with extra steps".

A CAP theorem for graphs

Pydantic frames the trade-off as a triangle: type safety, parallel execution and snapshots of graph state so a crashed run can resume from the last node. The author says he has not found a graph API that offers all three and does not think one can exist.

His reasoning centers on state. In the original pydantic-graph, a snapshot was the state plus the next node, which worked because only one node ran at a time. With parallelism, "where we are" becomes a set of in-flight nodes and half-filled joins, with several nodes mutating the same state object. A snapshot taken mid-run may capture only some of a node's updates, so resuming can run an update twice or never. Snapshotting only at barriers risks losing a step on a crash, and re-running in-flight nodes is unsafe because the runner cannot know whether a node already touched the outside world, such as sending an email.

The fix is for nodes to return a description of a change that the runtime applies at a commit point. That requires an order-independent merge rule per field, declared outside the node code. The checker can verify the rule's signature but not that it is commutative, nor that cross-field invariants hold after partial updates. Joining outputs is fine, the author says, since gather returns a typed tuple. Joining state is the problem.

He places existing systems on the triangle's sides:

  • Parallel and snapshotted: LangGraph, where nodes return updates, a checkpoint is written after every super-step, and reducers declared in an Annotated type hint merge writes. The merge itself stays out of the type checker's reach.
  • Typed and snapshotted: the original pydantic-graph, which was sequential.
  • Typed and parallel: pydantic-graph today, without snapshots.

Monty and Temporal as the runtime

If agents write the graph as code, the question becomes how to run that code. Pydantic's answer is Monty, a sandboxed Python interpreter built for this purpose. According to the article, Monty runs the code safely and can snapshot and resume at every external function call, which in the review example would be the reviewer and summarize sub-agents.

The article's summary lists where each property comes from: type safety from type hints, parallel execution from async, and durable execution from Temporal outside the sandbox and Monty inside it. The text provided breaks off before the author finishes describing the alternatives he tried, so details beyond this are not covered here.

For developers building agents, the message from Pydantic is to treat ordinary typed Python as the orchestration layer and keep graph diagrams as documentation rather than as the execution engine.

Source
Pydantic: The code is the graph

Related news

Pydantic benchmark: code mode roughly halves cost on long agent tasks
ResearchOctober 28, 2026, 10:00

Pydantic benchmark: code mode roughly halves cost on long agent tasks

Letting a model write a short program instead of calling tools one at a time cut cost by 58% and wall time by 51% on long tasks, according to a benchmark published by…

Pydantic maintainer wins AAIF award for MCP Python SDK work
For developersOctober 27, 2026, 10:00

Pydantic maintainer wins AAIF award for MCP Python SDK work

A Pydantic developer who maintains the MCP Python SDK has received the Outstanding Technical Contribution Award from the Agentic AI Foundation. The award was presented…

AI21 Cuts GitLab Duo Code Review Cost by 98% by Tuning Its Harness
ResearchOctober 22, 2026, 13:26

AI21 Cuts GitLab Duo Code Review Cost by 98% by Tuning Its Harness

AI21 Labs says it cut the cost of GitLab Duo Code Review by 98% on Martian's Code Review Bench without losing review quality. According to the company, all of the saving…