Journal de développement : ce qu'une feuille de calcul de 120 000 lignes casse réellement
Une session de travail sur une feuille de calcul de 121 254 lignes et 1,8 million de cellules, et les cinq éléments distincts qui ont dû changer avant qu'une grande analyse croisée puisse se terminer, vérifier sa sortie et renvoyer un rapport formaté utilisable.
La plupart des fonctionnalités des feuilles de calcul sont testées sur des données qui tiennent sur un écran. Ce journal couvre une session de travail sur un classeur de vente avec 121 254 lignes réparties sur 15 colonnes, soit environ 1,8 million de cellules — et une demande qui semble ordinaire : combiner les tableaux de produits, de clients, de commandes et de ventes, puis signaler les produits en baisse, les risques de réapprovisionnement et les clients de faible valeur.
Rien dans cette demande n'est exotique. Elle a quand même échoué à plusieurs reprises, pour des raisons qui n'avaient presque rien à voir avec l'analyse elle-même. Ce qui suit est ce qui a réellement cassé et ce qui a changé.
Une limite de plateforme, pas une requête lente
Le premier échec ressemblait à un bug dans le système de tâches durables. La véritable cause était une règle dans Google Apps Script : un module complémentaire d'éditeur ne peut pas créer un déclencheur temporel qui se déclenche plus d'une fois par heure..
La conception du travail en arrière-plan supposait un déclenchement d'une minute. Cette hypothèse s'est maintenue pendant le développement, où un script lié au conteneur peut être programmé librement, et a cessé de fonctionner au moment où le même code s'est exécuté en tant que module complémentaire installé. La demande d'installation du déclencheur ne s'est pas dégradée - elle a été lancée, et elle a lancé avant, le travail a été créé, donc le travail n'a jamais démarré.
Deux changements ont suivi. L'installation d'un déclencheur s'effectue désormais au mieux : il essaie une cadence d'une minute, revient à une cadence horaire, et finalement à aucun déclencheur du tout, et il ne lance jamais. Et la première étape de traitement s'exécute désormais dans la même exécution qui a créé la tâche, plutôt que dans un deuxième appel qui doit rechercher à nouveau la tâche.
Ce deuxième détail comptait plus qu'il n'y paraît. Les propriétés Apps Script ne sont pas lues et écrites de manière fiable lors des exécutions. Par conséquent, une tâche écrite quelques instants plus tôt pourrait revenir sous le nom "tâche introuvable" lors du tout prochain appel.
Signaler la progression n'est pas la même chose que terminer
Alors que le travail commençait enfin, il n'était toujours pas terminé. L'outil a exécuté une étape, puis a renvoyé un statut indiquant que le travail « continue en arrière-plan ».
Cette phrase était fausse. Sans déclencheur infra-horaire disponible, rien ne continue en arrière-plan. L'assistant a lu l'état, a transmis un pourcentage à l'utilisateur et s'est arrêté, laissant indéfiniment un travail stationné à 34 000 sur 121 253 lignes.
Le moteur d'exécution mène désormais le travail lui-même à son terme, dans le cadre d'un budget limité, et chaque appel d'état ultérieur fait avancer le travail plutôt que de simplement le lire. Si le budget est épuisé, le statut indique clairement que la tâche n’est pas terminée et que rien d’autre ne pourra la faire avancer.
Le principe mérite d'être énoncé directement : un rapport d'avancement n'est pas un livrable. Un utilisateur a demandé un tableau et non un pourcentage.
Une requête ne peut être traitée que par des outils que le modèle peut voir
Pour garantir la précision de la sélection d'outils, GetSheetAI divulgue un sous-ensemble de ses outils par tour en fonction de la demande. Ce mécanisme a été construit autour de l'ensemble d'outils Excel, et le module complémentaire Google Sheets enregistre 22 outils qui n'existent que là-bas. Ces outils étaient exclus de chaque demande.
L'effet était spécifique et facile à manquer. La demande d'un graphique à barres a révélé 6 des 44 outils, l'outil graphique étant parmi les outils cachés. Demander de trier une plage divulguée 5 sur 44, sans l'outil de tri. L'assistant ne refusait pas : il ne pouvait vraiment pas voir l'outil qui faisait le travail.
Sheets dispose désormais de son propre mappage outil-bundle, reflétant chaque homologue Excel, et le filtre passe par tout outil sur lequel il n'a pas d'opinion plutôt que de le supprimer. Un test lit désormais les noms des outils enregistrés directement à partir de la source, donc l'ajout d'un outil sans le classer fait échouer la construction au lieu de le rendre silencieusement inaccessible.
La même classe de lacunes est apparue dans le phrasé. Une requête chinoise signifiant « créer une nouvelle feuille » ne correspondait à aucune règle, car le modèle ne reconnaissait qu'un seul des deux mots courants pour une feuille. L'outil de création de feuille est resté masqué et l'assistant a signalé que la création d'une feuille de calcul était impossible. Ce n’était pas le cas.
Les messages d'erreur font partie du produit
Plusieurs échecs se résumaient à un message énonçant un problème sans indiquer la solution.
L'écriture dans une feuille qui n'existe pas a renvoyé "La ressource demandée n'existe pas." Cela se lit comme un complément défectueux. Il indique maintenant que la feuille n'existe pas, que l'outil d'écriture ne crée pas de feuilles et que deux appels le font.
Refuser la classification au niveau des lignes sur une plage très large a renvoyé un simple refus. L'étiquetage d'un résultat agrégé fonctionne quelle que soit la taille, donc le message nomme désormais ce chemin : groupez d'abord, puis appliquez les règles de classification au résultat groupé.
Une protection contre l'écrasement n'a renvoyé que blocked: true, ce qui se lit comme un échec. Il explique maintenant que la cible détient déjà des données et comment procéder.
Aucun de ces éléments n'est cosmétique. Dans chaque cas, le message précédent mettait fin à une tâche qui était encore réalisable.
Les expressions déterministes nécessitaient plus d'arithmétique
Dériver une année-mois telle que 201707 à partir d'une clé de date entière telle que 20170702 nécessite soit floor(x / 100), soit un modulo. Ni l’un ni l’autre n’existait. Deux tentatives ont échoué et la colonne dérivée a été abandonnée.
La couche d'expression comprend désormais floor, round, abs et mod, et l'erreur de fonction non prise en charge répertorie l'ensemble complet et donne cette expression exacte, plutôt que de nommer uniquement ce qui a été rejeté.
Où en est-il
Sur le même classeur, le chemin durable est désormais terminé : les 121 253 lignes sont traitées, regroupées, écrites et formatées, avec chaque morceau de résultat vérifié. Sur Excel, la même requête a généré une classification des 397 produits (132 sans ventes récentes, 101 signalés pour risque de réapprovisionnement, 99 en déclin, 65 normaux) calculée avec SUMIFS natif par rapport à la table source plutôt que de déplacer les données n'importe où.
Les valeurs de fonctionnement à connaître :
- seuil de routage durable : supérieur à 100 000 cellules ;
- fragmentation de la source : lectures limitées, vérifiées par fragment lors de la réécriture ;
- couverture de régression : 826 essais sur l'ensemble de l'exécution partagée ;
- exécution en arrière-plan sur les modules complémentaires Google Sheets : toutes les heures au mieux, de sorte que la barre latérale génère de longues tâches lorsqu'elle est ouverte.
Ce dernier point constitue une limite réelle plutôt que temporaire. Un module complémentaire installé ne peut pas planifier le travail plus fréquemment, donc un travail volumineux progresse pendant que la barre latérale est ouverte. Le point de contrôle durable signifie que sa fermeture ne perd aucun travail terminé, mais la description honnête est que le travail est piloté et non planifié.
La leçon plus large de cette session n'était pas une question d'échelle. Chacune de ces défaillances était le fait que le système connaissait quelque chose que l'utilisateur ne pouvait pas voir : une règle de plate-forme, un outil caché, un chemin pris en charge nommé nulle part dans l'erreur. C’était leur taille qui les rendait tous visibles à la fois.