Custom Orchestration
The orchestrator routes each conversation turn to the right agent and controls the flow of information between agents and users. ImplementAbstractOrchestrator to define custom routing logic.
Prerequisites
- AgenticAI Core SDK installed and configured.
- At least one agent configured and converted to
AgentMeta. See Creating Agents.
Message handling protocol
Incoming messages
The orchestrator’s_handle_message method receives a List[MessageItem]. The last item is either:
- A user message (
role='user') — when the user sends a query. - An agent response (
role='tool') — when an agent completes its task.
Outgoing messages
The method must return one of:| Return type | When to use |
|---|---|
ToolCall | Route to an agent or back to the user. |
ErrorMessage | When routing fails or an exception occurs. |
ToolCall fields:
tool_name— the agent to invoke, or"route_to_user"to respond to the user.message— the content sent to the agent or shown to the user.input,thought,reason— optional context for debugging and tracing.
Special agent: route_to_user
route_to_user is a built-in proxy for the user. Use it to deliver final answers or request clarification. The message field in the ToolCall is exactly what the user sees.
Create a custom orchestrator
SubclassAbstractOrchestrator and override _handle_message:
Routing strategies
Keyword-based routing
Round-robin routing
Task-based routing
Use memory in orchestrators
UseRequestContext to persist and retrieve orchestration state across turns:
Add distributed tracing
Decorate_handle_message and _select_agent with @tracer.observe to capture routing spans:
Common orchestration flows
User → agent → user (single-agent turn):Register the orchestrator
Pass the orchestrator class toapp.start:
Best practices
messagefield: This is the most important field inToolCall. For agents, it contains the task or question to process. Forroute_to_user, it is the exact response the user sees.- Error handling: Handle both success and error cases. Return
ErrorMessagefor routing failures and always implement aroute_to_userfallback. - Logging: Use
thoughtandreasonfields for debugging routing decisions. Log agent selection outcomes and track agent performance. - State management: Use memory stores to track conversation context and agent selection history across turns.
- Performance: Keep routing logic lightweight. Avoid blocking calls in
_handle_message. Use tracing to identify latency bottlenecks.