Guide 01 · 9 min
How to write a marketing loop
A loop is three prompts and a rule about when to stop. This works one through from a vague request to a file an agent can run unattended.
A loop is a marketing job written so an agent can finish it without you watching. It has four parts: a goal prompt, a verifier prompt, a stopping condition, and a note on what it is allowed to touch. If you can write those four things, you have a loop.
This works one through from a request a person would actually make.
Start with the request, not the prompt
Say someone asks: “make our pricing page better for AI search.”
That is not a loop. An agent handed that will do something, declare it good, and stop. There is no way to check it and no way to know when it is done. Every failure in this category starts here, with a request that sounds actionable and is not.
The fix is to ask what would have to be true for the job to be finished. Not “better”, but what specifically changed, and how would a second person confirm it without trusting the first.
For the pricing page, one honest answer: the page answers the three questions buyers actually ask about price, each in its own section, with a number that names its source. That is checkable. A script can count sections. A person can look for the numbers.
Write the goal prompt
The goal prompt tells the maker what to do. It is not a description of the outcome; it is an instruction with the constraints in it.
Read <page> and <buyer-questions-file>. Identify every question about price
that appears in the buyer questions file. For each one, check whether <page>
answers it in its own section. Where it does not, write that section, using
only numbers that appear in <claims-file> with their source. Do not change
any existing number. Do not add a claim that is not in the claims file.
Output a diff.
Three things make that work, and they are the same three every time:
- It names its inputs. The page, the questions file, the claims file. An agent that has to guess where the truth lives will invent it.
- It says what may not change. Existing numbers, unlisted claims. A loop without prohibitions will quietly rewrite things you did not want touched.
- It names the output form. A diff, not “improvements”. You cannot review a vibe.
Write the verifier prompt
This is the part most people skip, and skipping it is why most attempts fail. The verifier is a second agent, in a fresh session, that did not do the work. It grades the maker against the same spec and it has to be able to fail.
Read the diff and the original <page>. FAIL if any existing number changed.
FAIL if any added claim does not appear in <claims-file> with a source. FAIL
if any price question from <buyer-questions-file> still has no section. FAIL
if the diff touches anything outside the sections it claims to have added.
Otherwise PASS. Print the verdict and the reason.
Notice what it does not say. It never asks whether the writing is good. A verifier that grades taste will always pass, because the model that wrote the copy also thinks the copy is fine. Verifiers check facts, counts, and boundaries. Taste is your job at the gate.
The test for a verifier: can you describe an output it would reject? If you cannot, it is decoration. Write a deliberately broken version of the work and confirm the verifier catches it. This is worth doing once, by hand, before you trust the loop.
Write the stopping condition
One sentence, checkable by someone who was not in the room.
Every price question in the buyer questions file has a section on the page, no existing number changed, and the verifier printed PASS.
Compare that to “the pricing page is better for AI search.” The first is a state you can observe. The second is an opinion that arrives whenever the agent gets tired.
If you cannot write the stopping condition, the job is not ready to hand to an agent. That is not a failure of the agent. It means the request is still vague, and narrowing it is the actual work.
Decide what it may touch
Last, and quickest. Write down what the loop is allowed to do and what it may never do.
- May: read the page, read the files, write a diff, open a pull request.
- May not: publish, send, change a number, touch a file outside the page.
This is what makes the difference between a loop you can run unattended and one you have to watch. The constraint is not a formality; it is the thing that lets you walk away.
Put it in a file
Save the four parts as one markdown file in your project, for example
.claude/loops/pricing-answers.md. Every loop in the catalog is exactly this,
and you can download one to see the shape.
Then run it: paste the goal prompt into your agent, let it work, and when it stops, open a fresh session and paste the verifier. Read the verdict before you read the work.
What you will get wrong the first time
Three things, reliably:
The stopping condition will be too loose. You will write “the page is answer-ready” and discover the agent agrees with itself. Tighten it until it names a count or a comparison.
The verifier will never fail. Test it against a broken run before you trust a clean one. A checker that has never failed has not been tested.
The scope will creep. The agent will fix an adjacent thing it noticed. That is why the prohibitions matter and why the output is a diff you read.
None of this is wasted. Each failure tightens the file, and the file is the asset. The next run is better because the loop is better, not because the model is.
Next
- How to write a stopping condition, the part that decides whether any of this works.
- How to write a verifier that fails, the part most people skip.
- Or skip the writing and copy one that already runs.