Agent or Just a Script? Count the Branches That Depend on Reading Something

There is a ten-minute test that settles whether your automation needs an agent loop or just a script with a couple of model calls in the middle — and the two ways of guessing wrong are not equally recoverable.

Agent or Just a Script? Count the Branches That Depend on Reading Something

Most "should this be an agent?" arguments go in circles because both sides are describing the same automation in different vocabulary. There is a faster test, and it takes about ten minutes with a pen: write out the steps, then count how many decision points require someone to read something before choosing a path. That number tells you which tool you need.

Zero such branches means you want a script. One means you want a script with a single model call in the middle. Three or more, especially when the branches feed each other, is where an agent loop starts earning its cost.

🔍 The test, applied to a real chore

Take a common personal-productivity job: clearing the receipts that pile up in an email folder and turning them into expense entries.

Written as flat steps:

  1. Pull unread messages from the receipts folder.
  2. Find the attachment or the inline receipt body.
  3. Pull out vendor, date, total, currency.
  4. Decide which expense category it belongs to.
  5. Decide whether it needs a manager's approval.
  6. Create the entry in the expense tool.
  7. Mark the message read.

Now mark each step by what it needs in order to proceed. Steps 1, 2, 6 and 7 need an API and a field name — no reading required, the path is the same every time. Step 3 needs reading, but it always produces the same shape of output. Steps 4 and 5 need reading and judgment, but the judgment is bounded: a category from a fixed list, an approval flag from a threshold plus a policy.

That is one extraction call and two classification calls, in a fixed order, with no step changing what the next step does. It is not an agent. It is a script with three model calls inside it, and building it as an agent buys you nondeterminism, a token bill, and a harder debugging story in exchange for nothing.

for msg in unread("receipts"):
    doc = extract_receipt(msg)              # model call, fixed output shape
    doc.category = classify(doc, CATEGORIES)  # model call, closed set
    if doc.total > APPROVAL_LIMIT:
        route_for_approval(doc)
    create_expense(doc)
    mark_read(msg)

Every line is inspectable. A failure lands on a specific line with a specific input.

When the same chore does need a loop

Change one thing: some receipts arrive as a forwarded thread where the actual charge is three messages back, some are a link to a vendor portal rather than an attachment, and some are a subscription renewal that should be matched against an existing recurring entry instead of creating a new one.

Now the branches interact. Whether you need to follow a link depends on what the extraction found. Whether you match or create depends on a lookup you only knew to run after reading the vendor name. Whether you go back and re-read an earlier message in the thread depends on whether the first pass produced a total at all.

You cannot flatten that into a fixed sequence without writing a state machine that enumerates every combination — and the combinations keep arriving, because the inputs are other people's email. That is the actual definition of the boundary:

Use an agent when the next step depends on the result of the previous step in a way you cannot enumerate ahead of time.

Not "when the task is complex." Not "when it involves language." When the control flow itself is data-dependent and open-ended.

The three questions, in order

Run these against the steps you wrote down.

1. How many branches depend on reading unstructured input? Zero → script. One or two, independent of each other → script with model calls. Three or more that feed each other → candidate for an agent.

2. Can you list every path in advance? If you can draw the full flowchart on one page and it stays true next month, code the flowchart. A flowchart you keep amending after every surprise input is a loop wearing a disguise, and you will end up maintaining a worse version of one.

3. Does the work need to recover, not just fail? A script's answer to a bad input is to stop and log. If the acceptable behavior is "try the portal link, and if that's a login wall, fall back to asking the sender," you need something that can choose a different action after a failure. That recovery ability is most of what you are paying an agent for.

⚠️ The cost of guessing wrong in each direction

The two mistakes are not symmetrical, and that should tilt your default.

Script when you needed an agent: you get a growing pile of special cases. Annoying, visible, and cheap to fix — the rewrite is usually mechanical, because the steps you wrote down become the tools the agent calls. You lose some time.

Agent when you needed a script: you get flakiness in something that had a correct answer all along. The same receipt classifies two ways on two runs. Costs scale with volume instead of staying flat. Debugging means reading traces instead of a stack trace. And there is no obvious moment when someone declares it was the wrong shape, so it stays.

Being wrong toward "script" is recoverable. Being wrong toward "agent" tends to be permanent. Default to the script and let the special cases push you.

💡 The useful middle

Most real work is not one or the other end to end. The receipts job is a deterministic pipeline with three model calls and one branch — the forwarded-thread case — that genuinely needs to loop. Build the pipeline as a script, and let that one branch call a small agent with two or three tools scoped to exactly that problem.

That shape is worth aiming for on purpose: the deterministic parts stay deterministic and testable, and the loop is small enough that when it misbehaves you can read the whole trace without scrolling. An agent wrapped around the entire chore would have made all seven steps nondeterministic to fix one of them.

Count the branches first. The architecture usually falls out of the count.

Keep reading

Similar posts

Matched on shared tags and category — the more bars, the stronger the overlap with what you just read.