I used to spend most of my day typing at a model, which is prompt, read the answer, then prompt again. I was faster than I'd been without it, and still sitting inside the loop.
Now two agents run on my support inbox every morning. The first closes open tickets through the intercom API at 8am. The second reviews everything it closed at 10am, and reopens anything that shouldn't have been. It's doing the job I used to do.
Getting there took months, and what blocked me was never the wording of the prompt.
WHAT I TRIED FIRST:
I appended "don't stop until..." to the end of a long prompt. That works in the sense that the model keeps going. It doesn't work in the sense of telling me whether the result is right, since the thing doing the work is also the thing judging it. This is the whole problem.
WHAT ACTUALLY FIXED IT:
The fix is a checker inside the loop, not a better prompt. It has 3 parts and each one does a different job.
- An end state instead of a task, so there's something concrete to finish against. "Sort every file in my downloads folder into subfolders by type, keep going until no files are left"
- Something countable it can check itself against, since a model grading its own prose will always pass itself. Zero loose files, zero rows without a label, tests passing
- A guardrail so it can't do damage while nobody is watching. Don't delete anything, stop after 30 turns
That's the /goal command in claude code or codex, where a small fast model checks the condition on every pass and then verifies the whole thing at the end.
5 GOALS I'VE ACTUALLY RUN:
These are 5 I've run myself, so you can see the shape of them.
- Rename every invoice into this format in date order, until no file has its original name. Stop after 25 turns
- Categorise this spreadsheet until no row is missing a label
- Work through this stack of documents until none are left
- Clean up these captions until they all fit my brand voice rules
- Turn each of these rough ideas into hooks until the list is done
That means every one of them has a countable end. It's the whole requirement, not a coincidence.
Putting it on a schedule
Once that stops being interesting you put it on a schedule. Mine reads unread email at 9am, works out the 3 most important, and sends them to me on slack, with a constraint that it doesn't reply to anything.
RUNNING 2 AGENTS INSTEAD OF !
The pair at the top of this post is the part that changed how I work, and the timing matters as much as the split.
- The first runs at 8am, cleans up open support tickets through the intercom API, and posts a summary in slack with full links so I can click straight through. It doesn't stop until every open ticket is processed
- The second runs at 10am, two hours later since the first one takes a while. Its only job is to review every ticket the first one closed and confirm it should have been closed. If the reply didn't clearly solve the customer's problem, it reopens it
One practical note on the API:
I use the intercom API rather than the intercom connector, because the connector can't close tickets and the API can. You do that by creating a separate environment and putting the API key in as an environment variable. If a tool you need has no connector, that's the way around it.
Final thoughts:
I should say the hard part is defining what done means, not any of the above. For files that's easy, since done is countable. For something like whether a social post is good, I still haven't solved it.
The second agent is doing the job I used to do. That took me longer to get comfortable with than I expected.