Projet personnel · depuis 2024

Edukai, application iOS de révision pour les lycéens

Application iOS pour les lycéens : on importe un cours, l'application en extrait les concepts et interroge dessus. Un moteur pédagogique entretient une estimation statistique de la maîtrise de chaque concept et de la difficulté de chaque question, et commande la question suivante pour viser un taux de réussite cible.

  • Expo
  • React Native
  • NestJS
  • BullMQ
  • Redis
  • PostgreSQL
  • pgvector
  • Drizzle
  • TypeScript
  • OpenAI

Vidéo

Edukai en 32 secondes

Film de présentation sans voix off : il s'ouvre sur une pile de cours en pagaille, en tire un cours de biologie qu'il passe au crible, nomme ses concepts clés un à un, et montre l'application en faire des questions à choix multiple.

  • Accueil d'Edukai sur iPhone : la séance du jour annonce 25 concepts à revoir, au-dessus de la liste des cours importés.
  • Fiche d'un cours d'histoire sur la Première Guerre mondiale : 10 questions, 7 concepts, 3 acquis, et une prévision indiquant qu'au rythme actuel le modèle ne se rapproche pas du seuil d'acquisition.
  • Fiche du concept « La bataille de Verdun » : maîtrise acquise, histogramme de l'évolution de fragile à acquis, et les dernières réponses avec leur temps de réponse.
  • Question de géographie en cours de séance, première sur six : la bonne réponse est validée en vert et accompagnée d'une explication.

D'où vient le projet

Edukai part d'une idée à moi, que j'ai proposée en projet de fin d'études à Epitech, sur le parcours entrepreneuriat, l'un des trois proposés. Nous étions trois à la porter. Le projet a démarré en 2024, s'est achevé en février 2026, et je développe l'application sur mon temps libre depuis.

Le problème tient en une phrase que tout le monde a vécue : on apprend un cours par cœur pour un contrôle, et trois mois plus tard il n'en reste rien. C'est coûteux en temps et en énergie, et inefficace sur la durée. Un lycéen a ses cours, pas le temps de fabriquer ses propres questions, et aucune idée de ce qu'il maîtrise réellement. L'application prend le cours en entrée et rend les deux choses qui manquent, des questions et une mesure.

Le nom mélange l'éducation et l'intelligence artificielle. La mascotte est un manchot, symbole de travail collectif.

La première version, sur le web

La v1 était un site. On y déposait un cours ou des notes de cours, l'application les analysait, et il en sortait séparément un résumé et une liste de vingt questions d'entraînement. Les statistiques se limitaient à un pourcentage de bonnes réponses, avec un historique pour suivre la progression.

Une grande part de l'effort est passée dans le design et l'expérience : la maquette a été refaite plus de trois fois avant de nous satisfaire. Le but n'était pas de livrer un outil de plus, que personne ne comprendrait ni n'aurait envie d'ouvrir deux fois.

Côté école, toutes les notes du projet se sont jouées sur cette version, et c'est elle qui a validé l'année et le module.

Reprendre le projet seul

En mars 2026, mes deux coéquipiers sont partis, l'un en CDI, l'autre à son compte. J'ai repris le projet seul, et j'ai commencé par l'ouvrir en grand : ce qui tenait, ce qui ne tenait pas, et pourquoi. Nommer les faiblesses de sa propre solution est la partie la moins agréable de l'exercice, et c'est celle qui a décidé de la suite.

Deux conclusions en sont sorties. La première n'est pas technique : le web fermait le marché. Un lycéen révise dans le bus et entre deux cours, sur son téléphone, pas devant un navigateur. La v2 serait donc une application mobile, et ce choix a entraîné tout le reste.

La seconde portait sur le moteur. Mesurer la maîtrise par un pourcentage de bonnes réponses, et servir les questions dans l'ordre où elles sortaient, ne valait pas mieux qu'une fiche de révision. Il fallait un cœur plus précis et mieux ordonné, construit sur des notions établies plutôt que sur des règles inventées au fil de l'eau : la courbe de l'oubli et la difficulté adaptative.

Ce que fait l'application

Le parcours tient en cinq étapes. On importe un cours, l'application en extrait les concepts qu'il contient, puis une question est fabriquée, l'élève répond, et l'estimation de sa maîtrise est révisée.

L'extraction est une lecture libre du cours : rien n'est pioché dans une liste imposée. Chaque concept proposé est ensuite confronté à tous ceux que l'application connaît déjà, et selon qu'il leur ressemble assez ou non, il les rejoint ou il est créé et rattaché au référentiel de sa matière.

Dès l'import terminé, un travail de fond fabrique trois questions à choix multiple par concept. Faute d'élève à qui les ajuster, elles visent une difficulté neutre : le réglage fin ne commence qu'une fois que quelqu'un répond.

Les trois dernières étapes tournent ensuite en boucle, et c'est tout l'intérêt : chaque réponse change ce que l'application sait de l'élève, donc elle change aussi la question suivante.

Enchaînement vertical de cinq étapes. Les deux premières n’ont lieu qu’une fois par cours : un cours importé, puis ses concepts extraits. Les trois suivantes forment une boucle : une question est fabriquée, l’élève répond, l’estimation de sa maîtrise est révisée. Une flèche de retour remonte de cette révision vers la fabrication de la question, et le tour reprend à chaque réponse.

Le cours ne passe qu’une fois par l’extraction. Les trois dernières étapes, elles, tournent en boucle.

Ce que j'ai construit

Une application mobile native en Expo et React Native, adossée à une API NestJS. L'import d'un cours ne bloque pas l'écran : l'extraction part dans un worker asynchrone sur des files BullMQ, et l'application suit l'avancement pendant que le travail se fait.

L'extraction produit des concepts et des questions. Les concepts sont dédupliqués sémantiquement, leurs embeddings stockés en pgvector : au-delà d'un seuil de similarité, un concept fraîchement extrait est fusionné dans un concept existant plutôt que recréé, pour qu'un même point de cours présenté deux fois ne devienne pas deux concepts distincts.

Toute la génération reste cantonnée dans un seul paquet : une règle ESLint bloquante interdit d'importer le client OpenAI ailleurs, de sorte que la frontière d'architecture tienne sans dépendre de la discipline du moment.

Une fourchette plutôt qu'un score

Un seuil unique, du type « acquis au-dessus de 50 % de bonnes réponses », serait commode et faux : il met derrière le même chiffre l'élève qui a compris et celui qui a simplement eu de la chance sur trois questions. La maîtrise n'est jamais binaire, et la mesurer par un point revient à jeter ce qu'on ne sait pas encore.

Le moteur ne range donc pas l'élève derrière un pourcentage. Pour chaque concept il tient une fourchette, l'écart entre le niveau le plus bas et le niveau le plus haut qu'il juge encore plausibles, et c'est la largeur de cette fourchette qui dit à quel point il est sûr de lui. Large ne veut pas dire faible : large veut dire qu'il n'a pas encore de quoi trancher.

Chaque réponse resserre la fourchette, et le temps la rouvre : la confiance se dégrade à taux fixe par jour d'absence. Ce que l'élève gagne en répondant, il le reperd en ne revenant pas, et c'est cet équilibre que le moteur entretient. La confiance n'est donc pas une donnée entretenue à côté du score, elle est la fourchette elle-même. Sous le capot, la maîtrise de l'élève et la difficulté de chaque question sont deux gaussiennes sur une même échelle de logit, mises à jour par un filtre de type Kalman, et la variance est la confiance.

Les points d'expérience suivent la même règle : le moteur retient le plus haut niveau prouvé sur un concept et ne paie que le terrain gagné au-dessus. Reposer une question déjà facile ne rapporte donc rien, non pas parce que l'estimation ne bouge pas, mais parce qu'elle ne dépasse pas ce qui a déjà été payé. Ce repère s'érode avec l'oubli, de sorte que réapprendre un concept perdu de vue se paie à nouveau.

« Acquis » se lit donc sur la fourchette et jamais sur une moyenne : il faut à la fois que la borne basse passe le seuil, autrement dit que même en étant pessimiste l'élève réussisse assez souvent, et que la fourchette soit assez étroite. Une estimation haute mais incertaine et une estimation sûre mais moyenne échouent toutes les deux, pour des raisons opposées. Entre l'ignorance et l'acquisition, le concept passe par quatre états plutôt que par un interrupteur.

Trois états du même concept, lus sur une même échelle horizontale graduée fragile, en cours, solide, acquis. Au début, la courbe est large et plate et la fourchette couvre presque toute l’échelle, de fragile jusqu’au-delà de solide : le modèle n’a pas encore de quoi trancher. Après plusieurs réponses, la même courbe est resserrée et pointue, et la fourchette ne couvre plus qu’une bande étroite entre en cours et solide. Après une absence, la courbe s’est rouverte : la fourchette est de nouveau plus large que dans l’état précédent, sans revenir jusqu’à sa largeur de départ. Le centre de l’estimation est laissé identique dans les trois états, pour isoler ce qui change : la largeur.

La largeur de la fourchette est la confiance du modèle. Chaque réponse la resserre, et le temps la rouvre.

Comment la question suivante est choisie

Un moteur qui cherche à faire réussir l'élève lui sert des questions faciles, et une séance où tout passe n'apprend rien. Edukai prend le problème dans l'autre sens : il se fixe d'abord le taux de réussite qu'il veut obtenir, autour de 75 %, et c'est de cette cible qu'il déduit la difficulté de la question à servir. La difficulté n'est pas choisie puis subie, elle est calculée pour que l'issue reste incertaine.

Une zone de 60 à 85 % de réussite prévue est définie comme la bande productive, mais elle ne filtre rien pour l'instant : c'est un garde-fou écrit et testé, pas encore branché sur la décision. Le relèvement de la cible de 75 à 90 % après trois échecs d'affilée, délibérément au-dessus de cette bande pour remettre l'élève en selle, est écrit lui aussi et attend le même branchement.

Cette décision ne consiste pas à trier dans un stock figé. À chaque réponse, juste et fausse pareillement, le moteur repart de la fourchette qu'il vient de réviser, en déduit le concept à travailler et la difficulté à viser, et c'est à cette commande que la question suivante est fabriquée, dans un travail de fond pour que personne n'attende devant l'écran. Quand cette fabrication échoue, le repli prend parmi les questions déjà calibrées celle dont la difficulté est la plus proche de la cible.

Le format, lui, n'est jamais un levier de difficulté : choix multiple, vrai ou faux, texte à trous, réponses multiples, remise en ordre ou classement par catégories tournent pour la variété, et s'infléchissent seulement vers les formats les plus légers quand l'élève est en difficulté. Faire porter la difficulté au format reviendrait à la régler deux fois, dans deux endroits qui finiraient par se contredire.

L'espacement des révisions ne sort pas d'une table d'intervalles mais de cette même fourchette : elle se rouvre à taux fixe par jour d'absence, et la date de révision est le moment où elle sera retombée à l'ignorance de départ. L'intervalle est donc une inversion de ce taux d'oubli, borné entre un et six jours, les deux horizons que SM-2 donne pour la consolidation et le premier espacement réel.

Une courbe décroissante relie la difficulté de la question servie, en abscisse de plus facile à plus difficile, à la chance de la réussir, en ordonnée de 100 % à 0 %. Une ligne horizontale marque la cible : environ 75 % de réussite. Le point où cette ligne coupe la courbe est redescendu en pointillés sur l’abscisse, et c’est lui qui donne la difficulté à servir. La lecture va donc de la cible de réussite vers la difficulté, et non de la difficulté vers la réussite. À gauche de ce point, les questions presque toujours réussies n’apprennent rien ; à droite, les questions trop dures font décrocher.

La cible de réussite est posée d’abord, et la difficulté de la question s’en déduit. Jamais l’inverse.

Où en est le projet

La séance du jour pioche aujourd'hui dans tous les cours suivis plutôt que dans un seul. Elle écarte les concepts déjà acquis, classe les autres du plus faible et du plus incertain au mieux tenu, et garde un plancher par cours pour qu'un petit cours ne soit jamais enterré par un gros.

La suite serait de réviser en fonction d'une échéance, un contrôle, le bac, le brevet. Elle n'y est pas : aucune date d'examen n'est conservée côté serveur et rien dans la sélection n'en lit une. L'application sait compter les jours jusqu'à l'examen et le rappeler, mais ce compte à rebours ne change pas une seule question.

Le projet est toujours en développement, avec un premier cerveau qui tourne. Je ne sais pas jusqu'où il ira. Je veux le pousser parce qu'il me tient à cœur, et parce qu'il me rend meilleur techniquement.

Vous recrutez un développeur full-stack ?

Je recherche mon premier CDI après deux ans d’activité indépendante menés en parallèle de mes études. Pour échanger sur le poste et votre équipe, vous pouvez m’écrire ou me contacter sur LinkedIn.

Télécharger mon CV (PDF)Profil LinkedIn