AI Recsys

  • Area: Intelligence
  • Path: ai/recsys
  • Kind: Recommendation engine (RFC-001)

Role in the stack

koder-recsys ranks media items for products/horizontal/play/engine (the consumer flagship of Koder Play). Three streams feed a blender: vector ANN over ai/recsys useritem embeddings, co-watch graph, and trending heuristics. The engine adjudicates between variants via an integrated AB framework with anytime-valid mSPRT analysis.

Deployed as koder-recsys-server (axum, default 0.0.0.0:7800); RUST_LOG controls tracing; Prometheus /metrics available.

Substrate

  • User embeddings: in-memory, decay-weighted average of view signals; production swap to data/kdb kdb-vector.
  • Item embeddings (RECSYS-14): ItemEmbeddingStore trait + in-memory impl. kdb-vector adapter delivered alongside VectorCollection::search_linear (HNSW arrives in KDBN-540).
  • A/B framework: deterministic FNV-1a bucketing; mSPRT analyzer (RECSYS-15) decides Reject / Continue / Equivalence anytime — no alpha inflation under continuous peeking.

Key features

  • [x] Vector ANN (linear scan v0.1; HNSW pending on KDBN-540).
  • [x] Co-watch graph candidates.
  • [x] Trending detection over time-series view counts.
  • [x] Blender (vector × cowatch × trending, freshness boost, diversity penalty).
  • [x] AB exposure logging + mSPRT sequential analysis (RECSYS-015#019).
  • [x] Item embedding store (RECSYS-14).
  • [x] Bench harness with SLO baselines (RECSYS-13).
  • [x] Server bin wires all components — ItemStore + AbFramework + RateLimiter (RECSYS-16).
  • [x] v1recommend end-to-end mode — engine generates candidates from user embedding (RECSYS-17).
  • [x] Feedback ingests into EmbeddingStore — online learning loop closed (RECSYS-18).
  • [x] Cold-start fallback wired — cold_start: bool in response when history < 3 (RECSYS-20).
  • [x] Auto-exclude already-watched items from recommendations (RECSYS-21).
  • [x] Per-tenant rate limiter — token bucket, 1000 req/s default (RECSYS-22).
  • [x] Input validation: k capped at 1000 (RECSYS-23).
  • [x] GET /v1/experiments/:id/report — mSPRT analysis snapshot (RECSYS-26).
  • [x] kdb_recsys_blend_share blend-mix metric (RECSYS-27).
  • [x] kdb_recsys_cold_start_total cold-start rate counter (RECSYS-28).
  • [x] #[instrument] on ann_search with size fields (RECSYS-29).
  • [x] Per-tenant blend config override + PUT /v1/tenants/{tenant}/blend-config (RECSYS-33).
  • [x] POST /v1/feedback/batch — up to 100 events (RECSYS-39).
  • [x] Moderation-aware filter — ModerationGate trait, drops hidden items (RECSYS-30).
  • [x] Recsys event sink — RecsysEventSink trait, emits RecommendFeedbackExposure (RECSYS-31).
  • [x] Creator equity / fairness layer — apply_creator_quota (RECSYS-36).
  • [x] Bot/abuse trust score — Feedback.trust_score, TRUST_THRESHOLD = 0.3 (RECSYS-37).

SLO targets (RFC §SLOs)

  • p99 /v1/recommend200 ms.
  • Embedding update post-session ≤ 30 s.
  • Cold-start stable in ≤ 5 sessions.

Bench numbers: linear-scan ANN at 100k items is ~25 ms; embedding decay over 100 sessions ~540 µs; mSPRT analyze 10k exposures ~1.8 ms. All inside SLO budget. See services/ai/recsys/bench/baseline.json.

Interfaces

  • HTTP: POST /v1/recommend, POST /v1/feedback, POST /v1/embedding/refresh, GET /v1/experiments/:id/report, GET /healthz, GET /metrics.
  • Library: koder_recsys::{ann_search, blend, msprt_analyze, InMemoryItemStore, AbFramework, EmbeddingStore, HttpState}.

Open backlog

5 follow-up tickets in services/ai/recsys/backlog/pending/: tenant isolation (RECSYS-024 — needs auth middleware), Dart SDK client (RECSYS-032 — owned by enginessdkkoder_kit), kdb-vector HNSW adapter (RECSYS-034 — gated on datakdb RECSYS-540), cowatch kdb-graph adapter (RECSYS-35), streaming /v1recommend SSE (RECSYS-38).