Chapter 22

Orchestrate With Code Before Orchestrating With the Model

Having chosen an agentic scheme, it is easy to offload all coordination onto the model. But if the order can be expressed in ordinary code, it will come out cheaper, clearer, and easier to test. The model stays inside individual nodes but makes no extra decisions about control flow.

The set of proven patterns is small.

  • Chain - a sequence. Each stage simplifies the next, with a schema and a gate between them.
  • Route - separation. A classifier picks one specialized prompt or an ordinary handler.
  • Parallel - independent branches. Several tasks run at once and return typed results.
  • Loop - repeat with a limit. A check decides whether to continue, but max iterations is mandatory.
  • Evaluator - generate and revise. The quality criteria are clear, and feedback leads to a measurable improvement.
  • Fallback - degradation. When a model or tool is unavailable, the system picks a safe, simplified path.

In code this looks like an ordinary pipeline, where nodes call the model and the order is set explicitly.

TypeScript
const result = await pipeline([
  step("classify", classifySchema),
  branch({
    faq: step("retrieve", retrievalSchema),
    account: step("read_account", accountSchema),
    human: stop("handoff")
  }),
  step("compose", answerSchema),
  gate("citations_exist"),
  step("render")
], {
  timeoutMs: 8000,
  maxModelCalls: 3,
  onFailure: "safe_handoff"
});

And an important point about terminology.

Deterministic doesn't mean no LLM. Google ADK calls Sequential, Parallel, and Loop workflow agents but stresses: their control flow is set by code, not by the model's decision. The inner nodes may well use an LLM.

Links