Pattern C: Agent as Orchestrator

The agent coordinates multiple workflows, making decisions about what to trigger, in what order, and how to synthesize results across them. The agent is the decision-maker; each workflow is a capability it can invoke. Unlike Pattern B (which classifies and dispatches once), the orchestrator waits for results, reasons about them, and decides what to do next.

flowchart TD Agent["Orchestrator Agent"] -->|"1. verify identity"| KYC["Identity Verification<br/>Workflow"] KYC -->|"result: verified"| Agent Agent -->|"2. screen sanctions"| Sanctions["Sanctions Screening<br/>Workflow"] Sanctions -->|"result: partial match"| Agent Agent -->|"3. conflict - escalate"| Human["Human Review"] Human -->|"decision: clear"| Agent Agent -->|"4. provision account"| Account["Account Provisioning<br/>Workflow"] Account -->|"result: provisioned"| Agent Agent -->|"5. complete with full trace"| Done["__complete__"] style Agent fill:#f3e8ff,stroke:#9333ea style Human fill:#dbeafe,stroke:#3b82f6

When to Use

  • The process requires dynamic coordination across multiple sub-processes
  • The sequence of steps depends on intermediate results (not predetermined)
  • You need to synthesize information from multiple workflows before deciding the next step
  • The agent makes judgment calls -- not just routing, but resolving conflicts and escalating

Pattern C vs Pattern B

Pattern B = classify, dispatch to one workflow, done. The agent is a router.

Pattern C = trigger workflow, wait for result, trigger another workflow based on that result, synthesize, escalate if conflicted, trigger more workflows, complete. The agent is a coordinator making ongoing decisions.

The telltale sign of Pattern C: the agent calls wait: true on workflows and its reasoning trace shows conditional branching based on workflow results.

---

How It Differs From Pattern B

Pattern B: Trigger Pattern C: Orchestrator
Core question "Which workflow should handle this?" "How do I coordinate these workflows to complete a complex process?"
Workflow calls One, fire-and-forget Multiple, sequential or conditional
Uses wait: true? No -- dispatches and completes Yes -- needs results to make next decision
Result synthesis None -- delegates entirely Combines results across workflows, resolves conflicts
Human escalation Rare -- classification is usually clear Common -- conflicts between workflow results need judgment
Typical iterations 3-5 10-20
Iteration budget max_iterations: 8 max_iterations: 20
Timeout 60s 300-600s (waiting for workflow completions)

Tool Declaration

Pattern C agents need workflow tools declared with wait: true semantics. Since the orchestrator coordinates multiple workflows and may also use actions for direct lookups, the tools array typically includes both:

json
{
  "tools": [
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Verify identity against government databases and trade registers" },
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Screen against OFAC, EU, UN, and UK sanctions lists" },
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Enhanced due diligence -- deep background check for flagged entities" },
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Provision customer account, set up billing, assign account manager" },
    { "type": "action", "name": "gmail_send" }
  ]
}

Implicit tools (__complete__, __pause_for_human__, __store_memory__, __retrieve_memory__, __log_progress__) are auto-injected. You don't need to declare them.

Why workflows dominate Pattern C tools

In Pattern B, the tools array is action-heavy (classification tools) with a few workflow targets. In Pattern C, it's workflow-heavy -- the orchestrator's primary capability is triggering and coordinating sub-processes. Actions are secondary, used for direct communication (email, Slack) or lookups between workflow calls.

---

Complete Example: Customer Onboarding

An orchestrator agent that onboards a business customer -- running identity verification, sanctions screening, conditionally triggering enhanced due diligence, and escalating to a human when signals conflict.

Agent Configuration

json
{
  "objective": "Onboard business customer: {{input.company_name}}\n\nCustomer details:\n- Company: {{input.company_name}}\n- Country: {{input.country}}\n- Registration: {{input.registration_number}}\n- Contact: {{input.contact_name}} ({{input.contact_email}})\n\nProcess:\n1. Run identity verification\n2. Run sanctions screening\n3. If any concerns, run enhanced due diligence\n4. If still uncertain, request human review\n5. If approved, provision the account\n6. Send welcome email to contact",
  "tools": [
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Verify company identity -- checks trade registers, document authenticity, address verification" },
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Screen against global sanctions lists (OFAC, EU, UN, UK). Returns: clear, partial_match, or hit" },
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Enhanced due diligence -- deep background check, adverse media, PEP screening" },
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Provision customer account -- create org, set up billing, assign account manager" },
    { "type": "action", "name": "gmail_send" }
  ],
  "config": {
    "model": "gpt-4",
    "max_iterations": 20,
    "timeout_ms": 600000,
    "on_stuck": { "iterations": 3, "action": "escalate" }
  }
}

Execute via Standalone Agent API

bash
curl -X POST https://apisvr.tryhyphen.com/agents/execute \
  -H "X-Org-Id: acme-corp" \
  -H "Content-Type: application/json" \
  -d '{
    "objective": "Onboard business customer: Acme GmbH...",
    "tools": [
      { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000" },
      { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000" },
      { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000" },
      { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000" },
      { "type": "action", "name": "gmail_send" }
    ],
    "config": { "model": "gpt-4", "max_iterations": 20, "timeout_ms": 600000 }
  }'

Sample Reasoning Trace

Notice the long trace with conditional branching -- the agent waits for each workflow result and adapts its plan based on what comes back.

text
Iteration 1:
  Thought: "Starting onboarding for Acme GmbH. First step is identity verification."
  Action: __log_progress__
  Input: { "message": "Starting onboarding", "milestone": "begin" }

Iteration 2:
  Thought: "Running identity verification."
  Action: identity_verification  <-- resolved from wf_kyc_001
  Input: {
    "company_name": "Acme GmbH",
    "country": "DE",
    "registration_number": "HRB 12345",
    "wait": true,  <-- orchestrator waits for result
    "timeout_ms": 120000
  }
  Observation: {
    "status": "completed",
    "result": { "verified": true, "confidence": 0.92, "source": "trade_register" }
  }

Iteration 3:
  Thought: "Identity verified (92% confidence). Saving this and moving to sanctions."
  Action: __store_memory__
  Input: { "key": "kyc_result", "value": { "verified": true, "confidence": 0.92 } }

Iteration 4:
  Thought: "Now running sanctions screening."
  Action: sanctions_screening  <-- resolved from wf_san_002
  Input: {
    "company_name": "Acme GmbH",
    "country": "DE",
    "directors": ["Hans Mueller", "Maria Schmidt"],
    "wait": true,
    "timeout_ms": 120000
  }
  Observation: {
    "status": "completed",
    "result": {
      "overall": "partial_match",
      "matches": [{ "name": "Hans Mueller", "list": "EU", "score": 0.72,
                     "note": "Similar name on EU consolidated list" }]
    }
  }

Iteration 5:
  Thought: "Partial sanctions match -- 72% similarity on Hans Mueller.
            Identity passed but sanctions flagged. This is a conflict.
            I need enhanced due diligence before deciding."
  Action: __log_progress__
  Input: { "message": "Conflict: KYC pass but sanctions partial match. Running EDD.",
           "milestone": "conflict_detected" }

Iteration 6:
  Thought: "Running enhanced due diligence to resolve the conflict."
  Action: enhanced_due_diligence  <-- resolved from wf_edd_003
  Input: {
    "company_name": "Acme GmbH",
    "flagged_individual": "Hans Mueller",
    "flag_reason": "72% name match on EU consolidated list",
    "wait": true,
    "timeout_ms": 180000
  }
  Observation: {
    "status": "completed",
    "result": {
      "conclusion": "likely_false_positive",
      "confidence": 0.78,
      "reasoning": "Different date of birth, different nationality from listed entity"
    }
  }

Iteration 7:
  Thought: "EDD says likely false positive but only 78% confident. That's below
            my threshold. I should pause for human compliance review."
  Action: __pause_for_human__
  Input: {
    "question": "Sanctions screening flagged Hans Mueller (72% name match, EU list).
                 EDD concludes likely false positive (78% confidence).
                 Should we proceed with onboarding?",
    "options": ["Approve -- proceed with onboarding", "Reject -- deny application",
                "Request additional documentation"],
    "context_summary": "KYC: verified (92%). Sanctions: partial match on director.
                        EDD: likely false positive (78%).",
    "urgency": "medium"
  }

  --- AGENT PAUSED -- waiting for human review ---

  Human response: "Approve -- proceed with onboarding. Add monitoring note."

Iteration 8:
  Thought: "Human approved. Provisioning the account with a monitoring note."
  Action: account_provisioning  <-- resolved from wf_acc_004
  Input: {
    "company_name": "Acme GmbH",
    "country": "DE",
    "contact_email": "[email protected]",
    "risk_notes": "Sanctions false positive cleared by compliance (2026-02-08)",
    "monitoring_level": "enhanced",
    "wait": true,
    "timeout_ms": 60000
  }
  Observation: {
    "status": "completed",
    "result": { "account_id": "acct_xyz789", "status": "active" }
  }

Iteration 9:
  Thought: "Account provisioned. Sending welcome email."
  Action: gmail_send
  Input: {
    "to": "[email protected]",
    "subject": "Welcome to Hyphen -- Your Account is Ready",
    "body": "Dear Hans,\n\nYour Acme GmbH account has been provisioned..."
  }

Iteration 10:
  Thought: "Onboarding complete. All verification passed, account provisioned."
  Action: __complete__
  Input: {
    "answer": "Acme GmbH onboarded successfully. Identity verified, sanctions
              false positive cleared by compliance, account provisioned (acct_xyz789).
              Enhanced monitoring applied per compliance decision.",
    "confidence": 0.95,
    "summary": "KYC: pass | Sanctions: cleared (human review) | EDD: false positive | Account: active"
  }

Ten iterations. The agent ran four workflows sequentially, detected a conflict between KYC and sanctions results, ran additional due diligence, escalated to a human when confidence was insufficient, then completed provisioning after approval. That's the Pattern C signature -- ongoing decision-making across multiple workflow results.


Key Properties

  • wait: true on workflow triggers -- the orchestrator needs results to make the next decision. This is the defining characteristic vs Pattern B
  • Result synthesis -- the agent compares results across workflows (KYC pass + sanctions flag = conflict) and decides what to do
  • Conditional workflow triggering -- EDD only runs because sanctions flagged. The sequence is dynamic, not predetermined
  • Human escalation with full context -- when the agent pauses, the human sees the complete chain of reasoning and results
  • Higher iteration budget -- max_iterations: 20 accounts for the multi-workflow coordination. Each workflow call + reasoning takes ~2 iterations
  • Longer timeout -- timeout_ms: 600000 (10 minutes) because the agent is waiting for workflow completions

Pattern C vs Building It as a Deterministic Workflow

You could encode this same process as a deterministic workflow with conditional branches. When should you use Pattern C instead?

Use Pattern C when:

  • The process has too many conditional paths to enumerate upfront
  • You need natural language judgment ("is this a false positive?") between steps
  • The order of operations depends on results (not just branching on a value)
  • You want the agent to explain its reasoning for audit purposes

Use a deterministic workflow when:

  • The process is well-defined with clear branching rules
  • Every conditional can be expressed as a comparison operator
  • You don't need natural language reasoning between steps
  • Volume is high enough that LLM cost per run matters

In practice, many teams start with Pattern C for new processes (letting the agent figure out the logic), then graduate to deterministic workflows once the process stabilizes and the branching rules are well-understood.


Governance Model

Pattern C agents have the highest autonomy level, which means governance is most important:

  • Structural permissioning -- the agent can only trigger workflows and actions declared in its tools array. It cannot discover or invoke other workflows in your org
  • Reasoning traces -- every iteration is captured: thought, action, input, observation. The full chain of reasoning is queryable and auditable
  • Stuck detection -- if the agent loops without progress for 3 iterations, it escalates to a human rather than burning through iterations
  • Checkpoint/resume -- when the agent pauses for human input, its full state is persisted. The human's decision becomes part of the trace
  • Timeout enforcement -- timeout_ms prevents runaway orchestration. If workflows take longer than expected, the agent fails gracefully

Back to: Deployment Patterns Overview