You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This proposes a Thompson Sampling bandit as a new routing algorithm that learns from outcomes — directly addressing #445 ("conversation routing without a verifier").
Unlike the existing algorithms (static thresholds, LLM-as-judge, random split), this one improves as traffic flows: per-model posterior distributions over quality are sampled at routing time (exploration vs. exploitation trade-off) and updated from observed outcomes.
Design Sketch
The implementation composes entirely within Switchyard's existing trait model — no new traits required:
ThompsonSamplingAlgorithm (new Algorithm constructor)
├── ThompsonSamplingClassifier (Classifier<S> — samples target from Beta posteriors)
├── BanditFeedbackProcessor (Processor<S> — updates posteriors from ModelResponse events)
└── targets (model list)
Feedback signal: V1 uses tool-result signals (binary success/failure from Switchyard's existing tool signals) via an OutcomeScorer trait with a ToolSignalOutcomeScorer default. A richer scorer (e.g., quality-gate-based) can upgrade the signal later without touching the bandit.
Cold-start: config-driven prior per target (default alpha=1, beta=1 = uniform).
Scope cuts (v1, documented as future work):
No persistence across restarts (Switchyard has no storage layer yet)
No task-type conditioning (key on ModelId only)
No session affinity (per-turn sampling)
Dependency: would introduce rand_distr for Beta sampling (idiomatic Rust, more correct than hand-rolled gamma/Beta).
Open Questions
Before writing code, I'd like maintainer input on:
Crate placement:crates/libsy (alongside existing algorithms) vs. a new switchyard-bandit crate? I lean toward libsy per the crate-placement rules.
rand_distr dependency: acceptable for Beta sampling, or should sampling be built on rand alone (e.g., gamma sampling via rand) to avoid the new dep?
Prior semantics: is a config-driven prior per target the right cold-start model, or should priors derive from something Switchyard already tracks?
Background
I maintain Threshold — a TypeScript LLM routing monorepo with a Thompson Sampling bandit, quality gate, vibe detection, and quantization-aware scoring. Switchyard's backing and community make it the right home for these innovations. This is the first of four planned contributions (see contribution plan).
Happy to align on scope, naming, and structure before opening a PR.
Summary
This proposes a Thompson Sampling bandit as a new routing algorithm that learns from outcomes — directly addressing #445 ("conversation routing without a verifier").
Unlike the existing algorithms (static thresholds, LLM-as-judge, random split), this one improves as traffic flows: per-model posterior distributions over quality are sampled at routing time (exploration vs. exploitation trade-off) and updated from observed outcomes.
Design Sketch
The implementation composes entirely within Switchyard's existing trait model — no new traits required:
Feedback signal: V1 uses tool-result signals (binary success/failure from Switchyard's existing tool signals) via an
OutcomeScorertrait with aToolSignalOutcomeScorerdefault. A richer scorer (e.g., quality-gate-based) can upgrade the signal later without touching the bandit.Cold-start: config-driven
priorper target (defaultalpha=1, beta=1= uniform).Scope cuts (v1, documented as future work):
ModelIdonly)Dependency: would introduce
rand_distrfor Beta sampling (idiomatic Rust, more correct than hand-rolled gamma/Beta).Open Questions
Before writing code, I'd like maintainer input on:
Crate placement:
crates/libsy(alongside existing algorithms) vs. a newswitchyard-banditcrate? I lean towardlibsyper the crate-placement rules.Sequencing: is a tool-signal feedback default acceptable, or would maintainers prefer a quality-gate scorer to land first (ci: gate nemo-switchyard release publishing on tags #2 before fix: fix repo links #1) for richer feedback signals?
rand_distrdependency: acceptable for Beta sampling, or should sampling be built onrandalone (e.g., gamma sampling viarand) to avoid the new dep?Prior semantics: is a config-driven
priorper target the right cold-start model, or should priors derive from something Switchyard already tracks?Background
I maintain Threshold — a TypeScript LLM routing monorepo with a Thompson Sampling bandit, quality gate, vibe detection, and quantization-aware scoring. Switchyard's backing and community make it the right home for these innovations. This is the first of four planned contributions (see contribution plan).
Happy to align on scope, naming, and structure before opening a PR.