2026-06-28 Rétrospective
Aujourd'hui, j'ai laissé tourner le travail de collecte de Markdown en JSONL avec Qwen, et j'ai réfléchi à la façon dont on pourra rechercher et extraire ces JSONL lorsqu'ils seront finalement insérés dans la base de données.
Le programme de débogage AST que nous avions créé extrait les blocs de code d'un projet Godot. En partant de ces blocs, il nous fallait une stratégie pour rechercher et récupérer les JSONL docs_chunks, api_mapping, label_prototypes stockés dans la base. Nous avons donc documenté des stratégies de A à F, et pour le moment nous avons adopté la stratégie F.
Comme nous sommes encore en train de collecter le Markdown en JSONL, il est difficile de tester immédiatement l'insertion dans la base et la recherche via le récupérateur. J'ai donc, aujourd'hui, créé une checklist de 50 points et demandé à Qwen de générer un code Godot aléatoire. J'ai aussi produit des JSONL correspondants et non correspondants, puis, en lançant jsonl + prompt + chunk ensemble, j'ai observé comment Qwen les jugeait. Même en ne testant qu'une quinzaine d'exemples, j'ai rapidement constaté que cette tâche demandait plus d'effort que prévu.
Plan de test des 50 points et réalité
Initialement, je pensais tester les 50 fonctionnalités de Godot aujourd'hui.
Mais la réalité s'est avérée différente. J'ai d'abord dressé une liste de 50 fonctions susceptibles d'apparaître fréquemment sous forme de fonctions ou de petits blocs de code dans Godot 3, puis je l'ai organisée en document. J'ai également préparé un modèle de prompt pour vérifier, en lançant jsonl + prompt + chunk, si Qwen répondait « oui » ou « non » avec un appariement fondé correctement.
Au départ, il semblait suffisant de créer et vérifier chaque cas un par un. Cependant, chaque fonction testée nécessitait beaucoup plus de JSONL que prévu.
Il fallait examiner les trois tables docs_chunks, api_mapping, label_prototypes, et pour chacune créer à la fois des JSONL pertinents et des JSONL totalement hors sujet. En plus, il fallait distinguer les cas où la syntaxe était identique entre Godot 3 et Godot 4 et ceux où elle différait selon la version.
Lorsque la syntaxe était commune, on pouvait valider les JSONL de succès et d'échec des trois tables à partir d'un même code. En revanche, si la syntaxe n'était pas commune, il fallait créer des codes pour Godot 3 et Godot 4. Puis, les JSONL générés pour Godot 3 devaient être testés à la fois avec le code Godot 3 et avec le code Godot 4, et inversement pour les JSONL de Godot 4.
Au final, je n'ai testé qu'environ 5 des 50 cas aujourd'hui. C’est bien moins que prévu, mais il est peut‑être préférable de s’arrêter à ce stade. Si j'avais poussé les 50 cas à la main, j’aurais rapidement découvert que les critères étaient trop flous, ce qui aurait compliqué davantage les choses.
Syntaxe commune et critères de version
Le principal enseignement de ces tests est qu’il est difficile de séparer simplement Godot 3 et Godot 4.
Certaines fonctions ont une syntaxe presque identique dans les deux versions. Dans ce cas, forcer une distinction « Godot 3 uniquement » ou « Godot 4 uniquement » à partir d’un seul morceau de code serait absurde. Si la syntaxe est commune, il faut la traiter comme telle et vérifier que les JSONL pertinents et non pertinents des tables docs_chunks, api_mapping, label_prototypes sont correctement différenciés.
En revanche, les fonctions qui diffèrent selon la version sont plus complexes. Un JSONL créé selon les critères de Godot 3 peut parfois produire « oui » même avec du code Godot 4, et inversement, un JSONL basé sur Godot 4 peut donner « oui » avec du code Godot 3 à cause de certains champs. En particulier, les JSONL de migration contiennent à la fois la source et la cible, ce qui rend impossible une simple correspondance de chaînes de caractères.
Il faut donc à l’avenir enregistrer séparément « la version de référence du JSONL » et « la version du code testé ». Même un « oui » doit être distingué : est‑ce un « oui » légitime dû à une syntaxe commune, ou un « oui » ambigu lié à la présence de chaînes source/cible dans une migration ?
Nécessité d’enregistrer les scores F1
Si l’on ne note les résultats des tests que comme « succès » ou « échec », il devient difficile d’en extraire des motifs plus tard.
L’idée que j’ai eue aujourd’hui n’est pas tant de calculer immédiatement le F1‑score, mais de conserver les jugements bruts afin de pouvoir, plus tard, les analyser comme on le ferait pour la précision et le rappel. Par exemple, il faut consigner si un « oui » attendu a donné un « non », ou inversement, si un « oui » était justifié par une syntaxe commune ou était ambigu à cause d’une migration.
En accumulant ces données, on pourra plus tard déterminer si le problème vient du prompt, du critère de génération du JSONL, ou de la conception des champs de chaque table. À l’inverse, si l’on continue à noter tout à la main de façon approximative, il sera difficile de retracer l’origine d’une réponse particulière.
Même avec seulement 5 cas testés aujourd’hui, j’ai déjà repéré plusieurs points ambigus. À partir du sixième test, il sera donc préférable de revoir d’abord la méthode d’enregistrement et la stratégie de prompting avant de poursuivre la même approche de test.
Limites du test manuel
Copier le prompt, coller le bloc de code, insérer chaque JSONL, puis retranscrire la réponse de Qwen est extrêmement inefficace.
Faire les premiers essais à la main a aidé à établir des repères. Mais cela a aussi montré que chaque fonction nécessite plus de JSONL que prévu, qu’il faut séparer la syntaxe commune de la syntaxe propre à chaque version, et que le sens de « oui » et « non » varie selon le contexte.
Répéter cette méthode pour les 50 fonctions n’est pas réaliste. En saisissant tout manuellement, on risque des erreurs et il devient difficile de comparer les résultats ultérieurement.
C’est pourquoi je prévois de développer un outil de débogage. Un écran où l’on peut saisir le bloc de code, le type de table, la version de génération du JSONL, la version du code testé, la réponse attendue et la réponse réelle, tout en appelant Qwen automatiquement et en enregistrant le résultat. Comme nous l’avons fait via le web pour visualiser le flux AST → Retriever, il serait idéal de pouvoir répéter les tests de correspondance JSONL via une interface GUI ou une page de débogage.
Réflexions sur la génération de données de test pour le chatbot Qwen
Aujourd’hui, j’ai réfléchi à la création de données de test aléatoires avec le chatbot Qwen.
Ce que je voulais créer était un petit jeu de démon qui puisse perturber le mode de validation. Par exemple, demander à Qwen de générer un bloc de code Godot 3, un bloc de code Godot 4, ainsi que les JSONL pertinents et non pertinents conformes aux formats docs_chunks, api_mapping, label_prototypes.
Le problème, c’est que si l’on demande simplement « génère le JSONL correct et le JSONL incorrect », les réponses peuvent se mélanger de façon trop plausible. Selon que la syntaxe soit commune, propre à Godot 3, propre à Godot 4, ou qu’elle implique une migration source/target, les réponses « oui » ou « non » varient. Ainsi, même pour des données aléatoires, il faut indiquer la version de référence, la version du code testé, le type de table et la réponse attendue.
Ce que j’ai retenu, c’est qu’il faut affiner la méthode de génération de données de test et le prompt utilisé avec le chatbot Qwen. Ainsi, on pourra vérifier, même dans ces tests, si Qwen se contente de concaténer ses connaissances ou s’il se base réellement sur les preuves textuelles présentes dans le JSONL.
Conclusion du jour
Aujourd'hui n'était pas tant une journée de test de grande quantité, mais plutôt une journée où j'ai constaté que la stratégie de recherche Retriever et l'expérimentation d'appariement JSONL basée sur le chatbot Qwen demandent chacune plus de travail que prévu.
Au départ, je pensais pouvoir réaliser les 50 tests. Mais en réalité, même avec seulement 5 tests, de nombreux problèmes sont déjà apparus. Il y a des cas où Godot 3 et Godot 4 divergent complètement, mais il existe aussi des syntaxes communes, et comme avec le JSONL de migration où source et cible sont incluses, le jugement peut devenir instable.
Ce dont nous avons donc besoin maintenant, ce n'est pas d'augmenter aveuglément le nombre de tests, mais d'établir une structure pour consigner correctement les résultats des tests. Il faut enregistrer la version de référence pour la génération du JSONL, la version du code de vérification, le type de tableau, la réponse attendue, la réponse réelle et la raison d'ambiguïté. Ainsi, même après avoir effectué les 50 tests, on pourra les analyser non pas comme de simples impressions, mais comme des motifs.
J'ai commencé en pensant qu'il suffirait de créer des données aléatoires pour les tester, mais j'ai finalement réalisé la nécessité d'une méthode de génération de données de test avec le chatbot Qwen, d'une stratégie de prompt, ainsi que d'un outil de débogage appelé automatiquement. Après demain, à partir du sixième test, je devrai légèrement ajuster les critères et d'abord trouver un moyen de réduire le flux de répétitions manuelles.