Octov0.11.7
AI

AI Router

Route messages to named branches with an LLM.

The ai-router block asks an LLM to pick exactly one of several named, described routes for each message. Use it where the routing decision needs judgment (triaging tickets, classifying inbound email, dispatching webhooks by intent) and a switch condition would be brittle.

A complete example

This flow triages support tickets to a team:

service:
  name: ai-router

env:
  - name: ANTHROPIC_API_KEY
    required: true

connectors:
  - name: claude
    type: llm-anthropic
    settings:
      apiKey: ${ANTHROPIC_API_KEY}

flows:
  - name: triage
    process:
      - type: ai-router
        name: triage-ticket
        connector: claude
        prompt: >
          Read the support ticket in the message body and route it to the team
          best suited to handle it.
        guardrail: >
          If the ticket is ambiguous, spans multiple areas, or you are not
          confident, take the default (human triage) path.
        routes:
          - name: billing
            description: Payment failures, refunds, invoices, subscription changes.
            process:
              - type: set-payload
                settings:
                  value: '{"team": "billing"}'
          - name: technical
            description: Bugs, outages, API errors, integration problems.
            process:
              - type: set-payload
                settings:
                  value: '{"team": "technical"}'
        default:
          process:
            - type: set-payload
              settings:
                value: '{"team": "human-triage"}'
octo invoke --config samples/ai-router.yaml --flow triage \
  --data '{"subject":"I was double charged","body":"Please refund the extra charge."}'
# -> {"event_id":"…","body":{"team":"billing"}}

The ai-router sample in the visual editor

Like ai-agent, ai-router is a composite: its keys sit at the top level of the block.

How it decides

Each route's name and description are listed in the model's system prompt; the description is the routing contract, so write it precisely. The model gets read-only inspection tools (get_body, list_variables, get_variable) to look at the message, then calls a select_route tool whose argument is constrained to the configured route names. The chosen route's process chain runs on the message. The decision loop is capped at 5 model calls; a model that inspects without deciding falls through to the guardrail.

Guardrail and default

guardrail describes when the model should decline to pick a route; default is the flow that runs when it does, or when it never decides. Give it a real escape hatch such as a human-triage queue.

With no default configured, the guardrail passes the message through unchanged, the same behavior as a switch with no default branch.

Choosing between switch, ai-router, and ai-agent

BlockWhen
switchThe condition is computable: a field value, a status code, a CEL expression. Deterministic, free, instant. Prefer it whenever you can write the condition.
ai-routerThe condition needs judgment over unstructured content, but the outcome is one decision: pick a branch, run it, done.
ai-agentThe task needs multiple steps: gather data with tools, reason over results, produce an answer. An agent loops; a router decides once.

A common composition is a router in front of agents: cheap single-decision triage first, and only the routes that need multi-step work pay for an agent. Full field tables: AI Blocks reference.

On this page