Route Chat Messages to the Right Agent
The problem
Organizations deploy multiple agents for different functions:
- A support agent in the #support channel
- An ops agent that handles infrastructure alerts
- A code review agent for engineering channels
- A general assistant as the default fallback
Without a routing layer, each agent either listens to everything (noisy, wasteful) or requires per-agent channel configuration (fragile, hard to change). Routing logic ends up scattered across webhook handlers and if-else chains in application code.
How CAR solves it
Register multiple agents and define routing rules. CAR evaluates the rules on every inbound message and dispatches to the matching agent:
$ car agent add support-bot --endpoint=https://support.example.com $ car agent add ops-bot --endpoint=https://ops.example.com $ car agent add general-bot --endpoint=https://general.example.com $ car route add --channel-match="support-*" --agent=support-bot $ car route add --channel-match="ops-*" --agent=ops-bot $ car route add --default --agent=general-bot $ car start [car] 3 agents registered · 3 routes active · relay running
Messages from #support-general go to the support bot. Messages from #ops-alerts go to the ops bot. Everything else falls through to the general assistant.
How routing works
message.received → policy.decision.made (governance first) → route.decision.made (evaluate rules, select agent) → agent.invocation.requested (dispatch to selected agent) → ...delivery
The routing decision is recorded as a canonical event in the ledger. You can always see which agent handled which message and why.
Route rule types
Channel match
Route based on channel name patterns. --channel-match="support-*" matches any channel starting with "support-".
Default route
Fallback when no other rule matches. Every deployment should have a default route to avoid unhandled messages.
Dynamic routing
Supply a custom routeFn for advanced logic: content-based routing, user-based routing, or external service lookups.
What you get
- Centralized routing configuration — all rules in one place, managed via CLI or API
- Auditable route decisions — every
route.decision.madeevent records which agent was selected and why - Runtime updates — add, remove, or change routes without restarting the relay
- Governance before routing — policy runs before the route decision, so blocked messages never reach any agent