Prompt Is Not Runtime - xg.li
xg.li
SubscribeSign in
Prompt Is Not Runtime<br>LLMs shouldn't replay workflows. They should edit intent.
xg.li<br>May 23, 2026
Share
One afternoon in mid-April, product pinged us: the ad-launching agent had been spinning for twenty-plus minutes without success, spawning a pile of non-compliant campaigns along the way. Also, could I please add support for a finance app right now?<br>I work on launch infrastructure. The parameter support was easy enough. But when I looked at how the bot team had wired ad-launching into the agent, I found something else:<br>a 600-line markdown file.<br>Inside:<br>Parameter combinations for each objective
Per-error-code recovery branches
Cross-field constraints
Retry rules
Fallback paths
Meta ad launching is genuinely complex. The problem was never just filling in values—it’s field combinations, cross-field constraints, default inheritance, error recovery. Everything that should have lived in runtime had migrated, one rule at a time, into markdown.<br>Each new rule surfaced a new error shape on the next run. Each new branch made the prompt longer. The next run hit another Meta exception this file had never seen.<br>That afternoon a sentence surfaced in my head:<br>I don’t want to be a markdown-driven programmer.
Later I realized: the real problem wasn’t prompt length.<br>It was that:<br>We weren’t writing prompts. We were quietly rewriting a runtime.
Hidden Runtime
The 600-line prompt wasn’t mine. The bot team had hooked into an early version of my system’s API.<br>That API was designed for deterministic callers:<br>Microservices
Web UIs
Fixed workflows
Stable payloads
A caller is assumed to know:<br>The flow ordering
What each field means
Which values should inherit
Which should override
When to retry
An agent caller is not that thing. So execution semantics—implicitly carried by the system, the frontend state machine, the workflow engine—started leaking into the prompt:<br>What step 1 does
What step 2 does
Which errors trigger retry
Which fields can’t coexist
Which configs inherit by default
Things that should have lived in runtime got translated back into natural language and re-fed to a model that’s already doing semantic interpretation.<br>I’ve started calling this anti-pattern markdown parroting . Engineers write business workflows as markdown teaching material; the LLM replays the workflow pattern. Every new production error gets another paragraph: “this is how to recite it this time.”<br>The LLM is forced to re-execute the backend’s implicit logic in its own token stream. It isn’t a caller anymore. It’s a parrot being drilled by markdown.<br>Two Problems, Conflated
I initially thought this was one problem. Later I realized: the 600-line prompt had two completely different things compressed into the same natural-language patch.<br>The first: nobody holds the flow anymore.<br>A web UI used to hold execution state for the system:<br>Authenticate first
Then pick an objective
Then configure pixel
Then configure audience
That state machine and business-flow control disappeared in the bot form factor. So you start writing in the prompt: “step 1 does this, step 2 does this.”<br>The second: the payload is genuinely complex.<br>A Meta campaign has hundreds of parameters. Asking the LLM to assemble the correct payload in one shot is structurally unstable.<br>Both degenerated into the same fix: keep adding teaching material to the prompt. Every paragraph patches one error; every patch introduces the next prompt drift.<br>Continuing to edit the prompt just sinks you deeper into parroting.<br>Progressive Intent
That night, talking it through with ChatGPT, I realized we’d been framing this wrong—as a prompt-engineering problem. Split the schema finer, add more examples, write the prompt more precisely. But the entry question itself was wrong.<br>Not:<br>“How do we get the AI to write a correct big JSON in one shot?”
But:<br>“Why is the AI writing a big JSON in one shot at all?”
The full payload is an execution shape inherited from the RPC / HTTP API era. A deterministic caller already knows what it wants before issuing the request, so submitting a complete payload in one shot minimizes round-trips.<br>An LLM is not that kind of caller. Its intent doesn’t exist fully-formed in advance—it converges through reasoning, feedback, constraints, and user clarification.<br>What it’s actually good at isn’t generating complete runtime state in one shot. It’s converging on semantic intent under structured feedback.<br>I started calling this execution model progressive intent . Instead of submitting a final payload in one shot, the LLM edits a persistent intent substrate incrementally:<br>Express coarse intent first
Fill in details
Leave uncertain parts blank
Let the system surface gaps, conflicts, and candidate values
Complex business writes shift from “generate full payload in one shot” to “incrementally edit a persistent intent substrate.”<br>I call this substrate the draft . After each edit, the system returns something...