DEV Community

Cover image for Write your first loop
Nazeeh Vahora
Nazeeh Vahora

Posted on

Write your first loop

We are using AI to code for a significant amount of time now. With the space moving so quickly, there's a lot happening and with so much noise it's hard to keep track of.

Likewise, the way we code has evolved so much. from writing code manually using Stack Overflow, to using Copilot in VS Code, to using agent windows in our IDEs, to writing prompts and steering the agent to manage tasks, to now writing loops and letting the agent manage itself.

But writing loops is a relatively newer concept and there are still not a lot of examples to look at. So let’s see some practical examples of writing loops for a specific scenario.

What is a Loop?

Most people use AI the slow way: they write a prompt, wait, check the result, and prompt it again. Every step runs through you, the AI is just a tool in your hand.

The faster way is a loop. You hand the AI a goal, a way to verify the result, and a rule for when to stop, then you step out. You write the prompt once and it manages itself.

According to the Claude Code team, a loop is an agent repeating cycles of work until a stop condition is met. They categorize loops based on how they’re triggered, how they stop, and which primitive runs them. This gives us four kinds: turn-based, goal-based, time-based and proactive

Working Example

Consider you have a personal blog. It’s a static website in a GitHub repo, automatically deployed on every push.

Over the years, external links in your posts die. A tool gets rebranded, pages move, domains expire and now your post points to a 404.

This is a perfect first loop because the “done” condition is objective: a link either returns a successful response or it doesn’t.

By the end of this article, the blog will fix itself while you sleep.

Turn-based Loop: fix it once

triggered by: you. stops when: claude judges its done. verifier is: you.

Every prompt you send to the Claude Code already starts a loop i.e. agentic loop. Claude gathers context, acts, checks its work, repeats if needed and responds.

Check every post in content/posts for broken external links: request each external URL and treat anything that errors or returns a 4xx/5xx status as broken. For each dead link, find the current URL and update the post. When you're done, show me a list of every link you
checked and its status.
Enter fullscreen mode Exit fullscreen mode

claude sweeps the posts, fixes what it finds, and hands control back with the evidence you asked for. You read the list, spot-check a post and prompt again if something's off. Every cycle runs through you.

This works, but notice the ceiling: every cycle runs through you. you are the trigger and the verifier. The last line of the prompt, "show me every link and its status" is doing an important work. it forces the verification into the transcript, where you (and soon something else) can judge it.

Bridge to Loop 2: once the success criteria (“every external link returns a success status and the site builds”) is written down, you can hand off the judging to the agent.

Goal-based loop: keep going until it’s actually done

Triggered by: you, once. stops when: goal achieved or max number of turns reached

A single turn often isn't enough. Claude fixes forty links, three are still dead, and it stops anyway because it judged the work "good enough". The /goal command removes the judgement call.

/goal every external link across all posts has been requested and returns a success status, the site builds without errors, and no post is deleted or truncated — or stop after 10 turns
Enter fullscreen mode Exit fullscreen mode

Now, after every turn, a separate small model reads the conversation and checks your condition. If not met, claude gets sent back to work. Here, the evaluator's reason is treated as guidance, without you typing anything. The goal clears itself when the condition is met.

Three things make the goal condition reliable:

  • A measurable end state (e.g., “every link returns a success status”)

  • Visible evidence in the conversation

  • A hard limit (e.g., or stop after 10 turns)

One honest trade-off: A named command with an exit code is the most reliable evaluator. Start with a description; if the loop stops early or spins, pin the condition to a real command.

Time-based Loops: Watch Something External

Triggered by: The clock

Stops when: You stop it or it expires

Link rot doesn’t happen while you’re watching. Links break over weeks, and deploys fail when you’re not looking.

The first two loops only run when you manually trigger them. The /loop command runs a prompt on an interval instead:

/loop 30m check every external link on the live site and treat any that error or return 4xx/5xx as broken. If any are broken, fix them in the source post, commit, and push. If the last deploy failed, read the build log, fix the cause, and push. If everything is green, say so in one line.
Enter fullscreen mode Exit fullscreen mode

Every thirty minutes, Claude checks the live site and the last deploy, fixes what’s broken, and reports in one line when nothing is wrong.

Useful mechanics:

  • The interval leads the prompt: 5m, 30m, 2h, 1d. Omit it entirely /loop check every external link…) and Claude picks its own delay each iteration, short while something's in flight, longer when things are quiet.

  • Press Esc to stop a loop while it’s waiting

  • Loops expire after seven days (this is actually a safety feature)

It has a limitation though. /loop lives in your session, on your machine. If you close the laptop and the loop stops. Which is why we need the fourth kind.

Proactive loops: the blog fixes itself

Triggered by: A schedule, GitHub event, or API call (no human present)

Stops when: Each run exits when its job is done; the routine itself runs until you turn it off

For this, we use the /schedule command. This saves the prompt as a routine that runs on Anthropic’s cloud.

/schedule every Monday at 8am, check every external link across the blog's posts and treat any that error or return 4xx/5xx as broken. Fix each one (prefer the page's new URL, fall back to an archive.org snapshot), verify the site builds, and open a PR titled "Weekly link rot sweep" summarizing what changed. If nothing is broken, don't open a PR.
Enter fullscreen mode Exit fullscreen mode

Claude walks you through the setup conversationally (asking which repo, environment, etc.) and saves the routine to your account.

Every Monday it clones the repo fresh, does the sweep, and opens a pull request, even if your local machine is off.

Features of proactive loops:

  • Runs fully autonomously

  • Output is a PR, not a direct change to main

  • Can be triggered by schedules or GitHub events / API calls

  • Manage with: /schedule list, /schedule update, /schedule run

Differences Between the Four Loops

before looking at the differences, there are certain similarities like the task never changed. It was the same blog, same broken links and same acceptance condition. What changed was who does the job.

Who triggers Who verifies Who stops it
Turn-based You You Claude's judgment
/goal You, once Evaluator model vs. your condition Condition met, or turn cap
/loop The clock The check described in the prompt Esc, or 7-day expiry
Routine Schedule or event — nobody The check + a human PR review You disable the routine

My observations:

  • Prove it manually first. Don't skip loop 1, instead it is a manual proof that both the task and the check work.

  • Not everything needs a loop. If the task don't repeat, keep it as a prompt.

  • Metric here is the cost per accepted change, not cost per run. A loop that runs cheap but produces PRs you always reject is expensive.

Some more resources about loops: ⤵️

docs: https://code.claude.com/docs/en/goal

https://x.com/ClaudeDevs/status/2074208949205881033

https://x.com/AnatoliKopadze/article/2068328135611822149

Top comments (0)