Aller au contenu

Architecture · open source

Une gateway, un modèle, deux bases.

Les applications ne parlent jamais au modèle. La gateway est le seul composant exposé ; tout le reste vit sur le réseau interne.

01Principes

Six règles, pas plus.

  1. 01

    Contrat gelé

    Exactement /v1/systemone de TypeSafe. Ajouts en x_ ou sur des routes séparées.

  2. 02

    Backend interchangeable

    Le modèle est derrière DecisionBackend. Kev-0.8B est une implémentation.

  3. 03

    Contexte côté plateforme

    Le state est rendu par la gateway depuis des templates versionnés.

  4. 04

    Chaque décision est un enregistrement

    Identifiant, probabilités, backend, version de schéma, puis outcome.

  5. 05

    Abstention explicite

    Sous le seuil du schéma : abstain, jamais un choix arbitraire.

  6. 06

    Zéro réseau au runtime

    Poids montés depuis un volume Docker rempli une fois.

02Composants

Qui fait quoi.

La gateway concentre la logique. Le serveur modèle est pur et sans état : on en ajoute des réplicas pour monter en charge.

Application, puis gateway, puis kev.serve : la requête descend, la réponse typée remonte.POST/v1/systemoneanswersx_decision_idstate,questionsprobabilitésbrutesApplicationSDK TypeSafeGatewayauth · schéma · calibrationkev.serveKev-0.8B · CPU
ComposantTechnoResponsabilité
GatewayFastAPI, Pydantic v2, SQLAlchemy 2, httpxAuth, autorisation, rendu du state, validation, routage, journal, abstention
Serveur modèlekev.serve (PyTorch CPU)Inférence /v1/systemone pure, sans état, un conteneur par réplica
Console adminReact, Vite, TypeScript, shadcn/ui, TanStack QueryApplications, clés, schémas, templates, décisions, calibration, playground
PostgreSQL 16Référentiel et table decision partitionnée par mois
Redis 7Rate limit (token bucket), quotas, cache des schémas et templates publiés
SiteNext.js en export statique, NginxCe site

03Séquence

Un appel, de bout en bout.

L'insertion en base se fait après la réponse, en tâche de fond : elle ne pèse pas sur la latence.

Séquence d'un appel : l'application appelle la gateway ; la gateway contrôle le quota et lit le schéma dans Redis, rend le state, appelle kev.serve, applique la température et le seuil d'abstention, répond avec x_decision_id puis enregistre la décision dans PostgreSQL. Plus tard, l'application envoie l'outcome.ApplicationGatewayRedisPostgreSQLkev.servePOST /v1/systemonerate limit + quotaschéma + templatevalide les questions, rend le statePOST /v1/systemone { state, questions }probabilités par questiontempérature + seuil d'abstentionanswers + x_decision_idinsert decision (tâche de fond)… plus tardPOST /v1/decisions/{id}/outcome

04Déploiement

Une VM, un compose.

Caddy devant, TLS automatique. Pas de Kubernetes : on ajoute des réplicas modèle derrière la gateway, qui répartit en round-robin.

Caddy termine le TLS sur le port 443 et répartit : le site statique sur /, la gateway sur /v1 et /admin/v1, la console sur /console. La gateway (port 8080) parle aux réplicas du modèle kev.serve (port 8008), à PostgreSQL (5432) et à Redis (6379). Les poids du modèle sont dans un volume Docker rempli une fois et vérifié par SHA-256.

05Décisions

Ce qu'on a choisi, et pourquoi.

Chaque choix d'architecture avec les alternatives écartées. Les écarts constatés à l'implémentation sont consignés dans doc/decisions.md.