Instrumentation des métriques IA
Tu utilises une skill qui branche les métriques IA de LaunchDarkly autour d'un appel provider existant. Ton travail consiste à auditer ce qui existe déjà, choisir le bon tier dans l'échelle ci-dessous, et l'implémenter avec le minimum de formalités qui capture toujours les métriques dont l'onglet Monitoring a besoin (durée, tokens en entrée/sortie, succès/erreur, plus TTFT en streaming).
La chose la plus importante à bien maîtriser : default au tier le plus haut qui correspond à la forme de l'appel. Descendre plus bas ("écrire juste les appels tracker manuels") semble flexible mais te coûte de la dérive, des métriques manquées et des patterns hérités que les SDKs ont dépassés.
L'échelle à quatre tiers
C'est l'ordre que les READMEs SDK officiels (Python core, Node core, et chaque package provider) recommandent. Descends du sommet et arrête-toi au premier tier qui correspond :
| Tier | Pattern | Utilise quand | Suit automatiquement |
|---|---|---|---|
| 1 — Managed runner | Python : ai_client.create_model(...) retournant un ManagedModel, puis await model.invoke(...). <br>Node : aiClient.initChat(...) / aiClient.createChat(...) retournant un TrackedChat, puis await chat.invoke(...). |
L'appel est conversationnel (historique de chat, tour par tour). C'est par là que les READMEs provider commencent. | Durée, tokens, succès/erreur — tout ça, zéro appel tracker. |
2 — Package provider + trackMetricsOf |
tracker.trackMetricsOf(Provider.getAIMetricsFromResponse, () => providerCall()). Packages provider actuels : @launchdarkly/server-sdk-ai-openai, -langchain, -vercel (Node) et launchdarkly-server-sdk-ai-openai, -langchain (Python). |
La forme n'est pas une boucle de chat (complétion one-shot, sortie structurée, étape d'agent) mais le framework ou provider a un package. | Durée + succès/erreur du wrapper ; tokens de l'extracteur intégré getAIMetricsFromResponse du package. |
3 — Extracteur custom + trackMetricsOf |
Même wrapper trackMetricsOf, mais tu écris une petite fonction qui mappe la réponse provider à LDAIMetrics (tokens + succès). |
Aucun package provider n'existe (Anthropic direct, Gemini, Cohere, HTTP custom). | Durée + succès/erreur du wrapper ; tokens de ton extracteur. |
| 4 — Manuel brut | Appels séparés à trackDuration, trackTokens, trackSuccess / trackError, plus trackTimeToFirstToken pour les streams. |
Streaming avec TTFT, formes de réponse inhabituelles, suivi partiel, tout ce que Tier 2–3 ne peut pas envelopper proprement. | Seulement ce que tu appelles explicitement — c'est à toi de ne pas en oublier un. |
Un appel à track_openai_metrics / trackOpenAIMetrics / track_bedrock_converse_metrics / trackBedrockConverseMetrics / trackVercelAISDKGenerateTextMetrics est un raccourci hérité Tier-2. Ces helpers existent toujours dans la source SDK mais aucun des READMEs provider actuels ne les utilise — ils ont été remplacés par trackMetricsOf + Provider.getAIMetricsFromResponse. Ne les recommande pas pour du nouveau code ; si tu les vois dans une codebase existante, laisse-les tranquilles sauf si l'utilisateur est déjà en phase de nettoyage.
Workflow
1. Explore le site d'appel existant
Avant de choisir un tier, trouve l'appel provider et réponds à ces questions :
- [ ] Forme ? Est-ce une boucle de chat (historique + tour par tour), une complétion one-shot, une étape d'agent, ou quelque chose d'autre ? → détermine Tier 1 vs 2.
- [ ] Framework ? SDK provider brut ? LangChain / LangGraph ? Vercel AI SDK ? CrewAI ? Strands ? → détermine quel package Tier-2 provider (s'il y en a) s'applique.
- [ ] Provider ? OpenAI, Anthropic, Bedrock, Gemini, Azure, HTTP custom ? → référence avec la matrice de disponibilité des packages ci-dessous.
- [ ] Streaming ? Si oui, tu auras besoin du suivi TTFT, ce qui signifie Tier 4 pour la partie TTFT même si le reste est Tier 2.
- [ ] Langage ? Python ou Node ? La couverture du package provider diffère entre les deux.
- [ ] Utilise déjà une AI Config ? Si non, route vers
aiconfig-created'abord — le suivi requiert un tracker, obtenu en appelantcreate_tracker()/createTracker()sur l'objet config retourné parcompletion_config()/completionConfig()/initChat().
2. Consulte ton option Tier-2
Utilise cette matrice pour décider si Tier 2 (package provider) est disponible pour ta situation. Si ce n'est pas le cas, baisse à Tier 3 (extracteur custom). Si la forme est une boucle de chat, va à Tier 1 d'abord peu importe ce qui est dans cette matrice.
| Framework / provider | Package provider Python | Package provider Node | Référence |
|---|---|---|---|
| OpenAI (SDK direct) | launchdarkly-server-sdk-ai-openai |
@launchdarkly/server-sdk-ai-openai |
openai-tracking.md |
| LangChain / LangGraph | launchdarkly-server-sdk-ai-langchain |
@launchdarkly/server-sdk-ai-langchain |
langchain-tracking.md |
| Vercel AI SDK | — | @launchdarkly/server-sdk-ai-vercel |
(utilise la doc provider Vercel) |
| AWS Bedrock (Converse ou InvokeModel) | — (utilise LangChain-aws ou extracteur custom) | — (utilise LangChain-aws ou extracteur custom) | bedrock-tracking.md |
| Anthropic SDK direct | — | — | anthropic-tracking.md |
| Gemini / Google GenAI | — | — | gemini-tracking.md |
| Strands Agents | — (Tier 3 extracteur custom) | — (Tier 3 extracteur custom) | strands-tracking.md |
| Cohere, Mistral, HTTP custom | — | — | Tier 3 extracteur custom |
| N'importe quel provider, streaming + TTFT | — (Tier 4 seulement) | trackStreamMetricsOf (pas de TTFT) + TTFT manuel |
streaming-tracking.md |
3. Implémente à partir de la référence correspondante
Une fois que tu connais le tier et le provider, ouvre le fichier de référence et suis le pattern. Les références sont écrites pour que Tier 1 soit toujours le premier exemple, Tier 2/3 ensuite, et Tier 4 dernier. Arrête-toi au premier tier qui correspond à la forme de l'app.
Les garde-fous qui s'appliquent à chaque tier :
- Vérifie toujours
config.enabledavant de faire l'appel suivi. Une config désactivée signifie que l'utilisateur a flagué la feature — tu dois short-circuiter vers le fallback que l'app utilise (réponse en cache, erreur, chemin dégradé) plutôt que de faire l'appel provider du tout. - Enveloppe l'appel existant, ne le réécris pas. Tier 2 et Tier 3 sont conçus pour s'insérer autour d'un appel provider non modifié. Si tu te retrouves à réécrire l'appel pour le faire rentrer dans le tracker, tu es au mauvais tier — baisse d'un.
- Les erreurs sont gérées à l'intérieur de
trackMetricsOf. Le wrapper capture les exceptions, enregistretrackError()en interne, et relance — n'ajoute pasexcept: tracker.trackError()par-dessus, c'est un no-op qui déclenche aussi le garde-fou at-most-once. Tier 1 gère les deux chemins automatiquement. À Tier 4 (manuel, streaming,track_duration_of) l'appelant possède l'appel de suivi d'erreur. - Flush toujours avant de fermer. Appelle
ldClient.flush()(Python :ldclient.get().flush(); Node :await ldClient.flush()) avant de fermer le client. Les événements en arrière-plan risquent d'être perdus sinon — dans les scripts de courte durée et les services de long terme. En Node,ldClient.close()retourne une Promise ; awaite-la.
4. Vérifie
Confirme que l'onglet Monitoring se remplit :
- [ ] Fais passer une vraie requête par le chemin instrumenté.
- [ ] Ouvre l'AI Config dans LaunchDarkly → onglet Monitoring. La durée, les comptes de tokens et les comptes de génération doivent apparaître dans 1–2 minutes.
- [ ] Force une erreur (mauvaise clé API,
max_tokenszéro, n'importe quoi) et confirme que le compte d'erreurs s'incrémente. - [ ] Si streaming : vérifie que TTFT apparaît. S'il ne l'est pas, tu as probablement enveloppé la création du stream avec
trackMetricsOfmais n'as pas ajouté l'appel manueltrackTimeToFirstToken— vois streaming-tracking.md.
Référence rapide : méthodes tracker
Obtiens un tracker via la fabrique sur l'objet config : tracker = config.create_tracker() (Python v0.18.0+) ou const tracker = aiConfig.createTracker!() (Node v0.17.0+). Appelle la fabrique une fois par exécution et réutilise le tracker retourné pour chaque appel — chaque invocation de fabrique crée un nouveau runId qui tague chaque événement de suivi émis par ce tracker pour que les événements d'une exécution unique puissent être corrélés ensemble (via événements exportés / systèmes aval). L'onglet Monitoring agrège les événements plutôt que de les grouper par run aujourd'hui — le runId est utile quand les événements sont exportés ou requêtés en dehors de l'UI, et c'est l'identifiant sur lequel les garde-fous at-most-once du SDK sont keyés. Les méthodes ci-dessous sont la surface API brute — la plupart du temps tu ne dois pas les appeler individuellement ; utilise trackMetricsOf ou un managed runner Tier-1. La liste est ici pour que tu reconnaisses les méthodes dans du code existant et attrapes la bonne quand tu as vraiment besoin de Tier 4.
| Méthode (Python ↔ Node) | Tier | Ce qu'elle fait |
|---|---|---|
track_metrics_of(extractor, fn) / trackMetricsOf(extractor, fn) |
2 / 3 | Enveloppe un appel provider, capture durée + succès/erreur, appelle ton extracteur pour les tokens. C'est le tracker générique par défaut. |
track_metrics_of_async(extractor, fn) (Python) |
2 / 3 | Variante async du précédent. |
trackStreamMetricsOf(extractor, streamFn) (Node seulement) |
2 / 3 | Variante streaming. Capture l'usage par chunk quand l'extracteur gère les chunks. Ne capture pas auto TTFT. |
track_duration(ms) / trackDuration(ms) |
4 | Enregistre la latence en millisecondes. |
track_duration_of(fn) / trackDurationOf(fn) |
4 | Enveloppe un callable et enregistre la durée automatiquement. Ne capture pas les tokens ou succès — couple avec des appels explicites. |
track_tokens(TokenUsage) / trackTokens({input, output, total}) |
4 | Enregistre l'usage des tokens. |
track_time_to_first_token(ms) / trackTimeToFirstToken(ms) |
4 | Enregistre TTFT pour les réponses streaming. |
track_success() / trackSuccess() |
4 | Marque la génération comme réussie. Requis pour que l'onglet Monitoring la compte. |
track_error() / trackError() |
4 | Marque la génération comme échouée. N'appelle pas aussi trackSuccess() dans la même requête. |
track_feedback({kind}) / trackFeedback({kind}) |
tout | Enregistre un pouce vers le haut / pouce vers le bas depuis une UI de feedback. Indépendant du chemin succès/erreur. |
track_tool_call(name) / trackToolCall(name) |
tout | Enregistre une invocation d'outil unique par nom. Disponible sur les deux SDKs depuis Python v0.18.0 / Node v0.17.0. |
track_tool_calls([names]) / trackToolCalls([names]) |
tout | Variante batch — enregistre une liste d'invocations d'outils en un appel. |
track_judge_result(result) / trackJudgeResult(result) |
tout | Enregistre une évaluation par judge programmatique (consolide la paire ancienne track_eval_scores + track_judge_response). result.sampled indique si l'évaluation a tourné. |
track_openai_metrics(fn) / trackOpenAIMetrics(fn) |
hérité | Antérieur aux packages provider. Fonctionne encore ; ne l'utilise pas en nouveau code. Remplace par trackMetricsOf(OpenAIProvider.getAIMetricsFromResponse, fn). |
track_bedrock_converse_metrics(res) / trackBedrockConverseMetrics(res) |
hérité | Même histoire. Ne l'utilise pas en nouveau code. |
trackVercelAISDKGenerateTextMetrics(fn) (Node) |
hérité | Même histoire. Utilise trackMetricsOf avec l'extracteur du package provider Vercel. |
Skills connexes
aiconfig-create— préalable si l'app n'a pas encore d'AI Configaiconfig-custom-metrics— métriques métier (conversion, résolution, rétention) superposées sur les métriques IA que cette skill captureaiconfig-online-evals— score de qualité automatique (LLM-as-judge) sur les requêtes live échantillonnées ; complémentaire aux métriques iciaiconfig-migrate— l'étape 4 de la migration hardcoded-to-AI-Configs délègue à cette skill