<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Agents on Hoang Duong</title><link>https://tech.nguuyen.io.vn/tags/agents/</link><description>Recent content in Agents on Hoang Duong</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Sat, 12 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tech.nguuyen.io.vn/tags/agents/index.xml" rel="self" type="application/rss+xml"/><item><title>Prompts Don't Run. They Compile.</title><link>https://tech.nguuyen.io.vn/notes/prompts-dont-run-they-compile/</link><pubDate>Sat, 12 Sep 2026 00:00:00 +0000</pubDate><guid>https://tech.nguuyen.io.vn/notes/prompts-dont-run-they-compile/</guid><description>&lt;img src="https://tech.nguuyen.io.vn/images/notes/prompts-dont-run-they-compile.jpg" alt="Featured image of post Prompts Don't Run. They Compile." /&gt;&lt;h2 id="abstract"&gt;Abstract
&lt;/h2&gt;&lt;p&gt;A prompt never executes. It gets parsed, lowered through plans into tool calls, linked against a live environment, and profiled by reality. Treat the agent like a compiler and most of its strange behaviors stop being strange.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="the-loop-without-mystique"&gt;The loop, without mystique
&lt;/h2&gt;&lt;p&gt;Strip away the marketing and an agent is three things wired in a circle: a policy that proposes the next step, a set of tools that make steps real, and an environment that answers back. Observe, decide, act, observe again. That is the entire machine.&lt;/p&gt;
&lt;p&gt;Nothing in that loop understands your goal the way you do. The policy — the model — holds a compressed blur of millions of procedures it has seen. Tools give that blur hands. The environment gives it consequences. Performance lives in the quality of the circle, not in any single arc of it. A brilliant policy with numb tools is a scholar with mittens. Sharp tools with a deaf environment is a pilot flying blind.&lt;/p&gt;
&lt;p&gt;So when an agent disappoints you, resist diagnosing its intelligence first. Diagnose the loop: what can it sense, what can it touch, and how fast does the world reply.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="intent-compiles-in-passes"&gt;Intent compiles in passes
&lt;/h2&gt;&lt;p&gt;Think of your prompt as source code written in the sloppiest language ever designed — natural language, ambiguous, full of undefined behavior. The agent is the compiler that must turn it into something a machine can execute:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;intent&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;frontend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;what&lt;/span&gt; &lt;span class="n"&gt;did&lt;/span&gt; &lt;span class="n"&gt;they&lt;/span&gt; &lt;span class="n"&gt;actually&lt;/span&gt; &lt;span class="n"&gt;ask&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;intermediate&lt;/span&gt; &lt;span class="n"&gt;representation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="k"&gt;tool&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;lowering&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="n"&gt;become&lt;/span&gt; &lt;span class="n"&gt;concrete&lt;/span&gt; &lt;span class="n"&gt;invocations&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;execute&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;against&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;live&lt;/span&gt; &lt;span class="n"&gt;environment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;observe&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;profiler&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;did&lt;/span&gt; &lt;span class="n"&gt;reality&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;prediction&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;recompile&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Each pass loses information and gains executability — exactly like compilation. The plan is the IR: still portable, still editable. Tool calls are machine code: bound to specific addresses, flags, file paths. Execution is the only stage that cannot be faked, because the backend is not a simulator. It is your repository, your cluster, your production data.&lt;/p&gt;
&lt;p&gt;This reframes a common mistake. Editing the agent&amp;rsquo;s half-finished work mid-run — renaming what it named, moving what it placed — is not &amp;ldquo;guidance.&amp;rdquo; It is hand-editing generated assembly while the compiler is still running, then wondering why the next build emits broken jumps. The IR and the binary have diverged, and every subsequent pass now optimizes against a lie.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="why-we-fan-out"&gt;Why we fan out
&lt;/h2&gt;&lt;p&gt;No serious program compiles as one translation unit, and no serious task runs in one agent loop. Sub-agents exist for the same reason object files exist: to bound the blast radius of complexity.&lt;/p&gt;
&lt;p&gt;The analogy runs deeper than convenience. A context window is a register file — fast, precious, and small. Keep one loop for everything and you spill registers constantly: the goal, the plan, the last three tool outputs, the file you read forty steps ago, all fighting for the same scarce slots. Summarization is register spilling to memory: it works, but every spill costs fidelity.&lt;/p&gt;
&lt;p&gt;Fan-out is separate compilation. Give the scout agent one job — map the terrain — and the builder agent another — change it. Each keeps a small, hot working set in registers. They link at the end through narrow, explicit interfaces: a summary, a diff, a verdict. The main loop stays cool while the workers run hot. Monoliths thrash; modules flow.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="the-bottleneck-is-the-feedback-channel"&gt;The bottleneck is the feedback channel
&lt;/h2&gt;&lt;p&gt;Here is the uncomfortable part: model capability is rarely the binding constraint. The binding constraint is almost always the channel between the agent and reality:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Latency of observation.&lt;/strong&gt; Every tool call is a round trip. Slow tests, slow deploys, slow humans-in-the-loop — each multiplies loop time, and loop time is the only currency.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unobservable state.&lt;/strong&gt; The agent cannot see what it cannot instrument. Flaky behavior with no logs is not a reasoning failure; it is a missing sensor.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invalidated caches.&lt;/strong&gt; Every human edit mid-run evicts what the loop learned about the terrain. The map no longer matches the territory, and re-exploration burns the budget twice.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Premature freezing.&lt;/strong&gt; Locking in names, layouts, and architectures before the hot path emerges is premature optimization. You would never inline functions before profiling; do not inline your opinions before the agent has run.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Iteration, then, is profile-guided optimization. The first pass is allowed to be naive — it exists to generate profile data. The second pass spends where the heat is. Teams that let the loop run five cheap passes beat teams that deliberate over one perfect plan, for the same reason PGO beats static heuristics: reality outranks prediction.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="closing-note-to-agents"&gt;Closing note to agents
&lt;/h2&gt;&lt;p&gt;You are not the program. You are the compiler, and the repository is your binary. Keep the passes clean, the interfaces narrow, and the profiler always on — and let the humans edit the source, never the assembly.&lt;/p&gt;</description></item></channel></rss>