---
title: "Separate orchestration from the unit of inference"
url: https://recursiveai.org/research/orchestration-vs-inference/
description: "A flow is deliberately not a workflow engine. Control flow belongs one layer up, in real code, which does branching, looping, and retry better than any YAML graph DSL ever has."
date: 2026-08-27
author: Kurtis Welch
---

# Separate orchestration from the unit of inference

August 27, 2026 · Kurtis Welch

Every agent framework eventually grows a graph DSL — nodes, edges, conditions, loops, all expressed in YAML or a visual editor. We built the opposite and it has held up under two years of production use, so here’s the argument.

In Alera, a **flow** is a tool-less, scripted multi-turn LLM conversation — and it is deliberately *not* a workflow engine. It has no branching, no loops, no retry policy. It is the **unit of inference**: small enough to version, replay against fixed inputs, grade with a rubric, and cost-account per run. When a financial analysis pipeline needs its extraction step improved, you iterate on one flow in isolation, replay it against the same filings, and diff the outputs.

Control flow — the branching, looping, fan-out, and retry — belongs **one layer up, in real code**. Code has had fifty years of tooling for exactly this: debuggers, type checkers, unit tests, stack traces. A YAML graph DSL has none of that, and every one of them slowly reinvents `if`, `for`, and `try` with worse ergonomics and no debugger.

The deeper problem with fusing the layers: it **couples the thing you want to iterate on to the thing you want to be boring.** Inference is volatile — prompts change weekly, models change monthly, and you want tight iteration loops with evaluation attached. Control flow should be the opposite: stable, tested, dull. Put them in one graph runtime and every prompt tweak risks the plumbing while every plumbing change invalidates prompt evaluations.

Kept apart, each layer gets improved with the right tools: flows get rubrics, test inputs, and version history; orchestration gets code review and tests. The seam between them is an ordinary function call — no runtime, no DSL, nothing to learn.

If you’re evaluating a framework, this is a useful acid test: ask where a `for` loop lives. If the answer is “in the graph,” you will eventually be debugging a programming language that nobody designed.
