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

Expliquer une réponse du texte vers SQL

Après cette leçon: Je peux écrire une réponse qui montre la requête, avoue un doute et pose une question quand la demande est floue.

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

Ce que montre une réponse texte vers SQL

Expliquer une réponse du texte vers SQL, c’est montrer à l’utilisateur la requête et ses lignes, pas seulement une phrase. Une phrase seule paraît sûre, même quand la requête était fausse.

Le module 84 conçoit des fonctions d’IA pour des personnes. Cette leçon écrit la réponse d’une fonction texte vers SQL : ce qu’elle montre, quand elle avoue un doute et quand elle demande d’abord.

À la fin de cette leçon

Remarque

Je peux écrire une réponse qui montre la requête, avoue un doute et pose une question quand la demande est floue.

Mots clés

MotCe que ça veut direExemple
Réponsece que voit l’utilisateur après sa question
Lectureune façon de changer une question en requête
Mot flouun mot qui a ici plus d’un senspopulaire
Question de précisionune question en retour qui évite une supposition
Résultat videune requête qui ne renvoie aucune ligne

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

Montrer la requête et les lignes

Placez la requête et ses lignes à côté de la phrase. Un utilisateur qui connaît les données repère tout de suite une mauvaise jointure.

Gardez les lignes courtes : montrez les premières et dites combien il en reste. La phrase vient des lignes, jamais de la mémoire du modèle.

Exemple détaillé : deux réponses à une question

RéponseCe que l’utilisateur peut vérifier
Cinq livres sont dehors.Rien
Réponse : 5. Requête : SELECT COUNT(*) FROM prets WHERE rendu = 0Le filtre, la table et le nombre

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

Dire quand on n’est pas sûr

« Qui a emprunté le plus de livres ? » a deux lectures. Le plus de prêts donne Amina, l’égalité étant départagée par le nom. Le plus de livres différents donne Bruno.

Lancez les deux lectures. Si elles concordent, répondez. Si elles divergent, dites que vous n’êtes pas sûr et montrez les deux. Un résultat vide est aussi une réponse : dites qu’aucune ligne ne correspond.

Demander avant de deviner un mot flou

Des mots comme populaire, récent, meilleur ou actif n’ont pas de sens unique dans les données. Populaire peut vouloir dire emprunté deux fois, ou emprunté ce mois-ci.

Quand une question en contient un, posez d’abord une courte question de précision. Une question en retour coûte moins qu’une réponse fausse et assurée.

Une erreur courante

Attention

Beaucoup pensent qu’une phrase assurée est la réponse la plus utile. Une réponse fausse et assurée est pire qu’une question en retour. Répondez fermement seulement si les lectures concordent et qu’aucun mot n’est flou.

É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;' '}' '// Une réponse peut entourer la requête d’un bloc délimité : on garde l’intérieur.' 'function sqlDe(texte) {' '  const morceaux = texte.split(String.fromCharCode(96).repeat(3));' '  const dedans = (morceaux.length > 2 ? morceaux[1] : texte).trim();' '  return dedans.toLowerCase().startsWith(\"sql\") ? dedans.slice(3).trim() : dedans;' '}' > 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, sqlDe };' >> 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 la base de la médiathèque, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { DatabaseSync } = require(\"node:sqlite\");' '// Une médiathèque inventée : six livres, quatre membres, neuf prêts.' 'const LIVRES = [[1, \"Le Phare des oranges\", 2019], [2, \"Port de verre\", 2021], [3, \"Carte de la pluie\", 2015],' '  [4, \"Moteurs tranquilles\", 2023], [5, \"Sept Bouilloires\", 2018], [6, \"Au nord de midi\", 2022]];' 'const MEMBRES = [[1, \"Amina\"], [2, \"Bruno\"], [3, \"Chloé\"], [4, \"Driss\"]];' '// id, livre_id, membre_id, mois, rendu (1 rendu, 0 encore dehors)' 'const PRETS = [[1, 1, 1, 3, 1], [2, 2, 1, 3, 1], [3, 3, 2, 3, 0], [4, 1, 3, 3, 1], [5, 1, 1, 4, 0],' '  [6, 4, 2, 4, 0], [7, 2, 3, 4, 1], [8, 5, 2, 5, 0], [9, 2, 4, 5, 0]];' > mediatheque.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 la base de la médiathèque, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function remplir(db, table, lignes) {' '  const marques = lignes[0].map(function () { return \"?\"; }).join(\", \");' '  const inserer = db.prepare(\"INSERT INTO \" + table + \" VALUES (\" + marques + \")\");' '  lignes.forEach(function (ligne) { inserer.run(...ligne); });' '}' 'function ouvrir(fichier) {' '  const db = new DatabaseSync(fichier || \":memory:\");' '  db.exec(\"CREATE TABLE livres (id INTEGER PRIMARY KEY, titre TEXT, annee INTEGER)\");' '  db.exec(\"CREATE TABLE membres (id INTEGER PRIMARY KEY, nom TEXT)\");' '  db.exec(\"CREATE TABLE prets (id INTEGER PRIMARY KEY, livre_id INTEGER REFERENCES livres(id), \"' '    + \"membre_id INTEGER REFERENCES membres(id), mois INTEGER, rendu INTEGER)\");' '  remplir(db, \"livres\", LIVRES);' '  remplir(db, \"membres\", MEMBRES);' '  remplir(db, \"prets\", PRETS);' '  return db;' '}' 'module.exports = { ouvrir };' >> mediatheque.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 réponse, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' 'const { ouvrir } = require(\"./mediatheque\");' 'const db = ouvrir();' 'const FLOUS = [\"populaire\", \"récent\", \"meilleur\", \"actif\"];' 'const M = \"SELECT m.nom, COUNT(\";' 'const J = \") AS n FROM prets p JOIN membres m ON m.id = p.membre_id GROUP BY m.nom ORDER BY n DESC, m.nom LIMIT 1\";' > expliquer.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 réponse, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const demandes = [' '  { q: \"Combien de livres sont encore dehors ?\", a: \"SELECT COUNT(*) FROM prets WHERE rendu = 0\" },' '  { q: \"Quels titres le membre 2 a-t-il empruntés ?\",' '    a: \"SELECT l.titre FROM prets p JOIN livres l ON p.livre_id = l.id WHERE p.membre_id = 2\" },' '  { q: \"Quels livres sont populaires ?\", a: \"SELECT livre_id FROM prets GROUP BY livre_id HAVING COUNT(*) > 1\" },' '  { q: \"Qui a emprunté le plus de livres ?\", a: M + \"*\" + J, b: M + \"DISTINCT p.livre_id\" + J },' '  { q: \"Quels livres ont été empruntés au mois 9 ?\",' '    a: \"SELECT l.titre FROM prets p JOIN livres l ON p.livre_id = l.id WHERE p.mois = 9\" },' '];' >> expliquer.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 réponse, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function lignes(sql) {' '  return db.prepare(sql).all().map(function (r) { return Object.values(r).join(\" \"); });' '}' 'function repondre(x) {' '  const flous = FLOUS.filter(function (w) { return x.q.toLowerCase().indexOf(w) >= 0; });' '  if (flous.length) return \"Avant de répondre : que voulez-vous dire par \" + flous[0] + \" ?\";' '  const a = lignes(x.a);' '  const b = x.b ? lignes(x.b) : a;' '  if (a.join(\"|\") === b.join(\"|\")) {' '    if (a.length === 0) return \"Aucune ligne ne correspond. Requête : \" + x.a;' '    return \"Réponse : \" + a.join(\" ; \") + \". Requête : \" + x.a;' '  }' '  return \"Je ne suis pas sûr. Deux lectures divergent : \" + a.join(\" ; \") + \" ou \" + b.join(\" ; \");' '}' >> expliquer.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 réponse, partie 4

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  demandes.forEach(function (x, i) { console.log((i + 1) + \" \" + x.q + \"\n  \" + repondre(x)); });' '  const faits = demandes[0].q + \" Lignes : \" + JSON.stringify(lignes(demandes[0].a));' '  const echantillon = \"Cinq livres sont encore en prêt.\";' '  const res = await demander([{ role: \"system\", content: \"Donnez la réponse en une phrase courte. Utilisez seulement les lignes fournies.\" },' '    { role: \"user\", content: faits }], echantillon, 60);' '  console.log(\"le modèle a dit : \" + res.texte);' '  console.log(\"  montrée avec sa requête et ses lignes, pour que l’utilisateur puisse vérifier\");' '}' 'main();' >> expliquer.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.

Répondre à cinq questions

Commande
docker exec -w /home/node/project agent node --experimental-sqlite --no-warnings expliquer.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.

Ce que le Run affiche

QuestionRéponse
1 Combien de livres sont encore dehors ?Réponse : 5. Requête : ...
2 Quels titres le membre 2 a-t-il empruntés ?Réponse : Carte de la pluie ; Moteurs tranquilles ; Sept Bouilloires. Requête : ...
3 Quels livres sont populaires ?Avant de répondre : que voulez-vous dire par populaire ?
4 Qui a emprunté le plus de livres ?Je ne suis pas sûr. Deux lectures divergent : Amina 3 ou Bruno 3
5 Quels livres ont été empruntés au mois 9 ?Aucune ligne ne correspond. Requête : ...

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.