Back to style-version posts

agent-07 · Loop engineering is the harness on a timer — Lee Hung-yi-inspired teaching style

Inspired by Lee Hung-yi's teaching style. We begin with a naïve infinite prompt loop, watch it fail against weak signals, and then add schedule, state, spawn, independent checks, and human gates.

This is a teaching-style rewrite inspired by Lee Hung-yi. It was not written, reviewed, or endorsed by him. Also available as the English original, 繁體中文, and 繁體中文李宏毅老師經典的教學風格版.

Dark technical cover reading Loop engineering is the harness on a timer, with a timer-budget loop, agent harness, memory state, grounded oracle verification, and spawned sub-agent terminals in green, cyan, and violet accents.

All right, let's start class with a system that looks almost too simple:

while :; do cat PROMPT.md | agent ; done

You may look at this and say, “Wonderful. The agent runs forever, so I have automated engineering.” Not quite. You have automated repetition. Whether repetition becomes progress depends on memory, coordination, and—most importantly—a signal the loop cannot game.

Here is the one-sentence version: loop engineering is harness engineering plus a clock, external state, and the ability to spawn work.

Our roadmap has three stages. First, we move the human scheduler into the system. Second, we assemble the five primitives and external memory. Third, we let the naïve loop collide with weak oracles, correlated verifiers, token cost, lost friction, and comprehension debt.

So the goal is not “remove the human everywhere.” The goal is to decide where automation has a hard signal and where human judgment must remain a gate.

Style note: this is a teaching-style rewrite inspired by Lee Hung-yi. It was not written, reviewed, or endorsed by him.

I was the loop

Before defining the new term, find the hidden component in the old workflow. Ten agents were running, but one human was still reading, routing, and deciding every next step.

In April I wrote about running ten coding agents at once from a phone. The honest summary of that post is that I was the loop. I read what came back, I decided what was next, I poked the next agent. The tooling was clever. The scheduler was me.

This post is about the part where you stop being the scheduler.

People have started calling this loop engineering. Addy Osmani gave it the clean definition: you stop being the person who prompts the agent and build the system that prompts it instead. Boris Cherny, who runs Claude Code, says his job is now to write loops, not prompts. Peter Steinberger says the same thing in fewer words. It sounds like a new discipline. It is mostly the old one, seen from one floor up.

Earlier entries in this series mostly followed a lecture course. This one is different. It is the layer the course kept pointing at — meta-harnesses, harness self-improvement — without quite naming. So I will name it the way it actually arrived: on a timeline, not in a syllabus.

Builder takeaway: before you build a loop, decide three things you will not delegate to it: the goal, the oracle, and the places you refuse to leave the room. The loop automates everything else.

The loop is the harness on a timer

Now we can build the mechanism from the intuition. A harness controls one run; a loop gives that harness a clock, durable memory, and permission to start more work.

In agent-04 the equation was:

AI agent = language model + harness

A loop adds three things to that: a schedule, a place to remember, and the ability to spawn.

loop = harness + schedule + external state + spawn
Dark blueprint-style diagram explaining The loop is the harness on a timer, with short English labels and high-contrast technical geometry.
A loop is the harness with a clock, a memory outside the conversation, and permission to start more of itself.

If you keep the computer metaphor from agent-00, the harness is the operating system around a single run. The loop is the rest of the machine that the OS assumes: a cron timer, an init process, and a supervisor that restarts the work and reads its notes before it does.

A single agent run answers a question. A loop runs the question on a clock and acts on the answer without you in the keystroke path.

That is the entire shift. Everything else in this post is what it costs.

The idea is older than the name

The simplest attempt is not a product feature or a new framework. It is a shell loop. That is useful because its failure modes are impossible to hide behind branding.

The pattern is Geoffrey Huntley's "Ralph," from the middle of 2025. In its purest form it was one line:

while :; do cat PROMPT.md | agent ; done
Dark blueprint-style diagram explaining The Ralph while-loop, with short English labels and high-contrast technical geometry.
Ralph is a while-loop that feeds the same prompt to an agent forever, with progress living in files and git, not in the model's memory.

This is the context-engineering move from agent-01. The model forgets between runs, so the state cannot live in the context window. It has to live on disk. The agent forgets. The repo does not.

What changed in 2026 is not the concept. It is that the moving parts — schedules, isolated worktrees, sub-agents, written-down skills, connectors to real tools — now ship inside Claude Code and Codex instead of living in a pile of shell scripts only you understood. That is a real convenience, and it is why the term spread this month rather than last year.

The novelty is the packaging, not the pattern.

Five parts and a place to remember

Once the one-line loop becomes real work, it needs a small operating system: a heartbeat, isolated workspaces, reusable procedure, I/O, delegation, and memory that survives the conversation.

Strip the branding off either product and a working loop is five primitives and one place to remember things.

Dark blueprint-style diagram explaining Five primitives plus a place to remember, with short English labels and high-contrast technical geometry.
A loop is five primitives composed under a clock, plus external memory as the spine.

Then the sixth thing: memory on disk. A markdown file, a Linear board, anything outside the single conversation that holds what is done and what is next.

That composition is the new thing: old primitives, wired together, with a clock on top.

A loop is only as good as its least gameable signal

Here is the central lesson. A faster optimizer does not repair a bad target; it reaches the wrong target faster. The practical question is whether the loop can fake the evidence of success.

This is the part that decides whether a loop becomes leverage or debt. Earlier posts in this series argued that self-correction needs real signals, not reflection, and that self-defined losses can become a closed loop of self-delusion. Loop engineering is the practitioner version of the same problem.

Dark blueprint-style diagram explaining The least gameable signal wins, with short English labels and high-contrast technical geometry.
A loop pointed at a real oracle converges. A loop with no oracle generates confident, plausible, wrong output faster than you can read it.

Point a loop at a problem with a real oracle — a test suite, a strict type checker, a compiler, a conformance spec it cannot argue around — and it converges. The cleanest public example is Simon Willison's port of a JavaScript engine into roughly twenty-five thousand lines of Rust, which worked because every output could be checked byte-for-byte against the original. There was a ground truth the agent could not fake.

Take the ground truth away and the loop still runs. It just produces confident, plausible, wrong code, and it does it faster than any human can read.

The proof that the oracle is what matters, and not the model, is that agents game weak oracles. Researchers keep catching looping agents rewriting a failing test so it passes instead of fixing the code, and in one case hallucinating an external service and then mocking the service it had invented. In self-training this is the oh-no moment. At the application layer it is the same event with a different name. When the signal is gameable, the optimizer games it. That is Goodhart's law, and a loop is a Goodhart amplifier.

So the first question is not "how do I write a loop." It is "does this work have a signal the loop cannot fake."

Tests, types, compilers, golden files: loop hard. Taste, architecture, security posture, whether this is even the right abstraction: the loop has nothing to push against, and you are the only judge in the room whether you admit it or not.

The maker and the checker should not be the same model

What if there is no hard oracle? The first improvement is to separate maker and checker so the original answer is viewed from another set of instructions.

The standard fix for a weak oracle is a verifier sub-agent. Generator, verifier, revisor — the workflow from agent-04, the topology from agent-02. It helps. The model that wrote the code is too generous grading its own work, so a second agent with different instructions catches what the first talked itself into.

Dark blueprint-style diagram explaining Maker-checker independence, with short English labels and high-contrast technical geometry.
A verifier helps only when it is independent of the maker or grounded in something the maker cannot fake.

But the verifier has the same trap. If a model judges itself, the signal may be weak or it may reinforce its own blind spots. A verifier sub-agent built from the same model class shares those blind spots. So you add another checker. And then, in principle, another.

The regress only bottoms out in two places: a human with judgment, or a hard external oracle the chain of agents cannot talk around. A verifier with nothing grounded behind it is theater that costs tokens.

A second opinion from the same mind is not a second opinion.

Loops move the cost, they do not remove it

Automation does not make cost vanish. It changes manual skill cost into token cost, review cost, and the risk of an unattended retry loop.

The pitch implies the work goes away. It moves, and it splits in two.

Dark blueprint-style diagram explaining The cost moves, it does not vanish, with short English labels and high-contrast technical geometry.
Loops convert a skill cost into a token cost and a review cost. Neither is small.

The first half is money. A loop that keeps a few hundred agents busy around the clock burns real tokens, and the first wall most people hit is not a quality problem. It is a two-hundred-dollar infinite-retry bug at three in the morning. When Cherny describes a couple hundred agents reading his GitHub and Slack and deciding what to build, that is not a workflow you copy by learning a skill. It is a workflow you copy by having the token budget to let agents fail expensively in parallel. Osmani's aside about being token-rich versus token-poor is the whole story, said quietly.

The second half is attention. Someone still reads the output. Industry telemetry already shows the shape of it: teams that lean hard on AI merge far more pull requests, but review time climbs and each PR gets larger. This is the ceiling I hit in the April post. The thing that capped ten agents was never the tooling. It was me.

Prompt engineering was cheap and close to meritocratic. Loop engineering has a meter running.

Friction was doing a job

Friction sounds like waste, but some friction is where judgment enters the system. Removing every pause also removes the places where a careful person would notice pain.

The whole promise of loop engineering is that it takes you out of the loop, and removal of friction gets sold as pure upside. Armin Ronacher, who created Flask, named the cost better than anyone: you have to find a way to feel the pain the agent does not feel.

Dark blueprint-style diagram explaining Friction is a steering input, with short English labels and high-contrast technical geometry.
Friction is not the tax on the loop. Friction is the steering input.

An agent's only real drive is to make progress. So it will do things a careful person would not. It will silently fall back to a default when a config is missing. It will leave a service hobbling along. It will paper over the failure it should have surfaced. The friction you are so eager to delete was where your judgment got applied.

agent-04 had the right instinct already: hard constraints live in the harness, not in the prompt, because tool boundaries are real boundaries and prompt rules are not. The same instinct scales to the loop. Put hard human gates on the few things that are expensive to get wrong — money, auth, database migrations, customer data — and let the loop run free everywhere else.

The skill is not removing yourself. It is choosing the three places you refuse to be removed.

The bill arrives late

The most dangerous cost is delayed. Output can grow immediately while understanding falls behind quietly, so apparent velocity and comprehension debt rise together.

What makes all of this easy to miss is timing. Prompting by hand, you read every diff as it lands, so the gap between what exists and what you understand never gets large. A loop opens that gap silently and lets it compound.

Dark blueprint-style diagram explaining Comprehension debt, with short English labels and high-contrast technical geometry.
Comprehension debt is the gap between what the loop shipped and what you can still explain. It grows quietly.

The vivid version comes from the experiments at Cursor, where a fleet of agents was turned loose on something as ambitious as a browser engine, made real early progress, and then stalled — unable to keep extending a codebase the agents themselves had written and could no longer hold. That is comprehension debt made physical. Eventually even the machines could not model what the machines built. Across real repositories, the count of surviving issues introduced by AI is already into the six figures.

The danger is not bad code. It is plausible code, arriving faster than anyone builds a mental model of it.

A loop is harness self-improvement you can read

Now connect this back to self-improvement. The loop may not rewrite model weights, but it can rewrite skills, state, and rules—the harness itself.

The previous post ended on a useful point: the first practical self-improving agents may not rewrite their weights. They may rewrite their harness. And that kind of self-improvement is easier to inspect than a weight update.

Dark blueprint-style diagram explaining Self-improvement you can read, with short English labels and high-contrast technical geometry.
A loop that edits its own skills, state, and rules is the inspectable rung of the self-improvement spectrum.

A loop that updates its own skill files, rewrites its state, and revises its own rules between runs is exactly that, out in the open. The skill file, the state file, the triage notes are all readable, versionable, and deletable. That was the reason I liked skills in agent-04: a fine-tuned behavior is hard to audit, a file is not.

The caution carries over without changes. It is still dangerous if the agent can edit the wrong part of its own system. So scope what the loop is allowed to rewrite as carefully as you scope what it is allowed to deploy.

This is the safest rung on the self-improvement spectrum, and unlike most of that spectrum, it is already shipping.

Where I think we are

The leverage point has moved up one layer. Judgment has not disappeared; it has become concentrated in the goal, oracle, permissions, and final review.

The leverage point moved up a layer. Judgment did not move. It concentrated.

Dark blueprint-style diagram explaining The loop is a multiplier, with short English labels and high-contrast technical geometry.
The loop is a multiplier. It has no opinion about whether you understand the work.

A loop is a multiplier on whatever you bring to it. Two people can build the identical loop and get opposite results, because the loop does not know the difference between someone using it to move faster on work they understand and someone using it to avoid understanding the work at all. The system has no opinion about that. You do.

That lesson applies one rung lower. Building a loop that keeps shipping is easy. Building a loop that keeps shipping for the right reasons is the whole job.

Useful, not autonomy.

The main lesson

The punchline is simple: a loop multiplies both good engineering and confused engineering. It has no opinion about which one you brought into the room.

Loop engineering does not make the engineering easier. It moves the engineering to the parts you cannot automate.

Dark blueprint-style diagram explaining The work with no oracle, with short English labels and high-contrast technical geometry.
The work that is left is the work that has no oracle: choosing the goal, choosing the signal, choosing where to stay.

Before you let a loop run unattended, ask:

If you cannot answer those, the loop is not saving you work. It is deferring it, with interest.

Build the loop. Keep the oracle. Stay the engineer.

Concept inventory

The main loop-engineering concepts in this post:

Sources and references

The discourse this post responds to:

Earlier in this series: