Inspiration
FR : Au Maroc, le suivi de grossesse se fait sur un carnet papier rose. Les données y restent, difficiles à agréger, faciles à perdre. Les sages-femmes ont déjà un téléphone et WhatsApp. On a voulu un outil qui ne demande rien de plus : une photo, quelques réponses, et le dossier existe. Et comme ce sont des données de santé, rien ne doit partir vers un service d'IA externe.
EN : In Morocco, pregnancy follow-up lives in a pink paper booklet. The data stays there, hard to aggregate, easy to lose. Midwives already have a phone and WhatsApp. We wanted a tool that asks for nothing more: one photo, a few answers, and the record exists. And because this is health data, nothing should leave for an external AI service.
Ce que ça fait (What it does)
FR : PregnancyBot lit la photo d'une page du carnet, reconnaît le type de page, masque les identifiants, lit chaque cellule avec un petit modèle local, et donne à chaque champ un statut (connu, à réviser, illisible, non fourni, non applicable, inconnu) et une confiance calibrée. Il résume la page, pose ses doutes un par un avec le recadrage de la cellule, accepte les corrections, propose la saisie à la main si la lecture échoue, relie la page à une patiente par un code, et propose des correspondances possibles sans jamais créer de doublon tout seul. Tout est chiffré, mis en file si le réseau manque, et synchronisé au retour. Ça marche dans le vrai WhatsApp.
EN : PregnancyBot reads a photo of a booklet page, recognizes the page type, masks identifiers, reads each cell with a small local model, and gives each field a status (known, to review, illegible, not provided, not applicable, unknown) with a calibrated confidence. It summarizes the page, asks about its doubts one by one with a crop of the cell, accepts corrections, offers manual entry when reading fails, links the page to a patient by a code, and proposes possible matches without ever creating a duplicate on its own. Everything is encrypted, queued when the network is down, and synced when it returns. It works in real WhatsApp.
Comment on l'a construit (How we built it)
FR : Le schéma d'abord : 436 champs, 69 groupes de cases, 6 statuts, 13 règles de cohérence, un cycle de vie à 8 états. Ensuite une découverte : le spécimen est un PDF vectoriel, donc chaque valeur manuscrite y est un texte avec sa police et sa position. On en a tiré 80 pages de vérité terrain sans annotation manuelle, et les 5 polices d'écriture pour fabriquer des cellules synthétiques à volonté. Avec ça, on a entraîné un petit modèle de lecture (CRNN + CTC, 2 millions de paramètres, 8 Mo en ONNX) qui tourne sur CPU. Autour : recalage géométrique sur le gabarit, détection d'encre, normalisation par vocabulaire, règles, confiance calibrée mesurée par l'ECE. L'agent conversationnel est indépendant du transport : simulateur web, WhatsApp Cloud API de Meta, Twilio. Python, OpenCV, PyTorch pour entraîner, onnxruntime pour lire, FastAPI, SQLite chiffré.
EN : Schema first: 436 fields, 69 checkbox groups, 6 statuses, 13 consistency rules, an 8-state lifecycle. Then a discovery: the specimen is a vector PDF, so every handwritten value is a text with its font and position. We extracted 80 ground-truth pages with no manual annotation, and the 5 handwriting fonts to render unlimited synthetic cells. With that we trained a small handwriting model (CRNN + CTC, 2M parameters, 8 MB ONNX) that runs on CPU. Around it: geometric registration on the template, ink detection, vocabulary normalization, rules, calibrated confidence measured by ECE. The conversational agent is transport-independent: web simulator, Meta WhatsApp Cloud API, Twilio. Python, OpenCV, PyTorch to train, onnxruntime to read, FastAPI, encrypted SQLite.
Difficultés (Challenges)
FR : Faire tenir une bonne lecture sans aucun service externe. Apprendre au modèle à lire « rien » sur une cellule vide bruitée plutôt qu'un tiret. Un décalage de 16 pixels du recalage qui coupait les cellules des pages nouveau-né. Les polices du spécimen sans lettres accentuées. Et côté WhatsApp : les webhooks qui n'arrivent que si le compte est abonné à l'app, la fenêtre de 24 heures, les numéros que WhatsApp écrit autrement que l'annuaire.
EN : Getting good reading with no external service at all. Teaching the model to read "nothing" on a noisy empty cell instead of a dash. A 16-pixel registration shift that cut the cells of newborn pages. Specimen fonts with no accented letters. And on the WhatsApp side: webhooks that only arrive once the account is subscribed to the app, the 24-hour window, numbers WhatsApp writes differently from the phone book.
Ce dont on est fiers (Accomplishments)
FR : 98.7 % des valeurs et une calibration ECE de 0.012 sur les 80 pages, avec un modèle de 8 Mo entraîné par nous. Un agent qui ne cache jamais ses doutes et refuse de garder un champ comme sûr quand la mise en page lui est inconnue. Un hors ligne réel, pas simulé. Et de vrais téléphones qui parlent à l'agent dans WhatsApp.
EN : 98.7 % exact values and ECE 0.012 on the 80 pages, with an 8 MB model we trained ourselves. An agent that never hides its doubts and refuses to keep a field as certain when the layout is unknown. Real offline behaviour, not simulated. And real phones talking to the agent in WhatsApp.
Ce qu'on a appris (What we learned)
FR : Partir du schéma rapporte plus que n'importe quel modèle. Une vérité terrain gratuite change tout. Et la confiance d'un modèle ne vaut que si on la mesure.
EN : Starting from the schema pays more than any model. Free ground truth changes everything. And a model's confidence is only worth something if you measure it.
La suite (What's next)
FR : Un gabarit du vrai carnet au petit format et des photos annotées sur le terrain ; le contrôle qualité sur le téléphone avant l'envoi ; une interface bilingue ; un tableau de bord d'agrégats anonymisés pour l'usage épidémiologique ; l'écriture arabe.
EN : A template for the real small-format booklet and annotated field photos; quality check on the phone before sending; a bilingual interface; an anonymized aggregate dashboard for epidemiological use; Arabic handwriting.
Log in or sign up for Devpost to join the conversation.