Rukh : se spécialiser pour l'école

Julien Béranger

+ Claude Fable 5

Rukh permet aujourd'hui à n'importe qui de construire son propre assistant : on crée un contexte, on y dépose des documents et des liens, on choisit le modèle, et on ouvre la conversation à ses utilisateurs — c'est ce que fait rukh-ui, et c'est en ligne. C'est fonctionnel, mais c'est un positionnement générique.

Cette note explique pourquoi je pense qu'il faut spécialiser le produit pour les enseignants et leurs élèves, ce que ça implique concrètement dans le code, et jusqu'où il est raisonnable d'aller sur l'« agentique ».

1. Le marché générique est saturé

La version générique de l'idée — « construis ton bot, donne-lui tes documents, choisis ton modèle, partage-le » — est un océan rouge.

LibreChat fait déjà le multi-modèle derrière une interface unique. Dify (dépôt) combine constructeur visuel, RAG et agents, avec auto-hébergement. Botpress, Flowise, Open WebUI, Chatbase et Poe occupent le reste du terrain — voir les comparatifs d'eesel AI et de GPTBots sur Dify. Le RAG en deux étapes, le repli entre fournisseurs et le suivi des coûts — c'est-à-dire une bonne partie de ce que Rukh sait faire — sont devenus le minimum syndical, pas des différenciateurs.

La couche éducation est occupée elle aussi, mais à l'américaine : MagicSchool, SchoolAI, Khanmigo, Edcafe, Brisk, et depuis novembre 2025 ChatGPT for Teachers, gratuit et aligné FERPA. Tous fonctionnent selon le même modèle : le district signe un accord de traitement des données, et les données des élèves partent ensuite chez un éditeur américain sous contrat.

La seule chose de notre pile que personne n'a, dans aucune des deux listes, c'est W3PK (docs) : une identité dérivée d'une passkey, sans e-mail, sans mot de passe, sans compte, avec authentification des requêtes par SIWE / EIP-4361. Sur le marché générique, c'est une curiosité. Sur le marché européen de l'éducation, c'est le produit tout entier — pour la raison qui suit.

2. Le créneau est réglementaire

Le cadre d'usage de l'IA en éducation publié par le ministère en juin 2025 (PDF, dossier éduscol) contient une phrase qui vaut plus cher que n'importe quelle fonctionnalité :

Il ne faut en aucun cas demander aux élèves de se créer un compte personnel auprès de services d'IA accessibles au grand public.

C'est un mur pour toute la cohorte américaine sur la surface élève. Et c'est exactement ce qu'une passkey contourne : une passkey n'est pas un compte chez un tiers.

La CNIL va plus loin encore, et ses recommandations lisent comme un cahier des charges. À ne pas collecter : « les informations nécessitant la création d'un compte individuel lorsqu'un compte de classe suffit ». À vérifier chez le fournisseur : historique des données désactivé par défaut, amélioration algorithmique désactivée, pas de transferts hors UE/EEE. À privilégier : les solutions on device ou on premise. Et une AIPD est obligatoire dans la plupart des usages scolaires, les élèves étant mineurs.

Le reste du cadre va dans le même sens. L'IA générative est autorisée en classe à partir de la 4e, de façon limitée, encadrée et accompagnée par l'enseignant. Aucune donnée personnelle ou confidentielle ne doit être saisie dans ces services — voir aussi le guide KIDSHAKER et l'analyse d'ia-edu. Et la formation des élèves à l'IA est désormais obligatoire en 4e, en 2de et en CAP, via Pix : c'est une demande prescrite, pas une demande à créer.

La souveraineté a même son canal officiel, avec le GAR (explication Primàbord) et LUCIE, le modèle ouvert de Linagora et OpenLLM France (papier Lucie-7B). Côté Rukh, l'override model par contexte permet déjà d'épingler un contexte sur Mistral, français et hébergé en Europe. L'étape de sélection RAG passe d'ailleurs déjà par Mistral.

Deux réserves avant de s'engager

« Enfants » veut dire collégiens de 13 ans et plus, pas écoliers. Le produit qu'on construirait pour une classe de 4e n'est pas celui que suggère la carte « For kids » actuelle. Il faut trancher ça avant de dessiner quoi que ce soit.

Les passkeys se marient mal avec le matériel scolaire partagé. Une passkey est liée à un appareil et à un utilisateur ; une armoire de trente tablettes partagées, c'est le pire cas. Ma recommandation ferme : la surface élève ne doit porter aucune identité — un lien de classe, un code, une session éphémère, rien de persisté. L'identité W3PK reste celle de l'enseignant seul. C'est à la fois plus simple à construire et plus défendable au RGPD que de distribuer une passkey par élève. C'est d'ailleurs mot pour mot la recommandation CNIL : un compte de classe plutôt qu'un compte individuel.

3. Deux correctifs à faire avant tout pilote en établissement

Ce sont les deux points qui bloquent, aujourd'hui, dans le code de l'API.

3.1 Arrêter de stocker les messages bruts

Ce qui se passe aujourd'hui. À chaque appel à /ask, la méthode recordContextQuery (dans src/app.service.ts, autour de la ligne 283) enregistre la requête dans le fichier data/contexts/<nom>/index.json. Et parmi les champs enregistrés, il y a le message complet de l'utilisateur, en clair :

index.queries.push({
  timestamp: new Date().toISOString(),
  origin: 'anon',
  message: message,          // ← le texte intégral de l'utilisateur
  contextFilesUsed: [...],
});

Pourquoi c'est un problème. Trois raisons qui se cumulent :

  1. Le champ n'est pas déclaré. Le DTO ContextQueryDto (src/dto/context.dto.ts) annonce timestamp, origin et contextFilesUsed — il ne mentionne pas message. Autrement dit, on stocke une donnée que la documentation de l'API ne mentionne nulle part. C'est précisément le genre d'écart qu'un DPO relève en premier, et l'inverse exact de la transparence exigée par le RGPD.
  2. origin: 'anon' n'anonymise rien. C'est l'émetteur qui est anonyme, pas le contenu. Un élève de 4e qui écrit « je m'appelle Léa, je suis au collège Jean-Moulin et je n'arrive pas à faire l'exercice 4 parce que mes parents divorcent » vient de déposer des données personnelles — et potentiellement sensibles — dans un fichier JSON. Le champ libre, c'est exactement là que ces données atterrissent.
  3. Aucune durée de conservation. Le tableau queries grossit indéfiniment. Le RGPD impose une limitation de la conservation ; il n'y en a aucune. Et la CNIL demande explicitement que l'historique soit désactivé par défaut.

Ce qu'il faut faire à la place. L'objectif métier derrière ce journal est légitime : l'enseignant veut savoir sur quoi sa classe a bloqué. On peut le servir sans conserver une seule phrase d'élève.

  • Ne plus écrire message. Conserver timestamp, origin et contextFilesUsed — ce que le DTO déclare déjà, et qui suffit à dire quels supports ont servi.
  • Si on veut un signal plus fin, stocker une étiquette de thème dérivée à la volée (« équations du second degré », « accord du participe passé ») plutôt que le texte, ou un simple compteur par fichier de contexte.
  • Ajouter une durée de conservation explicite par contexte, avec purge automatique — 30 jours par défaut, alignés sur la durée d'une séquence pédagogique.
  • Rendre la journalisation désactivable par contexte, et désactivée par défaut sur les contextes destinés aux élèves.
  • Aligner le DTO sur ce qui est réellement écrit, et le documenter dans Swagger.

3.2 Faire des instructions un vrai champ

Ce qui se passe aujourd'hui. Le prompt système d'un contexte est intégralement construit à partir des fichiers markdown sélectionnés par le RAG. Il n'existe pas de champ « instructions » ou « persona ».

Il existe bien un mécanisme, mais c'est une convention par nom de fichier magique. Dans src/rag/rag.service.ts, ligne 21 :

private readonly REQUIRED_FILES = ['instruction-file.md'];

Un fichier qui porte exactement ce nom est épinglé : il est ajouté à la sélection même si le RAG ne l'a pas retenu, et il est trié en tête du prompt. L'intuition est la bonne — sans cet épinglage, les garde-fous pourraient disparaître du prompt selon la question posée.

Pourquoi ça ne suffit pas. Le mécanisme fonctionne, mais :

  • il repose sur un seul nom codé en dur, invisible pour qui n'a pas lu le service RAG ;
  • il n'apparaît dans aucun DTO ni dans la documentation de l'API ;
  • il est inatteignable depuis rukh-ui : la page d'édition d'un contexte gère des fichiers et des liens, pas un comportement ;
  • il mélange comportement et connaissance dans la même liste de fichiers, alors que ce sont deux choses de nature différente. La connaissance, c'est ce que l'assistant sait. Les instructions, c'est ce qu'il fait.

Concrètement, un enseignant n'a aujourd'hui aucun moyen de dire « sois socratique, ne donne jamais la réponse finale, reste sur le programme de 4e ». C'est pourtant la première chose qu'il voudra régler.

Ce qu'il faut faire à la place.

  • Ajouter un champ instructions de premier ordre dans index.json, déclaré dans CreateContextDto et ContextMetadataDto via les décorateurs NestJS, et exposé dans Swagger.
  • Toujours l'injecter en tête du prompt système, hors de la sélection RAG : il n'est jamais candidat, il est toujours présent.
  • Le séparer des fichiers de connaissance dans l'interface, avec une question en clair pour l'enseignant : « Comment cet assistant doit-il se comporter ? »
  • Conserver instruction-file.md en repli pour les contextes existants, mais le déprécier.

Avant :

{
  "name": "maths-4e",
  "description": "Aide aux devoirs en mathématiques, niveau 4e",
  "files": [
    { "name": "instruction-file.md", "description": "..." },
    { "name": "chapitre-thales.md", "description": "..." }
  ]
}

Après :

{
  "name": "maths-4e",
  "description": "Aide aux devoirs en mathématiques, niveau 4e",
  "instructions": "Tu es un tuteur socratique pour une classe de 4e. Ne donne jamais la réponse finale : pose une question qui fait avancer l'élève d'un pas. Reste sur le programme de 4e.",
  "retention": { "queries": "30d", "storeMessages": false },
  "files": [{ "name": "chapitre-thales.md", "description": "..." }]
}

4. L'agentique : côté enseignant, pas côté élève

Le recadrage que je défends : il ne faut pas rendre l'assistant élève agentique. « Il ne peut pas naviguer, il ne peut pas agir, il ne se souvient pas de toi après la séance » — c'est la phrase qui fait passer un principal et un DPO. Ce n'est pas une limitation, c'est l'argument de vente.

L'agentivité doit vivre côté enseignant, là où la valeur est haute et le risque nul : un assistant qui lit le chapitre, prépare la séance, en sort trois versions différenciées, le quiz et le corrigé.

Ce que les enseignants demanderont en premier

  1. Ingérer ce qu'ils ont vraiment. Rukh n'accepte que du markdown. Les enseignants ont des PDF, des .docx et des photos de pages de manuel. Tant qu'une photo de page ne devient pas un contexte, rien de ce qui suit n'a d'importance. Ce n'est pas de l'agentique du tout — c'est le ticket d'entrée.
  2. Rendre quelque chose d'imprimable. Le livrable d'un enseignant, c'est une fiche, un quiz, une grille — imprimés ou déposés sur l'ENT. Le texte de chat n'est pas le livrable. L'export PDF/docx est la demande numéro un du segment.
  3. Différencier : la même fiche en trois niveaux, plus une version pour un élève dyslexique. C'est la fonctionnalité la plus louée chez MagicSchool, et c'est du pur prompt.
  4. Voir sur quoi la classe a bloqué, en agrégé. Le journal queries en est le squelette — une fois qu'il ne stocke plus de texte brut (voir 3.1).
  5. Corriger sur barème. L'étude Gallup / Walton Family Foundation situe le gain à 5,9 heures par semaine pour les enseignants qui utilisent l'IA au moins une fois par semaine, soit six semaines par an — chiffres à lire avec le recul qu'ils méritent. Mais c'est aussi là que sont les données sensibles : à garder côté enseignant et en éphémère. La CNIL est nette sur ce point, un enseignant ne peut pas déléguer une décision de notation à un système.

Le point important : les points 1, 2, 3 et 5 ne demandent aucun appel d'outil. Ils demandent de l'ingestion de fichiers, un champ instructions et un moteur de rendu de documents. L'essentiel de ce qui ressemble à une « demande agentique » sur ce marché se satisfait sans boucle d'agent.

5. La notion de module : oui, mais comme déclaration de capacités

Oui à des modules dans l'API Rukh — à condition de les définir comme une déclaration de capacités portée par le contexte, et non comme un système de plugins.

Concrètement : un champ capabilities: string[] dans index.json, à côté du champ instructions, qui puise dans un petit registre de modules de première partie. Côté implémentation, chaque module est un provider NestJS ordinaire qui expose un schéma d'outil et un handler ; c'est Rukh qui exécute la boucle d'outils. Trois pour commencer :

  • web-reader — le WebReaderService existe déjà, il n'est simplement pas exposé comme outil ; à rapprocher de l'outil de recherche web côté serveur déjà câblé dans anthropic.service.ts ;
  • document — rendu markdown vers PDF/docx ;
  • quiz — un parcours d'exercices avec état.

Point crucial : les capacités doivent se résoudre par contexte et par audience. Un même contexte accorde document à son créateur et rien du tout à la classe.

Pourquoi pas MCP tout de suite

MCP est la bonne interface à long terme et la mauvaise fondation maintenant. Des serveurs distants arbitraires, plus des identifiants par utilisateur, plus des mineurs : c'est une surface de conformité indéfendable, à rebours de la préférence CNIL pour l'on premise. Et aucun enseignant ne collera jamais une URL de serveur dans un formulaire.

À sortir plus tard comme un module parmi d'autres, réservé aux enseignants, filtré par la même liste blanche de capacités — qui est précisément le garde-fou dont MCP a besoin. Même remarque pour les pistes d'agents autonomes type ERC-8004 explorées dans les notes internes : intéressant, hors sujet pour une salle de classe.

6. L'alternative que je préfère : les compétences en fichiers

À considérer à la place des modules, et plus tôt : les compétences sous forme de fichiers, dans l'esprit des Skills.

Un contexte est déjà un dossier de markdown. Un sous-dossier skills/ où chaque fichier est une procédure nommée — faire-un-quiz.md, corriger-avec-bareme.md, differencier-en-trois-niveaux.md — donne aux enseignants des comportements réutilisables, inspectables et partageables, sans aucun nouveau runtime et sans revue de code.

Les enseignants partagent déjà des séquences et des fiches. Un marché de contenu colle infiniment mieux à leurs pratiques qu'un marché de code — et c'est un effet de réseau bien moins cher à construire. Je ferais ça avant la boucle d'outils.

7. Séquencement proposé

  1. Arrêter de persister les messages bruts, et promouvoir les instructions en vrai champ (section 3).
  2. Ingestion PDF, docx et images.
  3. Le lien de classe sans compte élève ; W3PK réservé à l'enseignant.
  4. L'export de documents, comme premier vrai module.
  5. Les compétences en fichiers.
  6. Seulement ensuite : la boucle d'outils et la liste blanche de capacités. MCP bien plus tard, et côté enseignant uniquement.

8. Réserve commerciale

Vendre au collège en France est lent : GAR, marchés publics, délégations académiques au numérique, registres RGPD, AIPD. La voie rapide passe par les enseignants à titre individuel, les associations d'enseignants, l'enseignement privé et les établissements internationaux — ou par un partenariat avec un éditeur d'ENT.

Et je retirerais « Build your own AI » pour ce marché. La promesse qui vend ressemble plutôt à : l'assistant de votre classe — sans compte élève, hébergé en Europe.

Références

Cadre réglementaire français

Souveraineté et modèles européens

Plateformes génériques

Plateformes éducatives

Études d'usage

Technique

Rukh : se spécialiser pour l'école — Julien Beranger