Build1 distinct publisher2 min readUpdated
A dev.to walkthrough of the run graph finds one append-only history per run, copied whole into each model call. The step count sets the exponent; your tool outputs set the price.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
A four-step run sends ten copies of the history in total; a twelve-step run sends seventy-eight [1]. That is 7.8 times the payload, against the four times the dev.to post uses as its worked illustration [10][2]. The exponent is structural. The coefficient is not, and it lives in two places the run graph does not control.
The first is caching. The post's own pricing buckets put cache-write at roughly 1.25 times input and cache-read at about a tenth [11]. An append-only prefix that never changes is the friendliest possible input to a prompt cache, so where the provider actually serves it, the growth continues at something like a tenth the rate [3]. Prefix hit rate, not step count, is then the number worth wiring to a dashboard.
The second is what gets copied. The post quotes `messages[:] = _clean_message_history(ctx.state.message_history)` and does not say what that call strips [5]. Read strictly, the evidence supports history accumulating and being sliced whole into each step [2][4]; it does not establish that nothing ever leaves the wire before the request goes out.
The escape hatch is real, and it sits outside the loop. Every run method accepts a `message_history` argument, documented as the conversation so far, and `result.all_messages()` hands the transcript back [6], so between turns you choose what to replay. Within a single deep tool loop the author's own position is that the re-send is inherent to how tool calling works and true of every framework [7]. There is nothing to patch, then. What remains is a sizing question about tool outputs and loop depth, and that question belongs to whoever wrote the tools.
One source, and an interested one: the post closes by recommending the author's own npm package for turning real usage into a per-run dollar figure [11]. The mechanism does not lean on that, because it rests on quoted lines from `_agent_graph.py` in `pydantic_ai_slim` on main [14], which anyone can open and check against the version they actually installed. The 4x does lean on it, being an output of the tooling rather than of the arithmetic [10]. Take the exponent as documented and the multiplier as yours to measure.
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The author says he read the run graph in pydantic_ai_slim/pydantic_ai/_agent_graph.py on main to determine what the model receives on each pass of the loop.
The post quotes the line messages[:] = _clean_message_history(ctx.state.message_history) but does not state what that function removes.
A run of n steps sends roughly 1 + 2 + 3 + ... + n copies of history, which the author describes as O(n squared) cumulative tokens in the step count; a 3-step agent is fine, a 12-step agent that reads a couple of files is not, because each file's contents rides along on every later step.
Pydantic AI gives a typed agent: define an Agent, hand it tools, call agent.run(...), and it loops through model call and tool call until it produces a validated result.
Each run holds a single mutable conversation list on its state, message_history: list[_messages.ModelMessage], and on every model step the graph appends the outgoing request and then the model's response to it.
Nothing is removed from the list; it only grows, with tool calls and tool outputs riding inside those messages, and the heaviest passengers are usually the tool outputs such as search results, file contents and API responses.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Verbatim code quotes, one unpinned self-report, zero measurements
The mechanism claims are unusually specific for a single-source post: a named file, a quoted dataclass field, two append calls, the slice copy and the message_history signature, all internally consistent. But everything rests on one author's reading of a moving 'main' branch with no commit pin, no upstream doc or maintainer confirmation, and one quoted line (_clean_message_history) is left unexplained even though it sits between the history and the wire. No token count, dollar figure or profiled run is presented anywhere.
Existence of two self-published artifacts, no usage data
The only adoption-adjacent facts are the author's disclosure that his own npm package and Apache-2.0 GitHub Action exist and are versioned. There are no downloads, stars, deployments, third-party users, or reports of any Pydantic AI team encountering or mitigating the described cost pattern, so uptake cannot be scored without inventing facts.
Mechanism plausible, cost framing overstated
The structural finding is modest and largely conceded to be universal, yet the framing escalates to 'quadratic by design' and a 'silent 4x' reaching production. Three specifics push this positive: the post's own summation implies about 7.8x rather than 4x for 12 versus 4 steps; the cache-read multiplier it itself lists (~0.1x) would cut most of the re-sent prefix cost it prices at full rate; and the author states in the same piece that in-loop re-sending is inherent to every framework, which undercuts singling out Pydantic AI. No measured run supports the cost claim.
Problem statement terminates in the author's own paid-attention tooling
The post diagnoses a cost problem and then routes readers to two artifacts the author owns: the @wartzar-bee/tokenscope npm package (with install command) and the wartzar-bee/ci-guardrail GitHub Action (with a copy-paste workflow snippet). The scoped package name and repo owner match the publishing handle, and no ownership disclosure is made in the body. That is a strong promotional incentive to present the mechanism as costlier and less mitigated than the post's own caching and API-lever details imply.
Mechanism direction credible, magnitude and provenance thin
Confidence is moderate for the qualitative mechanism - the quoted code is specific and self-consistent, and the message_history lever is documented in the quoted signature - but low for anything quantitative. One publisher, one self-interested author, an unpinned branch read, an unexplained cleaning step, no measured run, and an internal arithmetic inconsistency together cap how much of this can be relied on without independent verification against a pinned release.
build
Microsoft ships an MIT-licensed agent kernel: policy rings, Ed25519 identity, kill switch1 distinct publisher
build
A 27B Apache-2.0 model in 17GB makes local inference a wiring decision, not a demo1 distinct publisher
build
Test count told you nothing about the merge gate; 17 attempts to beat it told you something1 distinct publisher
build
Three manual interventions in a month, and every guard was working as designed1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 22, 2026