How to Design a Loop That Automatically Prompts Your AI Agent: A Complete Guide

Have you ever found yourself going back and forth with an AI? You ask it to write code. It gives you something. You run it. It fails. You paste the error back. It fixes one thing but breaks another. You paste again. A few rounds later, you’re exhausted, and the clock has moved way too far.

That back-and-forth can be fully automated. Let me show you how to build a loop that prompts your agent over and over, on its own, until the job is done.

What Is a Loop, and Why Isn’t One Prompt Enough?

Many people think working with an AI agent means writing one really good prompt. You type your request. The agent replies. You’re done. That works for a quick question. But it does 「not」 work for a real job that needs many steps.

A real job looks like this: write the code → run the tests → tests fail → read the error → fix the code → run the tests again → repeat until everything passes.

Think of a chess game. A single prompt is a single move. You look at the board, make one move, and your turn ends. If you only ever make one move, you can never win a full game.

A loop is different. It’s a strategy — the set of rules that decides every move, checks the board after each move, and keeps playing until the game is won.

A prompt is a single move. A loop is a strategy.

We no longer play the game turn by turn, typing each prompt ourselves. We design the rules once, then let the agent play the full game on its own.

So how do we design these rules? Let’s learn the five parts of the loop.

The Five Parts of the Loop

A loop that prompts an agent has five parts. Don’t worry — we’ll go through each one in detail.

Part What it does
Define “done” The check that tells the loop when to stop
Build the context The fresh information we feed the agent each turn
Act and capture Run the step and grab the result
Close the loop with feedback Turn the result into the next prompt
Set stop conditions The guardrails that keep the loop safe

Here’s how these five parts fit together:

        +--------------------------------------------------+
        |                     The Loop                     |
        |                                                  |
        |   Build Context  --->  +-------+                 |
        |                        | Agent |                 |
        |                        +-------+                 |
        |                            |                     |
        |                            | acts                |
        |                            v                     |
        |                    Capture Result                |
        |                            |                     |
        |                            v                     |
        |                    Check "Done"? ----- Yes ---> Stop
        |                            |                     |
        |                            | No (feedback)       |
        |                            |                     |
        |                            +---------------------+
        |                       (next turn)                |
        +--------------------------------------------------+
                    Stop conditions wrap the whole loop

We build the context → the agent acts → we capture the result → we check if we’re done. If yes, we stop. If no, we feed the result back as the next prompt and go around again. The stop conditions wrap the whole thing to keep it safe.

Now let’s understand each part, one by one.

Step 1: Define What “Done” Looks Like

Before anything runs, you must answer one question: how will the loop know it has finished?

This is the first step, and it’s the most important one. If you can’t describe “done”, the agent has nothing to loop toward. It will either keep going forever or stop too early.

So write the success check first — in code, not in your head. Let’s say you’re building an agent that fixes a bug. For you, “done” means the tests pass. Other examples:

  • All tests pass
  • The output matches a schema
  • A score clears a threshold

Here’s a simple function:

def is_done(result):
    # done means all tests passed
    return result.tests_passed

This function returns True when the work is finished and False when it’s not. The loop will call this function after every turn.

This check becomes the heartbeat of your loop. Every turn, the loop checks the heartbeat. If the heart says done, the loop stops. If it says not yet, the loop goes around again.

「Always start here.」 Everything else in the loop is built on top of this check.

Step 2: Build the Context, Not the Instruction

Here’s where most people go wrong. They keep hand-feeding the agent — typing a new instruction each time, pasting files and errors manually.

Stop doing that. Instead of typing the instruction, build the context.

What does “context” mean here? It means everything the agent needs to make a good decision this turn:

  • The files it’s working on
  • The tools it can use
  • The error logs from the last run
  • The past attempts it has already made

The prompt is no longer typed by you. It’s assembled from the current state of the system.

Here’s the code:

def build_prompt(state):
    return f"""
    Goal: {state.goal}
    Files: {state.files}
    Last error: {state.last_error}
    Past attempts: {state.past_attempts}

    Decide the next step and make the change.
    """

Notice how the prompt is built from state. You don’t type the error by hand. You read it from the state and drop it into the prompt automatically. When the state changes, the prompt changes with it. That’s the whole point.

The loop stays the same on every turn. Only the context changes. The same build_prompt function gives a different prompt each time, because the state behind it has moved forward.

Step 3: Let the Agent Act and Capture Everything

Now run the step. Send the prompt you built to the agent, and the agent does its work — writes code, calls a tool, changes a file.

But the action is only half the job. The other half is to capture everything that came out of it:

  • The diff of what changed
  • The standard output from running the code
  • The failure message (if it failed)
  • The new state of the system

Here’s the code:

def act_and_capture(prompt, state):
    output = agent.run(prompt)   # the agent does the work
    result = run_checks(output)  # run tests, grab logs, get the diff
    return result

You’ve run the agent and captured the result. The result holds the diff, the output, and whether the checks passed.

Here’s the key idea: 「this output is not the finish line」. It becomes the raw material for the next prompt. The failure you just captured is exactly what you’ll feed back to the agent so it can fix the problem. So capture all of it — don’t throw anything away.

Step 4: Close the Loop with Feedback

You have a result. Now feed that result back through the “done” check from Step 1. This is what makes it a loop, not just a single move.

There are only two paths:

  • 「Passed? Stop.」 The job is done.
  • 「Failed? Turn the failure into the next prompt」 — automatically.

That second path is the magic. When the work fails, you don’t give up. You take the failure and turn it into the next instruction. Something like: “Tests failed with this error. Fix it.”

The agent then re-prompts itself using what just happened. You didn’t type that new prompt. The loop built it from the failure.

Here’s the code:

def loop(state):
    while True:
        prompt = build_prompt(state)      # Step 2: build context
        result = act_and_capture(prompt, state)  # Step 3: act and capture

        if is_done(result):               # Step 1: check done
            return result                 # passed, so stop

        # failed — turn the failure into the next prompt
        state.last_error = result.error
        state.past_attempts.append(result)

The loop closes on itself. If you’re done, return and stop. If not done, save the error into the state. The next turn’s build_prompt will include that error automatically. The agent re-prompts itself using the failure. The loop feeds itself.

Step 5: Set the Stop Conditions (Guardrails)

A loop with no way out is not a system — it’s a cost that never stops. If the agent keeps failing and the loop keeps running, it will burn time and money with no end. So you must design guardrails.

Set the stop conditions once, then let the loop run safely. Important guardrails:

  • 「Cap the retries」 — stop after a fixed number of turns, even if the job isn’t done.
  • 「Watch the cost」 — stop if you cross a budget for time or money.
  • 「Add a human checkpoint」 — for risky actions, pause and ask a person before proceeding.

Here’s the loop with guardrails added:

def loop(state, max_turns=10, max_cost=5.0):
    turns = 0
    cost = 0.0

    while turns < max_turns and cost < max_cost:
        turns += 1
        prompt = build_prompt(state)
        result = act_and_capture(prompt, state)
        cost += result.cost

        if is_done(result):
            return result   # success

        state.last_error = result.error
        state.past_attempts.append(result)

    return "stopped: hit a guardrail"   # safe exit

The loop now stops when the job is done, or when it runs out of turns, or when it crosses the budget. There’s always an exit. The loop can never run forever.

「Note」: The human checkpoint matters most for actions that are hard to undo — deleting a file, sending money, or pushing to production. For these, pause the loop and let a person say yes before the agent acts.

The Full Loop in Code

Now let’s put all five parts together in one place:

# Step 1: define done
def is_done(result):
    return result.tests_passed

# Step 2: build the context from state
def build_prompt(state):
    return f"""
    Goal: {state.goal}
    Files: {state.files}
    Last error: {state.last_error}
    Past attempts: {state.past_attempts}

    Decide the next step and make the change.
    """

# Step 3: act and capture
def act_and_capture(prompt, state):
    output = agent.run(prompt)
    return run_checks(output)

# Step 4 and 5: close the loop with feedback, inside guardrails
def loop(state, max_turns=10, max_cost=5.0):
    turns = 0
    cost = 0.0

    while turns < max_turns and cost < max_cost:
        turns += 1
        prompt = build_prompt(state)
        result = act_and_capture(prompt, state)
        cost += result.cost

        if is_done(result):
            return result

        state.last_error = result.error
        state.past_attempts.append(result)

    return "stopped: hit a guardrail"

The five parts work together as one system. Write this once, and the agent can finish multi‑step jobs on its own.

Walk Through One Run

Let’s walk through an example. Suppose the goal is “fix the failing login bug”.

「Turn 1」: The state has the goal and the files, but no error yet. Build the prompt and send it. The agent changes the code. Capture the result. The tests still fail with “password check returns true for empty password”. Not done, so save this error into the state.

「Turn 2」: Now build_prompt includes the error from Turn 1. The agent reads “password check returns true for empty password” and fixes that exact line. Capture the result. The tests pass.

「Turn 3」: There is no Turn 3. The is_done check returned True on Turn 2, so the loop stopped on its own.

Notice the most important thing: you didn’t type a single prompt during this run. The error from Turn 1 became the prompt for Turn 2 — automatically. The loop prompted the agent for you, and it stopped the moment the job was done.

Cost of Running the Loop

Here’s something that surprises people. Writing the code is cheap. Running the loop that writes it, again and again, is not.

The model writes a piece of code in seconds for a tiny cost. But the loop runs that model again and again, turn after turn, sometimes for hours. Every turn costs a little. A loop that runs all night could run thousands of turns. The real cost isn’t producing the code once. It’s all the turns the loop takes to get there.

That’s why the stop conditions from Step 5 matter so much. A loop that doesn’t stop isn’t just a bug — it’s a charge that keeps growing while you sleep.

Your most important job has changed. It’s no longer about writing one clever prompt. It’s about 「making sure the loop halts」. Cap the turns, watch the cost, and stop the moment the job is done.

Reusable Skills

Now let’s talk about what matters most in the long run. The loop itself is just the wiring. The real value is in the skills it calls.

What’s a skill? A small, reusable tool that does one job well. Instead of asking the model to figure out the same thing from scratch every turn, you turn that repeated work into a named tool the loop can call directly.

Here’s the rule: when you find yourself doing the same step again and again, pull it out and make it a skill. When you crack a hard problem, save that solution as a skill too. After that, the loop gets it for almost no cost on every later run.

A loop with no skills inside it asks the model to solve the same problems all over again on every turn. A loop that calls a set of sharp, tested skills gets stronger every time you add one. That’s what makes a loop grow more valuable over time — instead of just burning money.

Common Mistakes to Avoid

Most people make these mistakes when designing a loop. Learn them so you can avoid them:

Mistake Why it’s a problem How to fix it
No “done” check The loop never knows when to stop Always write Step 1 first
Hand-feeding the prompt You’re doing the work, not the loop Build the prompt from state
Throwing away the output The failure is the next prompt — you lose it Capture everything
No stop conditions Loop runs forever and keeps charging you Cap retries and watch cost
Forcing a loop on a one‑off task Over‑engineering for something that doesn’t repeat Use a plain prompt instead
No skills inside the loop The model re‑solves the same problems every turn Turn repeated work into reusable skills

So stop playing the game move by move. Design the loop once, give it a way to check itself and a way to stop, and then let it run.

Frequently Asked Questions

「What kinds of tasks are a good fit for a prompt loop?」

Tasks that need multiple steps and have an automatic “done” check. Examples: code fixing, test‑driven development, document generation, data cleaning. For one‑off Q&A or creative writing, a single prompt works fine.

「How do I know if a task is worth building a loop for?」

Ask yourself three questions: Does this task need more than two steps to finish? Can I write an automatic check for “done”? Will I run similar tasks repeatedly? If all three answers are yes, a loop is a good choice.

「What happens if the loop gets stuck in a failure cycle?」

It won’t — because you added stop conditions (max turns and cost caps). You can also add a human checkpoint. The loop always has a safe exit.

「How can I control the cost of running a loop?」

Three main ways: set a max number of turns, set a cost budget (e.g., $5.00), and build a library of reusable skills so the model doesn’t have to re‑invent solutions each turn. Also, choose the right‑sized model — not every task needs the largest, most expensive one.

「Can I nest one loop inside another?」

Yes. Complex tasks often need multi‑level loops. For example, an outer loop handles overall task planning, while an inner loop handles detailed execution of a single subtask. Just be mindful of total cost and complexity.

「What’s the relationship between a prompt loop and a large language model?」

The loop is the orchestration framework. The LLM is the execution engine. The loop handles task decomposition, state management, and flow control. The model handles the reasoning and actions on each turn.

「How should I start building my first loop?」

Start minimal. Write an is_done check (e.g., does a certain line exist in a file?). Write a simple build_prompt function. Add a max_turns=3 loop. Run it. Once it works, gradually add more skills and guardrails.

Summary

You no longer play the game move by move. You design the loop once, give it a self‑check and a way to stop, and then let it run.

  • A prompt is a single move. A loop is a strategy.
  • Five parts: define done, build context, act and capture, close with feedback, set stop conditions.
  • Write the “done” check first — before anything else.
  • Build prompts from state — never hand‑type them.
  • Capture every output — failures are the raw material for the next turn.
  • Always have guardrails: cap turns, watch cost, add human checkpoints when needed.
  • Extract reusable skills — that’s how the loop becomes more valuable over time.

That’s how you design a loop that prompts your agent to solve real, multi‑step problems — in a clean, simple, and safe way.