For developers
A small Python library. Bring your own models.
The core needs no web server, database server, or hosted account. Give it a decision-model adapter and, for optimization, a completion function for the LLM you choose. The web workspace is optional.
pip install "decision-flywheel @ git+https://github.com/AnthusAI/Cyclotron.git"- Decision model
- Jev · TypeSafe System One
- Decision model
- Kev · System One over HTTP
- Decision model
- Laya · runs locally
- Decision model
- System One clients · any Jev- or Kev-style client
- Optimizer LLM
- OpenAI · opt-in only
- Optimizer LLM
- LiteLLM · one interface to many providers
Another provider needs one small adapter class. MIT license. Python 3.10 or later.
import asyncio
from decision_flywheel import ClassifierConfig, DecisionFlywheel
from decision_flywheel.classifier_config import ClassifiedAnswers
from decision_flywheel.models import DecisionResult, DecisionTask, Item
class ScriptedModel:
"""Replace this with JevAdapter, KevAdapter, LayaAdapter, or your adapter."""
model_identity = "scripted-v1"
async def classify(self, config, target, training, *, now=None, event_sink=None):
answer = DecisionResult("include", {"include": 0.8, "exclude": 0.2})
return ClassifiedAnswers({"decision": answer}, self.model_identity, {}, 0)
task = DecisionTask("library", ("include", "exclude"), "Should this item be included?")
wheel = DecisionFlywheel("local.sqlite3", ClassifierConfig(task), ScriptedModel())
prediction = asyncio.run(wheel.predict(Item("item-1", {"text": "A useful paper"}), ()))
print(prediction.label, prediction.confidence) # include 0.8
print(wheel.history()[-1]["kind"]) # prediction
wheel.close()The shape of it
Cyclotrons, classifiers, and the loop around them.
One item through several classifiers.
All classifiers share one decision-model request. In a store created with sharing, the default for new stores, a supporting question that several classifiers need is asked once and feeds each one's ML model. Review routing is per classifier: each is selected on its own confidence and its own audit sample, and one checklist review can label several. Each classifier has its own store, rubric and ML model. Watch one item go through them →
Learning after the review.
Open a store with learning="deferred" and review() only records the labels and queues a learning pass for each labeled classifier, then returns. await cyclotron.learn() runs the queue, each classifier at most once per call, and pending_learning() lists what is waiting. With an asynchronous optimizer transport, the store is free while a pass waits on the optimizer, so reviews and decisions keep completing. The default is inline learning, which runs inside the review.
If a label the pass rests on is corrected, or a classifier's criteria change, during the wait, the pass is superseded: it is recorded, stays queued and runs again, up to a cap (max_superseded_passes). If a pass is interrupted, its own paid request is recorded as abandoned, and a repeat charge is possible; it is never silently re-paid.
Illustrative example. Deferred learning is opt-in; the default is inline learning, inside the review.