Skip to content

AI & Machine Learning·8 min read

Workflow or agent? How we decide before writing a line of code

If every step of a process can be written down before it runs, build a workflow and put an LLM call only where something has to be read and interpreted. Use an agent only when the next step depends on what the last one found, and cap it hard.

Anatoli NavahrodskiFounder & CEO, GlanitPublished 26 October 2026

Do you need an agent, or a workflow with one LLM step?

If you can write every step down before the process runs, you need a workflow. Write the rules in code, and add an LLM call only at the step where a person would otherwise have to read something and interpret it: a scanned invoice, a complaint email, a contract clause. An agent is justified when the next step depends on what the previous step found and you cannot list the possible paths in advance. Anthropic's engineering team drew this line in December 2024. Workflows orchestrate LLMs and tools "through predefined code paths". Agents "dynamically direct their own processes and tool usage". The same post recommends the simplest solution that works, which "might mean not building agentic systems at all".

In our view, most processes that arrive with an "agent" label belong in the first two buckets.

Our scoping test is plain. We ask the operations lead to draw the process as boxes and arrows, including the exceptions they handle by hand on a bad Monday. When the drawing closes (every arrow ends in a known box), we build that drawing as code and put the model inside one or two boxes. When the drawing keeps growing an "it depends" box that leads to different tools each time, that box is a candidate for an agent. The rest of the process stays deterministic around it. An agent that runs a whole business process end to end is something we would recommend only for a very unusual process.

17% deployed, over 40% headed for cancellation

The 2026 numbers describe a market that bought the word "agent" faster than it could run one. In the 2026 Gartner CIO and Technology Executive Survey, only 17% of organizations had deployed AI agents, while more than 60% expected to within two years. Gartner places agentic AI at the Peak of Inflated Expectations in its Hype Cycle for Agentic AI (published 2 April 2026) and notes that most deployments are narrowly scoped.

The cancellation forecast is older than most coverage implies. Gartner published it on 25 June 2025: over 40% of agentic AI projects will be canceled by the end of 2027, because of escalating costs, unclear business value or inadequate risk controls. The same release named "agent washing", the rebranding of AI assistants, RPA and chatbots as agents, and estimated that only about 130 of the thousands of agentic AI vendors are real. Since then Gartner has added two sharper forecasts. On 26 May 2026 it predicted that by 2027, 40% of enterprises will demote or decommission autonomous agents after governance gaps surface in production incidents. On 29 September 2026 it predicted that 70% of enterprises will abandon agentic AI built by vendor forward-deployed engineering by 2028, citing soaring costs and systems the customer cannot evolve alone.

Robert Szczerba's Forbes analysis of 7 July 2026 summed up the pattern as "a management problem wearing a technology costume". The causes he lists are governance, data access, ownership and ROI.

Model quality is missing from every one of these lists. A team that picks an agent for a process that did not need one inherits exactly the three problems Gartner names: a cost per run that grows with every reasoning step, a value case that is hard to separate from what a rules engine would have delivered, and a control surface that has to be governed at the highest autonomy level.

Which of your processes are workflows in disguise?

Anything with a fixed set of outcomes and a rulebook someone could write down. The usual suspects:

  • Invoice approval: match to PO and receipt, check tolerance, route by amount and cost centre. The only hard part is reading the invoice.
  • Support ticket triage when the categories are known and stable.
  • Employee or customer onboarding, renewal reminders, access reviews.
  • ETL and back-office sync between a CRM, an ERP and a billing system.

Two practitioner write-ups from August 2026 arrive at nearly the same list. Imversion's post names form routing, invoice matching, triage for known categories, ETL, onboarding and access reviews as false agent use cases, with the rule "if we can specify the workflow before runtime, we should". Onplana puts the cost of getting it wrong in one line: the choice "decides whether the thing you bought fails loudly or fails plausibly". A rules engine that hits an unknown case throws an error. An agent writes a confident, reasonable-looking wrong answer and moves on.

The diagnostic we use on an existing "agent" is the trace. Pull a few hundred runs and look at the sequence of tool calls. If almost every run takes the same steps in the same order, you are paying a planner that never plans, and that sequence should become code.

The automation vendors have moved the same way. UiPath made Maestro Flow generally available on 17 September 2026 as a third canvas next to BPMN and Case on one orchestration engine, and added evaluations for Maestro BPMN that combine deterministic evaluators with LLM-judge evaluators. Agents run as steps inside a modelled process there.

Where an LLM step earns its place

An LLM step belongs wherever the input is unstructured and the output can be checked. In practice that means three jobs: extracting fields from PDFs and emails, classifying free text into a known set of labels, and drafting text that a person or a template finishes. Our Invoice AI and Feedback AI projects are built this way. The model reads the document or the message, and deterministic code does the matching, posting and routing.

Each LLM step gets the same three guards:

  1. A schema. The model returns JSON validated against a Pydantic model or JSON Schema, and a validation failure is a retry or a human task. A half-parsed answer never travels downstream.
  2. A confidence floor with an explicit unknown label. Below the floor, the case goes to a human queue with the model's guess attached, so the reviewer starts from a draft.
  3. A log line per call with model ID, prompt version and the validated output, so an auditor can replay why a case went where it went.

The human queue does more work than it looks like. Its volume is the metric that tells you whether the step is good enough, and its resolved cases become the evaluation set for the next prompt or model change. Model routing and caching for these calls are covered in our piece on AI cost control, so we skip them here.

When does a bounded agent make sense, and what do we cap?

A bounded agent makes sense for the exceptions your workflow cannot enumerate: a supplier dispute that needs the contract, the order history and last month's emails, a research task where the next search depends on the last result, a failed reconciliation with no obvious cause. Anthropic describes the fit as "open-ended problems where it's difficult or impossible to predict the required number of steps". We put the agent behind the workflow, so it only sees cases that rules and the classifier have already declined.

Then we cap it. Maximum steps per run (Anthropic also recommends stopping conditions such as a maximum number of iterations). A token budget per run, enforced outside the model. A tool allowlist, read-only by default, with credentials scoped to that one agent. An approval gate before any write, payment or outbound message, which is Gartner's "act with approval" level from the May 2026 governance framework (observe, advise, act with approval, act autonomously). And every tool call goes into an audit log the agent cannot edit, which is why we run agents behind SealedRun.

The less visible cost is attack surface. Every email, PDF and web page an agent reads is input that can try to steer its next tool call, and every tool it can reach is a target. A classifier with no tools can at worst pick the wrong label. Tool servers need their own vetting, which we describe in MCP servers in production.

Four architectures, side by side

Read the table top to bottom as a ladder. Each row adds flexibility and moves the failure mode from loud to quiet, and the cost from fixed to variable. We climb only as far as the hardest case in the process requires. The comparison is qualitative, because no current public source gives per-run costs that would transfer across processes.

Deterministic workflow, workflow with LLM steps, bounded agent and open agent compared on cost, failure mode and auditability
ArchitectureCost per runTypical failure modeAuditability
Deterministic workflowFixed and close to zero; compute onlyLoud: unknown input raises an error or stopsFull: each decision maps to a versioned rule
Workflow + LLM stepsOne or a few model calls per case, predictableWrong label or field, caught by schema and confidence floorHigh: the path is fixed, model outputs are logged and replayable
Bounded agentVariable, limited by step and token capsPlausible wrong action, stopped at an approval gateMedium: needs full tool-call traces to reconstruct
Open agentVariable and unboundedPlausible wrong action that executesLow: reasoning differs run to run, hard to replay
Deterministic workflow, workflow with LLM steps, bounded agent and open agent compared on cost, failure mode and auditability — Qualitative comparison based on Anthropic's workflow/agent trade-offs (Dec 2024) and Gartner's 2026 governance guidance.

What we would do next time

Start with the router. Rules first, one validated classifier call second, and an agent only for what both decline, with the caps written into the call. A sketch of the shape we use for triage-type processes:

def route(case: Case) -> Decision:
    if hit := RULES.match(case):                      # 1. versioned rules
        return Decision(hit.queue, source="rule", rule_id=hit.id)

    label = classify(case.text, schema=Label)         # 2. one LLM call, validated
    if label.category != "unknown" and label.confidence >= 0.85:
        return Decision(label.queue, source="llm", prompt=label.prompt_version)

    if case.priority == "low":                        # 3. cheap cases go to people
        return Decision("human_review", source="fallback", guess=label)

    return run_agent(case,                            # 4. bounded agent
        tools=["crm.read", "kb.search", "orders.read"],
        max_steps=8, max_tokens=40_000,
        approval_required=["crm.write", "email.send"])

The thresholds are placeholders; we set them from the first few hundred historical cases. Then we watch where cases land each week. If step 4 handles a growing share of cases that end the same way, those endings become rules, and the agent shrinks.

Bring one process to us and we will tell you which of the four rows it belongs in. It is the first question in every AI and process automation project we scope. Describe the process here.

Frequently asked questions