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/kdbkdb-vector. - Item embeddings (RECSYS-14):
ItemEmbeddingStoretrait + in-memory impl. kdb-vector adapter delivered alongsideVectorCollection::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: boolin 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:
kcapped at 1000 (RECSYS-23). - [x]
GET /v1/experiments/:id/report— mSPRT analysis snapshot (RECSYS-26). - [x]
kdb_recsys_blend_shareblend-mix metric (RECSYS-27). - [x]
kdb_recsys_cold_start_totalcold-start rate counter (RECSYS-28). - [x]
#[instrument]onann_searchwith 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 —
ModerationGatetrait, drops hidden items (RECSYS-30). - [x] Recsys event sink —
RecsysEventSinktrait, 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/recommend≤ 200 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).