Workstation fiche technique : comment découvrir LLM et les goulots d'étranglement multi-agents avec OpenTélémétrie, Prometheus/Grafana/Thanos et plates-formes LLM telles que Langfuse / LMNR - y compris les schémas de portée, l'attribution des coûts, l'échantillonnage et les plafonds d'utilisation intensive. Compagnon: blog d'affaires · servir : Turbocompression des LLM · laboratoire : Laboratoire d'IA d'entreprise.
- Problème: Le coût et la latence de l'agent se cachent dans les sauts (LLM → outils → RAG → tentatives), et non dans une seule métrique « le modèle est lent ».
- Standard: Instrument avec OpenTelemetry ; un schéma d'attribut pour les jetons, le modèle, le locataire, l'itinéraire etestimate_cost_usd.
- Chemin des métriques : Prométhée (+ Thanos) pour les signaux dorés ; Grafana pour les tableaux SLO et FinOps.
- Chemin LLM : Langfuse/LMNR pour les traces, les scores, les ensembles de données et les versions d'invite.
- Contrôle: Jetons de plafond, appels d'outils et cycles de débogage ; modèles d'itinéraire par difficulté d'étape.
- Gagner: Mesurez le coût par tâche réussie avant d'acheter plus de GPU ou d'augmenter les quotas de API.
1. Que signifie le « goulot d'étranglement » pour les agents LLM
Les goulots d'étranglement du temps de formation (données, FLOP) diffèrent du temps de service et temps d'agent des goulots d'étranglement. Chez les agents de production, les modes de déchets dominants sont :
- Ballonnement rapide - invites système surdimensionnées, contexte non utilisé, accès au préfixe/cache manquants.
- Exagération du modèle — modèles de frontière utilisés pour les étapes de classification/itinéraire qu'un petit modèle peut effectuer.
- Boucles illimitées - tentatives d'outils et cycles d'auto-débogage sans budget strict (voir les compromis Self-Debugging dans Turbocompression des LLM).
- Attentes externes — Base de données vectorielle, SaaS API et portes humaines dans la boucle attribuées à tort à la « latence LLM ».
- Au service de la fragmentation — Gaspillage du cache KV sur le GPU (territoire PagedAttention/vLLM) après avoir déjà confirmé que le graphique de l'agent est sain.
Sans traces distribuées, vous ne pouvez pas les séparer. L'observabilité n'est donc pas un tableau de bord pratique : c'est le plan de contrôle pour FinOps et SRE sur les produits d'IA.
2. Architecture de référence
User / Orchestrator
→ Agent runtime (tools, RAG, LLM calls)
→ OpenTelemetry SDK (spans + metrics)
→ OTEL Collector (filter, sample, redact)
├─→ Prometheus / Thanos (rates, costs, SLOs)
├─→ Grafana (boards, alerts)
└─→ Langfuse / LMNR (traces, scores, datasets)
FinOps / policy layer reads the same metrics to enforce caps and model routing.
3. Schéma d'étendue OpenTelemetry pour les appels LLM
Adoptez une convention dans tous les frameworks (LangChain, agents Go/Python personnalisés, SDK Bedrock). Préférez les conventions sémantiques là où elles existent et étendez-les avec des attributs Workstation stables :
| Attribut | Exemple | Pourquoi |
|---|---|---|
gen_ai.system | openai / anthropique / substrat rocheux / vllm | Cumuls de fournisseurs |
gen_ai.request.model | claude-sonnet-4 / lama-3.1-8b | Coût et qualité par modèle |
gen_ai.usage.input_tokens | 1820 | Inducteur de coûts rapide |
gen_ai.usage.output_tokens | 410 | Inducteur de coût d’achèvement |
wsw.estimated_cost_usd | 0.0124 | FinOps sans rejoindre les fiches de prix plus tard |
wsw.tenant_id | acme-prod | Rétrofacturation |
wsw.route | support.triage | Attribution des fonctionnalités du produit |
wsw.agent_step | plan / outil / critique | Trouver des étapes coûteuses |
wsw.retry_n | 2 | Détection de boucle |
wsw.prompt_version | triage@v17 | Lien de régression |
from opentelemetry import trace
from opentelemetry.trace import Status, StatusCode
tracer = trace.get_tracer("workstation.agents")
PRICE_IN = 0.003 / 1000 # example $/token — load from config
PRICE_OUT = 0.015 / 1000
def complete_llm(model: str, prompt: str, tenant: str, route: str):
with tracer.start_as_current_span("gen_ai.chat") as span:
span.set_attribute("gen_ai.system", "openai")
span.set_attribute("gen_ai.request.model", model)
span.set_attribute("wsw.tenant_id", tenant)
span.set_attribute("wsw.route", route)
try:
resp = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
)
usage = resp.usage
cost = usage.prompt_tokens * PRICE_IN + usage.completion_tokens * PRICE_OUT
span.set_attribute("gen_ai.usage.input_tokens", usage.prompt_tokens)
span.set_attribute("gen_ai.usage.output_tokens", usage.completion_tokens)
span.set_attribute("wsw.estimated_cost_usd", round(cost, 6))
return resp.choices[0].message.content
except Exception as e:
span.record_exception(e)
span.set_status(Status(StatusCode.ERROR, str(e)))
raise
Pratique: calculer estimated_cost_usd à la travée. N'attendez pas un travail de nuit pour joindre le décompte des jetons aux fiches de prix : les astreintes et les propriétaires de produits ont besoin de FinOps en direct.
3b. Hiérarchie et bagages multi-agents
Les graphiques d'agent ont besoin d'un modèle parent/enfant stable pour que les coûts soient correctement cumulés :
session (root)
└─ agent.run {wsw.route, wsw.tenant_id}
├─ rag.retrieve {wsw.agent_step=retrieve}
├─ gen_ai.chat {wsw.agent_step=plan, model=…}
├─ tool.execute {tool=…, wsw.retry_n}
├─ gen_ai.chat {wsw.agent_step=synthesize}
└─ eval.score {score.name, score.value}
- Une racine par tâche utilisateur - pas par appel LLM. Coût de la séance = somme de l'enfant
wsw.estimated_cost_usd. - bagages - propager
wsw.tenant_idetwsw.routesur les travailleurs/files d'attente asynchrones afin que les étendues d'outils héritent des étiquettes de rétrofacturation sans refaire la plomberie sur chaque site d'appel. - Links — lorsqu'un sous-agent démarre une nouvelle trace (par exemple, un consommateur de file d'attente séparé), utilisez des liens span vers la session parent afin que Langfuse/Grafana puisse toujours assembler le graphique.
- Échantillonnage permanent, coût élevé — un échantillonnage de tête à 5–20 % convient aux chemins heureux ; forcer l'échantillonnage lorsque les dépenses de session dépassent un seuil ou un statut = ERREUR.
4. Des mesures qui comptent (Prometheus)
Exportez des histogrammes et des compteurs (via les métriques OTEL ou un client Prometheus). Ensemble minimum viable :
llm_requests_total{model,route,status}llm_tokens_total{model,direction}où direction ∈ {entrée, sortie}llm_estimated_cost_usd_total{model,tenant,route}llm_ttft_seconds/llm_e2e_secondshistogrammesagent_tool_calls_total{tool,status}agent_retries_total{route}agent_task_success_total{route}— dénominateur du coût par réussite
Requêtes FinOps dérivées (esquisses PromQL) :
# Cost per successful task (last 1h), by route sum(rate(llm_estimated_cost_usd_total[1h])) by (route) / sum(rate(agent_task_success_total[1h])) by (route) # Retry tax sum(rate(agent_retries_total[1h])) by (route) / sum(rate(llm_requests_total[1h])) by (route)
Thanos (ou Mimir/Cortex) est important lorsque Finance demande des dépenses de modèle d'un trimestre à l'autre. Le Prometheus local seul convient pour les gardes ; ce n'est pas une archive FinOps.
5. Tableaux et alertes Grafana
Expédiez trois audiences à partir d’une seule source de données :
- Sur appel : taux d'erreur, p95 e2e, échecs de dépendances (base de données vectorielle/outils).
- Plate-forme: jetons/s, utilitaire GPU (si auto-hébergé), profondeur de file d'attente, TTFT.
- FinOps/produit : $/succès par locataire et itinéraire, invites les plus coûteuses, combinaison de modèles.
Alerte à la brûlure, pas à la vanité :
- Coût par réussite > budget SLO pour 30 mois
- Taux de tentatives > 15 % pour un itinéraire
- brèche p95 e2e avec jetons d'entrée croissants (régression rapide)
6. Plateformes natives LLM : Langfuse, LMNR et amis
Les métriques vous le disent que les coûts ont augmenté ; Les plateformes LLM vous le disent quelle version d'invite et quelle portée d'outil je l'ai fait. Langfuse et LMNR sont des exemples open source de cette classe :
- Traces hiérarchiques (session → agent → LLM / spans d'outils)
- Scores humains et LLM-as-juge
- Ensembles de données pour une évaluation hors ligne lorsque vous modifiez les invites
- Télémétrie d'utilisation en option pour l'amélioration du produit (respecter les politiques de confidentialité)
Modèle d'intégration : conserver OTEL comme système d'enregistrement pour SRE ; double exportation ou pont vers Langfuse pour une ingénierie rapide. N'inventez pas un deuxième dictionnaire d'attributs incompatible.
Les expériences de framework telles que les environnements d'exécution d'agent axés sur la fonction (historiquement commercialisés autour d'agents de streaming structurés) peuvent réduire le passe-partout, mais traitent les frameworks de niche comme facultatifs – les normes d'observabilité leur survivent.
7. Pipeline de notation : manuel ou automatique
| Méthode | Mise en œuvre | Mode de défaillance |
|---|---|---|
| Manuel | Thumbs/rubriques dans l’interface utilisateur Langfuse ; avis sur les ensembles d'or. | N'évolue pas ; toujours nécessaire pour l’étalonnage. |
| Automatique | LLM-as-juge, vérifications d'unités, validateurs de schéma, rappel de récupération. | Jugez la dérive ; jeu s'il est optimisé uniquement pour le juge. |
Joindre les scores sous forme d'événements span ou de scores Langfuse saisis par wsw.prompt_version. Bénéficiez des promotions des invites de la même manière que vous gérez les versions d'applications : Ring Promoter pour le code ; portes d'évaluation pour les invites.
8. Processus de réduction des coûts (détaillé)
- Semaine de référence : aucun changement de comportement ; uniquement des instruments. Capturez $/succès, jetons/succès, taux de nouvelle tentative.
- Attribution: classez les itinéraires par dépenses × volume. Choisissez les trois premiers.
- Routage du modèle : diviser la classification/l'extraction en modèles petits/locaux ; garder la frontière de la synthèse. Mesurez à nouveau les scores de qualité.
- Chirurgie rapide : supprimer les schémas d'outils inutilisés ; raccourcir quelques plans ; activez le cache de préfixe là où cela est sûr.
- Bouchons de boucle : appels d'outils maximum, cycles d'auto-débogage maximum, interruption exponentielle avec disjoncteurs.
- Échantillonnage: conserver 100 % de métriques ; des traces d'échantillons (par exemple 5 à 20 %) ainsi qu'un échantillonnage permanent pour les erreurs et les sessions coûteuses.
- Rédaction: supprimer les informations personnelles des attributs span avant l'exportation ; stockez les invites complètes uniquement dans les magasins agréés avec TTL.
- Cadence de révision : Tableau FinOps hebdomadaire ; étalonnage mensuel du juge par rapport aux humains.
8b. Gestion de l'utilisation des agents avec des budgets en direct
Les tableaux de bord à eux seuls n’arrêtent pas les agents en fuite. Appliquez les budgets lors de l'exécution, émettez la décision sous la forme d'un événement d'envergure et alertez lorsque les sessions atteignent souvent le plafond :
# Pseudocode: hard budget around an agent session
class Budget:
def __init__(self, max_usd=0.50, max_tool_calls=8, max_llm_calls=12):
self.max_usd, self.max_tool_calls, self.max_llm_calls = max_usd, max_tool_calls, max_llm_calls
self.spent = 0.0
self.tools = self.llms = 0
def charge(self, usd: float, kind: str):
self.spent += usd
if kind == "tool":
self.tools += 1
else:
self.llms += 1
if self.spent > self.max_usd or self.tools > self.max_tool_calls or self.llms > self.max_llm_calls:
raise RuntimeError("agent budget exhausted")
- Plafonds par session - USD, appels LLM, appels d'outils (ci-dessus).
- Quotas quotidiens par locataire — Redis/compteur saisi par
wsw.tenant_id; retourner sur un chemin dégradé contrôlé une fois épuisé. - Politique de modèle par itinéraire — modèles de liste d'autorisation pour
support.triagecontrelegal.draft; rejeter ou rétrograder en cas d'échec de la politique et enregistrerwsw.policy_action=downshift. - Clés d'outils idempotentes - les arguments de l'outil de hachage afin que les nouvelles tentatives ne facturent pas deux fois les API externes.
- Formule de coût —
cost = in_tokens × p_in + out_tokens × p_out + tool_fees; rafraîchirp_in/p_outà partir d'une fiche de prix versionnée afin que les données historiques de Thanos restent comparables.
Métrique à surveiller après l'atterrissage des plafonds : agent_budget_exhausted_total{route,reason}. Un pic signifie soit un abus, une boucle d'outils rompue ou un budget trop serré pour les charges de travail réelles.
9. Croquis de configuration du collecteur
# otel-collector-config.yaml (illustrative)
receivers:
otlp:
protocols:
http:
grpc:
processors:
memory_limiter: {}
batch: {}
attributes/redact:
actions:
- key: gen_ai.prompt
action: delete
exporters:
prometheus:
endpoint: "0.0.0.0:8889"
otlp/langfuse:
endpoint: "${LANGFUSE_OTLP_ENDPOINT}"
headers:
Authorization: "Bearer ${LANGFUSE_KEY}"
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, attributes/redact, batch]
exporters: [otlp/langfuse]
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [prometheus]
10. Avantages, inconvénients et quand ne pas s'en soucier
Avantages : rétrofacturation, tri plus rapide des incidents, retour sur investissement mesurable sur les modifications d'invite/de modèle, pistes d'audit respectueuses de la conformité, langage partagé entre les équipes de ML et de plateforme.
Inconvénients : dette d'instrumentation; coût de stockage si vous conservez chaque invite pour toujours ; risque d'envoyer des informations personnelles dans le mauvais backend ; une autre console pour que les ingénieurs apprennent.
Ignorer (pour l'instant) si : vous disposez d'un seul travail par lots hors ligne avec des dépenses quotidiennes fixes et sans agents interactifs. Enregistrez toujours les jetons ; ignorez la pile multi-backend complète jusqu'à ce que la concurrence apparaisse.
11. Liste de contrôle de migration
- ☐ SDK OTEL dans le runtime de l'agent ; collecteur dans le cluster
- ☐ Les attributs Span incluent le modèle, les jetons, le coût, le locataire, l'itinéraire
- ☐ Métriques Prometheus + tableau Grafana FinOps
- ☐ Langfuse (ou LMNR) câblé pour au moins un chemin critique
- ☐ Limites strictes sur les jetons/outils/tentatives
- ☐ Politique de rédaction revue par la sécurité
- ☐ Bilan hebdomadaire du $/succès pour les meilleurs itinéraires
- ☐ Document ADR reliant l'observabilité → service (vLLM) → promotion (Ring Promoter)
12. Matériel Workstation associé
- Compagnon de blog d'entreprise
- Turbocompression des LLM — corrigez le service après avoir vu le goulot d'étranglement
- Ring Promoter — promouvoir les services d'agents avec des barrières de santé
- Muse Glimmer / agents locaux
- Contacter Workstation pour les missions Enterprise AI Lab
Références
Publié par Workstation.
