Ce produit n'est pas pris en charge par le site Datadog que vous avez sélectionné. ().
Aperçu
Les SDK LLM Observability de Datadog fournissent une instrumentation automatique ainsi que des API d’instrumentation manuelle pour offrir une observabilité et des insights sur vos applications LLM.
Variables d’environnement pour la configuration en ligne de commande
DD_SITE
requis - chaîne Site Datadog de destination pour la soumission des données LLM. Votre site est .
DD_LLMOBS_ENABLED
requis - entier ou chaîne Basculer pour activer la soumission des données à LLM Observability. Doit être défini sur 1 ou true.
DD_LLMOBS_ML_APP
optionnel - chaîne Le nom de votre application LLM, service ou projet, sous lequel toutes les traces et les spans sont regroupés. Cela aide à distinguer entre différentes applications ou expériences. Voir Directives de nommage des applications pour les caractères autorisés et autres contraintes. Pour remplacer cette valeur pour un span racine donné, voir Tracer plusieurs applications. Si non fourni, la valeur par défaut est celle de DD_SERVICE, ou la valeur d’un DD_LLMOBS_ML_APP propagé d’un service en amont. Remarque : Avant la version ddtrace==3.14.0, ceci est un champ requis.
DD_LLMOBS_AGENTLESS_ENABLED
optionnel - entier ou chaîne - par défaut : false Seulement requis si vous n’utilisez pas l’Agent Datadog, auquel cas cela doit être défini sur 1 ou true.
DD_API_KEY
optionnel - chaîne Votre clé API Datadog. Seulement requis si vous n’utilisez pas l’Agent Datadog.
Activez LLM Observability en exécutant votre application avec NODE_OPTIONS="--import dd-trace/initialize.mjs" et en spécifiant les variables d’environnement requises.
Remarque : dd-trace/initialize.mjs active automatiquement toutes les intégrations APM.
Variables d’environnement pour la configuration en ligne de commande
DD_SITE
requis - chaîne Le site Datadog pour soumettre vos données LLM. Votre site est .
DD_LLMOBS_ENABLED
requis - entier ou chaîne Basculer pour activer la soumission des données à LLM Observability. Doit être défini sur 1 ou true.
DD_LLMOBS_ML_APP
optionnel - chaîne Le nom de votre application LLM, service ou projet, sous lequel toutes les traces et les spans sont regroupés. Cela aide à distinguer entre différentes applications ou expériences. Voir Directives de nommage des applications pour les caractères autorisés et autres contraintes. Pour remplacer cette valeur pour un span racine donné, voir Tracer plusieurs applications. Si non fourni, la valeur par défaut est celle de DD_SERVICE, ou celle d’un DD_LLMOBS_ML_APP propagé depuis un service en amont. Remarque : Avant la version dd-trace@5.66.0, ceci est un champ requis.
DD_LLMOBS_AGENTLESS_ENABLED
optionnel - entier ou chaîne - par défaut : false Seulement requis si vous n’utilisez pas l’Agent Datadog, auquel cas cela doit être défini sur 1 ou true.
DD_API_KEY
optionnel - chaîne Votre clé API Datadog. Seulement requis si vous n’utilisez pas l’Agent Datadog.
Activez l’observabilité LLM en exécutant votre application avec dd-trace-java et en spécifiant les paramètres requis en tant que variables d’environnement ou propriétés système.
Vous pouvez fournir les paramètres suivants en tant que variables d’environnement (par exemple, DD_LLMOBS_ENABLED) ou en tant que propriétés système Java (par exemple, dd.llmobs_enabled).
DD_SITE ou dd.site
requis - chaîne Site Datadog de destination pour la soumission des données LLM. Votre site est .
DD_LLMOBS_ENABLED ou dd.llmobs.enabled
requis - entier ou chaîne Basculer pour activer la soumission des données à l’observabilité LLM. Doit être défini sur 1 ou true.
DD_LLMOBS_ML_APP ou dd.llmobs.ml.app
optionnel - chaîne Le nom de votre application LLM, service ou projet, sous lequel toutes les traces et spans sont regroupés. Cela aide à distinguer entre différentes applications ou expériences. Voir Directives de nommage des applications pour les caractères autorisés et autres contraintes. Pour remplacer cette valeur pour un span racine donné, voir Tracer plusieurs applications. Si non fourni, la valeur par défaut est celle de DD_SERVICE, ou celle d’un DD_LLMOBS_ML_APP propagé depuis un service en amont. Remarque : Avant la version 1.54.0 de dd-trace-java, ceci est un champ requis.
DD_LLMOBS_AGENTLESS_ENABLED ou dd.llmobs.agentless.enabled
optionnel - entier ou chaîne - par défaut : false Seulement requis si vous n’utilisez pas l’Agent Datadog, auquel cas cela doit être défini sur 1 ou true.
DD_API_KEY ou dd.api.key
optionnel - chaîne Votre clé API Datadog. Seulement requis si vous n’utilisez pas l’Agent Datadog.
optionnel - chaîne Le nom de votre application, service ou projet LLM, sous lequel toutes les traces et spans sont regroupés. Cela aide à distinguer entre différentes applications ou expériences. Voir Directives de nommage des applications pour les caractères autorisés et d’autres contraintes. Pour remplacer cette valeur pour une trace donnée, voir Tracer plusieurs applications. Si non fourni, la valeur par défaut est celle de DD_LLMOBS_ML_APP.
integrations_enabled - par défaut : true
optionnel - booléen Un indicateur pour activer le traçage automatique des appels LLM pour les LLM integrations supportées par Datadog. Si non fourni, toutes les intégrations LLM supportées sont activées par défaut. Pour éviter d’utiliser les intégrations LLM, définissez cette valeur sur false.
agentless_enabled
optionnel - booléen - par défaut : false Uniquement requis si vous n’utilisez pas l’Agent Datadog, auquel cas cela doit être défini sur True. Cela configure la bibliothèque ddtrace pour ne pas envoyer de données nécessitant l’Agent Datadog. Si non fourni, la valeur par défaut est celle de DD_LLMOBS_AGENTLESS_ENABLED.
site
optionnel - chaîne Le site Datadog pour soumettre vos données LLM. Votre site est . Si non fourni, la valeur par défaut est celle de DD_SITE.
api_key
optionnel - chaîne Votre clé API Datadog. Seulement requis si vous n’utilisez pas l’Agent Datadog. Si non fourni, la valeur par défaut est celle de DD_API_KEY.
env
optionnel - chaîne Le nom de l’environnement de votre application (exemples : prod, pre-prod, staging). Si non fourni, la valeur par défaut est celle de DD_ENV.
service
optionnel - chaîne Le nom du service utilisé pour votre application. Si non fourni, la valeur par défaut est celle de DD_SERVICE.
N'utilisez pas cette méthode de configuration avec la commande dd-trace/initialize.mjs.
Utilisez la fonction init() pour activer LLM Observability.
optionnel - chaîne Le nom de votre application LLM, service ou projet, sous lequel toutes les traces et spans sont regroupés. Cela aide à distinguer entre différentes applications ou expériences. Voir Directives de nommage des applications pour les caractères autorisés et autres contraintes. Pour remplacer cette valeur pour une trace donnée, voir Traçage de plusieurs applications. Si non fourni, cela prend par défaut la valeur de DD_LLMOBS_ML_APP.
agentlessEnabled
optionnel - booléen - par défaut : false Uniquement requis si vous n’utilisez pas l’Agent Datadog, auquel cas cela doit être défini sur true. Cela configure la bibliothèque dd-trace pour ne pas envoyer de données nécessitant l’Agent Datadog. Si non fourni, cela prend par défaut la valeur de DD_LLMOBS_AGENTLESS_ENABLED.
Options pour la configuration générale du traceur :
site
optionnel - chaîne Le site Datadog pour soumettre vos données LLM. Votre site est . Si non fourni, cela prend par défaut la valeur de DD_SITE.
env
optionnel - chaîne Le nom de l’environnement de votre application (exemples : prod, pre-prod, staging). Si non fourni, cela prend par défaut la valeur de DD_ENV.
service
optionnel - chaîne Le nom du service utilisé pour votre application. Si non fourni, cela prend par défaut la valeur de DD_SERVICE.
Variables d’environnement
Définissez les valeurs suivantes comme variables d’environnement. Elles ne peuvent pas être configurées par programme.
DD_API_KEY
optionnel - chaîne Votre clé API Datadog. Seulement requis si vous n’utilisez pas l’Agent Datadog.
Configuration AWS Lambda
Pour instrumenter une fonction AWS Lambda existante avec LLM Observabilité, vous pouvez utiliser l’Extension Datadog et les couches de langage respectives.
Invoquez votre fonction Lambda et vérifiez que les traces LLM Observability sont visibles dans l’interface utilisateur de Datadog.
Videz manuellement les traces LLM Observability en utilisant la méthode flush avant que la fonction Lambda ne retourne.
fromddtrace.llmobsimportLLMObsdefhandler():# function bodyLLMObs.flush()
importtracerfrom'dd-trace';constllmobs=tracer.llmobs;exportconsthandler=async(event)=>{// your function body
llmobs.flush();};
Après avoir installé le SDK et exécuté votre application, vous devriez vous attendre à voir des données dans LLM Observability provenant de l’auto-instrumentation. L’instrumentation manuelle peut être utilisée pour capturer des frameworks personnalisés ou des opérations provenant de bibliothèques qui ne sont pas encore prises en charge.
Instrumentation manuelle
Pour capturer une opération LLM, un décorateur de fonction peut être utilisé pour instrumenter facilement les flux de travail :
Pour tracer un span, utilisez llmobs.wrap(options, function) comme wrapper de fonction pour la fonction que vous souhaitez tracer. Pour une liste des types de span disponibles, consultez la documentation des types de span. Pour un traçage plus granulaire des opérations au sein des fonctions, consultez Traçage des spans en utilisant des méthodes en ligne.
Types de span
Les types de span sont requis et sont spécifiés sur l’objet options passé aux fonctions de traçage llmobs (trace, wrap et decorate). Consultez la documentation des types de span pour une liste des types de span pris en charge.
Remarque : Les spans avec un type de span invalide ne sont pas soumis à LLM Observability.
Capture automatique des arguments/de sortie/du nom de la fonction
llmobs.wrap (avec llmobs.decorate pour TypeScript) essaie de capturer automatiquement les entrées, les sorties et le nom de la fonction en cours de traçage. Si vous devez annoter manuellement un span, consultez Enrichir les spans. Les entrées et sorties que vous annotez remplaceront la capture automatique. De plus, pour remplacer le nom de la fonction, passez la propriété name sur l’objet d’options à la fonction llmobs.wrap :
functionprocessMessage(){...// user application logic
return}processMessage=llmobs.wrap({kind:'workflow',name:'differentFunctionName'},processMessage)
Conditions pour terminer un span pour une fonction enveloppée
llmobs.wrap étend le comportement sous-jacent de tracer.wrap. Le span sous-jacent créé lorsque la fonction est appelée se termine dans les conditions suivantes :
Si la fonction retourne une promesse, alors le span se termine lorsque la promesse est résolue ou rejetée.
Si la fonction prend un rappel comme dernier paramètre, alors le span se termine lorsque ce rappel est appelé.
Si la fonction ne prend pas de rappel et ne retourne pas de promesse, alors le span se termine à la fin de l’exécution de la fonction.
L’exemple suivant illustre la deuxième condition, où le dernier argument est un rappel :
Exemple
constexpress=require('express')constapp=express()functionmyAgentMiddleware(req,res,next){consterr=...// user application logic
// the span for this function is finished when `next` is called
next(err)}myAgentMiddleware=llmobs.wrap({kind:'agent'},myAgentMiddleware)app.use(myAgentMiddleware)
constexpress=require('express')constapp=express()functionmyAgentMiddleware(req,res){// the `next` callback is not being used here
returnllmobs.trace({kind:'agent',name:'myAgentMiddleware'},()=>{returnres.status(200).send('Hello World!')})}app.use(myAgentMiddleware)
Démarrer un span
Il existe plusieurs méthodes pour démarrer un span, en fonction du type de span que vous démarrez. Consultez la documentation des types de span pour une liste des types de span pris en charge.
Tous les spans sont démarrés en tant qu’instance d’objet de LLMObsSpan. Chaque span a des méthodes que vous pouvez utiliser pour interagir avec le span et enregistrer des données.
Finir un span
Les spans doivent être terminés pour que la trace soit soumise et visible dans l’application Datadog.
Pour terminer un span, appelez finish() sur une instance d’objet span. Si possible, enveloppez le span dans un bloc try/finally pour garantir que le span soit soumis même si une exception se produit.
Exemple
try{LLMObsSpanworkflowSpan=LLMObs.startWorkflowSpan("my-workflow-span-name","ml-app-override","session-141");// user logic// interact with started span}finally{workflowSpan.finish();}
Appels LLM
Si vous utilisez des fournisseurs ou des frameworks LLM pris en charge par les intégrations LLM de Datadog, vous n'avez pas besoin de démarrer manuellement un span LLM pour tracer ces opérations.
Pour tracer un appel LLM, utilisez le décorateur de fonction ddtrace.llmobs.decorators.llm().
Arguments
model_name
requis - chaîne Le nom du LLM invoqué.
name
optionnel - chaîne Le nom de l’opération. Si non fourni, name prend par défaut le nom de la fonction tracée.
model_provider
optionnel - chaîne - par défaut: "custom" Le nom du fournisseur de modèle. Remarque: Pour afficher le coût estimé en dollars américains, définissez model_provider sur l’une des valeurs suivantes : openai, azure_openai ou anthropic.
session_id
optionnel - chaîne L’ID de la session utilisateur sous-jacente. Voir Suivi des sessions utilisateur pour plus d’informations.
ml_app
optionnel - chaîne Le nom de l’application ML à laquelle l’opération appartient. Voir Traçage de plusieurs applications pour plus d’informations.
Exemple
fromddtrace.llmobs.decoratorsimportllm@llm(model_name="claude",name="invoke_llm",model_provider="anthropic")defllm_call():completion=...# user application logic to invoke LLMreturncompletion
Pour tracer un appel LLM, spécifiez le type de span comme llm, et optionnellement spécifiez les arguments suivants dans l’objet d’options.
Arguments
modelName
optionnel - chaîne - par défaut: "custom" Le nom du LLM invoqué.
name
optionnel - chaîne Le nom de l’opération. Si non fourni, name prend par défaut le nom de la fonction tracée.
modelProvider
optionnel - chaîne - par défaut: "custom" Le nom du fournisseur de modèle. Remarque: Pour afficher le coût estimé en dollars américains, définissez modelProvider sur l’une des valeurs suivantes : openai, azure_openai, ou anthropic.
sessionId
optionnel - chaîne L’ID de la session utilisateur sous-jacente. Voir Suivi des sessions utilisateur pour plus d’informations.
mlApp
optionnel - chaîne Le nom de l’application ML à laquelle l’opération appartient. Voir Traçage de plusieurs applications pour plus d’informations.
Exemple
functionllmCall(){constcompletion=...// user application logic to invoke LLM
returncompletion}llmCall=llmobs.wrap({kind:'llm',name:'invokeLLM',modelName:'claude',modelProvider:'anthropic'},llmCall)
Pour tracer un appel LLM, importez et appelez la méthode suivante avec les arguments listés ci-dessous :
optionnel - chaîne Le nom de l’opération. Si non fourni, spanName prend par défaut le type de span.
modelName
optionnel - Chaîne - par défaut : "custom" Le nom du LLM invoqué.
modelProvider
optionnel - Chaîne - par défaut : "custom" Le nom du fournisseur de modèle. Remarque: Pour afficher le coût estimé en dollars américains, définissez modelProvider sur l’une des valeurs suivantes : openai, azure_openai, ou anthropic.
mlApp
optionnel - Chaîne Le nom de l’application ML à laquelle l’opération appartient. Fournir une valeur non nulle remplace le nom de l’application ML fourni au début de l’application. Voir Traçage de plusieurs applications pour plus d’informations.
sessionId
optionnel - Chaîne L’ID de la session utilisateur sous-jacente. Voir Suivi des sessions utilisateur pour plus d’informations.
Exemple
importdatadog.trace.api.llmobs.LLMObs;publicclassMyJavaClass{publicStringinvokeModel(){LLMObsSpanllmSpan=LLMObs.startLLMSpan("my-llm-span-name","my-llm-model","my-company","maybe-ml-app-override","session-141");Stringinference=...// user application logic to invoke LLMllmSpan.annotateIO(...);// record the input and outputllmSpan.finish();returninference;}}
Flux de travail
Pour tracer une portée de flux de travail, utilisez le décorateur de fonction ddtrace.llmobs.decorators.workflow().
Arguments
name
optionnel - chaîne Le nom de l’opération. Si non fourni, name prend par défaut le nom de la fonction tracée.
session_id
optionnel - chaîne L’ID de la session utilisateur sous-jacente. Voir Suivi des sessions utilisateur pour plus d’informations.
ml_app
optionnel - chaîne Le nom de l’application ML à laquelle l’opération appartient. Voir Traçage de plusieurs applications pour plus d’informations.
Exemple
fromddtrace.llmobs.decoratorsimportworkflow@workflowdefprocess_message():...# user application logicreturn
Pour tracer une portée de flux de travail, spécifiez le span kind comme workflow, et spécifiez éventuellement des arguments sur l’objet options.
Arguments
name
optionnel - chaîne Le nom de l’opération. Si non fourni, name par défaut au nom de la fonction tracée.
sessionId
optionnel - chaîne L’ID de la session utilisateur sous-jacente. Voir Suivi des sessions utilisateur pour plus d’informations.
mlApp
optionnel - chaîne Le nom de l’application ML à laquelle l’opération appartient. Voir Suivi de plusieurs applications pour plus d’informations.
Exemple
functionprocessMessage(){...// user application logic
return}processMessage=llmobs.wrap({kind:'workflow'},processMessage)
Pour suivre un intervalle de flux de travail, importez et appelez la méthode suivante avec les arguments énumérés ci-dessous :
optionnel - Chaîne Le nom de l’opération. Si non fourni, spanName prend par défaut la valeur du span kind.
mlApp
optionnel - Chaîne Le nom de l’application ML à laquelle l’opération appartient. Fournir une valeur non nulle remplace le nom de l’application ML fourni au début de l’application. Voir Traçage de plusieurs applications pour plus d’informations.
importdatadog.trace.api.llmobs.LLMObs;publicclassMyJavaClass{publicStringexecuteWorkflow(){LLMObsSpanworkflowSpan=LLMObs.startWorkflowSpan("my-workflow-span-name",null,"session-141");StringworkflowResult=workflowFn();// user application logicworkflowSpan.annotateIO(...);// record the input and outputworkflowSpan.finish();returnworkflowResult;}}
Agents
Pour suivre l’exécution d’un agent, utilisez le décorateur de fonction ddtrace.llmobs.decorators.agent().
Arguments
name
optionnel - chaîne Le nom de l’opération. Si non fourni, name par défaut au nom de la fonction tracée.
optionnel - Chaîne Le nom de l’opération. Si non fourni, spanName par défaut au nom de la fonction tracée.
mlApp
optionnel - Chaîne Le nom de l’application ML à laquelle l’opération appartient. Fournir une valeur non nulle remplace le nom de l’application ML fourni au début de l’application. Voir Traçage de plusieurs applications pour plus d’informations.
optionnel - Chaîne Le nom de l’opération. Si non fourni, spanName par défaut au nom de la fonction tracée.
mlApp
optionnel - chaîne Le nom de l’application ML à laquelle l’opération appartient. Fournir une valeur non nulle remplace le nom de l’application ML fourni au début de l’application. Voir Traçage de plusieurs applications pour plus d’informations.
optionnel - chaîne Le nom de l’opération. Si non fourni, spanName prend par défaut le nom de la fonction tracée.
mlApp
optionnel - chaîne Le nom de l’application ML à laquelle l’opération appartient. Fournir une valeur non nulle remplace le nom de l’application ML fourni au début de l’application. Voir Traçage de plusieurs applications pour plus d’informations.
sessionId
optionnel - Chaîne L’ID de la session utilisateur sous-jacente. Voir Suivi des sessions utilisateur pour plus d’informations.
Embeddings
Pour tracer une opération d’embedding, utilisez le décorateur de fonction LLMObs.embedding().
Remarque : Annoter l’entrée d’une embedding span nécessite un formatage différent de celui des autres types de span. Voir Enriching spans pour plus de détails sur la façon de spécifier les entrées d’embedding.
Arguments
model_name
requis - chaîne Le nom du LLM invoqué.
name
optionnel - chaîne Le nom de l’opération. Si non fourni, name est défini sur le nom de la fonction tracée.
model_provider
optionnel - chaîne - par défaut : "custom"
session_id
optionnel - chaîne L’ID de la session utilisateur sous-jacente. Voir Suivi des sessions utilisateur pour plus d’informations.
ml_app
optionnel - chaîne Le nom de l’application ML à laquelle l’opération appartient. Voir Traçage de plusieurs applications pour plus d’informations.
Exemple
fromddtrace.llmobs.decoratorsimportembedding@embedding(model_name="text-embedding-3",model_provider="openai")defperform_embedding():...# user application logicreturn
Pour tracer une opération d’embedding, spécifiez le type de span comme embedding, et, éventuellement, spécifiez des arguments dans l’objet options.
Remarque : Annoter l’entrée d’une embedding span nécessite un formatage différent de celui des autres types de span. Voir Enrichissement des périodes pour plus de détails sur la façon de spécifier les entrées d’embedding.
Arguments
modelName
optionnel - chaîne - par défaut: "custom" Le nom du LLM invoqué.
name
optionnel - chaîne Le nom de l’opération. Si non fourni, name est défini sur le nom de la fonction tracée.
modelProvider
optionnel - chaîne - par défaut: "custom" Le nom du fournisseur de modèle.
sessionId
optionnel - chaîne L’ID de la session utilisateur sous-jacente. Voir Suivi des sessions utilisateur pour plus d’informations.
mlApp
optionnel - chaîne Le nom de l’application ML à laquelle l’opération appartient. Voir Traçage de plusieurs applications pour plus d’informations.
Exemple
functionperformEmbedding(){...// user application logic
return}performEmbedding=llmobs.wrap({kind:'embedding',modelName:'text-embedding-3',modelProvider:'openai'},performEmbedding)
Récupérations
Pour tracer une période de récupération, utilisez le décorateur de fonction ddtrace.llmobs.decorators.retrieval().
Remarque : Annoter la sortie d’une période de récupération nécessite un formatage différent de celui des autres types de périodes. Voir Enrichissement des périodes pour plus de détails sur la façon de spécifier les sorties de récupération.
Arguments
name
optionnel - chaîne Le nom de l’opération. Si non fourni, name par défaut au nom de la fonction tracée.
session_id
optionnel - chaîne L’ID de la session utilisateur sous-jacente. Voir Suivi des sessions utilisateur pour plus d’informations.
ml_app
optionnel - chaîne Le nom de l’application ML à laquelle l’opération appartient. Voir Traçage de plusieurs applications pour plus d’informations.
Exemple
fromddtrace.llmobs.decoratorsimportretrieval@retrievaldefget_relevant_docs(question):context_documents=...# user application logicLLMObs.annotate(input_data=question,output_data=[{"id":doc.id,"score":doc.score,"text":doc.text,"name":doc.name}fordocincontext_documents])return
Pour tracer un retrieval span, spécifiez le type de span comme retrieval, et, éventuellement, indiquez les arguments suivants dans l’objet options.
Remarque : Annoter la sortie d’un retrieval span nécessite un formatage différent de celui des autres types de span. Voir Enriching spans pour plus de détails sur la façon de spécifier les sorties de récupération.
Arguments
name
optionnel - chaîne Le nom de l’opération. Si non fourni, name par défaut au nom de la fonction tracée.
sessionId
optionnel - chaîne L’ID de la session utilisateur sous-jacente. Voir Suivi des sessions utilisateur pour plus d’informations.
mlApp
optionnel - chaîne Le nom de l’application ML à laquelle l’opération appartient. Voir Tracer plusieurs applications pour plus d’informations.
Exemple
Ce qui suit inclut également un exemple d’annotation d’un span. Voir Enrichissement des plages pour plus d’informations.
functiongetRelevantDocs(question){constcontextDocuments=...// user application logic
llmobs.annotate({inputData:question,outputData:contextDocuments.map(doc=>({id:doc.id,score:doc.score,text:doc.text,name:doc.name}))})return}getRelevantDocs=llmobs.wrap({kind:'retrieval'},getRelevantDocs)
Imbrication des spans
Commencer un nouveau span avant que le span actuel ne soit terminé établit automatiquement une relation parent-enfant entre les deux spans. Le span parent représente l’opération globale, tandis que le span enfant représente une sous-opération imbriquée plus petite.
fromddtrace.llmobs.decoratorsimporttask,workflow@workflowdefextract_data(document):preprocess_document(document)...# performs data extraction on the documentreturn@taskdefpreprocess_document(document):...# preprocesses a document for data extractionreturn
functionpreprocessDocument(document){...// preprocesses a document for data extraction
return}preprocessDocument=llmobs.wrap({kind:'task'},preprocessDocument)functionextractData(document){preprocessDocument(document)...// performs data extraction on the document
return}extractData=llmobs.wrap({kind:'workflow'},extractData)
importdatadog.trace.api.llmobs.LLMObs;importdatadog.trace.api.llmobs.LLMObsSpan;publicclassMyJavaClass{publicvoidpreprocessDocument(Stringdocument){LLMObsSpantaskSpan=LLMObs.startTaskSpan("preprocessDocument",null,"session-141");...// preprocess document for data extractiontaskSpan.annotateIO(...);// record the input and outputtaskSpan.finish();}publicStringextractData(Stringdocument){LLMObsSpanworkflowSpan=LLMObs.startWorkflowSpan("extractData",null,"session-141");preprocessDocument(document);...// perform data extraction on the documentworkflowSpan.annotateIO(...);// record the input and outputworkflowSpan.finish();}}
Enriching spans
Le paramètre métriques ici fait référence à des valeurs numériques attachées en tant qu'attributs sur des spans individuels — pas Datadog platform metrics. Pour certaines clés reconnues telles que input_tokens, output_tokens, et total_tokens, Datadog utilise ces attributs de span pour générer des métriques de plateforme correspondantes (comme ml_obs.span.llm.input.tokens) à utiliser dans les tableaux de bord et les moniteurs.
Le SDK fournit la méthode LLMObs.annotate() pour enrichir les spans avec des entrées, des sorties et des métadonnées.
La méthode LLMObs.annotate() accepte les arguments suivants :
Arguments
span
optionnel - Span - par défaut : le span actif actuel Le span à annoter. Si span n’est pas fourni (comme lors de l’utilisation de décorateurs de fonction), le SDK annote le span actif actuel.
input_data
optionnel - type sérialisable en JSON ou liste de dictionnaires Soit un type sérialisable en JSON (pour les spans non-LLM) ou une liste de dictionnaires avec ce format : {"content": "...", "role": "...", "tool_calls": ..., "tool_results": ...}, où "tool_calls" représente une liste optionnelle de dictionnaires d’appels d’outils avec les clés requises : "name", "arguments", et les clés optionnelles : "tool_id", "type", et "tool_results" représentent une liste optionnelle de dictionnaires de résultats d’outils avec la clé requise : "result", et les clés optionnelles : "name", "tool_id", "type" pour les scénarios d’appel de fonction. Remarque : Les embedding spans sont un cas particulier et nécessitent une chaîne ou un dictionnaire (ou une liste de dictionnaires) avec ce format : {"text": "..."}.
output_data
optionnel - type sérialisable en JSON ou liste de dictionnaires Soit un type sérialisable en JSON (pour les spans non-LLM) ou une liste de dictionnaires avec ce format : {"content": "...", "role": "...", "tool_calls": ...}, où "tool_calls" représente une liste optionnelle de dictionnaires d’appels d’outils avec les clés requises : "name", "arguments", et les clés optionnelles : "tool_id", "type" pour les scénarios d’appel de fonction. Remarque : Les retrieval spans sont un cas particulier et nécessitent une chaîne ou un dictionnaire (ou une liste de dictionnaires) avec ce format : {"text": "...", "name": "...", "score": float, "id": "..."}.
tool_definitions
optionnel - liste de dictionnaires Liste de dictionnaires de définition d’outils pour les scénarios d’appel de fonction. Chaque définition d’outil doit avoir une clé "name": "..." requise et des clés optionnelles "description": "..." et "schema": {...}.
metadata
optionnel - dictionnaire Un dictionnaire de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent ajouter comme informations de métadonnées pertinentes à l’opération d’entrée ou de sortie décrite par le span (model_temperature, max_tokens, top_k, etc.).
metrics
optionnel - dictionnaire Un dictionnaire de clés sérialisables en JSON et de valeurs numériques que les utilisateurs peuvent ajouter comme métriques pertinentes à l’opération décrite par le span (input_tokens, output_tokens, total_tokens, time_to_first_token, etc.). L’unité pour time_to_first_token est en secondes, similaire à la métrique duration qui est émise par défaut.
tags
optionnel - dictionnaire Un dictionnaire de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent ajouter comme tags sur le span. Exemples de clés : session, env, system et version. Pour plus d’informations sur les balises, voir Commencer avec les balises.
Exemple
fromddtrace.llmobsimportLLMObsfromddtrace.llmobs.decoratorsimportembedding,llm,retrieval,workflow@llm(model_name="model_name",model_provider="model_provider")defllm_call(prompt):resp=...# llm call hereLLMObs.annotate(span=None,input_data=[{"role":"user","content":"Hello world!"}],output_data=[{"role":"assistant","content":"How can I help?"}],metadata={"temperature":0,"max_tokens":200},metrics={"input_tokens":4,"output_tokens":6,"total_tokens":10},tags={"host":"host_name"},)returnresp@workflowdefextract_data(document):resp=llm_call(document)LLMObs.annotate(input_data=document,output_data=resp,tags={"host":"host_name"},)returnresp@embedding(model_name="text-embedding-3",model_provider="openai")defperform_embedding():...# user application logicLLMObs.annotate(span=None,input_data={"text":"Hello world!"},output_data=[0.0023064255,-0.009327292,...],metrics={"input_tokens":4},tags={"host":"host_name"},)return@retrieval(name="get_relevant_docs")defsimilarity_search():...# user application logicLLMObs.annotate(span=None,input_data="Hello world!",output_data=[{"text":"Hello world is ...","name":"Hello, World! program","id":"document_id","score":0.9893}],tags={"host":"host_name"},)return
Le SDK fournit la méthode llmobs.annotate() pour annoter les spans avec des entrées, des sorties et des métadonnées.
La méthode LLMObs.annotate() accepte les arguments suivants :
Arguments
span
optionnel - Span - default : le span actif actuel Le span à annoter. Si span n’est pas fourni (comme lors de l’utilisation de wrappers de fonction), le SDK annote le span actif actuel.
annotationOptions
requis - objet Un objet de différents types de données pour annoter le span.
L’objet annotationOptions peut contenir les éléments suivants :
inputData
optionnel - type sérialisable en JSON ou liste d’objets Soit un type sérialisable en JSON (pour les portées non-LLM) ou une liste de dictionnaires avec ce format : {role: "...", content: "..."} (pour les portées LLM). Remarque : Les portées d’incorporation sont un cas particulier et nécessitent une chaîne ou un objet (ou une liste d’objets) avec ce format : {text: "..."}.
outputData
optionnel - type sérialisable en JSON ou liste d’objets Soit un type sérialisable en JSON (pour les spans non-LLM) ou une liste d’objets avec ce format : {role: "...", content: "..."} (pour les portées LLM). Remarque : Les spans de récupération sont un cas particulier et nécessitent une chaîne ou un objet (ou une liste d’objets) avec ce format : {text: "...", name: "...", score: number, id: "..."}.
metadata
optionnel - objet Un objet de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent ajouter comme informations de métadonnées pertinentes à l’opération d’entrée ou de sortie décrite par le span (model_temperature, max_tokens, top_k, etc.).
metrics
optionnel - objet Un objet de clés sérialisables en JSON et de valeurs numériques que les utilisateurs peuvent ajouter comme métriques pertinentes à l’opération décrite par le span (input_tokens, output_tokens, total_tokens, etc.).
tags
optionnel - objet Un objet de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent ajouter comme tags concernant le contexte du span (session, environment, system, versioning, etc.). Pour plus d’informations sur les tags, voir Premiers pas avec les tags.
Exemple
functionllmCall(prompt){constcompletion=...// user application logic to invoke LLM
llmobs.annotate({inputData:[{role:"user",content:"Hello world!"}],outputData:[{role:"assistant",content:"How can I help?"}],metadata:{temperature:0,max_tokens:200},metrics:{input_tokens:4,output_tokens:6,total_tokens:10},tags:{host:"host_name"}})returncompletion}llmCall=llmobs.wrap({kind:'llm',modelName:'modelName',modelProvider:'modelProvider'},llmCall)functionextractData(document){constresp=llmCall(document)llmobs.annotate({inputData:document,outputData:resp,tags:{host:"host_name"}})returnresp}extractData=llmobs.wrap({kind:'workflow'},extractData)functionperformEmbedding(){...// user application logic
llmobs.annotate(undefined,{// this can be set to undefined or left out entirely
inputData:{text:"Hello world!"},outputData:[0.0023064255,-0.009327292,...],metrics:{input_tokens:4},tags:{host:"host_name"}})}performEmbedding=llmobs.wrap({kind:'embedding',modelName:'text-embedding-3',modelProvider:'openai'},performEmbedding)functionsimilaritySearch(){...// user application logic
llmobs.annotate(undefined,{inputData:"Hello world!",outputData:[{text:"Hello world is ...",name:"Hello, World! program",id:"document_id",score:0.9893}],tags:{host:"host_name"}})return}similaritySearch=llmobs.wrap({kind:'retrieval',name:'getRelevantDocs'},similaritySearch)
Le SDK fournit plusieurs méthodes pour annoter les spans avec des entrées, des sorties, des métriques et des métadonnées.
Annotationner les entrées et les sorties
Utilisez la méthode membre annotateIO() de l’interface LLMObsSpan pour ajouter des données d’entrée et de sortie structurées à un LLMObsSpan. Cela inclut des arguments optionnels et des objets de message LLM.
Arguments
Si un argument est nul ou vide, rien ne se passe. Par exemple, si inputData est une chaîne non vide tandis que outputData est nul, alors seul inputData est enregistré.
inputData
optionnel - Chaîne ou Liste<LLMObs.LLMMessage> Soit une chaîne (pour des spans non-LLM) ou une liste de LLMObs.LLMMessage pour des spans LLM.
outputData
optionnel - Chaîne ou Liste<LLMObs.LLMMessage> Soit une chaîne (pour des spans non-LLM) ou une liste de LLMObs.LLMMessage pour des spans LLM.
Messages LLM
Les spans LLM doivent être annotés avec des messages LLM en utilisant l’objet LLMObs.LLMMessage.
L’objet LLMObs.LLMMessage peut être instancié en appelant LLMObs.LLMMessage.from() avec les arguments suivants :
role
requis - Chaîne Une chaîne décrivant le rôle de l’auteur du message.
content
requis - Chaîne Une chaîne contenant le contenu du message.
Exemple
importdatadog.trace.api.llmobs.LLMObs;publicclassMyJavaClass{publicStringinvokeChat(StringuserInput){LLMObsSpanllmSpan=LLMObs.startLLMSpan("my-llm-span-name","my-llm-model","my-company","maybe-ml-app-override","session-141");StringsystemMessage="You are a helpful assistant";ResponsechatResponse=...// user application logic to invoke LLMllmSpan.annotateIO(Arrays.asList(LLMObs.LLMMessage.from("user",userInput),LLMObs.LLMMessage.from("system",systemMessage)),Arrays.asList(LLMObs.LLMMessage.from(chatResponse.role,chatResponse.content)));llmSpan.finish();returnchatResponse;}}
Ajout de métriques
Ajout en masse de métriques
La méthode membre setMetrics() de l’interface LLMObsSpan accepte les arguments suivants pour attacher plusieurs métriques en masse :
Arguments
metrics
requis - Map<String, Nombre> Une map de clés sérialisables en JSON et de valeurs numériques que les utilisateurs peuvent ajouter pour enregistrer des métriques pertinentes pour l’opération décrite par le span (par exemple, input_tokens, output_tokens ou total_tokens).
Ajouter une seule métrique
La méthode membre setMetric() de l’interface LLMObsSpan accepte les arguments suivants pour attacher une seule métrique :
Arguments
key
requis - Séquence de caractères Le nom de la métrique.
value
requis - int, long, ou double La valeur de la métrique.
Exemples
importdatadog.trace.api.llmobs.LLMObs;publicclassMyJavaClass{publicStringinvokeChat(StringuserInput){LLMObsSpanllmSpan=LLMObs.startLLMSpan("my-llm-span-name","my-llm-model","my-company","maybe-ml-app-override","session-141");StringchatResponse=...// user application logic to invoke LLMllmSpan.setMetrics(Map.of("input_tokens",617,"output_tokens",338,"time_per_output_token",0.1773));llmSpan.setMetric("total_tokens",955);llmSpan.setMetric("time_to_first_token",0.23);llmSpan.finish();returnchatResponse;}}
La méthode membre setTags() de l’interface LLMObsSpan accepte les arguments suivants pour attacher plusieurs tags en masse :
Arguments
tags
requis - Map<String, Object> Une map de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent ajouter comme tags pour décrire le contexte du span (pour exemple, session, environment, system, ou version).
Ajouter un seul tag
La méthode membre setTag() de l’interface LLMObsSpan accepte les arguments suivants pour attacher un seul tag :
Arguments
key
requis - Chaîne La clé du tag.
value
requis - int, long, double, boolean, ou chaîne La valeur du tag.
Exemples
importdatadog.trace.api.llmobs.LLMObs;publicclassMyJavaClass{publicStringinvokeChat(StringuserInput){LLMObsSpanllmSpan=LLMObs.startLLMSpan("my-llm-span-name","my-llm-model","my-company","maybe-ml-app-override","session-141");StringchatResponse=...// user application logic to invoke LLMllmSpan.setTags(Map.of("chat_source","web","users_in_chat",3));llmSpan.setTag("is_premium_user",true);llmSpan.finish();returnchatResponse;}}
Annotation des erreurs
Ajout d’un Throwable (recommandé)
La méthode membre addThrowable() de l’interface LLMObsSpan accepte l’argument suivant pour attacher un throwable avec une trace de pile :
Arguments
throwable
requis - Throwable Le throwable/l’exception qui s’est produite.
Ajout d’un message d’erreur
La méthode membre setErrorMessage() de l’interface LLMObsSpan accepte l’argument suivant pour attacher une chaîne d’erreur :
Arguments
errorMessage
requis - String Le message de l’erreur.
Définir un indicateur d’erreur
La méthode membre setError() de l’interface LLMObsSpan accepte l’argument suivant pour indiquer une erreur avec l’opération :
Arguments
error
requis - boolean true si le span a généré une erreur.
Exemples
importdatadog.trace.api.llmobs.LLMObs;publicclassMyJavaClass{publicStringinvokeChat(StringuserInput){LLMObsSpanllmSpan=LLMObs.startLLMSpan("my-llm-span-name","my-llm-model","my-company","maybe-ml-app-override","session-141");StringchatResponse="N/A";try{chatResponse=...// user application logic to invoke LLM}catch(Exceptione){llmSpan.addThrowable(e);thrownewRuntimeException(e);}finally{llmSpan.finish();}returnchatResponse;}}
Annotation des métadonnées
La méthode membre setMetadata() de l’interface LLMObsSpan accepte les arguments suivants :
metadata
requis - Map<String, Object> Une map de paires clé-valeur sérialisables en JSON qui contient des métadonnées pertinentes pour l’opération d’entrée ou de sortie décrite par le span.
Exemple
importdatadog.trace.api.llmobs.LLMObs;publicclassMyJavaClass{publicStringinvokeChat(StringuserInput){LLMObsSpanllmSpan=LLMObs.startLLMSpan("my-llm-span-name","my-llm-model","my-company","maybe-ml-app-override","session-141");llmSpan.setMetadata(Map.of("temperature",0.5,"is_premium_member",true,"class","e1"));StringchatResponse=...// user application logic to invoke LLMreturnchatResponse;}}
Annotation des spans auto-instrumentés
La méthode LLMObs.annotation_context() du SDK renvoie un gestionnaire de contexte qui peut être utilisé pour modifier toutes les étendues auto-instrumentées démarrées pendant que le contexte d’annotation est actif.
La méthode LLMObs.annotation_context() accepte les arguments suivants :
Arguments
name
optionnel - str Nom qui remplace le nom du span pour toutes les spans auto-instrumentés qui sont démarrées dans le contexte d’annotation.
prompt
optionnel - dictionnaire Un dictionnaire qui représente l’invite utilisée pour un appel LLM. Voir la documentation de l’objet Prompt pour le schéma complet et les clés prises en charge. Vous pouvez également importer l’objet Prompt depuis ddtrace.llmobs.utils et le passer en tant qu’argument prompt. Remarque : Cet argument ne s’applique qu’aux spans LLM.
tags
optionnel - dictionnaire Un dictionnaire de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent ajouter en tant qu’étiquettes sur le span. Clés d’exemple : session, env, system, et version. Pour plus d’informations sur les étiquettes, voir Démarrage avec les étiquettes.
Exemple
fromddtrace.llmobsimportLLMObsfromddtrace.llmobs.decoratorsimportworkflow@workflowdefrag_workflow(user_question):context_str=retrieve_documents(user_question).join(" ")withLLMObs.annotation_context(prompt=Prompt(id="chatbot_prompt",version="1.0.0",template="Please answer the question using the provided context: {{question}}\n\nContext:\n{{context}}",variables={"question":user_question,"context":context_str,}),tags={"retrieval_strategy":"semantic_similarity"},name="augmented_generation"):completion=openai_client.chat.completions.create(...)returncompletion.choices[0].message.content
Le SDK llmobs.annotationContext() accepte une fonction de rappel qui peut être utilisée pour modifier tous les spans auto-instrumentés démarrés pendant l’exécution de la fonction de rappel.
La méthode llmobs.annotationContext() accepte les options suivantes en premier argument :
Options
name
optionnel - str Nom qui remplace le nom du span pour tous les spans auto-instrumentés démarrés dans le contexte d’annotation.
tags
optionnel - objet Un objet de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent ajouter en tant qu’étiquettes sur le span. Exemples de clés : session, env, system et version. Pour plus d’informations sur les étiquettes, voir Démarrage avec les étiquettes.
Attachez des métadonnées d’invite structurées à la portée du LLM afin de pouvoir reproduire les résultats, auditer les modifications et comparer les performances des invites entre les versions. Lors de l’utilisation de modèles, l’observabilité du LLM fournit également suivi des versions basé sur les modifications de contenu des modèles.
Utilisez LLMObs.annotation_context(prompt=...) pour attacher des métadonnées d’invite avant l’appel au LLM. Pour plus de détails sur l’annotation de span, voir Enrichissement des spans.
Arguments
Arguments
prompt
requis - dictionnaire Un dictionnaire typé qui suit le schéma d’invite ci-dessous.
Structure de l'invite
Clés prises en charge :
id (str) : Identifiant logique pour cette invite. Doit être unique par rapport à ml_app. Par défaut, cela vaut {ml_app}-unnamed_prompt
version (str) : Étiquette de version pour l’invite (par exemple, “1.0.0”). Voir suivi des versions pour plus de détails.
variables (Dict[str, str]): Variables utilisées pour remplir les espaces réservés du modèle.
template (str) : Chaîne de modèle avec des espaces réservés (par exemple, "Traduire {{text}} en {{lang}}").
chat_template (Liste[Message]): Formulaire de modèle multi-message. Fournir une liste de { "role": "<role>", "content": "<template string with placeholders>" } objets.
tags (Dict[str, str]): Étiquettes à attacher à l’exécution de l’invite.
rag_context_variables (Liste[str]): Clés variables contenant le contenu de vérité de base/contexte. Utilisé pour la détection de hallucinations.
rag_query_variables (Liste[str]): Clés variables contenant la requête de l’utilisateur. Utilisé pour la détection de hallucinations.
Exemple : invite à modèle unique
fromddtrace.llmobsimportLLMObsdefanswer_question(text):# Attach prompt metadata to the upcoming LLM span using LLMObs.annotation_context()withLLMObs.annotation_context(prompt={"id":"translation-template","version":"1.0.0","chat_template":[{"role":"user","content":"Translate to {{lang}}: {{text}}"}],"variables":{"lang":"fr","text":text},"tags":{"team":"nlp"}}):# Example provider call (replace with your client)completion=openai_client.chat.completions.create(model="gpt-4o",messages=[{"role":"user","content":f"Translate to fr: {text}"}])returncompletion
Exemple : invite LangChain
Lorsque vous utilisez l’invite de LangChain avec auto-instrumentation, assignez des modèles à des variables avec des noms significatifs. L’auto-instrumentation utilise ces noms pour identifier les invites.
# "translation_template" will be used to identify the template in Datadogtranslation_template=PromptTemplate.from_template("Translate {text} to {language}")chain=translation_template|llm
Utilisez llmobs.annotationContext({ prompt: ... }, () => { ... }) pour attacher des métadonnées d’invite avant l’appel au LLM. Pour plus de détails sur l’annotation de portée, voir Enrichissement des portées.
Arguments
Options
prompt
requis - objet Un objet qui suit le schéma d’invite ci-dessous.
Structure de l'invite
Propriétés prises en charge :
id (chaîne) : Identifiant logique pour cette invite. Doit être unique par rapport à ml_app. Par défaut, cela vaut {ml_app}-unnamed_prompt
version (chaîne) : Étiquette de version pour l’invite (par exemple, “1.0.0”). Voir suivi des versions pour plus de détails.
variables (Record<string, string>) : Variables utilisées pour remplir les espaces réservés du modèle.
template (chaîne | Liste[Message]) : Chaîne de modèle avec espaces réservés (par exemple, "Traduire {{text}} en {{lang}}"). Alternatively, a list of { "rôle": "<role>", "contenu": "<template string with placeholders>" } objets.
tags (Record<string, string>) : Étiquettes à attacher à l’exécution de l’invite.
contextVariables (string[]) : Clés de variables contenant le contenu de vérité de base/contexte. Utilisé pour la détection de hallucinations.
queryVariables (string[]) : Clés de variables contenant la requête de l’utilisateur. Utilisé pour la détection de hallucinations.
Exemple : invite à un seul modèle
const{llmobs}=require('dd-trace');functionanswerQuestion(text){// Attach prompt metadata to the upcoming LLM span using LLMObs.annotation_context()
returnllmobs.annotationContext({prompt:{id:"translation-template",version:"1.0.0",chat_template:[{"role":"user","content":"Translate to {{lang}}: {{text}}"}],variables:{"lang":"fr","text":text},tags:{"team":"nlp"}}},()=>{// Example provider call (replace with your client)
returnopenaiClient.chat.completions.create({model:"gpt-4o",messages:[{"role":"user","content":f"Translate to fr: {text}"}]});});}
Notes
L’annotation d’une invite n’est disponible que sur les spans LLM.
Placez l’annotation immédiatement avant l’appel du fournisseur afin qu’elle s’applique au bon span LLM.
Utilisez une invite unique id pour distinguer différentes invites au sein de votre application.
Gardez les modèles statiques en utilisant la syntaxe des espaces réservés (comme {{nom_variable}}) and define dynamic content in the section des variables.
Pour plusieurs appels LLM auto-instrumentés dans un bloc, utilisez un contexte d’annotation pour appliquer les mêmes métadonnées d’invite à travers les appels. Voir Annotation des intervalles auto-instrumentés.
Suivi des versions
L’observabilité LLM fournit un versionnage automatique pour vos invites lorsque aucune version explicite n’est spécifiée. Lorsque vous fournissez un template ou chat_template dans vos métadonnées d’invite sans une étiquette version, le système génère automatiquement une version en calculant un hachage du contenu du modèle. Si vous fournissez une étiquette version, l’observabilité LLM utilise votre étiquette de version spécifiée au lieu d’en générer une automatiquement.
Le système de versionnage fonctionne comme suit :
Versionnage automatique : Lorsque aucune étiquette version n’est fournie, l’observabilité LLM calcule un hachage du contenu template ou chat_template pour générer automatiquement un identifiant de version numérique.
Versionnage manuel : Lorsqu’un version tag est fourni, LLM Observability utilise votre étiquette de version spécifiée exactement comme fournie
Historique des versions : Les versions générées automatiquement et manuellement sont conservées dans l’historique des versions pour suivre l’évolution des prompts au fil du temps
Cela vous donne la flexibilité de vous fier soit à la gestion automatique des versions basée sur les changements de contenu du modèle, soit de maintenir un contrôle total sur le versionnage avec vos propres étiquettes de version.
Surveillance des coûts
Attachez des métriques de jetons (pour le suivi automatique des coûts) ou des métriques de coûts (pour le suivi manuel des coûts) à vos plages LLM/embedding. Les métriques de tokens permettent à Datadog de calculer les coûts en utilisant les prix du fournisseur, tandis que les métriques de coûts vous permettent de fournir vos propres prix lors de l’utilisation de modèles personnalisés ou non pris en charge. Pour plus de détails, voir Coûts.
Si vous utilisez une instrumentation automatique, les métriques de tokens et de coûts apparaissent automatiquement sur vos spans. Si vous instrumentez manuellement, suivez les instructions ci-dessous.
Dans ce contexte, "métriques de tokens" et "métriques de coûts" se réfèrent à des paires clé-valeur numériques que vous attachez aux intervalles via le paramètre metrics de la méthode LLMObs.annotate(). Celles-ci sont distinctes des métriques LLM Observability de la plateforme Datadog. Pour les clés reconnues telles que input_tokens, output_tokens, input_cost, et output_cost, Datadog utilise ces attributs de span pour générer des métriques de plateforme correspondantes (telles que ml_obs.span.llm.input.cost) à utiliser dans les tableaux de bord et les moniteurs.
Cas d’utilisation : Utilisation d’un fournisseur de modèle commun
Datadog prend en charge des fournisseurs de modèles communs tels qu’OpenAI, Azure OpenAI, Anthropic et Google Gemini. Lorsque vous utilisez ces fournisseurs, vous devez simplement annoter votre demande LLM avec model_name, model_provider, et l’utilisation des tokens. Datadog calcule automatiquement le coût estimé en fonction des prix du fournisseur.
Le SDK LLM Observability fournit des méthodes pour exporter et soumettre vos évaluations à Datadog.
Pour créer des évaluateurs réutilisables basés sur des classes (BaseEvaluator, BaseSummaryEvaluator) avec des métadonnées de résultats riches, consultez le Guide du développeur d'évaluation.
Les évaluations doivent être regroupées en un seul span. Vous pouvez identifier le span cible en utilisant l’une de ces deux méthodes :
Regroupement basé sur des étiquettes - Regroupez une évaluation en utilisant une paire de balises clé-valeur unique qui est définie sur un seul span. L’évaluation échouera à se regrouper si la paire de balises clé-valeur correspond à plusieurs spans ou à aucun span.
Référence directe au span - Regroupez une évaluation en utilisant la combinaison de l’ID de trace unique du span et de l’ID du span.
Exporter un span
LLMObs.export_span() peut être utilisé pour extraire le contexte du span à partir d’un span. Cette méthode est utile pour associer votre évaluation au span correspondant.
Arguments
La méthode LLMObs.export_span() accepte l’argument suivant :
span
optionnel - Span Le span à partir duquel extraire le contexte du span (IDs de span et de trace). Si non fourni (comme lors de l’utilisation de décorateurs de fonctions), le SDK exporte le span actif.
Exemple
fromddtrace.llmobsimportLLMObsfromddtrace.llmobs.decoratorsimportllm@llm(model_name="claude",name="invoke_llm",model_provider="anthropic")defllm_call():completion=...# user application logic to invoke LLMspan_context=LLMObs.export_span(span=None)returncompletion
llmobs.exportSpan() peut être utilisé pour extraire le contexte du span à partir d’un span. Vous devrez utiliser cette méthode pour associer votre évaluation au span correspondant.
Arguments
La méthode llmobs.exportSpan() accepte l’argument suivant :
span
optionnel - Span Le span à partir duquel extraire le contexte du span (IDs de span et de trace). Si non fourni (comme lors de l’utilisation de wrappers de fonctions), le SDK exporte le span actif.
Exemple
functionllmCall(){constcompletion=...// user application logic to invoke LLM
constspanContext=llmobs.exportSpan()returncompletion}llmCall=llmobs.wrap({kind:'llm',name:'invokeLLM',modelName:'claude',modelProvider:'anthropic'},llmCall)
Soumettre des évaluations
LLMObs.submit_evaluation() peut être utilisé pour soumettre votre évaluation personnalisée associée à un span donné.
LLMObs.submit_evaluation_for est obsolète et sera supprimé dans la prochaine version majeure de ddtrace (4.0). Pour migrer, renommez vos appels LLMObs.submit_evaluation_for avec LLMObs.submit_evaluation.
Remarque : Les évaluations personnalisées sont des évaluateurs que vous implémentez et hébergez vous-même. Celles-ci diffèrent des évaluations prêtes à l’emploi, qui sont automatiquement calculées par Datadog à l’aide d’évaluateurs intégrés. Pour configurer des évaluations prêtes à l’emploi pour votre application, utilisez la page Observabilité LLM > Paramètres > Évaluations dans Datadog.
La méthode LLMObs.submit_evaluation() accepte les arguments suivants :
Arguments
label
requis - chaîne Le nom de l’évaluation.
metric_type
requis - chaîne Le type de l’évaluation. Doit être categorical, score, boolean ou json.
value
requis - chaîne, type numérique ou dict La valeur de l’évaluation. Doit être une chaîne (metric_type==categorical), un entier/float (metric_type==score), un booléen (metric_type==boolean) ou un dict (metric_type==json).
span
optionnel - dictionnaire Un dictionnaire qui identifie de manière unique le span associé à cette évaluation. Doit contenir span_id (chaîne) et trace_id (chaîne). Utilisez LLMObs.export_span() pour générer ce dictionnaire.
span_with_tag_value
optionnel - dictionnaire Un dictionnaire qui identifie de manière unique la portée associée à cette évaluation. Doit contenir tag_key (chaîne) et tag_value (chaîne).
Remarque : Exactement l’un de span ou span_with_tag_value est requis. Fournir les deux, ou aucun, soulève une ValueError.
ml_app
requis - chaîne Le nom de l’application ML.
timestamp_ms
optionnel - entier L’horodatage unix en millisecondes lorsque le résultat de la métrique d’évaluation a été généré. S’il n’est pas fourni, la valeur par défaut est l’heure actuelle.
tags
optionnel - dictionnaire Un dictionnaire de paires clé-valeur de chaînes que les utilisateurs peuvent ajouter comme tags concernant l’évaluation. Pour plus d’informations sur les tags, voir Getting Started with Tags.
assessment
optionnel - chaîne Une appréciation de cette évaluation. Les valeurs acceptées sont pass et fail.
reasoning
optionnel - chaîne Une explication textuelle du résultat de l’évaluation.
metadata
optionnel - dictionnaire Un dictionnaire contenant des métadonnées structurées arbitraires associées au résultat de l’évaluation.
Exemple
fromddtrace.llmobsimportLLMObsfromddtrace.llmobs.decoratorsimportllm@llm(model_name="claude",name="invoke_llm",model_provider="anthropic")defllm_call():completion=...# user application logic to invoke LLM# joining an evaluation to a span via a tag key-value pairmsg_id=get_msg_id()LLMObs.annotate(tags={'msg_id':msg_id})LLMObs.submit_evaluation(span_with_tag_value={"tag_key":"msg_id","tag_value":msg_id},ml_app="chatbot",label="harmfulness",metric_type="score",value=10,tags={"evaluation_provider":"ragas"},assessment="fail",reasoning="Malicious intent was detected in the user instructions.",metadata={"details":["jailbreak","SQL injection"]})# joining an evaluation to a span via span ID and trace IDspan_context=LLMObs.export_span(span=None)LLMObs.submit_evaluation(span_context=span_context,ml_app="chatbot",label="harmfulness",metric_type="score",value=10,tags={"evaluation_provider":"ragas"},assessment="fail",reasoning="Malicious intent was detected in the user instructions.",metadata={"details":["jailbreak","SQL injection"]})returncompletion
llmobs.submitEvaluation() peut être utilisé pour soumettre votre évaluation personnalisée associée à une portée donnée.
La méthode llmobs.submitEvaluation() accepte les arguments suivants :
Arguments
span_context
requis - dictionnaire Le contexte de la portée à associer à l’évaluation. Ceci devrait être la sortie de LLMObs.export_span().
evaluationOptions
requis - objet Un objet des données d’évaluation.
L’objet evaluationOptions peut contenir les éléments suivants :
label
requis - chaîne Le nom de l’évaluation.
metricType
requis - chaîne Le type de l’évaluation. Doit être l’un des suivants : “catégorique”, “score”, “booléen” ou “json”.
value
requis - string ou numeric La valeur de l’évaluation. Doit être une chaîne (pour “categorical” metric_type), un nombre (pour “score” metric_type), un booléen (pour “boolean” metric_type), ou un objet JSON (pour “json” metric_type).
tags
optionnel - dictionnaire Un dictionnaire de paires clé-valeur de chaînes que les utilisateurs peuvent ajouter comme tags concernant l’évaluation. Pour plus d’informations sur les tags, voir Getting Started with Tags.
assessment
optionnel - chaîne Une appréciation de cette évaluation. Les valeurs acceptées sont pass et fail.
reasoning
optionnel - chaîne Une explication textuelle du résultat de l’évaluation.
metadata
optionnel - dictionnaire Un objet JSON contenant des métadonnées structurées arbitraires associées au résultat de l’évaluation.
Exemple
functionllmCall(){constcompletion=...// user application logic to invoke LLM
constspanContext=llmobs.exportSpan()llmobs.submitEvaluation(spanContext,{label:"harmfulness",metricType:"score",value:10,tags:{evaluationProvider:"ragas"}})returncompletion}llmCall=llmobs.wrap({kind:'llm',name:'invokeLLM',modelName:'claude',modelProvider:'anthropic'},llmCall)
Utilisez LLMObs.SubmitEvaluation() pour soumettre votre évaluation personnalisée associée à une portée donnée.
La méthode LLMObs.SubmitEvaluation() accepte les arguments suivants :
Arguments
llmObsSpan
requis - LLMObsSpan Le contexte de la portée à associer à l’évaluation.
label
requis - string Le nom de l’évaluation.
categoricalValue ou scoreValue
requis - string ou double La valeur de l’évaluation. Doit être une string (pour les évaluations “categorical”) ou un double (pour les évaluations “score”).
tags
optionnel - Map<String, Object> Un dictionnaire de paires clé-valeur de chaînes utilisé pour ajouter des tags à l’évaluation. Pour plus d’informations sur les tags, voir Getting Started with Tags.
Exemple
importdatadog.trace.api.llmobs.LLMObs;publicclassMyJavaClass{publicStringinvokeChat(StringuserInput){LLMObsSpanllmSpan=LLMObs.startLLMSpan("my-llm-span-name","my-llm-model","my-company","maybe-ml-app-override","session-141");StringchatResponse="N/A";try{chatResponse=...// user application logic to invoke LLM}catch(Exceptione){llmSpan.addThrowable(e);thrownewRuntimeException(e);}finally{llmSpan.finish();// submit evaluationsLLMObs.SubmitEvaluation(llmSpan,"toxicity","toxic",Map.of("language","english"));LLMObs.SubmitEvaluation(llmSpan,"f1-similarity",0.02,Map.of("provider","f1-calculator"));}returnchatResponse;}}
Traitement des portées
Pour modifier les données d’entrée et de sortie sur les portées, vous pouvez configurer une fonction de traitement. La fonction du processeur a accès aux balises de portée pour permettre la modification conditionnelle des entrées/sorties. Les fonctions de processeur peuvent soit renvoyer la portée modifiée pour l’émettre, soit renvoyer None/null pour empêcher la portée d’être entièrement émise. Ceci est utile pour filtrer les portées contenant des données sensibles ou répondant à certains critères.
Exemple
fromddtrace.llmobsimportLLMObsfromddtrace.llmobsimportLLMObsSpandefredact_processor(span:LLMObsSpan)->LLMObsSpan:ifspan.get_tag("no_output")=="true":formessageinspan.output:message["content"]=""returnspan# If using LLMObs.enable()LLMObs.enable(...span_processor=redact_processor,)# else when using `ddtrace-run`LLMObs.register_processor(redact_processor)withLLMObs.llm("invoke_llm_with_no_output"):LLMObs.annotate(tags={"no_output":"true"})
Exemple : modification conditionnelle avec auto-instrumentation
Lors de l’utilisation de l’auto-instrumentation, la portée n’est pas toujours accessible contextuellement. Pour modifier conditionnellement les entrées et sorties sur les portées auto-instrumentées, annotation_context() peut être utilisé en plus d’un processeur de portée.
fromddtrace.llmobsimportLLMObsfromddtrace.llmobsimportLLMObsSpandefredact_processor(span:LLMObsSpan)->LLMObsSpan:ifspan.get_tag("no_input")=="true":formessageinspan.input:message["content"]=""returnspanLLMObs.register_processor(redact_processor)defcall_openai():withLLMObs.annotation_context(tags={"no_input":"true"}):# make call to openai...
Exemple : empêcher les portées d’être émises
fromddtrace.llmobsimportLLMObsfromddtrace.llmobsimportLLMObsSpanfromtypingimportOptionaldeffilter_processor(span:LLMObsSpan)->Optional[LLMObsSpan]:# Skip spans that are marked as internal or contain sensitive dataifspan.get_tag("internal")=="true"orspan.get_tag("sensitive")=="true":returnNone# This span will not be emitted# Process and return the span normallyreturnspanLLMObs.register_processor(filter_processor)# This span will be filtered out and not sent to DatadogwithLLMObs.workflow("internal_workflow"):LLMObs.annotate(tags={"internal":"true"})# ... workflow logic
Exemple : modification conditionnelle avec auto-instrumentation
Lors de l’utilisation de l’auto-instrumentation, la portée n’est pas toujours accessible contextuellement. Pour modifier conditionnellement les entrées et sorties sur les portées auto-instrumentées, llmobs.annotationContext() peut être utilisé en plus d’un processeur de portée.
const{llmobs}=require('dd-trace');functionredactProcessor(span){if(span.getTag("no_input")=="true"){for(constmessageofspan.input){message.content="";}}returnspan;}llmobs.registerProcessor(redactProcessor);asyncfunctioncallOpenai(){awaitllmobs.annotationContext({tags:{no_input:"true"}},async()=>{// make call to openai
});}
Exemple : empêcher les portées d’être émises
consttracer=require('dd-trace').init({llmobs:{mlApp:"<YOUR_ML_APP_NAME>"}})constllmobs=tracer.llmobsfunctionfilterProcessor(span){// Skip spans that are marked as internal or contain sensitive data
if(span.getTag("internal")==="true"||span.getTag("sensitive")==="true"){returnnull// This span will not be emitted
}// Process and return the span normally
returnspan}llmobs.registerProcessor(filterProcessor)// This span will be filtered out and not sent to Datadog
functioninternalWorkflow(){returnllmobs.trace({kind:'workflow',name:'internalWorkflow'},(span)=>{llmobs.annotate({tags:{internal:"true"}})// ... workflow logic
})}
Suivi des sessions utilisateur
Le suivi des sessions permet d’associer plusieurs interactions à un utilisateur donné.
Lors du démarrage d’une portée racine pour une nouvelle trace ou une portée dans un nouveau processus, spécifiez l’argument session_id avec l’ID de chaîne de la session utilisateur sous-jacente, qui est soumis comme un tag sur la portée. En option, vous pouvez également spécifier les tags user_handle, user_name et user_id.
L’ID représentant une seule session utilisateur, par exemple, une session de chat.
user_handle
Le pseudonyme de l’utilisateur de la session de chat.
user_name
Le nom de l’utilisateur de la session de chat.
user_id
L’ID de l’utilisateur de la session de chat.
Lors du démarrage d’une portée racine pour une nouvelle trace ou une portée dans un nouveau processus, spécifiez l’argument sessionId avec l’ID de chaîne de la session utilisateur sous-jacente :
Lors du démarrage d’une portée racine pour une nouvelle trace ou une portée dans un nouveau processus, spécifiez l’argument sessionId avec l’ID de chaîne de la session utilisateur sous-jacente :
importdatadog.trace.api.llmobs.LLMObs;publicclassMyJavaClass{publicStringprocessChat(intuserID){LLMObsSpanworkflowSpan=LLMObs.startWorkflowSpan("incoming-chat",null,"session-"+System.currentTimeMillis()+"-"+userID);StringchatResponse=answerChat();// user application logicworkflowSpan.annotateIO(...);// record the input and outputworkflowSpan.finish();returnchatResponse;}}
Traçage distribué
Le SDK prend en charge le traçage à travers des services ou des hôtes distribués. Le traçage distribué fonctionne en propageant les informations de portée à travers les requêtes web.
La bibliothèque ddtrace fournit certaines intégrations prêtes à l’emploi qui prennent en charge le traçage distribué pour des frameworks web et des bibliothèques HTTP populaires. Si votre application effectue des requêtes en utilisant ces bibliothèques prises en charge, vous pouvez activer le traçage distribué en exécutant :
Si votre application n’utilise aucune de ces bibliothèques prises en charge, vous pouvez activer le traçage distribué en propageant manuellement les informations de portée vers et depuis les en-têtes HTTP. Le SDK fournit les méthodes d’aide LLMObs.inject_distributed_headers() et LLMObs.activate_distributed_headers() pour injecter et activer les contextes de traçage dans les en-têtes de requête.
Injection des en-têtes distribués
La méthode LLMObs.inject_distributed_headers() prend une portée et injecte son contexte dans les en-têtes HTTP à inclure dans la requête. Cette méthode accepte les arguments suivants :
request_headers
requis - dictionnaire Les en-têtes HTTP à étendre avec les attributs de contexte de traçage.
span
optionnel - Span - default : The current active span. La portée dont le contexte doit être injecté dans les en-têtes de requête fournis. Toute portée (y compris celles avec des décorateurs de fonction), cela utilise par défaut la portée active actuelle.
Activation des en-têtes distribués
La méthode LLMObs.activate_distributed_headers() prend des en-têtes HTTP et extrait les attributs de contexte de traçage à activer dans le nouveau service.
Remarque : Vous devez appeler LLMObs.activate_distributed_headers() avant de commencer toute portée dans votre service en aval. Les portées commencées auparavant (y compris les portées de décorateurs de fonction) ne sont pas capturées dans le traçage distribué.
Cette méthode accepte l’argument suivant :
request_headers
requis - dictionnaire Les en-têtes HTTP pour extraire les attributs de contexte de traçage.
fromddtrace.llmobsimportLLMObsdefserver_process_request(request):LLMObs.activate_distributed_headers(request.headers)withLLMObs.task(name="process_request")asspan:pass# arbitrary server work
La bibliothèque dd-trace fournit des intégrations prêtes à l’emploi qui prennent en charge le traçage distribué pour les frameworks web populaires. L’activation du traceur active automatiquement ces intégrations, mais vous pouvez, de manière optionnelle, les désactiver avec :
consttracer=require('dd-trace').init({llmobs:{...},})tracer.use('http',false)// disable the http integration
Traçage avancé
Traçage des portées en utilisant des méthodes en ligne
Pour chaque type de portée, la classe ddtrace.llmobs.LLMObs fournit une méthode en ligne correspondante pour tracer automatiquement l’opération qu’implique un bloc de code donné. Ces méthodes ont la même signature d’argument que leurs homologues de décorateur de fonction, avec l’ajout que name prend par défaut la valeur du type de portée (llm, workflow, etc.) s’il n’est pas fourni. Ces méthodes peuvent être utilisées comme gestionnaires de contexte pour terminer automatiquement la portée après l’exécution du bloc de code inclus.
Exemple
fromddtrace.llmobsimportLLMObsdefprocess_message():withLLMObs.workflow(name="process_message",session_id="<SESSION_ID>",ml_app="<ML_APP>")asworkflow_span:...# user application logicreturn
Conserver une portée à travers les contextes
Pour démarrer et arrêter manuellement une portée dans différents contextes ou scopes :
Démarrez une portée manuellement en utilisant les mêmes méthodes (par exemple, la méthode LLMObs.workflow pour une portée de workflow), mais en appelant directement la fonction plutôt qu’en utilisant un gestionnaire de contexte.
Passez l’objet de portée comme argument à d’autres fonctions.
Arrêtez la portée manuellement avec la méthode span.finish(). Remarque : la portée doit être finalisée manuellement, sinon elle n’est pas soumise.
Exemple
fromddtrace.llmobsimportLLMObsdefprocess_message():workflow_span=LLMObs.workflow(name="process_message")...# user application logicseparate_task(workflow_span)returndefseparate_task(workflow_span):...# user application logicworkflow_span.finish()return
Forcer le vidage dans des environnements sans serveur
LLMObs.flush() est une fonction bloquante qui soumet toutes les données mises en mémoire tampon de LLM Observability au backend Datadog. Cela peut être utile dans des environnements sans serveur pour empêcher une application de se fermer tant que toutes les traces de LLM Observability ne sont pas soumises.
Traçage de plusieurs applications
Le SDK prend en charge le traçage de plusieurs applications LLM à partir du même service.
Vous pouvez configurer une variable d’environnement DD_LLMOBS_ML_APP au nom de votre application LLM, dans laquelle toutes les portées générées sont regroupées par défaut.
Pour remplacer cette configuration et utiliser un nom d’application LLM différent pour une portée racine donnée, passez l’argument ml_app avec la chaîne de caractères correspondant au nom de l’application LLM sous-jacente lors du démarrage d’une portée racine pour un nouveau traçage ou une portée dans un nouveau processus.
fromddtrace.llmobs.decoratorsimportworkflow@workflow(name="process_message",ml_app="<NON_DEFAULT_ML_APP_NAME>")defprocess_message():...# user application logicreturn
Traçage des portées en utilisant des méthodes en ligne
Le llmobs SDK fournit une méthode en ligne correspondante pour tracer automatiquement l’opération qu’implique un bloc de code donné. Ces méthodes possèdent la même signature d’arguments que leurs homologues en tant que fonctions wrapper, à la différence que name est obligatoire, car le nom ne peut pas être déduit d’un callback anonyme. Cette méthode terminera la portée dans les conditions suivantes :
Si la fonction retourne une promesse, alors la portée se termine lorsque la promesse est résolue ou rejetée.
Si la fonction prend un rappel comme dernier paramètre, alors la portée se termine lorsque ce rappel est appelé.
Si la fonction n’accepte pas de rappel et ne retourne pas de promesse, alors la portée se termine à la fin de l’exécution de la fonction.
Exemple sans rappel
functionprocessMessage(){returnllmobs.trace({kind:'workflow',name:'processMessage',sessionId:'<SESSION_ID>',mlApp:'<ML_APP>'},workflowSpan=>{...// user application logic
return})}
Exemple avec un rappel
functionprocessMessage(){returnllmobs.trace({kind:'workflow',name:'processMessage',sessionId:'<SESSION_ID>',mlApp:'<ML_APP>'},(workflowSpan,cb)=>{...// user application logic
letmaybeError=...cb(maybeError)// the span will finish here, and tag the error if it is not null or undefined
return})}
Le type de retour de cette fonction correspond au type de retour de la fonction tracée :
functionprocessMessage(){constresult=llmobs.trace({kind:'workflow',name:'processMessage',sessionId:'<SESSION_ID>',mlApp:'<ML_APP>'},workflowSpan=>{...// user application logic
return'hello world'})console.log(result)// 'hello world'
returnresult}
Décorateurs de fonction en TypeScript
Le SDK LLM Observability de Node.js propose une llmobs.decorate fonction qui sert de décorateur de fonction pour les applications TypeScript. Le comportement de traçage de cette fonction est identique à celui de llmobs.wrap.
Exemple
// index.ts
importtracerfrom'dd-trace';tracer.init({llmobs:{mlApp:"<YOUR_ML_APP_NAME>",},});const{llmobs}=tracer;classMyAgent{@llmobs.decorate({kind:'agent'})asyncrunChain(){...// user application logic
return}}
Forcer le vidage dans des environnements sans serveur
llmobs.flush() est une fonction bloquante qui soumet toutes les données mises en mémoire tampon de LLM Observability au backend Datadog. Cela peut être utile dans des environnements sans serveur pour empêcher une application de se fermer tant que toutes les traces de LLM Observability ne sont pas soumises.
Traçage de plusieurs applications
Le SDK prend en charge le traçage de plusieurs applications LLM à partir du même service.
Vous pouvez configurer une variable d’environnement DD_LLMOBS_ML_APP au nom de votre application LLM, dans laquelle toutes les portées générées sont regroupées par défaut.
Pour remplacer cette configuration et utiliser un nom d’application LLM différent pour une portée racine donnée, passez l’argument mlApp avec la chaîne de caractères correspondant au nom de l’application LLM sous-jacente lors du démarrage d’une portée racine pour un nouveau traçage ou une portée dans un nouveau processus.
functionprocessMessage(){...// user application logic
return}processMessage=llmobs.wrap({kind:'workflow',name:'processMessage',mlApp:'<NON_DEFAULT_ML_APP_NAME>'},processMessage)
Directives de nommage des applications
Le nom de votre application (la valeur de DD_LLMOBS_ML_APP) doit suivre ces directives :
Doit être une chaîne Unicode en minuscules
Peut comporter jusqu’à 193 caractères
Ne peut pas contenir de traits de soulignement contigus ou en fin de chaîne
Peut contenir les caractères suivants :
Alphanumériques
Traits de soulignement
Tirets
Deux-points
Points
Barres
Lectures complémentaires
Documentation, liens et articles supplémentaires utiles: