Skip to content

Classifiers Overview

A classifier runs before each turn and decides which agent should handle it. The Orchestrator calls classify(_:history:agents:), gets back a ClassifierResult, and dispatches to selectedAgent — or falls back to the default agent when selectedAgent is nil.

public struct ClassifierResult: Sendable {
public let selectedAgent: (any AgentProtocol)?
public let confidence: Double
public init(selectedAgent: (any AgentProtocol)?, confidence: Double)
}
public protocol Classifier: Sendable {
func classify(
_ input: String,
history: [ConversationMessage],
agents: [any AgentProtocol]
) async throws -> ClassifierResult
}
FieldTypeNotes
selectedAgent(any AgentProtocol)?The chosen agent, or nil when nothing matched. Always one of the agents passed to classify.
confidenceDoubleNominally 0...1. Captured for tracing only.
  1. The Orchestrator fetches merged conversation history from storage.
  2. It calls classifier.classify(_:history:agents:) with the user input, that history, and all registered agents.
  3. selectedAgent from the returned ClassifierResult is dispatched directly. No second lookup is performed — the agent instance must come from the agents parameter.
  4. When selectedAgent is nil, the Orchestrator routes to the first registered agent (the default).

Pass nil as the classifier when constructing the Orchestrator. Every turn goes straight to the first registered agent with no LLM call for routing.

let orchestrator = Orchestrator(classifier: nil, storage: storage)
ClassifierDescription
LLMClassifierUses an LLMClient and a select_agent tool call to pick the best agent. The default when a classifier is needed.
  • LLMClassifier — built-in LLM-based routing, init options, and custom instructions.
  • Custom classifiers — implement the Classifier protocol to write your own routing logic.