Building an AI Agent That Can Handle People Going Off-Script

25 August 2026

Building an AI Agent That Can Handle People Going Off-Script

I was working on a flight booking agent where the normal flow was straightforward:

Trip → Passengers → Flight → Meal → Confirm → Book

This kind of flow is easy to build with a traditional visual workflow tool.

You know what the user should answer. You know what happens next. You know exactly when an API should be called.

The problem is that users don't behave like that.

Someone can reach the confirmation step and suddenly say:

Actually, make it 3 passengers.

Now what?

A normal workflow needs a predefined branch for that exact case. A pure AI agent can probably understand it, but then I am trusting the model to remember where it was, update the right data, follow all the rules, and continue the booking correctly.

I didn't really like either option.

Why not just use a full AI agent?

The obvious solution is to give the whole conversation to an LLM and let it decide what to do.

Customer talks to the AI. The AI calls tools. Done.

In theory, that works.

But once this touches a real business process, I want some things to stay predictable.

If the user confirms a booking, I want to know exactly what happens next.

If there is a refund policy, I don't want the model inventing one.

If an API needs specific parameters, I don't want to hope the model remembers them correctly every time.

So I started thinking about AI as something that should sit around the workflow rather than replace it.

The hybrid approach

I kept the main booking flow deterministic.

The normal user still moves through:

Trip → Passengers → Flight → Meal → Confirm → Book

But when the user says something that doesn't match the current step, AI gets involved.

For example, the user is confirming the booking and says:

Change the passenger count to 3.

The system pauses the current flow.

It asks the AI to understand what the user wants.

The AI returns structured information saying that the user wants to modify the passengers.

Then the workflow sends them to the passenger correction flow.

Once that is done, it returns them to where they were before.

So AI handles the messy part.

The workflow handles the important part.

That ended up being the architecture I wanted.

Building it on top of Typebot

I didn't want to build another visual workflow editor from scratch.

Typebot already had most of what I needed for creating flows, so I used it as the base and started extending it.

The main thing I added was an AI-driven conversation interruption system.

The important part was remembering where the user was before the interruption.

If the user is currently at the confirmation stage, I store that state before sending them somewhere else.

Something like:

original_pause_stage = confirm

Now the system can temporarily move into another branch without losing the original conversation.

Once the correction is finished, it knows where to return.

Letting AI understand intent without controlling everything

I also didn't want the LLM to directly decide which nodes to execute.

Instead, I use structured output.

For the booking example, the AI might return values like:

  • want_flight

  • want_passengers

  • want_meal

If want_passengers is true, the workflow knows exactly what to do.

This keeps the AI's job small.

It understands what the user means.

The workflow decides what that means for the actual application.

I like this separation because I can still look at the visual flow and understand exactly how the business logic works.

AI needed to sit above the flow

One thing became clear while building this.

AI could not just be another block inside the workflow.

If I put an AI block between two steps, it only exists at that point.

But the user can go off-script anywhere.

They can change the passenger count during flight selection.

They can ask about meals during confirmation.

They can ask a completely unrelated question halfway through the booking.

So I treated the AI more like an interruption layer sitting above the workflow.

The workflow keeps running normally.

The AI only steps in when the conversation no longer matches what the flow expects.

Then it gives control back.

That was the part that made the whole system click for me.

Other things I ended up adding

Once I started using Typebot for more agent-like workflows, I hit a few other limitations too.

So I added things like:

  • Structured LLM output into variables

  • Dynamic cards generated from JSON

  • OpenRouter support

  • Better JSON array handling

  • Free-text input inside flows

  • Conversation history

  • API credential handling

  • Shopify-related actions

These helped make the system more useful.

But the interruption system is still the part I find most interesting.

The other features help AI work inside a workflow.

The interruption layer changes how AI and the workflow interact in the first place.

What I learned

I started this thinking I needed to make a workflow builder more agentic.

While building it, I realized that making everything autonomous is not necessarily better.

Pure AI agents are flexible, but harder to control.

Traditional workflows are reliable, but users eventually do something you did not predict.

The combination solves a lot of that.

Let the workflow handle the parts that should always behave the same way.

Let AI handle the parts where humans don't.

For business agents, I think that middle ground is much more useful than handing the entire process to an LLM.