Default Reward Map
If you do not provide a customreward_map in learning_config, the system uses these defaults:
| Interaction Type | Default Reward | Signal Strength | Description |
|---|---|---|---|
impression | 0.0 | Neutral | Result was rendered on screen (passive signal) |
view | 0.0 | Neutral | User viewed a result (not in default reward map) |
click | 1.0 | Moderate positive | User clicked a result |
dwell | 0.5 | Weak positive | User lingered on a result |
long_view | 1.0 | Moderate positive | Sustained engagement (dwell time > 30s) |
purchase | 3.0 | Strong positive | Conversion event |
add_to_cart | 2.0 | Positive | Intent to purchase |
wishlist | 0.0 | Neutral | User added to wishlist (not in default reward map) |
bookmark | 1.5 | Positive | User saved for later |
share | 1.5 | Positive | User shared the result |
positive_feedback | 2.0 | Strong positive | Explicit thumbs up |
negative_feedback | -2.0 | Strong negative | Explicit thumbs down |
query_refinement | 0.0 | Neutral | User modified their search (not in default reward map) |
zero_results | 0.0 | Neutral | Query yielded no results (not in default reward map) |
filter_toggle | 0.0 | Neutral | User modified filters (not in default reward map) |
skip | -0.5 | Weak negative | Result was shown but ignored |
return_to_results | -0.5 | Weak negative | User bounced back quickly |
0.0 — they are recorded but do not influence fusion weights.
Custom Reward Maps
Override the defaults by settingreward_map in learning_config:
When you provide a custom
reward_map, it replaces the defaults entirely. Only interaction types present in your map will influence fusion weights. Include every type you want to count.reward_value in the interaction metadata. When an interaction has multiple types, the reward with the largest absolute value is used (not summed). For example, ['click', 'purchase'] yields 3.0 (the purchase reward), not 4.0. This means changing the reward_map only affects future interactions — previously recorded interactions retain their original reward values.
Negative Signals
Negative rewards (negative_feedback, skip, return_to_results) penalize the feature that surfaced the result. Mechanically, a negative reward increments the Beta distribution’s beta parameter, making it less likely that the associated feature receives high weight in future queries:
Position Bias
Results shown at position 0 get clicked more often than results at position 10, regardless of relevance. This is position bias — a well-known problem in learning-to-rank systems. Auto-Tune records theposition field on every interaction for analytics and audit purposes. However, the current reward computation does not weight interactions by position — a click at position 8 receives the same reward value as a click at position 0. Position bias correction is a planned enhancement but is not yet implemented.
Temporal Decay
User preferences change over time. Auto-Tune applies exponential decay to older interactions so that recent behavior matters more:decay_factor | After 30 days | After 90 days | After 180 days | After 365 days |
|---|---|---|---|---|
1.0 (no decay) | 100% | 100% | 100% | 100% |
0.999 | 97% | 91% | 84% | 69% |
0.995 | 86% | 64% | 41% | 16% |
0.990 | 74% | 41% | 17% | 3% |
0.980 | 55% | 16% | 3% | ~0% |
learning_config:
decay_window_days are ignored entirely (not just decayed to near-zero, but excluded from the aggregation query).
Backfilling historical interactions
By default the server timestamps each interaction at the moment it’s recorded. If you’re migrating existing click/purchase logs into Mixpeek, passoccurred_at (ISO 8601) so temporal decay weights each interaction by its true age instead of treating everything as brand-new:
Python SDK
Omit
occurred_at for live interactions — the server stamps “now”. A naive datetime is interpreted as UTC, and a future value is clamped to now. Backfilled events (with occurred_at) bypass the real-time within-session cache so historical data can’t pollute live, in-session adaptation.Python SDK
REST
errors). The response now also includes per-item results with assigned interaction_ids.
The private API uses
feature_id while published (public) retrievers use document_id — they refer to the same field. Use whichever matches the endpoint you’re calling.Examples
E-commerce: purchases matter most
Content platform: engagement over clicks
Internal search: explicit feedback only
min_interactions threshold because explicit feedback is sparse.
Related
- Auto-Tune — overview of the full feedback loop
- Interactions — how to capture user behavior
- Rollout & Safety — safely deploying learned fusion

