Skip to content
AspirecoStart
All guides

Automation

Putting AI agents into a real process

Last revised 10 min read

The difference between an agent that demos well and an agent you would let touch a customer comes down to a handful of decisions, and none of them are the prompt. Here is where the human gate goes, what has to stay deterministic, and what to log.

Most of the interesting work in an agent system happens outside the model. The prompt is the part everyone shows you, and it is the part that changes least once the thing is running. What determines whether a pipeline survives contact with real customers is the scaffolding around it: which steps are allowed to be non-deterministic, where a person is required to press something, what happens when a provider returns nothing, and whether you can reconstruct a run three weeks later.

Two of the systems we have built are useful to think with, because both are pipelines with a model in the middle and a person at a specific point. POD Engine takes a cultural signal to a listed product: nine stages, fourteen production workflows, and exactly one human approval gate. Agent Console is the other half of the problem — six control surfaces in one screen, so the honest answer to "what is running right now" is not twenty minutes and four dashboards.

What the model is for, and what it is not for

A language model is good at three things in a business process: reading unstructured input that no schema could describe, producing a first draft, and classifying something genuinely fuzzy. It is bad at arithmetic, bad at giving you the same answer twice, and bad at being auditable.

Growth Engine has both kinds of step in one pipeline, which makes the boundary easy to see. One step fetches a prospect's homepage and scores it on six dimensions — first impression, mobile, search, call to action, trust and booking flow — returning three issues, three recommendations and one hook. That is a judgement about a page nobody has ever described in a database, so a model does it.

The other score is qualification: a nought-to-hundred number derived from rating, review volume and business type, which routes the lead to one of five service lines. That one is a function. No model, no network, same answer every time. It has to be, because someone will eventually ask why a lead was banded the way it was, and "the model felt that way on Tuesday" is not an answer.

The same line runs through Contractor OS, where money never touches a model or a floating-point number. Every calculation happens in integer cents, there are zero floating-point money values in the system, and every financial document posts a balanced journal entry. If a figure ends up on an invoice or in a ledger, it comes out of code you can read line by line.

The test we use

If you would be uncomfortable with a step producing a different answer tomorrow on the same input, it is not a model step. Write the function. The model can explain the result afterwards, if an explanation is what you actually wanted.

One gate, at the last reversible moment

POD Engine runs nine stages from trend to storefront: audience bootstrap, trend capture, scoring, idea generation, legal screening, approval, design generation, publishing to the printer, then social scheduling. Exactly one of them waits for a person. Everything upstream is mechanical and everything downstream is mechanical. The gate sits precisely where taste and legal risk live, and nowhere else.

The placement rule is simpler than it sounds: the gate goes immediately before the first step a stranger can see, or the first step that spends money. In POD Engine that is the moment before artwork is generated and published to the printer. In Growth Engine it is the send button — every draft waits for an approval tap before the mail worker touches it. In Content Factory it is publication: the pipeline writes drafts into the scheduler, and a person stands between the pipeline and the audience.

The temptation is to add gates everywhere, on the theory that more oversight is more safety. It is the opposite. The cost of an approval gate is not the operator's time, it is their attention, and attention does not divide cleanly. Spread the same person across a handful of gates a day and every one of them becomes a reflex. One gate that genuinely stops the line gets read.

The interface matters as much as the placement. POD Engine drives approvals and status through a chat bot, so the operator's entire interface is a phone. A gate that requires a laptop, a VPN and a dashboard login is a gate that gets approved from a car park without being read — which is worse than no gate at all, because it manufactures a record of a decision nobody made.

Screen before the human, not after

Look at the order of the middle stages in POD Engine: ideate, then screen, then approve. The legal review pass runs before a person ever sees the idea, not after they have approved it.

There are two reasons for that ordering. The first is that a human should not be the trademark check. Screening a design against brand and licensing risk is pattern work — done consistently or not at all — and a person doing it at pace all day will do it worse than a check that never gets bored. The second is queue hygiene. If the operator's queue is full of ideas that were never going to survive screening, the operator learns to skim, and you are back to the rubber stamp.

Growth Engine takes the same idea further, because outbound email in Canada has a regulator attached. Compliance there is code rather than a paragraph in a prompt. A contact address has to be published on the prospect's own site, with the source URL kept as evidence. Guessed and suppressed addresses fail closed — zero email addresses have ever been guessed by the system. The unsubscribe footer and mailing address are appended deterministically after the model has finished. And the banned-phrase check runs after the model, not instead of it.

The distinction worth keeping

A prompt is a request. A check is a guarantee. Anything you would have to defend to a regulator, a client or a rights holder belongs in the second category, and the fact that the model followed the instruction a hundred times in testing is not evidence about the hundred-and-first.

Design the failure case first

The question that separates a prototype from a system is not what happens when the model works. It is what the process does at three in the morning when a provider returns a 503, or half a response, or a response in the wrong shape.

Asisly answers phones, so its failure mode is the worst one available: silence. A caller will forgive a slightly wrong answer and will not forgive a long silence. The model path there sits behind a custom proxy that caches the unchanging half of every prompt, retries, falls back to a faster sibling model, and — if a turn is already half-streamed when it breaks — finishes it with a speakable line rather than trailing off. The first syllable lands about seventy-five milliseconds after the text, which is inside the pause a caller would leave anyway. Of the thirty-three languages it answers in, the seven the primary transcriber does not support are routed to a second provider rather than being quietly allowed to degrade.

Content Factory makes the same choice structurally. Every render stage has three fallback tiers, and B-roll comes from four licence-verified sources in a ranked cascade. Across forty-two niches and four language regions, a single provider outage does not empty the schedule; it produces a slightly worse video.

The general rule we apply: cosmetic steps fail open, irreversible steps fail closed. A missing stock clip should downgrade the output. A missing compliance record should stop the line.

Logged, and replayable

Logging an agent is not the same as logging a web request, because the interesting part is not the status code. You need the input the step received, the prompt that was actually assembled, the model and version that answered, the raw output, and what the downstream code did with it. Any one of those missing and a bad run becomes unexplainable.

Agent Console exists because that visibility spreads across tools faster than anyone plans for. It puts status, active sessions, agent profiles, transcript tails, memory search and infrastructure operations behind one interface, streams long-running output over server-sent events so jobs are watchable rather than polled, and keeps workflow runs and model spend on the same screen as service status, logs and restarts. Spend belongs there. On an agent pipeline, cost is an operational signal — a run that suddenly costs several times what it did last week is telling you something before any output looks wrong.

Replayable is the stronger property, and it is worth being honest about which steps can have it.

Step typeWhat to recordWhat replay means
Deterministic functionInputs, outputRe-run it, get the identical answer
Model callInput, assembled prompt, model and version, raw output, parsed resultYou cannot reproduce it — the log is the record
Human gateWho, when, the decision, and what was on screenReconstruct what the person was actually shown
Side effectRequest, response, idempotency keyProve it happened once rather than twice

Identity helps here more than most people expect. Growth Engine's intake webhook validates, deduplicates and assigns a lead ID before anything downstream sees the record, so every row created later carries a key that traces back to one sweep. POD Engine persists niches, design styles and scored ideas in Postgres, which is how the system learns which segments convert instead of restarting cold — and it means yesterday's decisions are still there to argue with.

Demo versus something you would let touch a customer

A demo has one happy path and an operator standing next to it. The gap to production is mostly unglamorous:

  • Tenancy. Asisly resolves the business from the number that was dialled, so one assistant serves many businesses without their data ever meeting. A demo containing one customer's data has not answered this question.
  • Test surface. The same system carries six hundred and forty-three backend tests, seventy versioned migrations and thirteen scheduled jobs on a quarter-hour cadence. Scheduled work is where agent systems rot quietly.
  • Determinism you can prove. Contractor OS ships a demo dataset that produces byte-identical figures on the embedded WebAssembly Postgres used locally and the managed Postgres in production — same revenue, same margin, balance sheet out by exactly 0.00 on both.
  • Demonstrable without credentials. Agent Console seeds every screen with representative data, so the product can be shown without handing anyone live access.
  • Checked, not assumed. When Shopflooring replatformed, every one of the 36,786 legacy URLs was mapped to a live destination before the DNS cutover, and those destinations were checked 300 for 300 against production. A redirect map that mostly works is a redirect map that does not.

Where to start

Write the process out as discrete steps before deciding where the model goes. POD Engine is fourteen workflows and nine stages, not one long prompt with tools attached, and that decomposition is what makes it possible to say which single stage a person owns. Then, for each step, ask two questions: does this need judgement, and is this reversible. The first answer tells you whether a model belongs there. The second tells you whether the gate goes before it.

Most processes need less model than the pitch suggests and more scaffolding than the budget assumes. That is not an argument against agents. It is the reason the ones that stay running are boring in the middle.

If you have a process in mind and want to know which parts of it should involve a model at all, tell us about it. The answer is often that two steps should, and the rest should be code.