Explorer les coûts des LLM
PostHog ajoute des métadonnées de coût par appel à chaque événement $ai_generation et $ai_embedding au moment de l'ingestion. Toute question sur les coûts se réduit à une agrégation sur ces deux types d'événements — la variation intéressante porte seulement sur la façon dont vous groupez, filtrez et comparez.
Cette skill couvre les investigations de coûts courantes : dépense totale, ventilations (modèle, fournisseur, utilisateur, trace, propriété personnalisée), analyse des tokens et des cache-hit, debugging de régression, et matérialisation des résultats sous forme d'insights, de tableaux de bord ou d'alertes.
Outils
| Outil | Objectif |
|---|---|
posthog:execute-sql |
HogQL ad-hoc pour toute agrégation de coût — l'outil principal de cette skill |
posthog:query-llm-traces-list |
Lister les traces avec les métriques de coût, tokens et erreurs récapitulés |
posthog:query-llm-trace |
Ventilation des coûts d'une seule trace sur tous ses événements |
posthog:read-data-schema |
Découvrir quelles propriétés personnalisées existent pour les ventilations |
posthog:insight-create |
Matérialiser un graphique de coût en tant qu'insight sauvegardé |
posthog:dashboard-create |
Regrouper des insights de coût dans un tableau de bord |
posthog:alert-create |
Alerter quand le coût dépasse un seuil |
Règles fondamentales
Trois règles couvrent la plupart des erreurs :
- Additionnez
$ai_total_cost_usdpour les rollups, jamais les composants. Les composants omettent les frais de requête et de recherche web. Les cellules de coût de l'interface additionnent$ai_total_cost_usdsurevent IN ('$ai_generation', '$ai_embedding'); faites de même. Schéma complet et justification dans propriétés de coût. - Incluez toujours
$ai_generationet$ai_embeddingdans les requêtes de coût, sauf si le projet ne démontre clairement qu'il n'utilise pas les embeddings — les omettre sous-compte silencieusement.$ai_traceet$ai_spanne portent aucun coût de rollup; certains wrappers SDK dupliquent$ai_total_cost_usdsur$ai_trace, donc ne l'incluez pas dans les rollups ou vous doublerez le comptage. - Définissez toujours une plage horaire. Les requêtes de coût sans plage horaire scannent la table complète des événements.
$ai_total_cost_usd est défini à l'ingestion via l'un des trois chemins (passthrough, tarification personnalisée, lookup automatique). Quand un coût semble incorrect, lisez d'abord $ai_cost_model_source — consultez sources de coût pour les règles de priorité et une requête diagnostique.
Les mathématiques du cache-hit dépendent du fait que le fournisseur rapporte les tokens du cache inclusivement ou exclusivement à $ai_input_tokens. Branchchez toujours sur le drapeau par événement $ai_cache_reporting_exclusive, jamais sur le nom du fournisseur — consultez comptabilité du cache pour la formule exclusive vs inclusive.
distinct_id est la dimension utilisateur canonique. Les clients attachent souvent des propriétés personnalisées (feature, tenant_id, workflow_name) — découvrez-les avec posthog:read-data-schema avant de grouper. Ne devinez pas les noms.
Workflow : dépense totale dans une fenêtre
posthog:execute-sql
SELECT round(sum(toFloat(properties.$ai_total_cost_usd)), 4) AS total_cost_usd
FROM events
WHERE event IN ('$ai_generation', '$ai_embedding')
AND timestamp >= now() - INTERVAL 30 DAY
Workflow : ventilations de coûts
Chaque question sur les coûts est une variation du même modèle — grouper par une dimension, agréger $ai_total_cost_usd. Consultez modèles de ventilation pour des recettes prêtes à l'exécution :
- Coût au fil du temps (quotidien)
- Coût par modèle
- Coût par utilisateur (gros dépensiers)
- Coût par trace (traces les plus onéreuses)
- Coût par dimension personnalisée
- Distribution du coût par appel
- Économies entrée vs sortie vs cache
Workflow : inspecter le coût d'une seule trace
Quand l'utilisateur colle une URL de trace et pose une question sur son coût, récupérez la trace et affichez la ventilation par événement :
posthog:query-llm-trace
{ "traceId": "<trace_id>", "dateRange": {"date_from": "-30d"} }
Additionnez $ai_total_cost_usd sur les événements retournés, groupés par nom de span ou modèle, pour montrer quelles étapes ont généré le coût. La réponse de trace inclut déjà totalCost par commodité.
Workflow : déboguer une régression de coûts
« Notre facture LLM a explosé — pourquoi ? » est presque toujours l'un de : plus d'appels, prompts plus grands, un nouveau modèle, ou un changement du taux de cache-hit. Parcourez-les dans l'ordre — consultez debugging de régression pour le playbook en 5 étapes.
Workflow : matérialiser en insight, tableau de bord ou alerte
Après que les requêtes ad-hoc répondent à la question, persistez-les en tant qu'insights, regroupez-les dans un tableau de bord, ou configurez les alertes. Consultez matérialisation pour du JSON prêt à l'exécution pour posthog:insight-create, posthog:dashboard-create, et posthog:alert-create.
Construction de liens d'interface
- Tableau de bord :
https://app.posthog.com/llm-analytics/dashboard - Liste des traces (triée par coût) :
https://app.posthog.com/llm-analytics/traces - Liste des générations :
https://app.posthog.com/llm-analytics/generations - Liste des utilisateurs (coût par utilisateur) :
https://app.posthog.com/llm-analytics/users - Trace unique :
https://app.posthog.com/llm-analytics/traces/<trace_id>?timestamp=<url_encoded_iso>
Affichez toujours un lien d'interface pour que l'utilisateur puisse vérifier visuellement.
Maintenir cette skill à jour
Le comportement de rapport des fournisseurs (quels tokens sont inclusifs vs exclusifs, où les coûts apparaissent) change au fil du temps et peut différer entre les versions du SDK pour le même fournisseur. Pour éviter la pourriture :
- Branchchez sur les drapeaux au niveau de l'événement (
$ai_cache_reporting_exclusive,$ai_cost_model_source) plutôt que sur des noms de fournisseur ou modèle codés en dur. Ces drapeaux sont la réponse résolue de l'ingestion pour l'événement spécifique et sont la source de vérité appropriée. $ai_total_cost_usdest toujours autoritaire pour les rollups — privilégiez-le par rapport à l'addition des composants, qui peuvent diverger à mesure que de nouvelles catégories de coût sont ajoutées.- Pour tout ce qui n'est pas couvert ici (nouvelles catégories de coût, modifications de la lookup de tarification, ajouts de fournisseurs), exécutez
posthog:docs-searchpour « calculating costs » ou « llm analytics » d'abord plutôt que de faire confiance à une règle codée en dur dans ce fichier. - Si vous trouvez cette skill contredisant l'interface, faites confiance à l'interface et signalez la skill pour une mise à jour.
Conseils
- Définissez toujours une plage horaire — les requêtes de coût sans plage horaire scannent la table complète des événements
- Incluez toujours
$ai_embeddingaux côtés de$ai_generationlors de la sommation des coûts; les embeddings sont bon marché par appel mais s'accumulent à l'échelle - Les coûts sont écrits à l'ingestion (consultez Calculating LLM costs) — si
$ai_total_cost_usdmanque ou est zéro, lisez d'abord$ai_cost_model_source:passthroughsignifie que le SDK a fourni les coûts;customsignifie tarification personnalisée des tokens;openrouter/manualsignifient lookup automatique; manquant signifie que le modèle n'a pas été trouvé (modèle personnalisé inhabituel, fine-tune). Grep :countIf(properties.$ai_total_cost_usd IS NULL)par(model, source) - La tarification personnalisée utilise des prix par token, pas par million — si un modèle à prix personnalisé semble ~1M× trop cher ou trop bon marché, c'est presque toujours le bug
- Excluez les appels en erreur des totaux de coûts uniquement quand explicitement demandé — les fournisseurs facturent toujours de nombreux modes d'erreur, et les inclure donne la facture véridique
- Pour les totaux par utilisateur, excluez les lignes où
distinct_id = properties.$ai_trace_id— certains SDK définissent par défaut distinct_id à l'ID de trace quand aucun utilisateur n'est défini - Le coût est additif dans les événements
$ai_generation+$ai_embeddingdans une trace; la sommation sur$ai_spandonne zéro.$ai_tracepeut porter$ai_total_cost_usdde certains wrappers SDK — ne l'incluez pas dans les rollups ou vous doublerez le comptage. Les événements$ai_evaluationportent aussi un coût mais ne font pas partie des rollups de l'interface standard; incluez-les uniquement quand l'utilisateur veut explicitement la dépense d'évaluation dans le total - Le taux de cache-hit dépend de
$ai_cache_reporting_exclusive— branchchez sur le drapeau au niveau de l'événement plutôt que sur le nom du fournisseur ou du modèle. Le comportement des fournisseurs et les versions du SDK changent; le drapeau est la réponse résolue de l'ingestion pour cet événement spécifique - Quand vous répondez à « pourquoi X est-il cher? », affichez le coût et la répartition des tokens — l'utilisateur veut presque toujours savoir s'il faut réduire les prompts, réduire les sorties, ou changer de modèle
- Avant de construire un tableau de bord personnalisé, vérifiez si les tuiles
/llm-analytics/dashboardstandard répondent déjà à la question — les recréer est du churn - Pour les grands tenants, matérialisez les requêtes de coût courantes en tant qu'insights et réutilisez via
insight-query; SQL ad-hoc est bon pour les one-offs mais le réexécuter à chaque chargement de tableau de bord est coûteux
Références
- propriétés de coût — schéma complet des propriétés, justification du coût total, règles d'ensemble d'événements
- sources de coût — comment les coûts sont définis à l'ingestion plus une requête diagnostique
- comptabilité du cache — fournisseurs exclusifs vs inclusifs, formule de taux de cache-hit
- modèles de ventilation — recettes SQL pour chaque ventilation courante
- debugging de régression — playbook en 5 étapes pour les pics de coûts
- matérialisation — JSON d'insight, tableau de bord et alerte