# Multi-agent routing — and why one agent is almost always the better answer

> **You want.** *"quiero rutear entre mi setter y soporte según lo que pregunte el lead"* ·
> *"cómo creo un intent workflow"* · *"multiple agents one account"* · *"agente padre e hijos,
> fallback agent"* · *"A/B testing entre dos agentes"* · *"route conversation to different agent
> multi-agent"* · *"INTENT_WORKFLOW ROUTER_WORKFLOW agent mode"*.
>
> **Short answer: build one agent.** Multi-agent routing exists, it works, and it is almost never
> the right tool. Read the two sections below before wiring anything.

## First — "workflow" names two unrelated things

This is why searching for routing lands you in the wrong document.

| | what it is | tool |
|---|---|---|
| **Workflow** | timed automation — follow-ups, notifications, reminders | `upsert_workflow` |
| **Workflow *mode*** | which agent answers a conversation | `update_agent_mode` |

`knowledge/workflows.md` documents the **first** (types `FOLLOW_UP`, `CUSTOM_NOTIFICATION`,
`CUSTOM_ACTION`, `SCHEDULE_REMINDER`). Routing is the **second** — an `agents.mode` of
`INDIVIDUAL`, `INTENT_WORKFLOW`, `A_B_WORKFLOW` or `ROUTER_WORKFLOW`. They share no table, no tool
and no field. Nothing you set with `upsert_workflow` affects routing, and nothing here affects
follow-ups.

If you came looking for follow-ups, you want `knowledge/follow-up-architecture.md`.

## Then — the reason not to

Production, checked 2026-08-18: **680 agents on `INDIVIDUAL`**, and of the 16 on a routing mode,
**every `INTENT_WORKFLOW` and `ROUTER_WORKFLOW` agent is inactive.** People ask about this far
more often than they run it, and the ones who built it are not using it.

That is not an accident of adoption. A routing layer adds a component that fails **silently**:

- The parent's `mode` and its child relations can disagree, and neither Studio nor the API tells
  you. Relations with `mode = INDIVIDUAL` means routing never runs and the parent answers
  everything. `mode ≠ INDIVIDUAL` with no relations means every message reaches a router with
  nowhere to send it.
- `workflow_agents` is a **replace, not a merge**: the call deletes every existing relation for the
  parent and inserts what you sent. Omit a child and it is detached, silently, with
  `{success: true}`. Always send the complete set — `list_agents` first, then resend all of them.
  (Calling with a non-`INDIVIDUAL` mode and *no* `workflow_agents` at all is rejected, on both the
  MCP tool and the REST route.)
- Meta delivers webhooks only to **linked** agents. Link the parent but not the children and
  follow-ups to routed conversations vanish with no error and no workflow run.
- A parent with no v5Config falls back to a permissive default, so it can speak while ignoring
  every constraint the children's prompts carry. *(Coaching vertical, 2026-05-21: 12 of 47
  outbound messages came from the router, using phrases the variants forbade.)*

**What to do instead.** One agent whose prompt handles both jobs. It is easier to iterate, easier
to debug, and there is no routing layer to misconfigure. If the two jobs really cannot share a
prompt, that is usually a sign they should be two agents on two channels, not one account with a
router.

## If you genuinely need it anyway

Rare but real cases: a single inbox that must serve two unrelated audiences, or a deliberate A/B
test of two prompts.

1. Build and test each child as a normal `INDIVIDUAL` agent first. A router cannot make a bad
   child good, and debugging both layers at once wastes a day.
2. `create_agent` the parent with the mode you want. `INTENT_WORKFLOW` re-evaluates every message
   (so it can re-route mid-conversation); `A_B_WORKFLOW` and `ROUTER_WORKFLOW` route the **first**
   message of a **new** conversation only, and never re-route existing ones.
3. `deploy_agent_sdk` the **parent**, all eight v5Config fields, before attaching anything.
   `create_agent` leaves the config empty, and an empty config is the permissive default above —
   so the parent ships able to override its children until you fill it. Confirm with
   `get_agent_config` that all eight are there, not just `keywords`.
4. `update_agent_mode` with the **complete** `workflow_agents` list — it is a replace, not a merge.
   `weight` matters only for `A_B_WORKFLOW`.
5. `set_connected_account` on **every** agent, parent and children. That tool is **Meta-only and
   additive**. If the traffic arrives through a CRM or a ManyChat relay it does not apply at all:
   a sync connection is assigned with `set_agent_crm_channel` (find it with `list_crm_connections`)
   and it holds exactly **one** `agent_id`, so giving it to the parent takes it away from whoever
   had it and there is no way to give the same relay to the children as well. On a relayed channel
   the children are therefore unlinked by construction — the vanishing-follow-ups failure above,
   with no fix available. See `knowledge/messaging-channels.md`.
6. Verify: `list_agents` shows the mode **and** the children; a real message is answered by a
   **child**, not the parent. Do not trust `{success: true}` — re-read the parent.

`set_on_conversation` is set for you at create time and is not caller-settable: `false` for
`ROUTER_WORKFLOW` and `A_B_WORKFLOW` so conversations pin to the variant, `true` otherwise. It also
gates pause-on-manual-outbound, which is why `update_agent_config` rejects `false` on an
`INDIVIDUAL` agent. Changing a parent's mode to `INDIVIDUAL` afterwards can strand it in a state
the API would no longer accept — recreate rather than patch.

A fallback agent — the one that takes no-match messages — is required, and it will reply. There is
no "neither agent should answer" path: if you need silence it has to come from that agent's own
prompt or from a contact limit. Note that `workflow_agents` carries only `agent_id` and `weight`,
with no fallback flag, so you cannot confirm which child holds the role by reading the relations.
Send a deliberately off-topic message and see who answers.

## See also

- `knowledge/workflows.md` — the *other* workflow (follow-ups, notifications, reminders)
- `knowledge/follow-up-architecture.md` — if you came here looking for follow-ups
- `knowledge/messaging-channels.md` — direct Meta vs CRM/relay channels, and which write tool owns each
- `knowledge/runbooks/agent-not-answering.md` — if a routed conversation goes silent
