Pydantic Founder: Graph Libraries Fail on Type Safety, Parallelism, and Snapshots; Code Is the Architecture
Pydantic founder Samuel Colvin argues that existing graph libraries face an irreconcilable conflict between type safety, parallel execution, and state snapshots. He advocates defining agent workflows in native Python code, executed securely via the sandboxed interpreter Monty, to resolve fundamental flaws in traditional graph architectures.
ImportanceStructurelPreuvesE3 inspectableTraitementStandard
In AI agent development, the debate over whether to use explicit graphs or loops/prompts as the core architecture is intensifying. In his article "The code is the graph," Pydantic founder Samuel Colvin presents a counterintuitive view: traditional graph libraries are a mistake, and the only graph that works is code itself. He argues that while humans writing specific business code is diminishing, developers must shift to higher-level tasks—defining problems, setting metrics and constraints, and making it easy for agents to iterate.
Colvin points out that most popular graph libraries (such as LangGraph or early pydantic-graph) attempt to abstract control flow through nodes and edges, leading to fundamental technical conflicts. He calls this the "CAP theorem for graphs": any developer building a graph agent wants three properties—type safety (ensuring correct data passing between nodes), parallel execution (supporting fan-out and join), and state snapshots (allowing resumption from a breakpoint after a crash). However, existing graph APIs cannot provide all three simultaneously.
The mechanism lies in the fact that when parallel execution is introduced, the "current run location" is no longer a simple node pointer but a set of in-flight nodes and half-filled joins. If multiple nodes modify shared state concurrently, the moment for writing a snapshot becomes ambiguous: some updates may have occurred, others not. To achieve serializable snapshots under parallelism, nodes must stop mutating state directly and instead return change descriptions, which the runtime applies at commit points via merge rules. This breaks type safety because merge rules (like reducers) are typically declared outside node code, and type checkers cannot verify their semantic correctness or cross-field invariants.