Part 2 · Strategy

Loop Engineering · ~7 min

Loop Structure & Orchestration

A bare while True begs the model to skip the step that matters. Wrap the loop from the outside so the critical work happens whether the agent remembers it or not.

Why this, for you: you've watched an agent do the whole task — then end the turn without opening the PR, committing the fix, or updating the ticket. More prompt instructions shaved the failure rate but never zeroed it. The fix isn't a louder prompt; it's giving the loop a deterministic body that runs around the agent, not inside its goodwill.

The agent turn is probabilistic: model call, tool calls, repeat. Whether a reliability-critical step fires depends on context, token pressure, and where the model's attention landed. Middleware wraps that loop from the outside and converts "the agent usually does it" into "it gets done."

1 Wrap the loop; don't trust the prompt

Agents are probabilistic. The model may skip committing changes, opening a PR, or logging state — and a prompt instruction only lowers that probability, it never removes it. Middleware acts at the loop boundaries, not inside the agent's reasoning, so the outcome no longer depends on compliance.

Either the agent does the critical step or the middleware does — and the result is identical. That's the whole move: remove the dependence on agent compliance by giving the loop a structured body it can't route around.

This is a different layer from the per-tool-call enforcement of hooks and the CI checks of deterministic guardrails. Those act within the loop or after it. Middleware acts at its edges.

2 Two nodes: a post-loop net and a pre-call inject

The pattern is two deterministic nodes bolted to the loop's boundaries — one after it ends, one before each model call.

Post-loop safety net. Runs after the loop exits. If the agent already did the step, the net does nothing; otherwise it does the step deterministically. The canonical shape comes from LangChain's Open SWE, modeled on the same blueprint Stripe, Ramp, and Coinbase built independently:

# open_pr_if_needed — runs after the agent loop exits def open_pr_if_needed(state): if not state.pr_opened: # agent didn't open a PR — do it deterministically create_pr(state.branch, state.title, state.body) return state

Pre-call message injection. Runs before each model call. It drains a queue of human feedback or external events into the conversation — without restarting the loop. That's how you steer a running agent from Slack or Linear and have it continue from where it was, not from scratch.

Critical stepWhy the agent may skip it
Open a PRThinks the task is done; PR feels implicit
Commit changesRan out of steps before cleanup
Update a log / ticketSide effect, not rewarded by completion
Apply cost cap / abortBudgets are easy to ignore mid-loop

3 Complementary layers, not one big prompt

Middleware doesn't replace prompts, hooks, or CI — it sits alongside them, each owning a different scope. The point of structuring the loop is that every reliability concern lands at the layer that can actually guarantee it:

LayerMechanismScope
PromptSystem-prompt instructionRequests compliance — probabilistic
Per-call hookPreToolUse / PostToolUseEnforces per-tool-call rules
CI guardrailLinter, tests, schema checkValidates output properties
Loop middlewareSafety-net + injection nodesGuarantees loop-level outcomes

In a Claude Code host, the same two patterns already exist: a Stop hook is your post-loop safety net (it fires when the agent would stop and can force continuation), and a UserPromptSubmit hook is your pre-call injection point.

Safety nets backfire without idempotency

A net relies on verifiable state. If the agent opens a PR but fails to persist state.pr_opened, the net opens a second one. And watch the fire-rate: if the net fires every run, it's masking a systematic prompt or tooling failure you should fix at the source — not hiding behind the net.

↪ Your win: a loop with a body, not a bare while-true

Retrieval practice — recall, don't peek

Question 1Loop middleware removes the dependence on agent compliance because it acts…

Question 2A post-loop safety net's job is to…

Question 3Pre-call message injection lets you steer a running agent by…

Question 4A safety net that fires on every run is a signal that…

Question 5 · spaced recall from an earlier lessonBefore you debug a misbehaving loop, the first thing to name is…

Ask me anything. Want a LangGraph sketch wiring an inject node and a commit node around your loop, or how to set a verifiable pr_opened flag a net can trust? Next in Part 2: Termination & Convergence Detection — how to know the loop is actually done, not just tired.
✎ Feedback