Skip to main content
Jonathan Andrei
Retour aux billets
Mai 20269 min de lecture

Donner une mémoire à une équipe de modération

La modqueue de Reddit traite chaque modérateur comme un agent isolé qui vide une boîte de réception. Le plus dur dans la modération, ce n'est pas le volume : c'est l'isolement du cas limite, l'incohérence qui s'installe dans une équipe, et le jugement qui s'en va quand un vétéran part. Memex est la mémoire qui manquait.

Devvit WebRedditModerationReactRedis

La modqueue de Reddit traite chaque modérateur comme un agent isolé qui vide une boîte de réception. Mais le plus dur dans la modération, ce n'est pas le volume. C'est l'isolement de la décision limite (ce « est-ce que ça dépasse les bornes ? » qu'on tranche seul à 2 h du matin), l'incohérence qui s'installe au sein d'une équipe distribuée, et le savoir institutionnel qui s'en va quand un modérateur vétéran part.

L'étude CHI 2026 sur l'usage réel de la modqueue a chiffré le problème : 84 % des modérateurs quittent la file pour aller chercher du contexte, et les équipes se télescopent sans cesse en rejugeant les mêmes cas. J'ai donc construit ce qui manquait. Pas une boîte de réception plus rapide : une mémoire pour l'équipe.

La plupart des outils rendent un modérateur plus rapide à vider une file. Memex fait décider l'équipe de façon cohérente dans le temps, et empêche ce savoir de s'évaporer.

Ça s'installe comme une seule application Devvit. Rien à configurer pour démarrer : choisissez une taille de quorum si vous voulez, et Memex commence à enregistrer chaque décision d'équipe dans une mémoire partagée dès le premier appel. Aucun service externe, aucun compte, aucun coût.

Decision DNA : comment a-t-on tranché là-dessus avant ?

Sur n'importe quel billet ou commentaire, Memex montre comment l'équipe a historiquement tranché sur du contenu similaire : le verdict dominant, un score de cohérence et les décisions passées les plus proches avec les raisons invoquées. Trois façons d'y accéder : directement depuis le menu de modération sur n'importe quel élément, en direct dans une salle Conclave, ou en collant une phrase dans l'outil « tester une phrase » du Rulebook.

La Decision DNA ouverte depuis le menu de modération sur un billet Reddit, montrant un verdict RETIRER dominant
La Decision DNA directement depuis le menu de modération sur un billet : verdict dominant, cohérence, et les décisions similaires au dossier.

Le détail astucieux, c'est qu'une faible cohérence est elle-même un signal. Un partage 50/50 n'est pas du bruit : c'est le système qui vous dit que le cas est réellement limite et mérite une décision d'équipe plutôt qu'un appel solitaire. Tout le moteur est local : similarité par trigrammes et Jaccard sur tokens, traitée par lots contre un Redis isolé par subreddit via mGet. Ça fonctionne sur tous les types de billets, y compris les liens, où le domaine est intégré pour reconnaître les domaines de spam et d'affiliation récurrents. Aucune API externe, aucune clé, aucun coût par commentaire, aucun entraînement de modèle sur les données Reddit. Ça tourne dès l'installation, sur un sub de 200 membres comme sur un sub de plusieurs millions, dans n'importe quelle langue.

Conclave : les cas limites deviennent des votes d'équipe

Les cas limites deviennent des salles de décision asynchrones réservées aux modérateurs. Les modérateurs votent Retirer, Garder, Avertir ou Escalader ; au quorum, l'action de consensus s'exécute automatiquement pour les actions réversibles. Les votes, la jauge de quorum et un indicateur de présence « qui révise » se mettent à jour en direct pour tout le monde dans la salle. Comme c'est asynchrone, un billet limite obtient une décision d'équipe équitable sans que tout le monde soit en ligne en même temps, ce qui est exactement la réalité d'une équipe de 5 modérateurs répartis sur plusieurs fuseaux horaires.

Une salle de décision Conclave de Memex montrant un billet de spam crypto acheminé pour un vote d'équipe
Une salle Conclave : un billet de spam crypto acheminé sur le mot-clé « crypto », avec la Decision DNA et le vote Retirer / Garder / Avertir / Escalader.

Le Living Rulebook : une mémoire que l'on peut fouiller

Chaque décision résolue devient un précédent. Le Living Rulebook est un billet qui montre les règles appliquées de l'équipe, pas seulement celles qui sont écrites : statistiques d'impact, barre de verdicts proportionnelle, vue d'activité sur 14 jours, conclaves ouverts et précédents récents. La boîte « tester une phrase » permet de coller n'importe quel contenu pour voir instantanément la Decision DNA de l'équipe avant d'agir.

Le Living Rulebook de Memex avec statistiques d'impact, vue d'activité 14 jours, barres de verdicts et l'outil tester-une-phrase
Le Living Rulebook : 21 décisions, une vue d'activité sur 14 jours, des barres par verdict, et l'outil « tester une phrase » avec de vrais exemples.

La Calibration et le Sweep

  • Calibration : les nouveaux modérateurs émettent des votes fantômes qui ne comptent pas dans le quorum ; un résumé hebdomadaire montre précisément où ils ont divergé du consensus, pour apprendre les standards de l'équipe en semaines plutôt qu'en mois.
  • Consistency Sweep : à la demande ou planifié, Memex audite les billets récents encore en ligne et signale ceux similaires à du contenu déjà retiré, en s'appuyant sur les décisions passées de l'équipe. Les éléments signalés sont rapportés dans la modqueue, jamais retirés automatiquement.
  • Il apprend aussi de chaque action de modération native : chaque retrait ou approbation manuel devient un précédent, donc la mémoire s'enrichit même quand l'équipe n'ouvre jamais de Conclave.
Un résumé de calibration hebdomadaire en modmail montrant où un nouveau modérateur a divergé du consensus
Le résumé de calibration hebdomadaire en modmail : l'accord avec le consensus, et précisément là où le nouveau modérateur a divergé.

La sécurité est un réglage, pas un espoir

Les bannissements ne s'exécutent jamais seuls. Ils apparaissent comme une recommandation exigeant un clic humain, conformément à la politique admin 2026 de Reddit sur les bots de bannissement. La taille du quorum, la fenêtre de vote et les règles d'acheminement automatique sont toutes des réglages explicites, avec « les escalades ne bannissent jamais automatiquement » activé par défaut. Un outil qui pose des actions de modération sur une communauté doit rendre ses garde-fous visibles et configurables, pas les enterrer dans le code.

Réglages de Memex : acheminement automatique, escalades-jamais-de-ban-auto, balayage planifié et la bascule optionnelle de correspondance sémantique
Réglages : acheminement automatique, escalades-jamais-de-ban-auto (activé), balayage planifié, et la bascule optionnelle de correspondance sémantique (désactivée par défaut).

Le plus dur : tout reconstruire, à quelques jours de l'échéance

J'ai fait tout le hackathon sur Devvit Blocks. Chaque fonctionnalité, chaque test, tout le frontend. Puis, tard dans le projet, une membre de la communauté (fsv, big.wheel sur le Discord Devvit) me l'a signalé directement : le moteur de custom-posts Blocks est en voie de retrait. Custom posts désactivés le 30 juin 2026, et plus aucune nouvelle app custom-post Blocks approuvée. Ce sur quoi j'avais passé tout le hackathon allait cesser de fonctionner, et comme nouvelle app je n'avais aucune approbation acquise sur laquelle me rabattre.

Crédit mérité : fsv (une bénévole de la communauté Devvit) a repéré ça et m'a orienté vers les annonces officielles. À lire si vous développez sur Devvit :

Alors, à quelques jours de l'échéance, j'ai décidé de reconstruire tout le frontend sur Devvit Web et de re-plateformer le serveur, en portant l'intégralité du moteur de décision intact. C'est la période la plus stressante du projet, mais je préfère soumettre quelque chose qui tourne encore après le 30 juin que quelque chose de soigné qui ne tourne plus. J'ai gardé la version Blocks d'origine sur une branche séparée pour référence.

La réécriture forcée a rendu Memex meilleur. Le vrai runtime serveur de Devvit Web est ce qui a débloqué la couche sémantique optionnelle (les appels d'embeddings vivent côté serveur) ; le template TypeScript plus strict a attrapé des bugs latents pendant le portage ; et la webview a donné au Living Rulebook une interface bien plus riche que ce que Blocks pouvait rendre. L'urgence de l'échéance est devenue la plus grande amélioration du projet.

La stack maintenant : une webview React 19 + Tailwind sur un serveur Hono, avec l'état dans un Redis isolé par subreddit. Un seul type de custom-post rend une carte d'aperçu en ligne dans le fil et une webview étendue ; le serveur classe chaque billet (Conclave ou Living Rulebook) et renvoie le bon instantané. Le moteur Decision DNA reste local par défaut, traité par lots contre Redis via mGet.

Historique, pour les curieux seulement : ces vidéos montrent la version Devvit Blocks d'avant la migration (l'interface dépréciée, pas l'app actuelle). La démo actuelle est en haut de ce billet.

Les pièges de Devvit Web

  • Inversion du modèle d'accès aux données : Blocks passait context.redis / context.reddit dans chaque fonction ; Devvit Web expose redis / reddit / context au niveau module depuis @devvit/web/server. Chaque appel de persistance et d'API Reddit a dû être refait.
  • reddit.getCurrentSubredditName() n'existe pas sur Web (seulement dans un exemple de doc). Le subreddit courant vient de context.subredditName / context.subredditId. Trouvé en lisant les définitions de types livrées, pas la doc en prose.
  • Thing-IDs typés : getPostById / getCommentById exigent désormais des types template-literal t3_ / t1_, donc les IDs stockés en chaîne ont eu besoin des helpers T3() / T1().
  • Aller-retour des données de formulaire : une action de menu et la soumission de son formulaire sont des requêtes distinctes, alors je gare l'entrée à moitié construite dans Redis indexée par le modérateur et la récupère à la soumission.
  • TypeScript plus strict : le template Web active noUncheckedIndexedAccess et exactOptionalPropertyTypes, ce qui a attrapé plusieurs bugs latents d'index/optionnels pendant le portage.

J'ai validé le devvit.json final contre le parseur de config livré par Devvit, et obtenu le type-check, ESLint, le build Vite et les 50 tests au vert.

La couche sémantique optionnelle

Le nouveau runtime serveur m'a permis d'ajouter une couche sémantique optionnelle : collez une clé d'API d'embeddings et Memex détecte automatiquement le fournisseur d'après sa forme (OpenAI ou Google Gemini), mêle le cosinus d'embedding au score local, et met les vecteurs en cache dans Redis. Désactivée par défaut, elle n'appelle jamais l'extérieur sans clé reconnue, donc l'app reste sans erreur dès l'installation. C'est la règle de conception que j'ai gardée partout : chaque dépendance externe doit se dégrader proprement jusqu'à rien.

Pourquoi c'est vraiment différent

L'espace « espace de travail de modération partagé » est encombré. La couche de mémoire institutionnelle, non. Aucune autre application Devvit ne fait remonter comment votre équipe a tranché sur du contenu similaire au moment de décider, ne note la cohérence des décisions, ni ne calibre les nouveaux modérateurs sur le schéma réel de l'équipe. Le vote et les mises à jour en direct sont le mécanisme de livraison ; la mémoire est le fossé défensif. Plus les touches discrètes : des mod-notes Reddit natives sur chaque décision d'équipe, et l'apprentissage de chaque action manuelle pour que la mémoire grandisse d'elle-même.

Ce que j'ai appris

Le goulot d'étranglement de la modération, ce n'est pas la vitesse de lecture ; c'est la légitimité des décisions et la cohérence de l'équipe. Reformuler de « rendre un modérateur plus rapide » à « donner une mémoire à l'équipe » a produit un outil que les modérateurs veulent vraiment. Et bâtir sur une plateforme en pleine transition m'a appris à faire confiance aux définitions de types livrées plutôt qu'à la doc en prose, et à concevoir chaque dépendance externe pour que l'app se dégrade proprement sans elle.

Essayez Memex sur votre subreddit

Memex est en ligne et gratuit à installer. Il fonctionne dès qu'on l'ajoute, sans rien à configurer pour démarrer.

Projet associé

Memex: Institutional Memory for Reddit Mod Teams

Voir le projet