Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt

Use this file to discover all available pages before exploring further.

KaireonAI models retrain on three different rhythms depending on what kind of model they are and how you configure them. This page explains the mechanisms, the per-algorithm defaults, and the API/UI toggles that change the cadence.

TL;DR

Model typeDefault cadenceWhat learns whenToggle
thompson_banditContinuous — every /respondα / β posteriors per armAlways on (hardcoded)
epsilon_greedyContinuous — every /respondpulls / totalReward per armAlways on (hardcoded)
bayesianContinuous (if priors set) OR scheduledpredictor priors → posteriorsautoLearn + learnMode
online_learnerContinuous — every /respondweight vectorAlways on (hardcoded)
scorecardNothing by defaultneeds scheduled or manual retrainautoLearn=true, learnMode="scheduled"
logistic_regressionNothing by defaultneeds scheduled or manual retrainautoLearn=true, learnMode="scheduled"
gradient_boostedNothing by defaultneeds scheduled or manual retrainautoLearn=true, learnMode="scheduled"
neural_cfNothing by defaultneeds scheduled or manual retrainautoLearn=true, learnMode="scheduled"
external_endpointOut of scopeThe platform doesn’t train external modelsn/a
Out-of-the-box defaults are conservative. Every new algorithmModel row starts with autoLearn: false, learnMode: "none", learnSchedule: null — so tabular models won’t retrain unless you explicitly turn it on. Bandits and online learners ignore these toggles and always learn on every respond, because that’s the entire point of those algorithm families.

The three retraining mechanisms

1. Continuous (incremental)

For four model types — thompson_bandit, epsilon_greedy, bayesian (when priors are configured), and online_learner — the platform performs an in-place state update on every /respond call that returns a positive or negative outcome. The respond handler reads the current modelState from DB, applies the algorithm-specific update rule, and writes the new state back, all in a single Prisma transaction. Side effects:
  • algorithmModel.modelState advances (e.g. Thompson arm’s α += 1 on positive, β += 1 on negative).
  • algorithmModel.trainingSamples increments by 1.
  • algorithmModel.lastLearnedAt is set to now.
There’s no scheduling involved and no work to do — once the model is live and receiving traffic, it learns in real time. This is the right behavior for these algorithm families because they’re designed for online updates and would be wasteful to retrain in batch.

2. Scheduled offline retrain

For scorecard, logistic_regression, gradient_boosted, and neural_cf, learning is a full pass over accumulated training data. The platform runs a periodic cron (/api/v1/cron/scheduled-retrains) that:
  1. Finds every model with autoLearn: true AND learnMode IN ("scheduled", "both").
  2. For each, checks now - lastLearnedAt >= parseScheduleToMs(learnSchedule || "24h").
  3. If due, enqueues a retrain job that recomputes weights / trees / embeddings from the last N interaction-history rows.
  4. On completion, writes new modelState, metrics, metricsHistory[], predictors[].importance, and bumps both lastTrainedAt and lastLearnedAt.
The default cadence when learnSchedule is null is every 24 hours. Override with any of: "15m", "1h", "6h", "1d", "7d", or a cron expression like "0 3 * * *" (daily at 03:00 UTC).

3. Drift-triggered retrain

Independent of the schedule, the platform runs runScheduledDriftChecks on every cron tick. For each active model with drift monitoring enabled, it computes a Population Stability Index (PSI) and KL divergence on the predictor features comparing the last 24h vs the training-set baseline. If PSI exceeds the configured threshold (default 0.25, configurable per model), the model is enqueued for retrain immediately — regardless of when it was last trained. This catches sudden distribution shifts (a deployed pricing change, a new audience segment, a regulatory event) that would otherwise wait for the next nightly window.

Toggling the cadence — API

Every field shown below can be set on POST /api/v1/algorithm-models (model creation) and PUT /api/v1/algorithm-models/{id} (update):
# Turn on nightly retrains for a gradient-boosted model
curl -X PUT https://playground.kaireonai.com/api/v1/algorithm-models/$MODEL_ID \
  -H "Content-Type: application/json" \
  -d '{
    "autoLearn": true,
    "learnMode": "scheduled",
    "learnSchedule": "24h"
  }'

# Retrain every 6 hours instead
curl -X PUT https://playground.kaireonai.com/api/v1/algorithm-models/$MODEL_ID \
  -H "Content-Type: application/json" \
  -d '{ "learnSchedule": "6h" }'

# Pause auto-learning entirely (model continues to score, but state is frozen)
curl -X PUT https://playground.kaireonai.com/api/v1/algorithm-models/$MODEL_ID \
  -H "Content-Type: application/json" \
  -d '{ "autoLearn": false, "learnMode": "none" }'

Field reference

FieldTypeDefaultDescription
autoLearnbooleanfalseMaster switch. When false, scheduled retrains are skipped even if learnMode is set. Bandit / online-learner continuous updates ignore this flag — they always run.
learnMode"none" | "incremental" | "scheduled" | "both""none""scheduled" = nightly retrain only. "incremental" = update on every respond (only meaningful for bayesian; bandits/online-learners do this regardless). "both" = both. "none" disables all auto-learning.
learnSchedulestring | nullnull (→ 24h)Time interval ("15m", "6h", "24h", "7d") or cron expression ("0 3 * * *"). Only consulted when learnMode includes "scheduled".

Toggling the cadence — UI

In the Studio at Algorithms → Models → , the model-detail panel has a Learning section with the same three controls: an autoLearn toggle, a learnMode dropdown, and a learnSchedule text field with format hints. Changes save via PUT and take effect on the next cron tick (within 60 seconds in production).
This is what we’d reach for if you handed us a fresh tenant tomorrow:
  • Cold-start with sparse historical data. Pick a thompson_bandit or epsilon_greedy. The continuous-learning behavior means the model is useful from request #1 — no warm-up needed. Move to bayesian after you have ~10k interactions and want to incorporate predictor features.
  • Steady-state tabular workload with predictable churn. scorecard or gradient_boosted with autoLearn: true, learnMode: "scheduled", learnSchedule: "24h". Nightly is enough for most NBA workloads where the underlying customer behavior doesn’t shift hour-to-hour.
  • Volatile distribution (pricing tests, seasonal pushes, regulatory changes). Same as above but "6h" cadence AND configure drift checks. The drift trigger catches the sudden shift; the schedule keeps the model fresh on stable days.
  • Catalogs with fast turnover (new offers daily). Drop the schedule lower ("4h") or use drift-triggered exclusively — neural-cf especially benefits from fresh embeddings against the current catalog.
  • Compliance-sensitive deployments where every retrain needs human review. Set autoLearn: false and use the model promotion endpoint (POST /algorithm-models/{id}/promote) to manually advance retrained candidates through draft → shadow → challenger → champion with audit-log review at each step.

Common questions

“My scorecard model’s metricsHistory is empty. Did it train?” Almost certainly not. New models ship with autoLearn: false; the scheduled-retrains cron skips them. Flip autoLearn: true, learnMode: "scheduled" and wait for the next cron tick. Or trigger a one-off retrain via the Studio’s “Retrain now” button (which calls /api/v1/algorithm-models/{id}/train). “My Thompson bandit’s arms aren’t moving.” Three possibilities. First, check that /respond calls actually carry outcomeTypeKey — without a classifiable outcome the bandit can’t update. Second, check lastLearnedAt on the model: if it’s null, no incremental update has fired, which usually means the model isn’t wired into the active decision flow’s score node. Third, check modelState.arms — if it’s {} or missing, the model hasn’t been initialized; either re-create the model (its init path will seed arms from the candidate offers) or set arms explicitly via PUT. “What’s the difference between lastTrainedAt and lastLearnedAt?” lastTrainedAt is set by full offline retraining (the cron-driven flow). lastLearnedAt is set by either offline retraining OR by any incremental update (every respond for bandits / online learners). So a Thompson bandit will have lastLearnedAt advancing every minute and lastTrainedAt permanently null — that’s correct, because Thompson doesn’t have an offline-train concept. A scheduled gradient_boosted will have both fields advance together every 24h. “Can I retrain on-demand for testing?” Yes. POST /api/v1/algorithm-models/{id}/train triggers an immediate offline retrain regardless of schedule. Useful for evaluating data fixture changes before a flow goes live.
See also: Algorithms & Models | Algorithm Models API | Experiments — Shadow vs Champion/Challenger