Loop Engineering: I Stopped Prompting Agents, and Started Designing Systems That Prompt Them For Me
2 hours spent prompting an agent to review PRs. Realized that doesn't scale. Then read Boris Cherny's quote: "I don't prompt Claude anymore. I have loops running that prompt Claude." That's loop engineering - design systems that prompt agents.
0xNN · · 11 min read
I remember exactly the moment I realized I was using AI agents wrong. July 2026, reviewing a pull request on this blog's repo. I opened Claude Code, typed: "review this PR, find bugs, give suggestions." Waited 2 minutes. Read the output. Prompted again: "fix bug on line 45." Waited. Prompted again: "add a test for the fix." Waited. Prompted again: "run the tests, if they fail, fix them."
2 hours passed. I felt productive - PR reviewed, bug fixed, test added. But my time went into the prompt box, not into technical decisions. I became a prompt operator, not an engineer. You write 1 prompt, wait, read, write another, wait, read. That's a loop - but you're the loop, not the agent.
Then I read a quote from Boris Cherny (Head of Claude Code at Anthropic): "I don't prompt Claude anymore. I have loops running that prompt Claude and figuring out what to do. My job is to write loops." One sentence that changed how I think. You don't have to prompt the agent. You have to design the system that prompts the agent. That's loop engineering.
This isn't a tutorial on "how to use the loop-engineering CLI." It's the philosophy of why the mindset is different, how it compares to the prompt engineering we've been using, and why I think this isn't hype - it's an evolution that was a long time coming.
---
Prompt Engineering Is Still Manual Labor
Prompt engineering = the art of writing instructions for an LLM so its output matches your expectations. You craft detailed prompts, provide context, give examples, give constraints. The better the prompt, the better the output.
That's a valid skill. I still use it daily - writing system prompts for this blog, giving Claude instructions to write articles in the MSNCode voice. But prompt engineering has a fundamental limit: you have to prompt manually every time you want something done.
Imagine you have 5 PRs that need review. Prompt engineering approach: open Claude, prompt for the first PR, wait, read, prompt for the second PR, wait, read, etc. 5x manual labor. You don't scale. You're the bottleneck.
Loop engineering answers: why are you the one prompting? Why not design a system that prompts the agent every time a new PR arrives, runs the review, gives you a report, and you only read the result?
The philosophy shifts: from "I prompt the agent" to "I design the loop that prompts the agent." You go up one level of abstraction. You're not coding prompts, you're coding the system that codes prompts.
---
What Is Loop Engineering, Really
Cobus Greyling (who popularized the term via his GitHub repo) defines it like this: loop engineering = designing systems that schedule, triage, and orchestrate AI agents on a cadence, with state that persists outside the conversation, and human gates for risky things.
The core philosophy: agents are stateless. You have to provide state. If you chat with Claude Code, it forgets the context from 1 hour ago. Loop engineering provides a "memory spine" - STATE.md, LOOP.md, run logs - that the agent reads every time the loop runs.
Analogy: prompt engineering is like giving instructions to an assistant every time you want something done. "Review this PR." "Fix this bug." Every time, from scratch. Loop engineering is like writing an SOP that the assistant runs automatically every hour: "check for new PRs, if any, review, report to Slack. If none, sleep."
The 5 building blocks that make loop engineering work (from Cobus's repo):
1. Automations / Scheduling - when the loop runs. Every hour? Every day? Every time a new PR lands? Cron job, GitHub Actions, systemd timer. Without scheduling, you're back to manual operation.
2. Worktrees - safe parallel execution. If the agent wants to write code, it works in an isolated git worktree. Doesn't touch the main branch. If it fails, throw away the worktree. If it succeeds, merge.
3. Skills - persistent knowledge. Project context, codebase conventions, the things you usually put in CLAUDE.md or AGENTS.md. The agent reads this every loop, so it doesn't have to be reminded.
4. Plugins & Connectors (MCP) - reach into your real tools. GitHub, Slack, Jira, database. Via MCP (Model Context Protocol), the agent can read issues, create PRs, send messages. Without this, the loop can only "read local files, write local files."
5. Sub-agents - maker/checker split. One agent writes code, another verifies. Why? Because the agent that writes code isn't objective reviewing its own code. Maker writes, checker verifies, then the result goes to the human gate.
Plus Memory / State - the backbone outside the conversation. STATE.md that records: "PR #45 reviewed, 2 bugs found, fix in worktree X, waiting for human approval." The agent reads this every loop, so it knows what's been done, what's pending. Without state, every loop starts from zero.
---
Anatomy of One Loop
Here's the flow of one loop running (as in the Cobus repo README):
[Schedule] → [Triage Skill] → [Read/Write STATE] → [Isolated Worktree]
→ [Implementer agent] → [Verifier agent (tests + gates)]
→ [MCP/Git/Tickets] → [Human Gate?]
→ safe/allowlisted → [Commit/PR]
→ risky/ambiguous → [Escalate to human, with full context]
→ back to [Schedule]
Step by step:
Schedule fires (e.g., every 15 minutes). The loop reads GitHub: any new PRs? Any CI failures? Any issues labeled bug?
Triage Skill decides: which are priority? Which can be auto-fixed? Which need escalation? This skill is persistent - you write the rules once, they're used every loop.
Read STATE: the agent reads STATE.md - "PR #45 already reviewed, PR #46 isn't. CI failed on PR #44, cause is dependency conflict." The agent knows context without you providing it.
Isolated Worktree: the agent creates a new git worktree to work in. Doesn't touch the main branch. If it fails, rm -rf the worktree.
Implementer agent writes code: fixes the bug, adds tests, whatever triage decided.
Verifier agent runs tests, lint, type check. If it fails, back to the implementer. If it passes, continue.
MCP/Git/Tickets: the agent commits to the worktree, creates a PR, updates issue status. Via MCP connector, not manually.
Human Gate: if the change is safe and allowlisted (e.g., docs update, dependency patch), auto-merge. If it's risky or ambiguous, escalate to human with full context - "loop found bug X in PR Y, fix is in worktree Z, tests pass, but it touches payment logic, needs your review."
---
7 Production-Ready Patterns
Cobus's repo lists 7 patterns that people are actually using:
| Pattern | Cadence | Level | Token cost |
|---|---|---|---|
| Daily Triage | 1 day | L1 report | Low |
| PR Babysitter | 5-15 min | L1 watch | High |
| CI Sweeper | 5-15 min | L2 cautious | Very high |
| Dependency Sweeper | 6h-1d | L2 patch-only | Medium |
| Changelog Drafter | 1d or tag | L1 draft | Low |
| Post-Merge Cleanup | 1d-6h | L1 off-peak | Low |
| Issue Triage | 2h-1d | L1 propose-only | Low |
What I'm personally interested in: Daily Triage and PR Babysitter. Daily Triage = every morning, the agent scans the repo, reports: "3 new issues, 2 PRs pending review, 1 CI failure." You read the report over coffee, not scroll GitHub manually. PR Babysitter = every 15 minutes, the agent checks open PRs, if there's a conflict or CI failure, alerts you. You don't have to monitor constantly.
The L1/L2/L3 levels matter. L1 = report only, doesn't fix. L2 = assisted fix, but human approval before merge. L3 = unattended, auto-merge. The philosophy: start at L1, only go up to L2/L3 once you trust it. Don't jump to L3. That's a recipe for disaster.
---
Comparison: Prompt Engineering vs Loop Engineering
This is the question everyone's waiting for. Which is better?
My answer: not "which is better." They're different layers. Prompt engineering is the individual-level skill - how you talk to an agent. Loop engineering is the system-level skill - how you design infrastructure that talks to an agent.
| Aspect | Prompt Engineering | Loop Engineering |
|---|---|---|
| Layer | Individual - you vs agent | System - loop vs agent |
| Manual labor | High - you prompt every time | Low - you design once, loop runs |
| Scalability | Linear with your effort | Exponential - 1 loop runs 1000x |
| State | Stateless - every prompt is new | Stateful - STATE.md, run logs |
| Verification | You read output manually | Sub-agent verify + human gate |
| Context | You provide every prompt | Skills + MCP provide automatically |
| Cost | Token per prompt | Token per loop (can explode if not budgeted) |
| Use case | One-off, exploratory, creative | Repetitive, scheduled, monitoring |
| Failure mode | Bad output | Comprehension debt (you don't read what the loop ships) |
| Skill needed | Writing clear instructions | Designing systems: scheduling, state, gates |
The philosophy I hold: prompt engineering is a foundational skill, loop engineering is an advanced skill. You can't design a good loop if you can't write a good prompt. But you won't scale if you only write prompts. Level up: good prompts → good loops.
---
When to Use Loops, When to Stick with Prompts
Use prompt engineering when:
• The task is one-off. "Help me debug this error." No loop needed, just prompt once.
• The task is creative. "Write an article about X." Loops don't help, they get in the way - creativity needs dialogue.
• You're exploring. "Try using library X, how does it go?" You need real-time interaction, not a scheduled loop.
• The task is complex but one-shot. "Refactor this module into microservices." One long session, not a repeating loop.
Use loop engineering when:
• The task is repetitive. "Review every new PR." "Fix every CI failure." "Update dependencies every day."
• The task is predictable. You know the input (new PR, CI fail), you know the expected output (review report, fix PR).
• You want to scale. 5 manual PR reviews = 5x your time. 1 loop = 0 of your time, just read the report.
• The task is low-risk to automate (L1). "Just report, don't fix." For L2/L3, be careful.
Me personally: 70% prompt engineering, 30% loop engineering. Repetitive stuff (monitoring, triage) → loop. Creative stuff (writing articles, designing systems) → prompt. You don't have to be 100% one. Choose the tool based on the problem.
---
What I Learned From Trying
1. Token costs can explode. Sub-agents + long-running loops = token burn. I once set up a PR Babysitter that ran every 5 minutes. 1 day = 288 loops. Each loop reads PR + context = 5000 tokens. 288 × 5000 = 1.4 million tokens per day. With Claude Sonnet, that's $4-5/day just to monitor PRs. Build a loop-cost estimate before committing.
2. Comprehension debt is real. The loop runs, fixes bugs, merges PRs. You don't read everything. 1 month later, your codebase has changed without you understanding why. Comprehension debt grows faster than code debt. My rule: every L2/L3 loop must generate a summary that humans read. If not, that loop becomes a black box.
3. Verification is still your responsibility. The loop makes a PR, tests pass, auto-merges. But "tests pass" doesn't mean "code is correct." Tests might not cover edge cases. Logic can be wrong even when tests are green. L3 unattended is dangerous if you don't have a solid test suite. Start L1, then L2, then L3.
4. State is what makes loops powerful. Without STATE.md, every loop starts from zero. With state, the loop knows: "PR #45 was reviewed yesterday, skip. PR #46 is new, review it." State = memory. Memory = context. Context = better output.
5. Loops don't know business context. A loop can fix a technical bug, but it doesn't know "this feature was deprioritized by product." Human gates are still important for decisions that need business context.
---
Common Misconceptions
"Loop engineering = no need for prompt engineering." - Wrong. You still have to write good prompts - but the prompts go into skills/triage rules, not the chat box. Good skills = good loops. You level up, you don't replace levels.
"Loop engineering = autopilot." - Dangerous. An L3 unattended loop without verification = recipe for disaster. Quote Addy Osmani: "Build the loop. But build it like someone who intends to stay the engineer, not just the person who presses go."
"Loop engineering is only for big teams." - No. A solo dev with 3 repos can use Daily Triage. Token cost is low (L1 report only). What matters: start small.
"Loop engineering replaces dev jobs." - It doesn't. Loops reduce manual labor (monitoring, triage), but decisions remain human. You become the architect who designs the system, not the operator who runs it.
---
An Honest Closing
I won't say "prompt engineering is dead." It's not. Prompt engineering is still a fundamental skill. But loop engineering is an evolution that was a long time coming. When I realized 2 hours of my time went into prompting an agent to review PRs, when I could design 1 loop that prompts the agent every 15 minutes and I only read the report - that was the "ah, so that's how" moment.
The philosophy I bring now: you don't have to be a prompt operator. You can be a loop designer. Go up one level of abstraction. From "I write prompts" to "I design systems that write prompts." That's the difference between an engineer who scales and one who's stuck.
If you want to try it, start small. Clone Cobus's repo, run npx @cobusgreyling/loop-init . --pattern daily-triage --tool claude. Set up L1 reporting first - every morning, the agent scans the repo, reports to you. Doesn't fix anything, just reports. If that's already useful, go up to L2. If L2 is stable, go to L3. But don't jump to L3. An unattended loop without verification = a time bomb.
Boris Cherny said: "My job is to write loops." I agree. But my addition: your job isn't just to write loops, but to read what the loop ships. A loop without human comprehension = comprehension debt piling up. A loop with human review = a system that scales. Choose the second.