Automation and workflows
Most of what gets pitched as an agent is better as a workflow: cheaper, faster, and easier to reason about. We build both, and the first useful thing we do is tell you which one a job needs.
01When
Workflow, agent, or both
The choice is not a matter of taste. It follows from one question: does the path vary with the input, or is it the same every time?
- a workflow
- The path is known, the same every time, and a person could write it down as steps. Deterministic, cheap, and debuggable, because every run took the route you wrote.
- an agent
- The path varies with the input, and enumerating every branch would be longer than describing the goal. You give it tools and a stopping condition instead of a flowchart.
- both
- The common answer. A workflow handles the deterministic spine, and calls an agent for the one step that needs judgment. The agent's output goes back into the workflow, where the rules still apply.
We will recommend the workflow when the workflow is the right answer, even though it is the smaller piece of work. A scripted job you can read top to bottom is worth more to your team than a model deciding something that was never in doubt.
02Wire
What we actually build
The parts below are the difference between a job that works on your laptop and one that runs unattended on a Sunday night.
- triggers
- Webhooks, schedules, queues and inbound email, whichever the system already emits. We listen to what exists rather than asking your team to click something new.
- background jobs
- Work that runs without a browser tab open, with a queue in front of it, so a slow API call never blocks the request that started it.
- idempotency
- Every job carries a key, so a retry does not send the message twice or refund twice. The second attempt recognizes the first and returns the same result.
- retries and backoff
- Transient failures retry on a curve. Permanent failures stop immediately rather than hammering an API that has already told you no.
- dead letter
- Anything that fails past its retries lands somewhere a person will actually look, with the trace attached, so the fix starts from evidence rather than a guess.
03Gate
Where a person signs off
A human gate is only real if someone sees it, understands it, and cannot ignore it into a default. Here is how we wire one.
-
The queue lives where the team already works
Approvals arrive inside the tool the team is already in, not a new dashboard nobody opens. If the work happens in a shared inbox, a chat channel or the CRM, the gate goes there.
-
The approver sees the write, the record and the trace
Not a yes or no button on its own. The approver sees what the job intends to write, the record it would touch, and the steps that led there, so approving is a judgment rather than a reflex.
-
An unapproved action expires
When the window closes, the action fails closed. It does not execute by default because nobody looked. The job records that it timed out and why it was waiting.
-
Escalation has a name and a clock
You tell us who gets it next and after how long. We write that into the job, so an expired approval moves to the next person on the path instead of dying in a queue.
04Trust
What keeps a workflow trustworthy
Unattended work fails quietly unless you build for the failure first. These four are not extras we add at the end.
Every run records its trigger, its inputs, each call it made and what came back. When someone asks why an order was not fulfilled on Friday, the answer is a run you can open, not a theory.
Jobs are keyed so a replay is safe. Retrying a run that already sent the email, moved the deal or issued the refund returns the first result instead of doing it a second time.
Every job has a defined end for the case where it cannot finish: retry, escalate, or dead letter. Nothing is left to time out silently, and no failure is handled by hoping the next run picks it up.
Concurrency, rate limits and model spend are set per workflow and enforced inside the run. A backlog drains at a speed your APIs allow, rather than at whatever speed the queue can push.
Where this connects
Workflow work usually arrives attached to something else: an agent that needs a spine around it, or a platform whose automations have run out of room.
05Asked
Questions we get asked first
Can you work with the automation tool we already use?
Usually, yes. If a workflow already runs in a tool your team knows, we keep it there and build around it. We move a step into code only when the tool cannot express what the step needs: an idempotency key, a backoff curve, a dead letter path a person can work through. When we do move it, the trigger and the queue stay visible to the people who owned them before.
What happens when an approval is never actioned?
It expires. An unapproved action does not execute when the clock runs out; it fails closed, records why, and escalates to the next person on the path you set. Nothing sits in a queue forever, and nothing goes out because the approver was away.
How do you stop a retry storm hitting our API?
Retries run on an exponential backoff with jitter, and only for failures that could succeed on a second attempt. A permanent failure, such as a rejected payload or a record that no longer exists, stops on the first response and goes to the dead letter queue instead of being tried again. Concurrency and rate limits are set per integration, so a backlog drains at a speed the API allows.
Bring us the job that keeps getting done by hand
Describe the trigger, the steps, and the one decision you would not let a script make. We will tell you which parts are a workflow, which part needs an agent, and where the approval belongs.