MG12 design
← All articles Essay · Conversational architecture

One conversation, two engines

Teams are trying to build entire journeys inside a chat model, and hitting the thing a model cannot give them: the same result every time. The answer is not to retreat to forms. It is one conversation with two engines behind it, where the model narrows and translates, a deterministic process executes and guarantees, and the customer never notices the seam.

The ambition is right. Someone should be able to say what they want, in their own words, and end up with the thing having happened. No menu tree, no eight-screen form, no being told to call between nine and five.

What goes wrong is the assumption that one model, given enough instruction, can carry the whole journey. It cannot, and not because it is not good enough yet. It is because a journey contains two kinds of work with opposite requirements, and the property that makes a model excellent at the first is precisely what disqualifies it from the second.

In the first half of a journey, variance is a feature. In the second half it is a defect. One engine cannot be both.

What only the model can do

Take a real request: find me a sofa for under £2,000 that would look right in a neo-classical boutique.

One of those constraints is a filter. The other is not a filter at all. There is no neo_classical column, and there never will be. What has to happen is a translation, from something the customer can express into structure the catalogue can be searched by: a palette, a set of materials, a leg profile, a formality, some things to exclude. That translation is genuinely hard, it is what people used to visit a showroom for, and a form cannot do it at any price.

So the first half of the journey is a funnel, and it does two jobs rather than one. It narrows, from an unbounded request to a determinate one. And it translates, adding structure the customer never supplied and could not have been asked for. Anyone arguing for putting conversational AI back in its box is proposing to throw that away, and it is the most valuable thing in the system.

Where it has to stop

Then the customer says yes, and the work changes character completely. Capture the order. Apply the delivery rules for that postcode. Check the finance eligibility. Take payment. Raise the fulfilment request.

There is exactly one correct outcome for each of those, and this is where the same model becomes a liability:

  • A business rule in a prompt is not a business rule. It is a strong suggestion with a good compliance rate. A rule that fires ninety-seven times out of a hundred is not a rule, and the real problem is not the three: it is that you cannot identify them. The same rule in a decision table is inspectable, testable, changeable without a release, and defensible afterwards.
  • Models are weak at exhaustive mandatory capture. Not through carelessness, through objective. They optimise for a plausible result, and a plausible order is one with the delivery instruction quietly missing. A process definition knows what is mandatory. A prompt only hopes.
  • "It usually applies the rule" is not a defensible position. For anything touching money, credit, eligibility or a duty of care, you have to show which rule was applied to this case. Not that the system generally behaves well.

But it all still happens in the chat

Here is where most implementations take the wrong turn. Having correctly worked out that the second half must be deterministic, they hand the customer to a form. A new screen, a mode switch, a "click here to complete your order". That is where conversion goes to die, and it throws away everything the conversation had established.

It is unnecessary, because the thing that has to be deterministic is the process definition, not the interface. The definition owns which fields exist, which are mandatory, what validates, which rules apply and in what order. How those steps are presented is a separate question, and one of the available answers is: as turns in the conversation the customer is already having.

So it is not chat, then workflow. It is one conversation with two engines behind it. Some turns are authored by the model. Some are a process step rendering itself. The customer cannot tell, and does not need to.

The rule that makes it safe

The model proposes; the process disposes. The model never writes to the system of record. It can offer a candidate value, a candidate interpretation, a candidate order. A deterministic component validates that candidate against the definition and either accepts it or rejects it. You cannot make a language model deterministic. You can absolutely make the system deterministic, by demoting the model to a proposer.

The contract defines the seam

If the two halves are engines rather than phases, the obvious question is when the first one has finished. The answer is unusually clean: the funnel's exit criterion is the process's input contract. The deterministic side already declares what it needs, so it can tell the conversational side what "done" means, rather than the conversation deciding for itself when it has probably gathered enough.

Three things fall out of that, all of them free.

  • Clarifying questions stop being a prompting art. They are derived: ask about what the contract still needs. Which is also the honest answer to a weak opening query.
  • Completeness is declared rather than remembered. The mandatory set lives in the definition, so nothing depends on the model keeping a checklist in its head.
  • The boundary becomes testable. You can assert that a conversation reached a satisfiable contract. No amount of prompt discipline gives you an assertion.

The state that both engines read and write has to be one persisted thing, not a payload passed across the seam. Hand a rich conversation to a process that accepts eight typed fields and everything that did not fit a field evaporates, and the customer gets asked for something they already told you. That is the whisper game, located precisely at the most expensive possible moment.

The part everyone underestimates

If both engines share one surface, something has to decide, every single turn, which of them owns it. The process is waiting on the delivery date. The customer has just typed something. Is that the delivery date, or is it a question about returns?

That arbitration is deterministic work and it defaults to the process: while a step is pending, the process owns the turn unless the utterance is clearly something else. Get that backwards and the model will helpfully interpret a mandatory field, produce a paraphrase that looks like an answer, and satisfy the step. The workflow now believes it has a validated delivery date that no human ever confirmed, and you have reintroduced exactly the non-determinism the process existed to remove. Which is why the model may never satisfy a field. It may only propose a value for one.

And the classification is genuinely hard, because the signal is tiny and the frequency is enormous. "Blue" is an answer to a colour field. "Do you have it in blue?" is a question. Same word, one turn apart, hundreds of times per conversation. It is the routing problem at micro scale, on the thinnest evidence in the system. Wrong one way and you answer a question nobody asked. Wrong the other and you capture "Do you have it in blue" as the delivery instruction.

Interruption is not abandonment

The reason to keep the conversation available throughout, rather than treating the funnel as a phase that ends, is that customers interrupt themselves constantly. Mid-capture they want to know the returns policy, or change the colour, or check whether it fits through a doorway.

In a one-way handoff, that is either a dead end or a loss of everything captured. In a single conversation over a suspendable process, it is a turn: the step waits, the question is answered, the step resumes. But resumption has to be explicit and visible. After the returns answer, something has to say "right, back to the delivery date", because the customer cannot see that three fields remain the way they could on a form. Without that, processes stall silently and people walk away believing they have ordered something they have not.

That is not a nicety. It is two of Shneiderman's rules, closure and reduced memory load, arriving as hard architectural requirements the moment you put a process inside a chat.

On the no-code part

Process definitions should be editable by the people who own the rules, and that is the real argument for codeless workflow tooling: a pricing rule or an eligibility threshold changes without a release, and the definition stays inspectable by someone who can tell whether it is right.

It is worth being honest about the failure mode, though. No-code is a claim about who maintains something, not about whether it is correct, and these tools grow two-hundred-node diagrams that are harder to reason about than the code they replaced, with nothing you could call a test. Version the definitions, keep them diffable, and be able to run one against a set of cases before it goes live. Otherwise you have moved the fragility rather than removed it. Both Syntalyze and Aurum are built around this split, and the versioned, testable definition is the part that makes it survivable.

The short version

The model narrows and translates. The process executes and guarantees. The contract between them defines when one hands to the other, and the whole thing happens inside a single conversation the customer never leaves.

That boundary will move. As models improve, more of the journey can sit on the conversational side, and it should. But it has a floor, and the floor is anything with a legal or financial definition of correct. No model release is going to make "usually applied the right rule" an acceptable answer.

Building something this applies to?

Start a conversation