lokeshrana9999/llm-scan

Localise chaque appel LLM dans un dépôt et génère un plan de route (routes.json). Utilisez-le lorsque l'utilisateur demande « auditer mon utilisation LLM », « pourquoi ma facture LLM est élevée », « accélérer mes appels LLM », « où appelons-nous le modèle », « cartographier nos appels LLM » ou commence toute revue de coût ou de latence LLM. Exécutez-le en premier ; llm-capture et llm-diagnose ont besoin de sa sortie.

Qu'est-ce que llm-scan ?

llm-scan est une compétence d'agent d'IA qui audite en lecture seule un dépôt entier pour identifier chaque endroit où du code effectue un appel à un modèle de langage (LLM). Elle est utile pour les développeurs et les ingénieurs qui veulent comprendre leur utilisation des LLM avant d'optimiser les coûts, de réduire la latence ou d'auditer la sécurité. La compétence génère un fichier routes.json dans un répertoire work/<repo>, documentant chaque site d'appel avec des métadonnées telles que le fournisseur, le modèle, le streaming, les marqueurs de cache, et si la route est en production ou en test. Elle prend en charge plusieurs plateformes d'agents de codage (Claude Code, Codex, etc.) en lisant un fichier de délégation spécifique à l'agent. Elle fonctionne en recherchant des appels SDK, des sous-processus CLI, des appels HTTP, des modèles de décision, des appels de réchauffement, ainsi que des appels non-LLM comme la reconnaissance vocale, en marquant ces derniers comme kind: non_llm et en les listant séparément. Elle identifie également les journaux d'utilisation existants et les lacunes d'utilisation, fournissant une base pour les compétences ultérieures llm-capture et llm-diagnose. Les nombres de coûts et de latence ne sont pas estimés ici, mais sont délégués à scripts/calc.py.

Compatible avec✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/lokeshrana9999/llm-cost-skills/tree/HEAD/skills/llm-scan

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait llm-scan ?

Cette compétence cartographie chaque site d'appel LLM et journal d'utilisation d'un dépôt dans work/<repo>/routes.json. Elle est en lecture seule : ne jamais éditer, formater, commiter ou exécuter quoi que ce soit dans le dépôt cible.

0. configuration

  1. Détectez quel agent de codage vous êtes : Claude Code, ou Codex (ou tout autre agent de codage). Lisez uniquement le fichier correspondant, delegation/claude.md ou delegation/codex.md, dans ce pack. Il indique quelle étape est confiée à un assistant rapide et bon marché et laquelle vous reste.
  2. Définissez <pack> comme le dossier qui contient scripts/calc.py (deux niveaux au-dessus de ce fichier) et <repo> comme le nom du dossier du dépôt cible. Créez <pack>/work/<repo>/ ; toutes les sorties vont là. N'écrivez jamais dans le dépôt cible.

1. trouver chaque site d'appel

Parcourez l'ensemble du dépôt (ignorez node_modules, .venv, dist, build, .git, les fichiers de verrouillage). Comptez tous ces éléments :

  • Appels SDK : tout appel de bibliothèque client qui envoie une invite à un modèle (chat, messages, completions, responses, embeddings, helpers de streaming, frameworks d'agents).
  • Appels de sous-processus CLI : un agent ou un modèle CLI exécuté à partir du code en mode non interactif (un indicateur d'impression tel que -p, exec, --prompt), y compris les workers chauds de longue durée et les pipes stream-json.
  • Appels HTTP : requêtes directes vers une URL d'API de modèle, une passerelle, un proxy ou un point de terminaison auto-hébergé.
  • Modèles de décision, de passerelle, de classification, de routage, de reclassement et de jugement, même s'ils sont minuscules ou bon marché. Ce sont aussi des appels LLM.
  • Appels de réchauffement, de maintien en vie et de vérification de santé qui touchent un modèle : enregistrez-les comme des routes (ils n'ont souvent aucune utilisation dans les journaux ; voir usage_gaps).
  • Appels dans les tests, scripts, notebooks et tâches cron : listez-les, mais marquez "live": false s'ils ne s'exécutent jamais en production.
  • Appels de modèle non LLM (reconnaissance vocale, synthèse vocale, OCR, services de vision facturés par minute ou par image) : hors de portée pour la tarification. Listez-les avec "kind": "non_llm" afin que le rapport puisse dire qu'ils ont été vus et non tarifés.

Recherchez les imports de clients, les noms d'hôtes d'API, les chaînes model= / "model":, max_tokens, stream, cache_control, et les lancements de sous-processus de CLI de modèles. Ouvrez ensuite chaque résultat et lisez la fonction qui l'entoure.

2. enregistrer chaque route

Écrivez une entrée par site d'appel. L'id de route est chemin/relatif.ext:nom_fonction ; pour une méthode, chemin/relatif.ext:Classe.méthode ; utilisez <module> si c'est au niveau racine. Utilisez la même orthographe d'id partout (routes.json, lignes, rapport).

champsignification
idfichier:fonction ou fichier:Classe.méthode
kindsdk, cli, http, non_llm
providercomme le code le montre, sinon null
modella chaîne du modèle exactement comme écrite, ou la clé de configuration / la variable d'environnement qui la définit (alors aussi model_source). Lorsque le modèle d'une route varie à l'exécution, écrivez "varies" et nommez la configuration ou la source dans model_source
streamingtrue / false / null
cache_markersexplicit (le code marque les points de cache d'invite), implicit (pas de marques, mais un préfixe stable, un processus chaud ou une valeur par défaut du fournisseur peut le mettre en cache), none (rien ne suggère la mise en cache), unknown
max_tokensle nombre, ou null si non défini
retriesnombre et où (SDK par défaut, wrapper, boucle), ou 0
user_waitstrue si une personne attend la réponse (chat, voix, interface utilisateur en direct) ; false pour batch, arrière-plan, cron ; "unknown" si vous ne pouvez pas le dire
decision_modeltrue pour les passerelles, routeurs, classifieurs, juges
decision_shapedtrue si la réponse est un verdict minuscule qui alimente une branche de code (une énumération, un booléen, une étiquette, un score) et la route s'exécute par événement ou par élément ; false si la réponse est du texte libre ou une sortie structurée longue ; "unknown" si vous ne pouvez pas le dire. Enregistrez-le pour chaque route ; calc le détecte également à partir des journaux (p50 de sortie de 5 tokens ou moins sur 50+ appels)
toolsoù les définitions d'outils ou de fonctions sont construites et envoyées (fichier:fonction, et combien sont envoyées par appel si le code le montre), ou null si la route n'en envoie aucune. Faits uniquement ; les chiffres proviennent des journaux
livetrue ; false si test uniquement ; "unknown" si vous ne pouvez pas le dire
statelesstrue si chaque appel est autonome (une passerelle ou un classifieur par événement qui n'envoie aucun tour précédent) ; false si une conversation ou un mémo s'agrandit à travers les appels ; "unknown"
notesune courte ligne, uniquement des faits que vous avez vus

Utilisez null (ou "unknown" là où le tableau le permet) lorsque vous ne pouvez pas le dire. Ne devinez jamais une valeur.

3. trouver les journaux d'utilisation

Trouvez où l'application enregistre déjà l'utilisation (tokens, coût, latence, délai avant le premier token, succès). Recherchez les fichiers journaux, JSONL, CSV, SQLite ou les tables de base de données, les appels de traçage et de métriques, et les champs d'utilisation du fournisseur sauvegardés à partir des réponses. Pour chacun, enregistrez :

  • le chemin ou la table et le format ;
  • les NOMS des champs, jamais les valeurs ;
  • si un champ contient le texte de l'invite ou de la réponse (has_text_fields) ;
  • quels ids de route il couvre.

N'ouvrez pas les valeurs du journal au-delà des premières lignes nécessaires pour apprendre les noms des champs, et ne copiez aucun texte à partir d'elles.

Notez également, par NOM de champ uniquement, si les journaux enregistrent les définitions d'outils ou l'utilisation d'outils par appel (un nombre d'outils envoyés, la taille des définitions d'outils en tokens, un nombre d'appels d'outils dans la réponse) ; llm-capture transforme ceux-ci en tools_defined, tool_schema_tokens et tool_calls. Si les journaux ne les contiennent pas, dites-le dans usage_gaps.

Enregistrez également usage_gaps : de courtes notes simples (une ligne chacune, uniquement des faits) là où des appels ont lieu mais les journaux ne contiennent aucune utilisation de tokens ou les nombres journalisés ne peuvent pas être considérés comme fiables tels quels. Exemples : « les appels de réchauffement sur la route X sont journalisés sans utilisation », « le coût journalisé est un total cumulé par processus », « la route Y n'est pas du tout journalisée ». Les comptes sont les bienvenus (« vu N fois ») lorsque vous les lisez à partir des noms de champs et des comptes uniquement.

4. écrire routes.json

Écrivez <pack>/work/<repo>/routes.json :

{
  "repo": "<repo>",
  "root": "<chemin absolu du dépôt cible>",
  "scanned": "<YYYY-MM-DD>",
  "routes": [
    {"id": "chemin/fichier.py:Classe.méthode", "kind": "cli", "provider": null, "model": "<chaîne>", "model_source": null,
     "streaming": true, "cache_markers": "implicit", "max_tokens": null, "retries": 0,
     "user_waits": true, "decision_model": false, "decision_shaped": false, "tools": null, "live": true, "stateless": false, "notes": ""},
    {"id": "chemin/stt.py:transcrire", "kind": "non_llm", "live": true, "notes": "reconnaissance vocale, non tarifé"}
  ],
  "usage_logs": [
    {"path": "<chemin relatif ou table>", "format": "jsonl", "fields": ["<noms uniquement>"],
     "has_text_fields": true, "covers_routes": ["chemin/fichier.py:Classe.méthode"]}
  ],
  "usage_gaps": ["<une courte note chacune>"]
}

5. terminer

Dites à l'utilisateur en quelques lignes combien de routes vous avez trouvées, lesquelles sont orientées utilisateur, quels journaux d'utilisation existent et les éventuelles usage_gaps. N'estimez pas les coûts ou les vitesses ici ; les chiffres proviennent uniquement de scripts/calc.py.

Exécutez ensuite la compétence suivante, llm-capture.

Skills associés