PRISME France 2030 · Culture & IA

SPEC — SPEC_MARTY_AMELIORATION_CONTINUE_VESPA_GPU_CLIENT

Vérifier la maturitéSpecDoc. générale

Périmètre : SPEC_MARTY_AMELIORATION_CONTINUE_VESPA_GPU_CLIENT

Références :

SPEC — Marty : amélioration continue par feedback (Vespa), calcul opportuniste sur GPU client, apprentissage fédéré et transport pair‑à‑pair (WebRTC / WebSocket / TURN / libp2p / Y.js)

Date : 2026-04-24 (v1.2.2 — intégration du modèle fédéré : contrat MartyFederatedModelV1, registre versionné, compatibilité client, artefacts signés, politique de promotion et audit par modèle ; v1.2.1 — granularité étendue : sous‑tiers HIGH+/HIGH/MID+/MID/LOW+/LOW/DEGRADED, curseur intensité 0–100 + 6 presets, toggles consentement par tâche × sous‑finalité, fenêtres horaires utilisateur, quotas L1–L7, score de sélection cohorte multi‑dimensionnel)

Statut : Spécification normative v1.2 — proposée à validation produit + DPO (le défaut « consentement on » est subordonné à validation DPO ; sinon fallback automatique opt‑in). Implémentation incrémentale par phases F0 → F9 ; chaque phase est désactivable par flag, et chaque flux respecte les invariants existants (le NLU propose, le serveur autorise, Baserow reste source de vérité métier).

Périmètre : Boucle d’amélioration continue de Marty via retours utilisateurs (explicites + implicites) exploités par Vespa (signaux de pertinence, reranking, embeddings), accélération des réponses (cache multi‑niveau, prefetch, edge inference, SSE), calcul opportuniste GPU client lorsque l’utilisateur est inactif (embeddings, indexation locale, distillation), apprentissage fédéré des composants légers (rerank cross‑encoder, calibration NLI, adaptateurs LoRA‑like, intent mini‑classifier) avec différentielle privée, agrégation sécurisée, robustesse byzantine, et transport pair‑à‑pair entre navigateurs via WebRTC DataChannels (signalisation WebSocket, NAT traversal STUN/TURN coturn, options avancées libp2p pour le routage distribué et Y.js pour la synchronisation collaborative CRDT).

Statut documentaire : cette spec est transverse. Elle s’appuie sur les SPECs existantes (Marty, Vespa, ONNX, cache IA, agent adaptatif, offline, accessibilité) sans casser leurs contrats. Elle introduit quatre contrats normatifs (MartyFeedbackEventV1, MartyContributionV1, MartyFederatedModelV1, MartyP2PFrameV1), un protocole * et un canal de signalisation p2p. La couche Baserow WebSocket existante (websocket service, Composant interface) n’est pas modifiée ; le canal P2P Marty est totalement séparé.

Références transverses :

Schéma directeur : . Extraits techniques en anglais admis ; UI = i18n strict.

Suivi implémentation — salve IA/Marty (2026-05-09)

Synthèse jalons / chaîne cible alignés sur §3 (boucle feedback), §3.3–§3.4 (Vespa), §5 (GPU client idle) et §9 (F0–F2, F4–F5) — hors périmètre immédiat de cette salve : fédération F6+, transport P2P (§6.10+), tuning bundle NLU F3 (traiter en salve dédiée si besoin).

1. Contexte et objectifs

1.1 Pourquoi

Marty produit aujourd’hui des réponses correctes pour la plupart des branches, mais :

1.2 Objectifs (cibles chiffrées)

  1. Boucle d’amélioration continue : transformer chaque interaction Marty / recherche / Vespa en signal exploitable (clics, abandons, reformulations, votes, conversion vers action exécutée) ; cible +10 pts CTR top‑3 à 90 j vs baseline.
  2. Accélération : p95 ≤ 350 ms sur les requêtes répétitives (warm path), ≤ 1.2 s sur le cold path ; TTFB SSE ≤ 200 ms pour les réponses longues.
  3. Calcul opportuniste GPU client : déléguer aux navigateurs inactifs (idle, consenti par défaut, modulé par capacités matérielles + choix UI, budget énergétique non débrayable) des micro‑tâches d’embedding et d’indexation locale ; cible ≥ 60 % d’utilisateurs HIGH/MID contribuant au moins une fois / semaine (rendu atteignable par le défaut on combiné à la modulation matérielle), ≥ 20 % de tier MID/LOW dans les cohortes fédérées (équité matérielle), aucun appareil ne dépassant ses budgets physiques.
  4. Réseau fédéré : entraîner un rerank cross‑encoder distillé et un mini‑intent classifier par FedAvg différentielle privée + agrégation sécurisée, avec budget (ε ≤ 8, δ ≤ 1e‑5) sur l’horizon de vie du modèle, et promotion gated par golden set.
  5. Transport pair‑à‑pair : ≥ 70 % des messages d’agrégation fédérée échangés en WebRTC direct (sans relais TURN), TURN utilisé pour ≤ 25 % des connexions, ≤ 5 % des participants en mode dégradé HTTPS centralisé. Économie de bande passante coordinator ≥ 50 % vs mode étoile pur.
  6. Souveraineté : zéro corpus utilisateur ne sort de l’infrastructure ; signaux agrégés, anonymisés, bornés ; aucune PII brute. Le serveur de signalisation et le serveur TURN sont auto‑hébergés sur l’infra Grainerie (pas de service tiers type Twilio/Xirsys).

1.3 Hors‑périmètre (explicite)

2. Vue d’ensemble (architecture cible)

┌──────────────────────────────────────────────────────────────────────────────┐
│ Navigateur (Qwik) │
│ ┌─────────────────┐ ┌─────────────────────┐ ┌──────────────────────┐ │
│ │ Marty UI │ │ Telemetry Bus │ │ Idle Compute Worker │ │
│ │ /recherche │─►│ (events feedback) │ │ (WebGPU / WASM) │ │
│ │ Header search │ │ - vue / clic │ │ - embeddings batch │ │
│ └────────┬────────┘ │ - reformulation │ │ - distillation │ │
│ │ │ - vote 👍/👎 │ │ - rerank précalculé │ │
│ ▼ │ - abandon │ │ - rounds fédérés │ │
│ ┌─────────────────┐ │ - exécution action │ └──────────┬───────────┘ │
│ │ Embed worker │ └──────────┬──────────┘ │ │
│ │ ONNX (q/doc) │ │ │ │
│ └────────┬────────┘ │ │ │
│ ▼ ▼ ▼ │
│ POST /api/vespa/search POST /api/ai/feedback POST /api/ai/contributions │
│ GET /api/ai/stream GET /api/ai/federated/round │
└────────────┬─────────────────────┼───────────────────────────┼───────────────┘
             ▼ ▼ ▼
  ┌──────────────────┐ ┌────────────────────┐ ┌────────────────────────────┐
  │ BFF Qwik │ │ Feedback collector │ │ Federated coordinator │
  │ /api/vespa/* │ │ (anonymisation, │ │ (manifest, secure agg, │
  │ /api/ai/* │ │ rate limit, sign) │ │ DP noise, robust agg) │
  └────────┬─────────┘ └─────────┬──────────┘ └──────────┬─────────────────┘
           ▼ ▼ ▼
  ┌──────────────────┐ ┌────────────────────┐ ┌────────────────────────────┐
  │ Vespa cluster │ │ Vespa interactions │ │ Aggregator + Trainer │
  │ docs / index │◄─│ (events stream) │ │ (offline batch, golden set, │
  │ rank profiles │ │ → ranking signals │ │ distillation, promotion) │
  └──────────────────┘ └────────────────────┘ └──────────────┬─────────────┘
                                                                ▼
                                                Bundle de modèles signé,
                                                déployé via ai-models-config.json

Quatre flux principaux :

  1. Recherche / NLU (chaud) — search, query, stream (SSE).
  2. Feedback (asynchrone, fire‑and‑forget) — feedback.
  3. Contributions GPU client (best‑effort, batché, idle) — contributions.
  4. Réseau fédéré (rounds périodiques) — round, manifest, upload delta, sa share (secure aggregation).

3. Boucle d’amélioration continue (feedback)

3.1 Signaux capturés

3.1.1 Signaux explicites

SignalDéclencheur UIPayload
vote_up / vote_downBoutons 👍 / 👎 sur réponse Marty{ requestId, branch, score, comment? }
clarification_chosenPuce de clarification cliquée{ requestId, clarificationId, optionKey }
result_pinnedÉpingle un résultat pertinent{ queryId, docId, rankShown }
result_hiddenMasque/rejette un résultat{ queryId, docId, reason? }
report_problemSignalement libre (modale){ requestId, category, freeText }
correction_inlineÉdition inline d’une entité reconnue (lieu, date){ requestId, slot, beforeValue, afterValue }

3.1.2 Signaux implicites

SignalDétectionUsage ranking
result_clickedClic / navigation vers un résultatCTR par (query_norm, docId, rank)
result_dwell_timeTemps passé avant retourPertinence implicite (≥ 8 s = positif)
query_reformulatedNouvelle requête ≤ 30 s, similarité ≥ 0.6Marqueur de non‑satisfaction
query_abandonedOuverture résultats puis fermeture sans interactionMarqueur négatif léger
action_executedMarty propose action → confirmation et succèsRenforce branche / intent
action_cancelledModale fermée sans confirmationPénalise mapping
marty_response_replacedRéponse spéculative remplacée par autoritaire (§16)Marqueur de divergence client/serveur (debug)

3.1.3 Données interdites (jamais collectées)

3.2 Schéma d’événement MartyFeedbackEventV1

{
  "eventVersion": "v1",
  "eventId": "ulid",
  "eventTimeMs": 1745500000000,
  "eventType": "result_clicked",
  "session": {
    "sessionIdHash": "base32_8ch",
    "userIdHash": "base32_8ch", // salé serveur, rotation quotidienne
    "rolesHash": "base32_8ch",
    "locale": "fr",
  },
  "context": {
    "routeId": "/recherche",
    "view": "calendar",
    "embed": false,
    "filtersFingerprint": "ctx1a2b3c4d",
    "deviceTier": "MID",
  },
  "request": {
    "requestId": "uuid",
    "queryId": "uuid",
    "branch": "where_event",
    "intentKey": "where_event.lookup",
    "structuredUnderstandingHash": "8ch",
    "modelBundleVersion": "v3.2.1",
    "rankProfile": "hybrid_with_feedback",
    "alpha": 0.62,
  },
  "result": {
    "docId": "calendar_event:558:42",
    "tableId": 558,
    "rowId": 42,
    "rankShown": 3,
    "scoreVespa": 0.81,
    "scoreCrossEncoder": 0.62,
  },
  "outcome": {
    "dwellMs": 12450,
    "reformulatedAfter": false,
    "actionExecuted": false,
    "ttftMs": 187,
    "ttfsMs": 220,
  },
  "consent": {
    "telemetry": "granted",

---

*Synthèse PRISME — 3083 lignes dans la source complète.*

**Voir aussi PRISME :** IA fédérée Marty · Nœud IA Expérimental

{

"eventVersion": "v1",

"eventId": "ulid",

"eventTimeMs": 1745500000000,

"eventType": "result_clicked",

"session": {

"sessionIdHash": "base32_8ch",

"userIdHash": "base32_8ch", // salé serveur, rotation quotidienne

"rolesHash": "base32_8ch",

"locale": "fr",

},

"context": {

"routeId": "/recherche",

"view": "calendar",

"embed": false,

"filtersFingerprint": "ctx1a2b3c4d",

"deviceTier": "MID",

},

"request": {

"requestId": "uuid",

"queryId": "uuid",

"branch": "where_event",

"intentKey": "where_event.lookup",

"structuredUnderstandingHash": "8ch",

"modelBundleVersion": "v3.2.1",

"rankProfile": "hybrid_with_feedback",

"alpha": 0.62,

},

"result": {

"docId": "calendar_event:558:42",

"tableId": 558,

"rowId": 42,

"rankShown": 3,

"scoreVespa": 0.81,

"scoreCrossEncoder": 0.62,

},

"outcome": {

"dwellMs": 12450,

"reformulatedAfter": false,

"actionExecuted": false,

"ttftMs": 187,

"ttfsMs": 220,

},

"consent": {

"telemetry": "granted",


Synthèse PRISME — 3083 lignes dans la source complète.

Voir aussi PRISME : IA fédérée Marty · Nœud IA Expérimental