• Leonid Medovyy

Deterministic Control over Probabilistic Language Models

The integration of Large Language Models (LLMs) into production software architectures requires rigorous operational control over stochastic text generation.

While recent industry literature emphasizes complex, decentralized topologies such as autonomous multi-agent swarms and cyclic self-healing graphs, empirical observations of production failures indicate that premature adoption of high-autonomy frameworks introduces severe observability deficits and compounding error rates. When an opaque cyclic graph fails in a production environment, the resulting diagnostic complexity taxes the cognitive load of engineering operators, who must inspect deep stack traces obscured by proprietary framework abstractions.

We propose a hierarchical taxonomy of orchestration primitives and demonstrate that three foundational topologies (Sequential Pipelines, Supervisor Routers, and Bounded Human-in-the-Loop Circuit Breakers) suffice to resolve the vast majority of enterprise automation requirements. Furthermore, we illustrate how implementing these topologies using Plain Old Ruby Objects (POROs) and the RubyLLM library eliminates the cognitive overhead of custom Domain-Specific Languages (DSLs), preserving state visibility, testability, and operational resilience.

Introduction: The Observability Crisis in Multi-Agent Systems

Modern software engineering relies on deterministic execution guarantees, explicit state transitions, and inspectable call stacks. In contrast, autoregressive language models operate as probabilistic token generators. Bridging this paradigm gap is the central challenge of agentic systems engineering.

A prevalent anti-pattern in contemporary AI engineering is the immediate deployment of complex multi-agent orchestration frameworks before establishing single-call reliability or deterministic routing. Engineering teams frequently construct cyclic graphs composed of multiple autonomous agents debating within shared memory buffers prior to verifying whether a system can reliably classify and route a single incoming payload.

From a systems reliability perspective, cyclic, unconstrained multi-agent topologies exhibit two critical vulnerabilities:

  1. Compounding Stochastic Variance: If a single LLM invocation succeeds with probability p \in (0, 1), a linear chain of n independent calls without validation exhibits a cumulative success probability of p^n. In an unconstrained cyclic graph where agents dynamically trigger subsequent turns, n becomes a random variable, causing variance in latency, token expenditure, and output fidelity to grow non-linearly.
  2. Abstraction-Induced Cognitive Load: During an operational incident, rapid fault isolation depends on the transparency of the execution stack. Acute stress elevates physiological arousal and narrows working memory capacity. When state transitions are hidden behind proprietary framework decorators, asynchronous message buses, and forty-frame stack traces, operators cannot trace the causal link between a specific prompt state and a downstream system failure.

To mitigate these risks, software architects must prioritize structural simplicity and explicit control flow. Agent orchestration is fundamentally the application of classical control theory and discrete state machines to bound probabilistic inference. Before exploring decentralized swarms, engineering organizations must establish operational mastery over three foundational execution topologies: Sequential Pipelines, Supervisor Routers, and Human Handoff Circuit Breakers.

Taxonomic Stratification of the Orchestration Stack

To evaluate architectural trade-offs systematically, orchestration primitives can be stratified into four hierarchical layers ordered by operational criticality and dependency:

  • Layer 1: Foundational Primitives. This layer encompasses single-inference reliability, explicit system instructions, constrained schema enforcement (structured outputs), and transparent message history management. No higher-order topology can compensate for instability at the foundational layer.
  • Layer 2: Core Control Topologies (The Foundational Triad). This layer governs deterministic data routing and execution halting across discrete inference boundaries. It consists of Sequential Pipelines (linear functional composition), Supervisor Routers (upfront intent classification and dispatch), and Human Handoff Circuit Breakers (bounded execution loops with risk-triggered interrupts).
  • Layer 3: Stability and Resilience Mechanisms. This layer enforces operational invariants, including explicit step budgets, tool execution sandboxing, context window pruning, and idempotent retry policies for transient API faults.
  • Layer 4: High-Autonomy Topologies (Decorations). This layer includes autonomous multi-agent debates, cyclic state graphs, and dynamically spawning agent swarms. While visually compelling in theoretical demonstrations, these patterns are rarely required when Layers 1 through 3 are properly engineered.

A comparative analysis of the Layer 2 Core Control Topologies demonstrates how each pattern addresses a specific failure mode inherent to probabilistic models using standard Ruby control primitives:

Orchestration Topology Formal Operational Role Primary Stochastic Failure Mode Mitigated Native Ruby Control Primitive
Sequential (Pipeline) Decomposes a complex transformation into a composition of narrow functions f_3(f_2(f_1(x))) Context window degradation, attention dilution, and conflicting system constraints Local variable binding and sequential method composition
Supervisor (Router) Maps an unstructured input space X to a discrete set of specialized handlers {S_1, S_2, \dots, S_k} Suboptimal generalization caused by forcing a single prompt to execute incompatible domain tasks case / when conditional branching and immutable Hash lookup tables
Human Handoff Enforces a halting condition over an iterative tool-use loop when risk or ambiguity metrics exceed a threshold \tau Unbounded hallucination loops, unauthorized state mutations, and high-liability autonomous actions until loop iterating over .step with an explicit early return interrupt

Architectural Evaluation: Native Language Primitives vs. Graph DSLs

A primary obstacle in mastering agentic workflows is the proliferation of heavyweight orchestration frameworks that impose custom Directed Acyclic Graph (DAG) abstractions, proprietary state serializers, and complex decorator chains. These frameworks require engineers to translate standard conditional logic (if/else) and iteration (while/until) into framework-specific node and edge definitions. This extraneous cognitive load diverts engineering attention away from domain modeling and prompt optimization.

An alternative architectural paradigm utilizes a general-purpose object-oriented language with high expressiveness, specifically Ruby paired with the RubyLLM framework. Evaluating this approach against graph-based DSLs reveals two distinct structural advantages:

  1. Isomorphic Domain Modeling via Self-Documenting Primitives: Within RubyLLM Agents, an autonomous unit is defined via standard class inheritance (class TriageAgent < RubyLLM::Agent). Conversational state is encapsulated within a standard object (RubyLLM.chat) that exposes an intuitive method interface including .ask, .with_tools, and .messages, as specified in the RubyLLM Chat Guide. Consequently, the syntactic structure of the code maps directly to the semantic structure of the domain problem.
  2. Transparent State Transitions via Plain Old Ruby Objects (POROs): Execution branching and state accumulation do not require specialized graph compilation steps. Ruby natively provides pattern matching, case/when evaluation, functional fold operations via Enumerable#reduce, and lexical scoping. Because the orchestrator is a standard Ruby object, state inspection at any execution boundary can be performed using standard input/output streams (puts) or interactive debuggers (binding.irb) without deserializing opaque framework state objects.

In this architecture, the source code itself serves as the execution graph, eliminating the impedance mismatch between orchestration logic and application code.

Pattern 1: Sequential Orchestration (The Linear Pipeline)

Theoretical Motivation

Transformer-based language models rely on self-attention mechanisms where token representations are computed relative to all preceding tokens in the context window. When a single prompt is overloaded with multiple distinct cognitive tasks (such as raw entity extraction, normative policy verification, and stylistic response generation), instructions compete for attention weights. This phenomenon, known as instruction interference, leads to constraint violation and formatting drift.

Sequential Orchestration resolves instruction interference through task decomposition and functional composition. Let X represent the raw input space. Instead of constructing a monolithic prompt M(x), the workflow is factored into a linear sequence of specialized agents A_1, A_2, A_3, where each agent operates under a tightly constrained system prompt and passes a narrowed intermediate representation to the subsequent stage:

y_1 = A_1(x), \quad y_2 = A_2(y_1), \quad y_{\text{final}} = A_3(y_1, y_2)

By isolating each cognitive transformation, context bloat is prevented, and each model invocation operates within a high-signal regime. Furthermore, decoupling the stages allows architects to assign heterogeneous models optimized for specific latency, cost, and reasoning profiles to each step.

Implementation in RubyLLM

In the following implementation, a customer refund workflow is decomposed into three isolated agents: fact extraction (utilizing a low-latency model, gemini-3.7-flash), policy auditing (utilizing a high-reasoning model, claude-sonnet-5), and communication drafting.

require "ruby_llm"

# Stage 1: Information Extraction Specialist
# Optimized for high recall and zero editorializing using a fast model.
class FactExtractorAgent < RubyLLM::Agent
  model "gemini-3.7-flash"
  instructions "Extract only verifiable dates, dollar amounts, and account IDs from the input. Output bullet points."
end

# Stage 2: Normative Policy Evaluator
# Evaluates structured facts against strict business invariants.
class PolicyAuditorAgent < RubyLLM::Agent
  model "claude-sonnet-5"
  instructions "Given extracted facts, state whether the request qualifies for a refund (under 30 days and under $500)."
end

# Stage 3: Client Communication Synthesizer
# Translates internal audit states into external-facing natural language.
class ResponseDrafterAgent < RubyLLM::Agent
  model "claude-sonnet-5"
  instructions "Write a direct, three-sentence customer email communicating the policy decision."
end

# Deterministic Orchestrator: Linear Pipeline
class RefundPipeline
  def call(raw_ticket)
    facts    = FactExtractorAgent.new.ask(raw_ticket).content
    decision = PolicyAuditorAgent.new.ask(facts).content
    
    ResponseDrafterAgent.new.ask(
      "Facts:\n#{facts}\n\nPolicy Decision:\n#{decision}"
    ).content
  end
end

pipeline = RefundPipeline.new
puts pipeline.call("Order #9812 placed 12 days ago for $140. Item arrived cracked.")

Operational Characteristics

This implementation follows the RubyLLM Agentic Workflows pattern without introducing external state-machine dependencies or message-brokering infrastructure. State propagation is managed entirely through local variable assignments (facts and decision) within the #call method. From a diagnostic standpoint, if the terminal output exhibits defects, an engineer can log or assert against the intermediate variables facts and decision independently, isolating whether the fault occurred during entity extraction, policy evaluation, or text synthesis.

Pattern 2: Supervisor Orchestration (The Deterministic Router)

Theoretical Motivation

Language models exhibit performance trade-offs across domain specializations and computational scales. A model fine-tuned for creative prose generation frequently hallucinates when generating syntactically strict SQL queries or diagnosing stack traces. Conversely, invoking a frontier reasoning model (gpt-5.6 or claude-sonnet-5) for routine classification or FAQ retrieval incurs unnecessary latency and financial cost.

Supervisor Orchestration introduces a two-tier topology consisting of a lightweight classifier node (the Supervisor) and a set of isolated domain specialists. The Supervisor does not attempt to resolve the domain query. Instead, its output space is constrained via a formal grammar or JSON schema to emit a discrete routing token r \in {\text{billing}, \text{technical}, \text{security}}. Deterministic application code then maps token r to the corresponding specialist class S_r.

Implementation in RubyLLM

By combining RubyLLM’s structured output schema with an immutable Ruby Hash constant (SPECIALISTS), the routing mechanism becomes deterministic, fast, and fully auditable:

require "ruby_llm"

class BillingSpecialist < RubyLLM::Agent
  model "claude-sonnet-5"
  instructions "Resolve invoice, charge, and refund inquiries with exact ledger steps."
end

class TechnicalSpecialist < RubyLLM::Agent
  model "gpt-5.6"
  instructions "Diagnose API errors, stack traces, and webhook failures. Provide runnable fixes."
end

class SecuritySpecialist < RubyLLM::Agent
  model "claude-sonnet-5"
  instructions "Handle compromised keys, suspicious logins, and access revocations immediately."
end

# The Supervisor Node: Enforces a strict categorical output distribution
class SupervisorRouterAgent < RubyLLM::Agent
  model "gemini-3.7-flash"
  instructions "Classify the incoming support request into the single best specialist category."

  schema do
    string :route, enum: %w[billing technical security]
    string :reason, description: "One-sentence justification for the selected route"
  end
end

# Deterministic Orchestrator: The Router
class SupportSupervisor
  SPECIALISTS = {
    "billing"   => BillingSpecialist,
    "technical" => TechnicalSpecialist,
    "security"  => SecuritySpecialist
  }.freeze

  def call(user_query)
    classification = SupervisorRouterAgent.new.ask(user_query).parsed
    route_key      = classification.fetch("route")

    specialist_class = SPECIALISTS.fetch(route_key, TechnicalSpecialist)
    specialist_class.new.ask(user_query).content
  end
end

supervisor = SupportSupervisor.new
puts supervisor.call("Our production webhook is returning HTTP 502 on payload delivery.")

Operational Characteristics

In this topology, the probabilistic boundary is strictly confined to the intent classification step (SupervisorRouterAgent.new.ask(user_query).parsed). Because the schema enforces an enumeration constraint (enum: %w[billing technical security]), the parsed output is guaranteed to conform to the expected structural contract. Furthermore, requiring the model to generate a reason field provides an audit log for classification decisions while leveraging chain-of-thought dynamics to improve classification accuracy. Most importantly, the dispatch logic (SPECIALISTS.fetch(route_key, TechnicalSpecialist)) is pure Ruby code that can be unit-tested in milliseconds using mock payloads, completely decoupled from external LLM API calls.

Pattern 3: Bounded Autonomy and Human Handoff (The Circuit Breaker)

Theoretical Motivation

In tool-augmented LLM systems (often referred to as ReAct loops), a model iteratively emits tool-invocation requests, observes the execution results, and decides whether to invoke additional tools or return a final response. Allowing this loop to execute until the model voluntarily halts introduces severe operational risk. In production environments, actions such as executing high-value financial transfers, mutating production database records, or responding to formal legal threats carry irreversible organizational liability.

To govern autonomous tool execution safely, the orchestration layer must implement a Circuit Breaker pattern. Formally, let the conversation state at step t be H_t. The orchestrator must enforce two invariants:

  1. Temporal Bounding: Execution must terminate if t \ge T_{\max}, preventing infinite loops caused by recurring tool errors or model repetition.
  2. Semantic Interrupts: After every state transition H_t \to H_{t+1}, the orchestrator inspects the intermediate message before returning control to the model. If a risk predicate R(H_{t+1}) evaluates to true, autonomous execution halts immediately, and the complete state transcript H_{t+1} is serialized for human operator intervention.

Implementation in RubyLLM

While standard invocations in RubyLLM using .ask automatically resolve tool calls to completion, the library also exposes fine-grained iteration primitives: .ask_later (which appends the user message to the state buffer without triggering inference) and .step (which executes exactly one turn of inference or tool execution). Pairing these primitives with a dedicated RubyLLM Tool creates a deterministic circuit breaker:

require "ruby_llm"

# Interrupt Signal Tool: Encapsulates escalation metadata
class EscalateToHuman < RubyLLM::Tool
  description "Pause automation and escalate to a human operator when a request exceeds $500 or involves legal threats."
  param :reason, desc: "Clear summary of why human intervention is required"
  param :risk_level, desc: "low, medium, or high"

  def execute(reason:, risk_level:)
    { status: "escalated", reason: reason, risk_level: risk_level }.to_json
  end
end

class FrontlineAgent < RubyLLM::Agent
  model "claude-sonnet-5"
  instructions "Help customers with standard account questions. Always call EscalateToHuman if the dispute exceeds $500 or mentions legal action."
  tools EscalateToHuman
end

# Deterministic Orchestrator: Step-Bounded Loop Controller
class GuardedSupportSession
  MAX_STEPS = 5

  def run(user_message)
    chat = RubyLLM.chat(model: "claude-sonnet-5")
      .with_instructions("Help customers. Escalate disputes over $500 or legal threats via EscalateToHuman.")
      .with_tools(EscalateToHuman)

    # Queue the user input without triggering an autonomous completion loop
    chat.ask_later(user_message)

    steps = 0
    until chat.complete? || steps >= MAX_STEPS
      steps += 1
      message = chat.step

      # Inspect the execution boundary immediately following tool resolution
      if message&.role == :tool && message.content.include?('"status":"escalated"')
        return {
          state: :human_handoff_required,
          payload: JSON.parse(message.content),
          transcript: chat.messages.map { |m| "[#{m.role.upcase}] #{m.content}" }
        }
      end
    end

    { state: :resolved_by_agent, reply: chat.messages.last.content }
  end
end

session = GuardedSupportSession.new
result  = session.run("You double-charged our corporate card $2,400 and my legal team is drafting a complaint.")

if result[:state] == :human_handoff_required
  puts "CIRCUIT BREAKER TRIPPED: #{result[:payload]['reason']}"
  puts "Passing #{result[:transcript].size} transcript messages to human operator queue."
else
  puts result[:reply]
end

Operational Characteristics

By replacing the black-box .ask loop with an explicit until loop driving chat.step, control authority is inverted back to the host Ruby runtime. On each iteration, the host application evaluates both the step budget (steps >= MAX_STEPS) and the post-tool state boundary (message&.role == :tool). When EscalateToHuman is invoked, the return statement immediately exits the loop prior to the model generating a subsequent conversational turn. This architecture guarantees zero extraneous token expenditure after an escalation trigger and preserves an immutable, chronological audit trail (chat.messages) for the receiving human operator.

Empirical Verification and Applied Protocols

In systems engineering, theoretical familiarity with a design pattern is distinct from operational competence. Explaining the mechanics of a supervisor router during an architectural review does not guarantee the ability to diagnose a misbehaving multi-agent pipeline under production incident conditions. Building reliable intuition requires deliberate practice with the underlying execution primitives before introducing third-party graph abstractions.

To validate the concepts presented in this paper, practitioners should execute the following three verification protocols within a standalone Ruby environment using the ruby_llm gem:

  1. Protocol 1: Linear Pipeline Verification. Construct a three-stage sequential pipeline that ingests unstructured server log data, passes it through a structured entity extractor agent, routes the extracted entities to a root-cause diagnostic agent, and terminates at a Markdown report synthesizer agent. Enforce state transitions exclusively through three local Ruby variables and measure how modifications to the first agent’s system prompt propagate downstream.
  2. Protocol 2: Decision Boundary Calibration. Implement a SupervisorRouterAgent configured with three distinct domain routes. Subject the router to an evaluation suite of ten ambiguous, multi-intent edge-case prompts. Iteratively refine the system instructions and schema descriptions until the categorical classification distribution achieves deterministic repeatability across multiple test runs.
  3. Protocol 3: Interrupt Latency and Halting Verification. Implement a step-bounded controller utilizing chat.ask_later and chat.step governed by a hard MAX_STEPS constant and an escalation tool. Inject adversarial prompts designed to trigger the escalation threshold and verify via transcript inspection that the loop terminates immediately upon tool execution without permitting a follow-up model inference turn.

Conclusion

Reliable agent orchestration does not require complex graph DSLs, cyclic autonomous debates, or opaque framework abstractions. By treating language models as bounded probabilistic functions within native object-oriented control structures, engineering teams can eliminate unnecessary architectural complexity.

Mastering Sequential Pipelines, Supervisor Routers, and Human Handoff Circuit Breakers in plain Ruby provides the observability, testability, and deterministic control required to deploy language models safely in production environments.

Agent orchestration is fundamentally the application of classical control theory and discrete state machines to bound probabilistic inference. Mastering Sequential Pipelines, Supervisor Routers, and Human Handoff Circuit Breakers in plain Ruby provides the observability, testability, and deterministic control required to deploy language models safely in production environments.