Lentille de goulot d'étranglement
Trouvez le goulot d'étranglement. Prouvez l'amélioration.
Conservez la collecte en local ; ne téléchargez pas le code source, les traces ou les rapports par défaut. Les instructions portables et les scripts fournis ne nécessitent pas de fournisseur d'agent particulier. Résolvez les chemins des scripts fournis par rapport à ce fichier SKILL.md. L'interface en ligne de commande nécessite Python 3.10+ ; les adaptateurs cibles prennent en charge Python 3.10+ et Node.js 22+. Node prend en charge les modes benchmark/CPU ; Python prend également en charge le profilage d'allocation.
Découvrir et se mettre d'accord sur la charge de travail
Lisez les instructions du projet, les manifestes, les lockfiles, les points d'entrée et les tests de performance/correctitude existants sans importer les modules du projet ni exécuter les hooks de configuration. Identifiez le langage, le framework, l'interpréteur, les dépendances et l'opération lente réelle. Sélectionnez l'adaptateur Python ou Node et le runtime du projet existant. Pour un autre langage, expliquez les limites du collecteur et proposez un profileur approprié plutôt que de prétendre que les adaptateurs fournis le prennent en charge.
Choisissez une charge de travail représentative et bornée avec un jeu de données stable, une graine, un niveau de concurrence, une politique de cache et un résultat attendu. Préférez un benchmark existant de confiance ou un petit pilote relu qui vérifie le résultat. La collecte de test et les imports d'application exécutent également du code. Si aucune charge de travail exécutable n'est disponible, fournissez des hypothèses et un plan de collecte ; n'inventez jamais de mesures.
Avant d'exécuter un dépôt inconnu, montrez l'interpréteur exact, le répertoire de travail, la commande et les arguments, le nombre d'invocations, le timeout, les chemins de sortie et les effets possibles sur la base de données/réseau/fichiers. Obtenez l'autorisation pour cette charge de travail concrète si elle n'est pas déjà couverte par la conversation. L'autorisation d'inspecter ou de profiler n'est pas une autorisation de modifier le code de l'application. Demandez avant toute modification, sauf si l'utilisateur a déjà autorisé l'optimisation. Ne demandez pas à nouveau pour un périmètre déjà approuvé et inchangé. L'installation de dépendances, l'attachement à des processus et l'accès à la production nécessitent leur propre autorisation applicable.
Le collecteur exécute du code avec les permissions de l'utilisateur : la séparation des sous-processus et les timeouts ne constituent pas un bac à sable de sécurité. Utilisez des fixtures ou une base de données de test si nécessaire. Ne transmettez jamais d'identifiants dans les ID de charge de travail ou les arguments de ligne de commande ; les arguments et les chemins sont enregistrés localement. Les rapports peuvent révéler des chemins internes. N'exécutez pas de commandes inconnues simplement pour découvrir ce qu'elles font.
Collecter des preuves
Lisez references/measurement.md pour les commandes, les définitions de métriques, les décisions statistiques et les codes de sortie. Le format partagé version 2 est défini dans references/measurement.schema.json. Exécutez le collecteur fourni uniquement pour la charge de travail autorisée. Recollectez les artefacts anciens ou ad-hoc plutôt que de deviner leurs limites de métriques manquantes.
- Collectez d'abord un benchmark non instrumenté. Sauvegardez tous les échantillons, les métadonnées d'environnement, l'identité de la charge de travail et la révision du code. Chaque échantillon utilise un nouveau processus. Un warmup écarté est également un nouveau processus ; il ne réchauffe pas l'état de l'application dans les processus suivants.
- Collectez les profils CPU et, pour Python, les profils d'allocation dans des invocations séparées. Leurs temporisations sont diagnostiques et ne peuvent pas remplacer les temporisations du benchmark. Le mode CPU Node conserve un profil V8 et des diagnostics de boucle d'événements ; les hits d'échantillons ne sont pas des comptes d'appels et le profil V8 inclut le démarrage du collecteur. La collecte par défaut du benchmark et de l'allocation exécute chacune la charge de travail huit fois (un warmup, sept exécutions enregistrées) ; un profil CPU ajoute une invocation sans warmup. Incluez ces comptes dans le plan approuvé.
- Conservez la base de référence avant toute modification. Utilisez des noms de sortie frais : les scripts refusent de remplacer les artefacts. Choisissez un répertoire de résultats durable et conservez chaque JSON avec son répertoire d'artefacts adjacent. Enregistrez l'identité du jeu de données, les hachages des fichiers
--input, la graine, la révision, les fichiers--sourcepertinents et la politique de cache. La graine enregistrée n'ensemence pas le code de l'application ; les métadonnées automatiques ne peuvent pas établir l'état réel du cache ou les entrées non spécifiées. - Lorsque cela a du sens, utilisez
--expected-stdoutavec une réponse connue relue de manière indépendante. Chaque invocation, y compris les warmups, est vérifiée. Sans cet oracle, la comparaison automatisée laisse l'exactitude non évaluée ; exécutez et rapportez les tests du projet séparément. L'égalité étroite de la sortie ne couvre pas toutes les invariants de l'application. - Préférez un pilote fini pour une API Python ou un worker. L'outil fourni n'est pas un générateur de charge HTTP, un échantillonneur de processus en direct, un profileur CPU à l'échelle du thread ou un moniteur d'arbre de processus. Il ne mesure pas directement les octets d'E/S, les comptes de requêtes, les percentiles de requêtes ou le débit. Si nécessaire, choisissez une instrumentation supplémentaire avec l'utilisateur et enregistrez sa portée/charge.
Diagnostiquer et proposer
Pour chaque constatation, citez l'artefact, la fonction/fichier/ligne, le nombre d'appels ou la taille d'allocation, et le temps propre/accumulé pertinent. Distinguez fait observé, hypothèse et changement proposé. Les temps cumulés se chevauchent dans l'arbre d'appels ; ne les additionnez jamais en un pourcentage du temps total. Un temps cumulé élevé identifie un chemin coûteux, pas nécessairement la fonction à réécrire.
Un temps CPU inférieur au temps réel peut suggérer une attente, mais ne prouve pas une causalité disque, base de données ou réseau. Un appel de fonction répété n'est pas une preuve de requêtes N+1 : obtenez les comptes/portées de requêtes et inspectez la boucle. Les instantanés d'allocation décrivent les allocations actives au moment de l'instantané, pas toutes les allocations transitoires ou une fuite. Confirmez les fuites suspectées avec des charges de travail répétées et des preuves de rétention. Énoncez explicitement les inconnues.
Priorisez les changements par contribution mesurée, bénéfice probable, coût d'implémentation, risque de correctitude et compromis de ressources. Décrivez les effets d'invalidation de cache, d'ordre, de transaction, de concurrence et de mémoire si pertinents. Ne promettez pas un pourcentage d'amélioration avant de l'avoir mesuré.
Optimiser et vérifier dans les limites de l'autorisation
Effectuez le plus petit changement autorisé et préservez le travail non connexe. Exécutez les tests de correctitude pertinents et comparez les sorties/invariants sur la même fixture. Un code de sortie de processus réussi seul ne constitue pas une vérification de correctitude.
Répétez le même benchmark et les profils affectés avec le même environnement, charge de travail, graine, politique de cache, nombre d'exécutions et timeout. rerun exécute le code actuel avec la requête enregistrée et vérifie les hachages d'entrée ; il ne restaure pas une révision historique. Comparez le timing non instrumenté au timing non instrumenté, et les métriques mémoire similaires. Le JSON commun ne rend pas interchangeables différentes portées de processus/thread ou intervalles de timing d'exécution. Si une dépendance/interpréteur/charge de travail change, signalez-le comme une expérience distincte plutôt que de contourner les vérifications d'incompatibilité.
Utilisez la commande de comparaison fournie pour séparer les changements médians/moyens descriptifs, les seuils pratiques configurés et les preuves de permutation d'échantillons indépendants sur les différences de moyennes (corrigé par Holm parmi les métriques comparées). Sélectionnez les seuils avant de visualiser les résultats ; la valeur par défaut de 5 % n'est pas universellement significative. Le chevauchement des plages n'est pas le test de signification. Le test suppose des échantillons indépendants et échangeables ; inspectez la variabilité et répétez ou entrelacez les mesures A/B lorsque la dérive pourrait invalider cette hypothèse. Des résultats non concluants n'établissent pas l'équivalence.
Le statut automatisé verified_improvement est limité à la charge de travail mesurée et aux oracles de sortie correspondants réussis, nécessite une amélioration pratique prise en charge de la métrique primaire, et est bloqué par des régressions pratiques prises en charge dans d'autres métriques comparées. Les échecs de vérification de sortie avec le code 3 bloquent la vérification même si l'exécution est plus rapide. --fail-on-regression fait échouer les régressions pratiques prises en charge avec le code 1 ; un code de sortie nul pour une comparaison non concluante ne certifie pas une amélioration. Ne présentez pas un résultat non évalué ou échoué dans le récit. Exécutez des charges de travail voisines représentatives si elles existent et sont autorisées. Revendiquez une couverture de régression uniquement pour les scénarios testés. Arrêtez d'étendre les expériences lorsque la question convenue est répondue, une exécution échoue, les limites d'autorisation sont atteintes ou des mesures comparables ne peuvent pas être obtenues.
Fournir le résultat
Utilisez le langage de l'utilisateur. Chaque collecte/comparaison émet un rapport Markdown et du JSON ; ajoutez une interprétation de l'agent dans le langage de l'utilisateur tout en conservant les preuves brutes. Commencez par ce qui a été trouvé, ses preuves, et la prochaine expérience, puis incluez :
- Périmètre, commande, environnement/révisions, entrées, nombre de répétitions et limites de mesure.
- Constatations avec preuves et confiance ; séparez les suggestions non mesurées.
- Modifications effectuées ou proposées, compromis et vérifications de correctitude avec commandes/résultats.
- Médianes et moyennes avant/après, min/max, nombre d'échantillons et pourcentages de changement pour chaque métrique comparable. Les tests et les décisions pratiques utilisent les moyennes ; les changements médians sont descriptifs. Incluez les unités et les limites de processus/thread/démarrage. Un changement positif signifie des valeurs plus élevées ; négatif signifie plus faibles. Marquez les bases nulles comme indéfinies.
- Statut : base de référence mesurée, non concluant, amélioration / régression observée ou amélioration vérifiée. Réservez l'amélioration vérifiée pour des mesures répétées comparables plus des vérifications de correctitude réussies. Un gain de vitesse avec une mémoire accrue est un compromis, pas un avantage inconditionnel.
- Chemins non testés, métriques indisponibles, bruit, action suivante et la commande rerun enregistrée concrète. Étiquetez clairement les démonstrations à réponse connue de
scripts/demo.pyfournies et ne réutilisez jamais leurs nombres comme résultats d'application.
Les fichiers Markdown/JSON sont la base portable ; un agent peut ajouter un graphique en utilisant ses outils de présentation disponibles. Ne dépendez pas d'un tableau de bord hébergé, d'un point de terminaison IA externe, d'un connecteur propriétaire ou d'un outil graphique optionnel pour terminer ce flux de travail.