Перейти до вмісту

ADR-0014: Інтелект як дані — offline-артефакти замість online-інференсу

Статус: accepted · 2026-07-12 · власник @Vladbandurin

Serving abitly-recsys тримається на інваріанті детермінізму: видача однозначна за (inputs, policyVersion, editorialVersion, featureSnapshotId) → точний кеш-ключ, відтворюваність, admin-preview = prod-видача. Online ML-інференс цей інваріант ламає і додає другий always-on сервіс. Дані рекомендацій за природою batch: co-application — річний знімок кампанії, декларований інтент змінюється рідко.

«Інтелект заходить як дані, не як код». Увесь ML — offline Python batch: apps/compute (uv) у тому ж монорепо, запуск ECS Scheduled Task (патерн Scheduler→Fargate як в abitly-ads sync), нічний. Артефакти — версіоновані таблиці в Postgres recsys під snapshotId (item_item_edges, фічі, intent read-model), без S3/parquet-прошарку у v1. Serving (NestJS) лише читає артефакти і застосовує policy ⊕ editorial; персональна видача — детерміністичний scoring (eligibility-SQL + matching), не інференс.

Відхилена альтернатива

Section titled “Відхилена альтернатива”

Окремий online Python-скорер за /v1/rank (шлях, який спека 2026-06-06 §9 тримала за замовчуванням для «ML пізніше») — виправданий лише з появою behavioral feedback loop реального часу; контракт його не блокує.

  • + Інваріант детермінізму та дешевий fail-open виживають (артефакт застарів → показуємо вчорашній); нема другого always-on сервісу.
  • + Offline eval артефактів (coverage/overlap/staleness → Grafana) ловить «матриця зіпсувалась» до користувача.
  • Жодного real-time навчання/оновлення видач між прогонами batch.

Деталі — spec docs/superpowers/specs/2026-07-12-recommendation-core-design.md §5–6 (репо abitly-mc).