PromptABCD
FeaturesLearnHow it worksUse casesFAQGuideBlogContext Blocks
Sign inGet started free
Sign inSign up
PromptABCD

A calm home for your best AI prompts. Save them once, find them in seconds, reuse them forever.

Product

  • Features
  • Chrome Extension
  • Free Courses
  • How it works
  • Use cases
  • Blog
  • Context Blocks
  • Export Anywhere
  • FAQ

Resources

  • User guide
  • Learn prompting
  • Sign in
  • Get started free

© 2026 PromptABCD. All rights reserved.

Privacy PolicyTerms and Conditions
Home/Blog/Agent Loop Engineering/Interrupting and Resuming an Agent Loop
Agent Loop Engineering

Interrupting and Resuming an Agent Loop

Most agents can't be paused — kill one mid-task and its work is gone. Building a pause resume agent loop takes one design change. Here's the fragile version and the resumable fix.

August 23, 2026·8 min read
ShareShare
⚡Featured Prompt— copy and use right now
def run(task):
    messages = [system, user(task)]
    plan = None
    for step in range(max_steps):
        reply = model.call(messages)          # all state is local
        messages.append(reply.as_message())
        if reply.tool_calls:
            for c in reply.tool_calls:
                messages.append(tool_result(c.id, run_tool(c)))
        elif reply.finished:
            return reply.answer
    # if the process dies here, `messages` and `plan` die with it

Here's something most people don't realize until it costs them: the typical agent can't be paused. Stop it mid-task — a crash, a deploy, a user closing the tab — and everything it had done evaporates. Not slowed, not queued: gone. The agent had made ten tool calls, gathered real results, and formed a plan, and killing it threw all of that away because the entire state lived in memory that died with the process. A pause resume agent loop treats that as unacceptable, and the fix is a single design change. Let's tear apart the fragile version and build the resumable one.

Being able to interrupt and resume isn't a luxury feature. It's what lets an agent survive a deployment, wait for a human approval, respect a rate limit, or recover from a crash without redoing hours of work. And the difference between an agent that can and one that can't comes down to where its state lives.

That last point is the entire lesson compressed to a sentence, and it's worth sitting with. Nothing about resumability is about the model's intelligence, the quality of the prompts, or the cleverness of the tools. It's a pure architecture question: is the agent's working state trapped inside a running process, or does it live somewhere the process can die without taking it along? Two agents identical in every other respect — same model, same prompt, same tools — differ completely on whether an interruption is a catastrophe or a shrug, based only on that one storage decision.

Before: The Weak Prompt

Here's the fragile loop — the shape almost every agent starts as:

hljs python
[object Object], ,[object Object],(,[object Object],):
    messages = [system, user(task)]
    plan = ,[object Object],
    ,[object Object], step ,[object Object], ,[object Object],(max_steps):
        reply = model.call(messages)          ,[object Object],
        messages.append(reply.as_message())
        ,[object Object], reply.tool_calls:
            ,[object Object], c ,[object Object], reply.tool_calls:
                messages.append(tool_result(c.,[object Object],, run_tool(c)))
        ,[object Object], reply.finished:
            ,[object Object], reply.answer
    ,[object Object],

What this does: holds the entire agent state — transcript, plan, progress — in local variables that exist only inside the running function, so any interruption erases all of it with no way to pick back up.

Kill this at step ten and you restart at step zero. The ten tool calls, the accumulated context, the half-formed answer — all unrecoverable, because none of it was ever written anywhere but volatile memory.

Why It Fails

The state is trapped in the process. Everything the agent knows lives in local variables, which means the agent's memory and the process's lifetime are the same thing. When the process ends — for any reason — the agent's entire working state ends with it. There's no seam to stop at and nothing to resume from.

This isn't a rare-crash problem. It shows up constantly: you can't deploy new code without killing in-flight agents and losing their work; you can't pause an agent for a human to approve a risky step; you can't stop and requeue an agent that's hit a rate limit. All of these need the same thing — the ability to freeze state and thaw it later — and the in-memory loop offers no way to do it.

That's the reframe worth holding onto: a pause resume agent loop isn't a feature you add for a specific scenario, it's a capability that unlocks a whole category of scenarios at once. Deploys, approvals, rate-limit backoff, crash recovery — they look like four different requirements, but they're one requirement wearing four hats. Solve "freeze and thaw state" once and all four fall out for free. Which is exactly why it's worth building into the loop's foundation rather than bolting onto whichever scenario forces the issue first.

⚠️ Common mistake: Assuming you'll add resumability later if you need it. Retrofitting it means untangling state from a loop that assumed state lived in local variables — touching every place the loop reads or writes progress. Building the state as an explicit, serializable object from the start costs little; bolting it on after the loop is woven around local variables is a rewrite. This is a decision to make early.

⚡ Pro tip: Ask of any agent, "if this process died right now, what would I lose?" If the answer is "everything," your state lives in the wrong place. A resumable agent can answer "nothing since the last checkpoint," and that difference is entirely about where state is stored, not how smart the agent is.

After: The Improved Prompt

The fix is to make state an explicit, serializable object that lives outside the loop's local scope — saved after each step, loaded to resume.

hljs python
[object Object], ,[object Object],(,[object Object],):
    state = load_state(run_id) ,[object Object], AgentState.new(task)   ,[object Object],
    ,[object Object], ,[object Object], state.done ,[object Object], state.step < max_steps:
        ,[object Object], state.should_pause():                          ,[object Object],
            save_state(run_id, state)
            ,[object Object], Paused(run_id)
        reply = model.call(state.messages)
        state.apply(reply)                                ,[object Object],
        ,[object Object], reply.tool_calls:
            ,[object Object], c ,[object Object], reply.tool_calls:
                state.add_observation(c.,[object Object],, run_tool(c))
        save_state(run_id, state)                         ,[object Object],
    ,[object Object], state.result

What this does: keeps all progress in an explicit

AgentState
object that's saved after every step and loaded by
run_id
on entry — so the loop can pause at a clean seam or die unexpectedly and later resume exactly where it stopped.

hljs python
[object Object], ,[object Object],(,[object Object],):
    ,[object Object], run(state.task, run_id)     ,[object Object],

What this does: restarts the loop for a given run, which loads the persisted state and continues from the last checkpoint instead of starting over — turning interruption from data loss into a pause.

Breaking Down Each Element

Three changes make the loop resumable.

Explicit state — an

AgentState
object holding the transcript, step, plan, and progress — replaces scattered local variables, giving you one thing to save and load. Checkpointing every step — persisting that state after each iteration — means the most you ever lose is one step's work, not the whole run. And the pause seam — a clean check between steps where the loop can stop and save — turns "kill the process" into "pause and resume" for the planned cases like approvals and deploys.

Together they move the agent's memory out of the process and into durable storage. The process becomes disposable; the state persists. That's the whole shift.

And it's a shift in how you think about the process, not just where you put a variable. In the fragile design the process is the agent — kill it and the agent is gone. In the resumable design the process is merely a worker that happens to be advancing the agent right now; the agent itself lives in the checkpoint and can be picked up by any worker, later, elsewhere. That decoupling is what makes everything else — deploys, approvals, backoff, recovery — possible, because none of them care which process does the work as long as the state outlives any single one.

⚡ Pro tip: Checkpoint between steps, at a clean boundary, never mid-tool-call. Resuming is only safe if every saved state is consistent — a checkpoint taken while a tool was half-executed resumes into a corrupt state. Save after a step fully completes, so every checkpoint represents a coherent moment you can safely restart from.

Variations for Different Contexts

Resumability enables different capabilities per context.

A platform engineer running long agents makes them survive deploys — in-flight agents checkpoint, the process restarts on new code, and they resume mid-task instead of dying. A compliance-sensitive workflow uses the pause seam for human approval — the agent pauses before a risky action, waits for a person to approve, and resumes on their signal. A batch-processing team uses resumability to respect rate limits — an agent that hits a limit saves state, requeues, and resumes later, rather than failing and restarting from scratch.

Same resumable-state mechanism, three capabilities — durability, human-in-the-loop, and graceful backoff — that the in-memory loop simply can't offer.

⚡ Pro tip: Give every run a stable, external

run_id
from the moment it starts, not one generated inside the process. The id is the handle you use to resume, so it has to outlive the process — a caller-supplied or database-issued id means you can always find and restart a run, where a process-local id vanishes with the crash you needed it to survive.

⚡ Pro tip: Version your state schema. When you change what

AgentState
holds, old saved states from before the change can't load cleanly — a stamped version lets you migrate or safely discard them, so a schema change doesn't silently corrupt every in-flight resume. Cheap to add up front, painful to add after the first bad migration.

Save and Reuse This

The explicit-state pattern — a serializable state object, per-step checkpointing, and a pause seam — is the same for any agent regardless of what it does. Swap what

AgentState
holds for your task, and the save/load/resume machinery of a pause resume agent loop carries over unchanged.

I keep the

AgentState
skeleton and the load-checkpoint-resume loop saved and versioned in PromptABCD alongside the loop code, so every new agent is resumable from its first run — instead of the in-memory default that runs fine until the first crash, deploy, or approval gate turns hours of real work into nothing. The pattern costs a few extra lines on the first agent and saves a rewrite on every one after.

pause resumeagent loopstatecheckpointingai agentsreliability

Continue Reading

The Prompts That Drive Each Loop Step
Agent Loop Engineering

The Prompts That Drive Each Loop Step

One vague system prompt was making an agent loop badly — wrong tools, no stopping, no progress. Great agent loop prompts drive each step deliberately. Here's the teardown and the fix.

August 23, 2026·8 min read
Cost per Loop Iteration: Budgeting Token Spend
Agent Loop Engineering

Cost per Loop Iteration: Budgeting Token Spend

Most teams budget agent loop token cost by the total and miss where it actually goes. Here's a case where the real cost hid in re-sent context, and the fix that cut spend 60%.

August 23, 2026·8 min read
How to Handle Partial Failures Inside the Loop
Agent Loop Engineering

How to Handle Partial Failures Inside the Loop

What happens when one tool call in a batch fails but the rest succeed? Handling agent loop partial failure well is the difference between a resilient agent and one that dies on a hiccup.

August 23, 2026·8 min read

Save the prompts from this post

PromptABCD is a free prompt manager. Paste, organize, and reuse your best AI prompts — no more hunting through chat history.

Start free →
← PreviousStreaming Intermediate Steps From the LoopNext →Checkpointing Agent State Between Iterations
Share this post:
ShareShare