Pattern B: Agent as Workflow Trigger

The agent operates as a smart ingestion layer. It receives unstructured input, reasons about it, and dispatches to one downstream workflow with structured parameters. The agent's job is classification and routing -- once it triggers the workflow, it's done.

flowchart LR Input["Unstructured Input<br/>(email, document, webhook)"] --> Agent["ReAct Agent<br/><i>classify > extract > route</i>"] Agent -->|"invoice detected"| W1["Invoice Processing<br/>Workflow"] Agent -->|"support request"| W2["Support Ticket<br/>Workflow"] Agent -->|"vendor inquiry"| W3["Vendor Onboarding<br/>Workflow"] style Agent fill:#f3e8ff,stroke:#9333ea

When to Use

  • Input arrives in unstructured form (emails, documents, free-text webhooks)
  • You don't know upfront which workflow to run
  • The agent needs to classify, extract fields, and dispatch -- then it's finished
  • The agent is a router, not a coordinator. It triggers one workflow and completes

Pattern B vs Pattern C

Pattern B = the agent figures out which workflow to run, triggers it, and is done. One decision, one dispatch.

Pattern C = the agent coordinates multiple workflows, waits for results, synthesizes across them, and makes further decisions based on what comes back. Ongoing reasoning across several steps.

If your agent triggers a workflow and doesn't need to care about the result, that's Pattern B. If it triggers a workflow, waits for the result, then decides what to do next -- that's Pattern C.

---

How It Differs From Pattern C

Pattern B: Trigger Pattern C: Orchestrator
Workflow calls Triggers one workflow Coordinates multiple workflows
Waits for result? No -- fires and completes (wait: false) Yes -- waits for each result before deciding next step
Decision complexity Single classification decision Multi-step reasoning with synthesis across results
Typical iterations 3-5 (classify, extract, dispatch, complete) 10-20 (run workflow, analyze, run next, synthesize, escalate)
Agent's role Intelligent router Decision-maker and coordinator
After dispatch Agent completes immediately Agent continues reasoning

Tool Declaration

Pattern B agents need classification actions and workflow targets declared as typed tools. Since the agent routes to one of several possible workflows, declare each target workflow in the tools array:

json
{
  "tools": [
    { "type": "action", "name": "classify_document" },
    { "type": "action", "name": "extract_fields" },
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Process and reconcile invoices against POs" },
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Triage and respond to support tickets" },
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Onboard new vendors with verification" }
  ]
}

The engine resolves these in two batched queries -- one for all actions, one for all workflows -- and presents them to the LLM by their human-readable names. Implicit tools (__complete__, __log_progress__, etc.) are auto-injected; you don't declare them.

Typed declarations

Use { "type": "action", "name": "..." } for registered actions and { "type": "workflow", "id": "..." } for workflows. Workflows are referenced by ID (survives renames) but presented to the LLM by their name from the database. See Tool Declaration Reference for details.

---

Complete Example: Document Classifier and Router

A standalone agent that receives a document, classifies it, extracts relevant fields, and triggers the correct processing workflow.

Agent Configuration

json
{
  "objective": "Classify this incoming document and route it to the correct processing workflow.\n\nDocument content:\n{{input.document_text}}\n\nSender: {{input.sender_email}}\nReceived: {{input.received_at}}",
  "tools": [
    { "type": "action", "name": "classify_document" },
    { "type": "action", "name": "extract_fields" },
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Process invoices -- match to POs, flag exceptions, route for approval" },
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Handle support requests -- triage, investigate, respond" },
    { "type": "workflow", "id": "wfl-123e4567-e89b-12d3-a456-426614174000", "description": "Vendor onboarding -- verify business, set up account" }
  ],
  "config": {
    "model": "gpt-4",
    "max_iterations": 8,
    "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": "Classify this incoming document and route it...",
    "tools": [
      { "type": "action", "name": "classify_document" },
      { "type": "action", "name": "extract_fields" },
      { "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" }
    ],
    "config": { "model": "gpt-4", "max_iterations": 8 }
  }'

Sample Reasoning Trace

Notice the short iteration count -- the agent classifies, extracts, dispatches, and finishes. No waiting for workflow results.

text
Iteration 1:
  Thought: "I need to classify this document first."
  Action: classify_document
  Input: { "text": "Invoice #INV-2024-0891..." }
  Observation: { "category": "invoice", "confidence": 0.97 }

Iteration 2:
  Thought: "It's an invoice with high confidence. Let me extract the key fields."
  Action: extract_fields
  Input: { "text": "Invoice #INV-2024-0891...", "document_type": "invoice" }
  Observation: {
    "invoice_number": "INV-2024-0891",
    "vendor": "Acme Supplies",
    "amount": 4250.00,
    "due_date": "2026-03-15"
  }

Iteration 3:
  Thought: "Classification and extraction done. Triggering the invoice processing
            workflow. I don't need to wait for it -- my job is routing."
  Action: invoice_processing  <-- resolved from wf_inv_001
  Input: {
    "invoices": [{
      "invoice_number": "INV-2024-0891",
      "vendor": "Acme Supplies",
      "amount": 4250.00,
      "due_date": "2026-03-15"
    }],
    "source": "email_ingestion",
    "sender": "[email protected]",
    "wait": false
  }
  Observation: { "workflow_run_id": "run-123e4567-e89b-12d3-a456-426614174000", "status": "running" }

Iteration 4:
  Thought: "Invoice workflow triggered successfully. I'm done."
  Action: __complete__
  Input: {
    "answer": "Document classified as invoice (97% confidence). Triggered
              invoice_processing workflow (run-123e4567-e89b-12d3-a456-426614174000) with extracted fields.",
    "confidence": 0.97
  }

Four iterations. Classify, extract, dispatch, complete. That's the Pattern B signature.


Key Properties

  • Typed workflow tools give the agent a menu of possible destinations -- it picks the right one based on classification
  • wait: false on the workflow trigger -- the agent doesn't need to wait for invoice processing to complete. It classifies and routes
  • Standalone execution -- this agent runs via POST /agents/execute, not inside a workflow. It is the entry point
  • Short iteration budget -- max_iterations: 8 is plenty. If the agent needs more, you're probably looking at Pattern C

Scaling the Pattern

For high-volume ingestion, combine with a foreach loop in a wrapper workflow:

json
{
  "name": "batch_document_processor",
  "definition": {
    "actions": [
      {
        "type": "loop",
        "properties": {
          "mode": "foreach",
          "items_path": "@input.documents",
          "item_variable_name": "doc",
          "actions_to_execute": [
            {
              "type": "loop",
              "properties": {
                "mode": "react",
                "objective": "Classify and route: {{doc.text}}",
                "tools": [
                  { "type": "action", "name": "classify_document" },
                  { "type": "action", "name": "extract_fields" },
                  { "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" }
                ],
                "max_iterations": 6
              }
            }
          ],
          "max_concurrency": 5,
          "failure_strategy": "continue_on_error"
        }
      }
    ]
  }
}

Anti-Pattern: When Pattern B Becomes Pattern C

If you find yourself writing an objective like this, you've outgrown Pattern B:

text
"Classify this document, trigger the right workflow, WAIT for the result,
and if it fails, try a different workflow, then send a summary email."

The moment your agent needs to wait for results and make further decisions, you're in Pattern C territory. Pattern B agents fire and forget.

Next: Pattern C: Agent as Orchestrator