Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Lire une page : texte et champs

Après cette leçon: Je peux transformer une page de zones de texte en lignes dans l’ordre de lecture et en tirer les champs avec leur confiance.

Leçon de 70 min7 commandesLab agent de code IA : utiliser opencode pour expliquer et corriger du code, et vérifier son travail

Une facture photographiée n’est pas du texte

Une boutique photographie une facture papier et veut le total dans sa base de données. La photo n’est que des pixels. Un programme de lecture doit d’abord trouver les mots.

Il rend chaque morceau de texte avec sa place sur la page. Votre code les remet ensuite dans l’ordre et en tire les champs.

À la fin de cette leçon

Remarque

Je peux transformer une page de zones de texte en lignes dans l’ordre de lecture et en tirer les champs avec leur confiance.

Mots clés

MotCe que ça veut direExemple
Zoneun morceau de texte et sa place sur la page
Ordre de lecturel’ordre dans lequel une personne lirait les zones
Champune étiquette et la valeur à côtéTotal : 46,50
Confiancele degré de certitude du lecteur, de 0 à 100
Tolérancel’écart permis entre deux zones d’une même ligne

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Une page est une liste de zones

Un lecteur de pages ne vous rend pas un seul bloc de texte. Il vous rend une liste de zones. Chaque zone porte un texte, sa place (x vers la droite, y vers le bas) et une confiance de 0 à 100.

La liste n’est dans aucun ordre utile. Deux zones qui semblent former une ligne peuvent être à quelques pixels d’écart.

Quatre zones d’une page

TextexyConfiance
Total :4020098
46,5012020161
Nom :406097
Amina1206295

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

L’ordre de lecture demande une tolérance

Pour lire une page, vous triez les zones de haut en bas. Vous les groupez ensuite en lignes. Puis vous triez chaque ligne de gauche à droite.

Les zones d’une ligne sont rarement au même y exact. Une zone rejoint donc une ligne quand son y est à moins d’une tolérance de la première zone de la ligne. Ici, la tolérance est de 5 pixels.

Une erreur courante

Attention

Beaucoup trient les zones par y seul et les lisent dans cet ordre. Une valeur un peu plus haute que son étiquette passe alors avant elle. Groupez d’abord les zones en lignes avec une tolérance, puis triez chaque ligne par x.

Un champ est une étiquette et sa valeur

Dans un formulaire, une étiquette comme Total : est suivie de sa valeur sur la même ligne. Pour tirer un champ, cherchez une zone qui finit par deux-points et prenez la zone suivante de la ligne.

Gardez la confiance avec la valeur. Un chiffre faible veut dire qu’une personne doit vérifier : un chiffre mal lu ressemble exactement à un chiffre juste.

Écrire l’assistant du modèle, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// Les jetons d’une réponse, ou null si elle n’en donne pas.' 'function compter(donnees, nom) {' '  return donnees.usage && typeof donnees.usage[nom] === \"number\" ? donnees.usage[nom] : null;' '}' > model.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire l’assistant du modèle, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function demander(messages, echantillon, max) {' '  try {' '    const res = await fetch(base + \"/v1/chat/completions\", {' '      method: \"POST\",' '      headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' '      body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' '      signal: AbortSignal.timeout(30000),' '    });' '    if (res.ok === false) throw new Error(\"statut \" + res.status);' '    const d = await res.json();' '    return { texte: d.choices[0].message.content, entree: compter(d, \"prompt_tokens\"), sortie: compter(d, \"completion_tokens\"), enregistre: false };' '  } catch (erreur) {' '    console.log(\"Échantillon enregistré : aucun modèle n’a répondu (\" + erreur.message + \").\");' '    return { texte: echantillon, entree: null, sortie: null, enregistre: true };' '  }' '}' 'module.exports = { demander };' >> model.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire le script de la page, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'const boites = [' '  { texte: \"46,50\", x: 120, y: 201, conf: 61 },' '  { texte: \"Total :\", x: 40, y: 200, conf: 98 },' '  { texte: \"Facture\", x: 40, y: 10, conf: 99 },' '  { texte: \"Amina\", x: 120, y: 62, conf: 95 },' '  { texte: \"Nom :\", x: 40, y: 60, conf: 97 },' '  { texte: \"12/03/2026\", x: 120, y: 99, conf: 88 },' '  { texte: \"Date :\", x: 40, y: 100, conf: 98 },' '];' > page3.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire le script de la page, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function lignes(liste, tol) {' '  const triees = liste.slice().sort(function (a, b) { return a.y - b.y || a.x - b.x; });' '  const sortie = [];' '  for (const b of triees) {' '    const derniere = sortie[sortie.length - 1];' '    if (derniere && Math.abs(b.y - derniere[0].y) <= tol) derniere.push(b);' '    else sortie.push([b]);' '  }' '  return sortie.map(function (l) { return l.sort(function (a, b) { return a.x - b.x; }); });' '}' >> page3.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire le script de la page, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function champs(ls) {' '  const trouves = {};' '  for (const l of ls) {' '    for (let i = 0; i < l.length - 1; i++) {' '      if (l[i].texte.endsWith(\":\")) trouves[l[i].texte.slice(0, -1).trim().toLowerCase()] = { valeur: l[i + 1].texte, conf: l[i + 1].conf };' '    }' '  }' '  return trouves;' '}' >> page3.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire le script de la page, partie 4

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const ls = lignes(boites, 5);' '  for (const l of ls) console.log(l.map(function (b) { return b.texte; }).join(\" \"));' '  const c = champs(ls);' '  console.log(JSON.stringify(c));' '  const faibles = Object.keys(c).filter(function (k) { return c[k].conf < 90; });' '  console.log(\"à vérifier à la main : \" + faibles.join(\", \"));' '  const q = \"Écrivez une question courte qui demande à une personne de confirmer un total lu avec une faible confiance.\";' '  const reponse = await demander([{ role: \"user\", content: q }], \"Merci de comparer ce total avec la page papier : est-ce bien 46,50 ?\", 40);' '  console.log(\"réponse : \" + reponse.texte);' '}' 'main();' >> page3.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Lire la page et tirer les champs

Commande
docker exec -w /home/node/project agent node page3.js

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Les lignes affichées

LigneCe qu’elle montre
Nom : AminaDeux zones jointes en une ligne, l’étiquette d’abord
Date : 12/03/2026y 99 et y 100 sont dans la tolérance de 5
{"nom":{...},"date":{...},"total":{...}}Chaque champ avec sa valeur et sa confiance
à vérifier à la main : date, totalLes deux valeurs sous 90

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

À propos de ce labo et de sa source: Lab agent de code IA : utiliser opencode pour expliquer et corriger du code, et vérifier son travail

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.