Référence du SDK Agent Observability.

Ce produit n'est pas pris en charge par le site Datadog que vous avez sélectionné. ().

Présentation

Les SDK Agent Observability fournissent une instrumentation automatique ainsi que des API d’instrumentation manuelle pour offrir de l’observabilité et des insights sur vos applications LLM.

Configuration

Prérequis

  • Le dernier package ddtrace est installé (Python 3.7+ requis) :
    pip install ddtrace
    
  • Le dernier package dd-trace est installé (Node.js 16+ requis) :
    npm install dd-trace
    
  • Vous avez téléchargé le dernier dd-trace-java JAR. Le SDK Agent Observability est pris en charge dans dd-trace-java v1.51.0+ (Java 8+ requis).

Activez Agent Observability en exécutant votre application avec la commande ddtrace-run et en spécifiant les variables d’environnement requises.

Remarque: ddtrace-run active automatiquement toutes les intégrations Agent Observability.

DD_SITE=<YOUR_DATADOG_SITE> DD_API_KEY=<YOUR_API_KEY> DD_LLMOBS_ENABLED=1 \
DD_LLMOBS_ML_APP=<YOUR_ML_APP_NAME> ddtrace-run <YOUR_APP_STARTUP_COMMAND>

Variables d’environnement pour la configuration en ligne de commande

DD_SITE
requis - chaîne
Site Datadog de destination pour la soumission de données LLM. Votre site est .
DD_LLMOBS_ENABLED
requis - entier ou chaîne
Basculez pour activer la soumission de données à Agent Observability. Doit être défini sur 1 ou true.
DD_LLMOBS_ML_APP
optionnel - chaîne
Le nom de votre application, service ou projet LLM, sous lequel toutes les traces et tous les spans sont regroupés. Cela permet de distinguer les différentes applications ou expériences. Consultez les directives de nommage des applications pour connaître les caractères autorisés et les autres contraintes. Pour remplacer cette valeur pour un span racine donné, consultez Tracer plusieurs applications. Si elle n’est pas fournie, cette valeur prend par défaut celle de DD_SERVICE, ou la valeur d’un DD_LLMOBS_ML_APP propagé depuis un service en amont.
Remarque: Avant la version ddtrace==3.14.0, il s’agit d’un champ obligatoire.
DD_LLMOBS_AGENTLESS_ENABLED
facultatif - entier ou chaîne - par défaut: false
Requis uniquement si vous n’utilisez pas le Datadog Agent, auquel cas cela doit être défini sur 1 ou true.
DD_LLMOBS_SAMPLE_RATE
facultatif - nombre à virgule flottante - par défaut : 1.0
La fraction de traces conservée par Agent Observability. Voir Échantillonnage de traces.
DD_API_KEY
optionnel - _ chaîne_
Votre clé d’API Datadog. Requis uniquement si vous n’utilisez pas le Datadog Agent.
DD_MCP_CAPTURE_INTENT
facultatif - entier ou chaîne - par défaut : false
Lorsqu’il est défini sur 1 ou true, ajoute un argument à chaque outil de serveur MCP demandant au modèle appelant de décrire pourquoi il a choisi d’appeler l’outil. L’intention est enregistrée sur le span de l’outil.

Activez Agent 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.

DD_SITE=<YOUR_DATADOG_SITE> DD_API_KEY=<YOUR_API_KEY> DD_LLMOBS_ENABLED=1 \
DD_LLMOBS_ML_APP=<YOUR_ML_APP_NAME> NODE_OPTIONS="--import dd-trace/initialize.mjs" node <YOUR_APP_ENTRYPOINT>

Variables d’environnement pour la configuration en ligne de commande

DD_SITE
requis - chaîne
Le site Datadog vers lequel soumettre vos données LLM. Votre site est .
DD_LLMOBS_ENABLED
requis - entier ou chaîne
Basculez pour activer la soumission de données à Agent Observability. Doit être défini sur 1 ou true.
DD_LLMOBS_ML_APP
optionnel - chaîne
Le nom de votre application, service ou projet LLM, sous lequel toutes les traces et tous les spans sont regroupés. Cela permet de distinguer les différentes applications ou expériences. Consultez les directives de nommage des applications pour connaître les caractères autorisés et les autres contraintes. Pour remplacer cette valeur pour un span racine donné, consultez Tracer plusieurs applications. Si elle n’est pas fournie, cette valeur prend par défaut celle de DD_SERVICE, ou la valeur d’un DD_LLMOBS_ML_APP propagé depuis un service en amont.
Remarque: Avant la version dd-trace@5.66.0, il s’agit d’un champ obligatoire.
DD_LLMOBS_AGENTLESS_ENABLED
facultatif - entier ou chaîne - par défaut: false
Requis uniquement si vous n’utilisez pas le Datadog Agent, auquel cas cela doit être défini sur 1 ou true.
DD_LLMOBS_SAMPLE_RATE
facultatif - nombre à virgule flottante - par défaut : 1.0
La fraction de traces conservée par Agent Observability. Voir Échantillonnage de traces.
DD_API_KEY
optionnel - _ chaîne_
Votre clé d’API Datadog. Requis uniquement si vous n’utilisez pas le Datadog Agent.

Activez Agent Observability en exécutant votre application avec dd-trace-java et en spécifiant les paramètres requis sous forme de variables d’environnement ou de propriétés système.

DD_SITE=<YOUR_DATADOG_SITE> DD_API_KEY=<YOUR_API_KEY> \
java -javaagent:path/to/your/dd-trace-java-jar/dd-java-agent-SNAPSHOT.jar \
-Ddd.service=my-app -Ddd.llmobs.enabled=true -Ddd.llmobs.ml.app=my-ml-app -jar path/to/your/app.jar

Variables d’environnement et propriétés système

Vous pouvez fournir les paramètres suivants sous forme de variables d’environnement (par exemple, DD_LLMOBS_ENABLED) ou de 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 de données LLM. Votre site est .
DD_LLMOBS_ENABLED ou dd.llmobs.enabled
requis - entier ou chaîne
Basculez pour activer la soumission de données à Agent Observability. 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, service ou projet LLM, sous lequel toutes les traces et tous les spans sont regroupés. Cela permet de distinguer les différentes applications ou expériences. Consultez les directives de nommage des applications pour connaître les caractères autorisés et les autres contraintes. Pour remplacer cette valeur pour un span racine donné, consultez Tracer plusieurs applications. Si elle n’est pas fournie, cette valeur prend par défaut celle de DD_SERVICE, ou la valeur d’un DD_LLMOBS_ML_APP propagé depuis un service en amont.
Remarque: Avant la version 1.54.0 de dd-trace-java, il s’agit d’un champ obligatoire.
DD_LLMOBS_AGENTLESS_ENABLED ou dd.llmobs.agentless.enabled
facultatif - entier ou chaîne de caractères - par défaut : false
Requis uniquement si vous n’utilisez pas le Datadog Agent, auquel cas cela doit être défini sur 1 ou true.
DD_API_KEY ou dd.api.key
optionnel - _ chaîne_
Votre clé d’API Datadog. Requis uniquement si vous n’utilisez pas le Datadog Agent.

Au lieu d’utiliser la configuration en ligne de commande , vous pouvez également activer Agent Observability par programmation.

Utilisez la fonction LLMObs.enable() pour activer Agent Observability.

N'utilisez pas cette méthode de configuration avec la commande. ddtrace-run N'utilisez pas cette méthode de configuration avec la commande.
from ddtrace.llmobs import LLMObs
LLMObs.enable(
  ml_app="<YOUR_ML_APP_NAME>",
  api_key="<YOUR_DATADOG_API_KEY>",
  site="<YOUR_DATADOG_SITE>",
  agentless_enabled=True,
)
Paramètres
ml_app
optionnel - chaîne
Le nom de votre application, service ou projet LLM, sous lequel toutes les traces et tous les spans sont regroupés. Cela permet de distinguer les différentes applications ou expériences. Consultez les directives de nommage des applications pour connaître les caractères autorisés et les autres contraintes. Pour remplacer cette valeur pour une trace donnée, consultez Tracer plusieurs applications. Si aucune valeur n’est fournie, la valeur par défaut est DD_LLMOBS_ML_APP.
integrations_enabled - par défaut: true
optionnel - booléen
Un indicateur pour activer automatiquement le traçage des appels LLM pour les intégrations LLM prises en charge par Datadog. Si aucune valeur n’est fournie, toutes les intégrations LLM prises en charge 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
Requis uniquement si vous n’utilisez pas le Datadog Agent, auquel cas cela doit être défini sur True. Ceci configure la bibliothèque ddtrace pour ne pas envoyer de données nécessitant le Datadog Agent. S’il n’est pas fourni, la valeur par défaut est celle de DD_LLMOBS_AGENTLESS_ENABLED.
site
optionnel - _ chaîne_
Le site Datadog vers lequel soumettre vos données LLM. Votre site est . S’il n’est pas fourni, la valeur par défaut est celle de DD_SITE.
api_key
optionnel - chaîne
Votre clé d’API Datadog. Requis uniquement si vous n’utilisez pas le Datadog Agent. S’il n’est pas 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). S’il n’est pas fourni, la valeur par défaut est celle de DD_ENV.
service
optionnel - chaîne
Le nom du service utilisé pour votre application. S’il n’est pas fourni, la valeur par défaut est celle de DD_SERVICE.
sample_rate
optionnel - float
La fraction de traces conservée par Agent Observability. Nécessite ddtrace 4.12.0 ou une version ultérieure. Lorsqu’il est défini, ceci prévaut sur DD_LLMOBS_SAMPLE_RATE. Voir Échantillonnage de traces.
capture_intent
optionnel - booléen - par défaut : false
Lorsqu’il est défini sur True, ajoute un argument à chaque outil de serveur MCP demandant au modèle appelant de décrire pourquoi il a choisi d’appeler l’outil. L’intention est enregistrée sur le span de l’outil. S’il n’est pas fourni, la valeur par défaut est celle de DD_MCP_CAPTURE_INTENT.
N'utilisez pas cette méthode de configuration avec la dd-trace/initialize.mjs commande.

Utilisez la fonction init() pour activer Agent Observability.

const tracer = require('dd-trace').init({
  llmobs: {
    mlApp: "<YOUR_ML_APP_NAME>",
    agentlessEnabled: true,
  },
  site: "<YOUR_DATADOG_SITE>",
  env: "<YOUR_ENV>",
});

const llmobs = tracer.llmobs;

Options pour la configuration llmobs

mlApp
optionnel - chaîne
Le nom de votre application, service ou projet LLM, sous lequel toutes les traces et tous les spans sont regroupés. Cela permet de distinguer les différentes applications ou expériences. Consultez les directives de nommage des applications pour connaître les caractères autorisés et les autres contraintes. Pour remplacer cette valeur pour une trace donnée, consultez le traçage de plusieurs applications. S’il n’est pas fourni, la valeur par défaut est DD_LLMOBS_ML_APP.
agentlessEnabled
optionnel - booléen - par défaut: false
Uniquement requis si vous n’utilisez pas le Datadog Agent, auquel cas il doit être défini sur true. Ceci configure la bibliothèque dd-trace pour ne pas envoyer de données nécessitant le Datadog Agent. S’il n’est pas fourni, la valeur par défaut est DD_LLMOBS_AGENTLESS_ENABLED.
sampleRate
optionnel - nombre
La fraction de traces conservée par Agent Observability. Nécessite dd-trace 5.110.0 ou une version ultérieure. Lorsqu’il est défini, ceci prévaut sur DD_LLMOBS_SAMPLE_RATE. Voir Échantillonnage de traces.

Options de configuration générale du traceur :

site
optionnel - _ chaîne_
Le site Datadog vers lequel soumettre vos données LLM. Votre site est . S’il n’est pas fourni, la valeur par défaut est celle de DD_SITE.
env
optionnel - chaîne
Le nom de l’environnement de votre application (exemples: prod, pre-prod, staging). S’il n’est pas fourni, la valeur par défaut est DD_ENV.
service
optionnel - chaîne
Le nom du service utilisé pour votre application. S’il n’est pas fourni, la valeur par défaut est celle de DD_SERVICE.
Variables d’environnement

Définissez les valeurs suivantes en tant que variables d’environnement. Elles ne peuvent pas être configurées par programmation.

DD_API_KEY
optionnel - _ chaîne_
Votre clé d’API Datadog. Requis uniquement si vous n’utilisez pas le Datadog Agent.

Pour instrumenter une fonction AWS Lambda existante avec Agent Observability, vous pouvez utiliser l’extension Datadog et les couches de langage respectives.

  1. Ouvrez un Cloudshell dans la console AWS.
  2. Installez le client CLI Datadog
npm install -g @datadog/datadog-ci
  1. Définissez la clé d’API et le site Datadog
export DD_API_KEY=<YOUR_DATADOG_API_KEY>
export DD_SITE=<YOUR_DATADOG_SITE>

Si vous possédez déjà ou préférez utiliser un secret dans Secrets Manager, vous pouvez définir la clé d’API en utilisant l’ARN du secret :

export DATADOG_API_KEY_SECRET_ARN=<DATADOG_API_KEY_SECRET_ARN>
  1. Installez votre fonction Lambda avec Agent Observability (cela nécessite au moins la version 77 de la couche d’extension Datadog)
datadog-ci lambda instrument -f <YOUR_LAMBDA_FUNCTION_NAME> -r <AWS_REGION> -v 127 -e 99 --llmobs <YOUR_LLMOBS_ML_APP>
datadog-ci lambda instrument -f <YOUR_LAMBDA_FUNCTION_NAME> -r <AWS_REGION> -v 142 -e 99 --llmobs <YOUR_LLMOBS_ML_APP>
datadog-ci lambda instrument -f <YOUR_LAMBDA_FUNCTION_NAME> -r <AWS_REGION> -v 27 -e 99 --llmobs <YOUR_LLMOBS_ML_APP>
  1. Appelez votre fonction Lambda et vérifiez que les traces Agent Observability sont visibles dans l’interface utilisateur Datadog.

Videz manuellement les traces Agent Observability en utilisant la méthode flush avant que la fonction Lambda ne renvoie une valeur.

from ddtrace.llmobs import LLMObs
def handler():
  # function body
  LLMObs.flush()
import tracer from 'dd-trace';
const llmobs = tracer.llmobs;

export const handler = async (event) => {
  // your function body
  llmobs.flush();
};

Après avoir installé le SDK et exécuté votre application, vous devriez voir des données dans Agent 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.

Échantillonnage des traces

L'échantillonnage des traces est disponible dans le SDK Python (ddtrace 4.12.0 ou version ultérieure) et le SDK Node.js (dd-trace 5.110.0 ou version ultérieure). Le SDK Java ne prend pas en charge l'échantillonnage des traces.

L’échantillonnage des traces définit la fraction de traces qu’Agent Observability conserve. Comme la facturation d’Agent Observability est basée sur le volume de spans que vous envoyez, définir un taux d’échantillonnage est un moyen de contrôler vos coûts liés à Agent Observability. Le SDK prend la décision d’échantillonnage sur le span racine et l’applique à tous les spans enfants de ce span racine, y compris les spans créés dans les services en aval via le distributed tracing.

L’échantillonnage n’affecte pas vos métriques d’Agent Observability, y compris les métriques de token et de coût. Comme les spans non échantillonnés sont supprimés après que Datadog a ingéré vos traces, ces métriques restent basées sur 100 % du trafic instrumenté de votre application, quel que soit le taux d’échantillonnage spécifié. L’échantillonnage des traces est également indépendant des contrôles intégrés à l’application tels que les règles d’automatisation et l’échantillonnage des traces APM, qui s’appliquent après l’ingestion.

Configurez le taux d’échantillonnage via l’un des deux mécanismes suivants :

Le taux d’échantillonnage est un nombre à virgule flottante compris entre 0.0 (aucune trace conservée) et 1.0 (toutes les traces conservées). La valeur par défaut est 1.0. Les valeurs hors plage sont ignorées.

Définissez le taux d’échantillonnage avec la variable d’environnement :

DD_LLMOBS_SAMPLE_RATE=0.5 ddtrace-run <YOUR_APP_STARTUP_COMMAND>

Ou passez sample_rate à LLMObs.enable(), qui prévaut sur la variable d’environnement :

from ddtrace.llmobs import LLMObs

LLMObs.enable(
  ml_app="<YOUR_ML_APP_NAME>",
  sample_rate=0.5,
)

Définissez le taux d’échantillonnage avec la variable d’environnement :

DD_LLMOBS_SAMPLE_RATE=0.5 NODE_OPTIONS="--import dd-trace/initialize.mjs" <YOUR_APP_STARTUP_COMMAND>

Ou passez sampleRate sous llmobs à init(), qui prévaut sur la variable d’environnement :

const tracer = require('dd-trace').init({
  llmobs: {
    mlApp: "<YOUR_ML_APP_NAME>",
    sampleRate: 0.5,
  },
});

const llmobs = tracer.llmobs;

Instrumentation manuelle

Pour capturer une opération LLM, un décorateur de fonction peut être utilisé pour instrumenter facilement les flux de travail :

from ddtrace.llmobs.decorators import workflow

@workflow
def handle_user_request():
    ...

ou une approche basée sur un gestionnaire de contexte pour capturer des opérations précises :

from ddtrace.llmobs import LLMObs

with LLMObs.llm(model="gpt-4o"):
    call_llm()
    LLMObs.annotate(
        metrics={
            "input_tokens": ...,
            "output_tokens": ...,
        },
    )

Pour obtenir une liste des types de spans disponibles, consultez la documentation sur les types de spans. Pour un traçage plus granulaire des opérations au sein des fonctions, consultez Traçage des spans à l’aide de méthodes en ligne.

Pour tracer un span, utilisez llmobs.wrap(options, function) comme wrapper de fonction pour la fonction que vous souhaitez tracer. Pour obtenir une liste des types de spans disponibles, consultez la documentation sur les types de spans. Pour un traçage plus granulaire des opérations au sein des fonctions, consultez Traçage des spans à l’aide de 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 sur les types de span pour obtenir une liste des types de span pris en charge.

Remarque : Les spans avec un type de span non valide ne sont pas soumis à Agent Observability.

Capture automatique des arguments/sorties/noms de fonction

llmobs.wrap (ainsi que llmobs.decorate pour TypeScript) tente 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 Enrichissement des 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 :

function processMessage () {
  ... // user application logic
  return
}
processMessage = llmobs.wrap({ kind: 'workflow', name: 'differentFunctionName' }, processMessage)

Conditions de fin d’un span pour une fonction enveloppée

llmobs.wrap étend le comportement sous-jacent de tracer.wrap. Le span sous-jacent créé lors de l’appel de la fonction est terminé dans les conditions suivantes :

  • Si la fonction renvoie une promesse, le span se termine lorsque la promesse est résolue ou rejetée.
  • Si la fonction prend une fonction de rappel comme dernier paramètre, le span se termine lorsque cette fonction de rappel est appelée.
  • Si la fonction n’accepte pas de fonction de rappel et ne renvoie pas de promesse, 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 une fonction de rappel :

Exemple

const express = require('express')
const app = express()

function myAgentMiddleware (req, res, next) {
  const err = ... // 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)

Si l’application n’utilise pas la fonction de rappel, il est recommandé d’utiliser un bloc tracé en ligne à la place. Consultez Traçage des spans à l’aide de méthodes en ligne pour plus d’informations.

const express = require('express')
const app = express()

function myAgentMiddleware (req, res) {
  // the `next` callback is not being used here
  return llmobs.trace({ kind: 'agent', name: 'myAgentMiddleware' }, () => {
    return res.status(200).send('Hello World!')
  })
}

app.use(myAgentMiddleware)

Démarrage d’un span

Il existe plusieurs méthodes pour démarrer un span, selon le type de span que vous démarrez. Consultez la documentation sur les types de span pour obtenir 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 possède des méthodes que vous pouvez utiliser pour interagir avec le span et enregistrer des données.

Terminer 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 de span. Si possible, enveloppez le span dans un bloc try/finally pour vous assurer que le span est soumis même si une exception se produit.

Exemple

    try {
        LLMObsSpan workflowSpan = 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.
Si vous instrumentez manuellement un span LLM, vous devez enregistrer les nombres de jetons (tels que input_tokens, output_tokens, et total_tokens) en annotant le span. Consultez Enrichissement des spans pour plus d'informations.

Pour tracer un appel LLM, utilisez le décorateur de fonction ddtrace.llmobs.decorators.llm().

model_name
requis - chaîne
Le nom du LLM appelé.
name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas 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’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
ml_app
optionnel - _ chaîne_
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

from ddtrace.llmobs import LLMObs
from ddtrace.llmobs.decorators import llm

@llm(model_name="claude", name="invoke_llm", model_provider="anthropic")
def llm_call(prompt):
    completion = ... # user application logic to invoke LLM
    LLMObs.annotate(
        input_data=[{"role": "user", "content": prompt}],
        output_data=[{"role": "assistant", "content": completion}],
        metrics={"input_tokens": 4, "output_tokens": 6, "total_tokens": 10},
    )
    return completion

Pour tracer un appel LLM, spécifiez le type de span comme llm, et spécifiez éventuellement les arguments suivants sur l’objet options.

modelName
optionnel - chaîne - par défaut: "custom"
Le nom du LLM appelé.
name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas 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’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
mlApp
optionnel - _ chaîne_
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

function llmCall (prompt) {
  const completion = ... // user application logic to invoke LLM
  llmobs.annotate({
    inputData: [{ role: "user", content: prompt }],
    outputData: [{ role: "assistant", content: completion }],
    metrics: { input_tokens: 4, output_tokens: 6, total_tokens: 10 }
  })
  return completion
}
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 :

import datadog.trace.api.llmobs.LLMObs;
LLMObs.startLLMSpan(spanName, modelName, modelProvider, mlApp, sessionID);
spanName
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, spanName prend par défaut le type de span.
modelName
optionnel - chaîne - par défaut: "custom"
Le nom du LLM appelé.
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 appartient l’opération. La fourniture d’une valeur non nulle remplace le nom de l’application ML fourni au démarrage de l’application. Consultez Traçage de plusieurs applications pour plus d’informations.
sessionId
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.

Exemple

import datadog.trace.api.llmobs.LLMObs;

public class MyJavaClass {
  public String invokeModel() {
    LLMObsSpan llmSpan = LLMObs.startLLMSpan("my-llm-span-name", "my-llm-model", "my-company", "maybe-ml-app-override", "session-141");
    String inference = ... // user application logic to invoke LLM
    llmSpan.annotateIO(...); // record the input and output
    llmSpan.setMetrics(Map.of(
      "input_tokens", 617,
      "output_tokens", 338,
      "total_tokens", 955
    ));
    llmSpan.finish();
    return inference;
  }
}

Workflows

Pour tracer un span de workflow, utilisez le décorateur de fonction ddtrace.llmobs.decorators.workflow().

name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, name prend par défaut le nom de la fonction tracée.
session_id
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
ml_app
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

from ddtrace.llmobs.decorators import workflow

@workflow
def process_message():
    ... # user application logic
    return

Pour tracer un span de workflow, spécifiez le type de span comme workflow et spécifiez éventuellement des arguments sur l’objet options.

name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, name prend par défaut le nom de la fonction tracée.
sessionId
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
mlApp
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

function processMessage () {
  ... // user application logic
  return
}
processMessage = llmobs.wrap({ kind: 'workflow' }, processMessage)

Pour tracer un span de workflow, importez et appelez la méthode suivante avec les arguments listés ci-dessous :

import datadog.trace.api.llmobs.LLMObs;
LLMObs.startWorkflowSpan(spanName, mlApp, sessionID);
spanName
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, spanName prend par défaut le type de span.
mlApp
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. La fourniture d’une valeur non nulle remplace le nom de l’application ML fourni au démarrage de l’application. Consultez Traçage de plusieurs applications pour plus d’informations.
sessionId
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.

Exemple

import datadog.trace.api.llmobs.LLMObs;

public class MyJavaClass {
  public String executeWorkflow() {
    LLMObsSpan workflowSpan = LLMObs.startWorkflowSpan("my-workflow-span-name", null, "session-141");
    String workflowResult = workflowFn(); // user application logic
    workflowSpan.annotateIO(...); // record the input and output
    workflowSpan.finish();
    return workflowResult;
  }
}

Agents

Pour tracer l’exécution d’un agent, utilisez le décorateur de fonction ddtrace.llmobs.decorators.agent().

name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, name prend par défaut le nom de la fonction tracée.
session_id
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
ml_app
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

from ddtrace.llmobs.decorators import agent

@agent
def react_agent():
    ... # user application logic
    return

Pour tracer l’exécution d’un agent, spécifiez le type de span comme agent et spécifiez éventuellement des arguments sur l’objet options.

name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, name prend par défaut le nom de la fonction tracée.
sessionId
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
mlApp
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

function reactAgent () {
  ... // user application logic
  return
}
reactAgent = llmobs.wrap({ kind: 'agent' }, reactAgent)

Pour tracer l’exécution d’un agent, importez et appelez la méthode suivante avec les arguments listés ci-dessous

import datadog.trace.api.llmobs.LLMObs;
LLMObs.startAgentSpan(spanName, mlApp, sessionID);
spanName
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, spanName prend par défaut le nom de la fonction tracée.
mlApp
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. La fourniture d’une valeur non nulle remplace le nom de l’application ML fourni au démarrage de l’application. Consultez Traçage de plusieurs applications pour plus d’informations.
sessionId
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.

Appels d’outils

Pour tracer un appel d’outil, utilisez le décorateur de fonction ddtrace.llmobs.decorators.tool().

name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, name prend par défaut le nom de la fonction tracée.
session_id
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
ml_app
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

from ddtrace.llmobs.decorators import tool

@tool
def call_weather_api():
    ... # user application logic
    return

Pour tracer un appel d’outil, spécifiez le type de span comme tool et, éventuellement, spécifiez des arguments sur l’objet options.

name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, name prend par défaut le nom de la fonction tracée.
sessionId
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
mlApp
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

function callWeatherApi () {
  ... // user application logic
  return
}
callWeatherApi = llmobs.wrap({ kind: 'tool' }, callWeatherApi)

Pour tracer un appel d’outil, importez et appelez la méthode suivante avec les arguments listés ci-dessous :

import datadog.trace.api.llmobs.LLMObs;
LLMObs.startToolSpan(spanName, mlApp, sessionID);
spanName
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, spanName prend par défaut le nom de la fonction tracée.
mlApp
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. La fourniture d’une valeur non nulle remplace le nom de l’application ML fourni au démarrage de l’application. Consultez Traçage de plusieurs applications pour plus d’informations.
sessionId
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.

Tâches

Pour tracer un span de tâche, utilisez le décorateur de fonction LLMObs.task().

name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, name prend par défaut le nom de la fonction tracée.
session_id
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
ml_app
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

from ddtrace.llmobs.decorators import task

@task
def sanitize_input():
    ... # user application logic
    return

Pour tracer un span de tâche, spécifiez le span kind comme task et, éventuellement, spécifiez des arguments sur l’objet options.

name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, name prend par défaut le nom de la fonction tracée.
sessionId
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
mlApp
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

function sanitizeInput () {
  ... // user application logic
  return
}
sanitizeInput = llmobs.wrap({ kind: 'task' }, sanitizeInput)

Pour tracer un task span, importez et appelez la méthode suivante avec les arguments listés ci-dessous :

import datadog.trace.api.llmobs.LLMObs;
LLMObs.startTaskSpan(spanName, mlApp, sessionID);
spanName
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, spanName prend par défaut le nom de la fonction tracée.
mlApp
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. La fourniture d’une valeur non nulle remplace le nom de l’application ML fourni au démarrage de l’application. Consultez Traçage de plusieurs applications pour plus d’informations.
sessionId
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.

Embeddings

Pour tracer une embedding operation, utilisez le décorateur de fonction LLMObs.embedding().

Remarque : L’annotation de l’entrée d’un span embedding nécessite un formatage différent de celui des autres types de span. Consultez Enrichissement des spans pour plus de détails sur la façon de spécifier les entrées d’embedding.

model_name
requis - chaîne
Le nom du LLM appelé.
name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas 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’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
ml_app
optionnel - _ chaîne_
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

from ddtrace.llmobs.decorators import embedding

@embedding(model_name="text-embedding-3", model_provider="openai")
def perform_embedding():
    ... # user application logic
    return

Pour tracer une embedding operation, spécifiez le span kind comme embedding, et spécifiez éventuellement des arguments sur l’objet options.

Remarque : L’annotation de l’entrée d’un span embedding nécessite un formatage différent de celui des autres types de span. Consultez Enrichissement des spans pour plus de détails sur la façon de spécifier les entrées d’embedding.

modelName
optionnel - String - par défaut: "custom"
Le nom du LLM invoqué.
name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, name est défini sur le nom de la fonction tracée.
modelProvider
optionnel - String - par défaut: "custom"
Le nom du fournisseur de modèle.
sessionId
optionnel - _ chaîne_
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
mlApp
optionnel - _ chaîne_
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

function performEmbedding () {
  ... // user application logic
  return
}
performEmbedding = llmobs.wrap({ kind: 'embedding', modelName: 'text-embedding-3', modelProvider: 'openai' }, performEmbedding)

Retrievals

Pour tracer un span de récupération, utilisez le décorateur de fonction ddtrace.llmobs.decorators.retrieval().

Remarque : L’annotation de la sortie d’un retrieval span nécessite un formatage différent de celui des autres types de span. Consultez Enrichissement des spans pour plus de détails sur la façon de spécifier les sorties de récupération.

name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, name prend par défaut le nom de la fonction tracée.
session_id
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
ml_app
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

from ddtrace.llmobs.decorators import retrieval

@retrieval
def get_relevant_docs(question):
    context_documents = ... # user application logic
    LLMObs.annotate(
        input_data=question,
        output_data = [
            {"id": doc.id, "score": doc.score, "text": doc.text, "name": doc.name} for doc in context_documents
        ]
    )
    return

Pour tracer un span de récupération, spécifiez le type de span comme retrieval, et spécifiez éventuellement les arguments suivants sur l’objet options.

Remarque : L’annotation de la sortie d’un retrieval span nécessite un formatage différent de celui des autres types de span. Consultez Enrichissement des spans pour plus de détails sur la façon de spécifier les sorties de récupération.

name
optionnel - chaîne
Le nom de l’opération. S’il n’est pas fourni, name prend par défaut le nom de la fonction tracée.
sessionId
optionnel - chaîne
L’identifiant de la session utilisateur sous-jacente. Consultez Suivi des sessions utilisateur pour plus d’informations.
mlApp
optionnel - chaîne
Le nom de l’application ML à laquelle appartient l’opération. Consultez Traçage de plusieurs applications pour plus d’informations.

Exemple

Ce qui suit inclut également un exemple d’annotation d’un span. Consultez Enrichissement des spans pour plus d’informations.

function getRelevantDocs (question) {
  const contextDocuments = ... // 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

Le démarrage d’un nouveau span avant que le span actuel ne soit terminé trace automatiquement une relation parent-enfant entre les deux spans. Le span parent représente l’opération plus large, tandis que le span enfant représente une sous-opération imbriquée plus petite au sein de celui-ci.

from ddtrace.llmobs.decorators import task, workflow

@workflow
def extract_data(document):
    preprocess_document(document)
    ... # performs data extraction on the document
    return

@task
def preprocess_document(document):
    ... # preprocesses a document for data extraction
    return
function preprocessDocument (document) {
  ... // preprocesses a document for data extraction
  return
}
preprocessDocument = llmobs.wrap({ kind: 'task' }, preprocessDocument)

function extractData (document) {
  preprocessDocument(document)
  ... // performs data extraction on the document
  return
}
extractData = llmobs.wrap({ kind: 'workflow' }, extractData)
import datadog.trace.api.llmobs.LLMObs;
import datadog.trace.api.llmobs.LLMObsSpan;

public class MyJavaClass {
  public void preprocessDocument(String document) {
  LLMObsSpan taskSpan = LLMObs.startTaskSpan("preprocessDocument", null, "session-141");
   ...   // preprocess document for data extraction
   taskSpan.annotateIO(...); // record the input and output
   taskSpan.finish();
  }

  public String extractData(String document) {
    LLMObsSpan workflowSpan = LLMObs.startWorkflowSpan("extractData", null, "session-141");
    preprocessDocument(document);
    ... // perform data extraction on the document
    workflowSpan.annotateIO(...); // record the input and output
    workflowSpan.finish();
  }
}

Enrichissement des spans

Le metrics Le paramètre ici fait référence aux valeurs numériques jointes en tant qu'attributs sur des spans individuels — et non aux métriques de la plateforme Datadog. Pour certaines clés reconnues telles que input_tokens, output_tokens, et total_tokens, Datadog utilise ces attributs de span pour générer les métriques de plateforme correspondantes (telles que ml_obs.span.llm.input.tokens) pour une utilisation dans les dashboards 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 :

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 - JSON serializable type or list of dictionaries
Either a JSON serializable type (for non-LLM spans) or a list of dictionaries with this format: {"content": \"...\", \"role\": \"...\", \"tool_calls\": ..., \"tool_results\": ..., \"audio_parts\": ..., \"image_parts\": ...}, où "tool_calls" est une liste optionnelle de dictionnaires d’appels d’outils avec les clés requises : "name", "arguments", et "tool_id" , "type" et "tool_results" est 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. "audio_parts" et "image_parts" sont des listes facultatives de dictionnaires de médias pour les spans multimodaux, chacun avec un "mime_type" requis et exactement l’un des suivants : "content" (média encodé en base64, inclus en ligne) ou "attachment_key". Note : Les spans d’embedding sont un cas particulier et nécessitent une chaîne ou un dictionnaire (ou une liste de dictionnaires) avec ce format : {"text": "..."}.

output_data a: facultatif - type sérialisable en JSON ou liste de dictionnaires
Soit un type sérialisable en JSON (pour les spans non-LLM), soit une liste de dictionnaires avec ce format : {"content": "...", "role": "...", "tool_calls": ..., "audio_parts": ..., "image_parts": ...}, où "tool_calls" est une liste facultative de dictionnaires d’appels d’outils avec les clés requises : "name", "arguments", et les clés facultatives : "tool_id", "type" pour les scénarios d’appel de fonction. "audio_parts" et "image_parts" sont des listes facultatives de dictionnaires de médias pour les spans multimodaux, chacun avec un "mime_type" requis et exactement l’un des suivants : "content" (média encodé en base64, inclus en ligne) ou "attachment_key". Note : Les spans de récupération 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 a: facultatif - 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 "description": "..." et "schema": {...} facultatives.

metadata a: facultatif - dictionnaire
Un dictionnaire de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent ajouter en tant qu’informations de métadonnées pertinentes pour l’opération d’entrée ou de sortie décrite par le span (model_temperature, max_tokens, top_k, etc.).

metrics a: facultatif - dictionnaire
Un dictionnaire de clés sérialisables en JSON et de valeurs numériques que les utilisateurs peuvent ajouter en tant que métriques pertinentes pour 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 a: facultatif - dictionnaire
Un dictionnaire de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent ajouter en tant que tags sur le span. Exemples de clés : session, env, system et version. Pour plus d’informations sur les tags, consultez Getting Started with Tags.

cost_tags a: facultatif - liste de chaînes
Une liste de clés de tag (déjà définies avec tags ou annotées précédemment sur le même span) à propager en tant que tags personnalisés sur les métriques de coût et de jeton LLM générées. Les entrées qui ne font pas référence à une clé de tag existante sont ignorées. Voir Suivi des coûts pour plus de détails.

Exemple

from ddtrace.llmobs import LLMObs
from ddtrace.llmobs.decorators import embedding, llm, retrieval, workflow

@llm(model_name="model_name", model_provider="model_provider")
def llm_call(prompt):
    resp = ... # llm call here
    LLMObs.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"},
    )
    return resp

@workflow
def extract_data(document):
    resp = llm_call(document)
    LLMObs.annotate(
        input_data=document,
        output_data=resp,
        tags={"host": "host_name"},
    )
    return resp

@embedding(model_name="text-embedding-3", model_provider="openai")
def perform_embedding():
    ... # user application logic
    LLMObs.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")
def similarity_search():
    ... # user application logic
    LLMObs.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

@llm(model_name="gpt-realtime", model_provider="openai")
def voice_turn(user_audio_bytes):
    import base64
    resp = ... # multimodal (audio) llm call here
    LLMObs.annotate(
        span=None,
        input_data=[
            {
                "role": "user",
                "content": "Hey, how are you?",  # transcript of the input audio
                "audio_parts": [
                    {"mime_type": "audio/wav", "content": base64.b64encode(user_audio_bytes).decode("utf-8")}
                ],
            }
        ],
        output_data=[
            {
                "role": "assistant",
                "content": "Hey! I'm doing great, thanks for asking. How about you?",
                "audio_parts": [
                    {"mime_type": "audio/wav", "content": base64.b64encode(resp.audio_bytes).decode("utf-8")}
                ],
            }
        ],
    )
    return resp

@llm(model_name="gpt-4o", model_provider="openai")
def describe_image(image_bytes):
    import base64
    resp = ... # multimodal (vision) llm call here
    LLMObs.annotate(
        span=None,
        input_data=[
            {
                "role": "user",
                "content": "What is in this image?",
                "image_parts": [
                    {"mime_type": "image/png", "content": base64.b64encode(image_bytes).decode("utf-8")}
                ],
            }
        ],
        output_data=[{"role": "assistant", "content": "The image shows a golden retriever puppy."}],
    )
    return resp

Les messages annotés avec audio_parts ou image_parts s’affichent sous forme de lecteurs audio et d’images intégrés dans la vue de trace :

Un span LLM dans la vue de trace Agent Observability. Le message d'entrée de l'UTILISATEUR affiche un lecteur audio intégré avec la transcription « Hey, how are you? », et le message de sortie de l'ASSISTANT affiche une commande « Click to play audio » avec la transcription « Hey! ». Je vais très bien, merci de demander. « How about you? ».
Un span LLM dans la vue de trace Agent Observability. Le message d'entrée de l'UTILISATEUR affiche l'invite « What is in this image? ». avec une photo intégrée d'un chiot noir, et le message de sortie de l'ASSISTANT le décrit comme un chiot Labrador Retriever noir sur une surface en bois.

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 :

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 wrappers de fonction), le SDK annote le span actif.
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
facultatif - type sérialisable en JSON ou liste d’objets
Soit un type sérialisable en JSON (pour les spans non-LLM), soit une liste de dictionnaires avec ce format: {role: \"...\", content: \"...\", audioParts: [...], imageParts: [...]} (pour les spans LLM). audioParts et imageParts sont des listes facultatives d’objets multimédias pour les spans multimodaux, chacun avec un mimeType requis et exactement un élément parmi content (média encodé en base64, transporté en ligne) ou attachmentKey. Remarque : Les spans d’embedding sont un cas particulier et nécessitent une chaîne ou un objet (ou une liste d’objets) avec ce format : {text: "..."}.
outputData
facultatif - type sérialisable en JSON ou liste d’objets
Soit un type sérialisable en JSON (pour les spans non-LLM), soit une liste d’objets avec ce format : {role: "...", content: "...", audioParts: [...], imageParts: [...]} (pour les spans LLM). audioParts et imageParts sont des listes facultatives d’objets multimédias pour les spans multimodaux, chacun avec un mimeType requis et exactement un élément parmi content (média encodé en base64, transporté en ligne) ou attachmentKey. 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
facultatif - objet
Un objet de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent ajouter en tant qu’informations de métadonnées pertinentes pour l’opération d’entrée ou de sortie décrite par le span (model_temperature, max_tokens, top_k, etc.).
metrics
facultatif - objet
Un objet de clés sérialisables en JSON et de valeurs numériques que les utilisateurs peuvent ajouter en tant que métriques pertinentes pour l’opération décrite par le span (input_tokens, output_tokens, total_tokens, etc.).
tags
facultatif - objet
Un objet de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent ajouter en tant que tags concernant le contexte du span (session, environment, system, versioning, etc.). Pour plus d’informations sur les tags, consultez Getting Started with Tags.
costTags
facultatif - tableau de chaînes
Une liste de clés de tag (déjà définies avec tags ou annotées précédemment sur le même span) à propager en tant que tags personnalisés sur les métriques de coût et de jeton LLM générées. Les entrées qui ne font pas référence à une clé de tag existante sont ignorées. Voir Suivi des coûts pour plus de détails.

Exemple

function llmCall (prompt) {
  const completion = ... // 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" }
  })
  return completion
}
llmCall = llmobs.wrap({ kind:'llm', modelName: 'modelName', modelProvider: 'modelProvider' }, llmCall)

function extractData (document) {
  const resp = llmCall(document)
  llmobs.annotate({
    inputData: document,
    outputData: resp,
    tags: { host: "host_name" }
  })
  return resp
}
extractData = llmobs.wrap({ kind: 'workflow' }, extractData)

function performEmbedding () {
  ... // 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)

function similaritySearch () {
  ... // 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)

function voiceTurn (userAudioBytes) {
  const resp = ... // multimodal (audio) llm call here
  llmobs.annotate({
    inputData: [
      {
        role: "user",
        content: "Hey, how are you?", // transcript of the input audio
        audioParts: [{ mimeType: "audio/wav", content: userAudioBytes.toString("base64") }]
      }
    ],
    outputData: [
      {
        role: "assistant",
        content: "Hey! I'm doing great, thanks for asking. How about you?",
        audioParts: [{ mimeType: "audio/wav", content: resp.audioBuffer.toString("base64") }]
      }
    ]
  })
  return resp
}
voiceTurn = llmobs.wrap({ kind: 'llm', modelName: 'gpt-audio', modelProvider: 'openai' }, voiceTurn)

function describeImage (imageBytes) {
  const resp = ... // multimodal (vision) llm call here
  llmobs.annotate({
    inputData: [
      {
        role: "user",
        content: "What is in this image?",
        imageParts: [{ mimeType: "image/png", content: imageBytes.toString("base64") }]
      }
    ],
    outputData: [{ role: "assistant", content: "The image shows a golden retriever puppy." }]
  })
  return resp
}
describeImage = llmobs.wrap({ kind: 'llm', modelName: 'gpt-4o', modelProvider: 'openai' }, describeImage)

Les messages annotés avec audioParts ou imageParts s’affichent sous forme de lecteurs audio et d’images intégrés dans la vue de trace :

Un span LLM dans la vue de trace Agent Observability. Le message d'entrée de l'UTILISATEUR affiche un lecteur audio intégré avec la transcription « Hey, how are you? », et le message de sortie de l'ASSISTANT affiche une commande « Click to play audio » avec la transcription « Hey! ». Je vais très bien, merci de demander. « How about you? ».
Un span LLM dans la vue de trace Agent Observability. Le message d'entrée de l'UTILISATEUR affiche l'invite « What is in this image? ». avec une photo intégrée d'un chiot noir, et le message de sortie de l'ASSISTANT le décrit comme un chiot Labrador Retriever noir sur une surface en bois.

Pour les complétions de chat audio OpenAI, audioParts sont également capturés automatiquement par les intégrations LLM de Datadog—aucune annotation manuelle n’est requise. Contrairement à audioParts, imageParts ne sont actuellement pas capturés automatiquement et doivent être annotés manuellement ; une capture automatique est prévue pour une version ultérieure.

Le SDK fournit plusieurs méthodes pour annoter les spans avec des entrées, des sorties, des métriques et des métadonnées.

Annotation des entrées et des 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 les arguments optionnels et les 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 alors que outputData est nul, seul inputData est enregistré.

inputData
optionnel - Chaîne ou Liste<LLMObs.LLMMessage>
Soit une chaîne (pour les spans non-LLM), soit une liste de LLMObs.LLMMessage pour les spans LLM.
outputData
optionnel - Chaîne ou Liste<LLMObs.LLMMessage>
Soit une chaîne (pour les spans non-LLM), soit une liste de LLMObs.LLMMessage pour les 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 - String
Une chaîne décrivant le rôle de l’auteur du message.
content
requis - String
Une chaîne contenant le contenu du message.

Exemple

import datadog.trace.api.llmobs.LLMObs;

public class MyJavaClass {
  public String invokeChat(String userInput) {
    LLMObsSpan llmSpan = LLMObs.startLLMSpan("my-llm-span-name", "my-llm-model", "my-company", "maybe-ml-app-override", "session-141");
    String systemMessage = "You are a helpful assistant";
    Response chatResponse = ... // user application logic to invoke LLM
    llmSpan.annotateIO(
      Arrays.asList(
        LLMObs.LLMMessage.from("user", userInput),
        LLMObs.LLMMessage.from("system", systemMessage)
      ),
      Arrays.asList(
        LLMObs.LLMMessage.from(chatResponse.role, chatResponse.content)
      )
    );
    llmSpan.finish();
    return chatResponse;
  }
}

Attacher des métriques

Attacher plusieurs métriques en masse

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, Number>
Une carte 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).

Attacher une seule métrique

La méthode membre setMetric() de l’interface LLMObsSpan accepte les arguments suivants pour attacher une métrique unique :

Arguments
key
requis - CharSequence
Le nom de la métrique.
value
requis - int, long ou double
La valeur de la métrique.

Exemples

import datadog.trace.api.llmobs.LLMObs;

public class MyJavaClass {
  public String invokeChat(String userInput) {
    LLMObsSpan llmSpan = LLMObs.startLLMSpan("my-llm-span-name", "my-llm-model", "my-company", "maybe-ml-app-override", "session-141");
    String chatResponse = ... // user application logic to invoke LLM
    llmSpan.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();
    return chatResponse;
  }
}

Attacher des tags

Pour plus d’informations sur les tags, consultez Getting Started with Tags.

Attacher plusieurs tags en masse

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 carte de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent attacher en tant que tags pour décrire le contexte du span (par exemple, session, environment, system, ou version).

Attacher un seul tag

La méthode membre setTag() de l’interface LLMObsSpan accepte les arguments suivants pour attacher un seul tag :

Arguments
key
requis - String
La clé du tag.
value
requis - int, long, double, booléen ou String
La valeur du tag.

Exemples

import datadog.trace.api.llmobs.LLMObs;

public class MyJavaClass {
  public String invokeChat(String userInput) {
    LLMObsSpan llmSpan = LLMObs.startLLMSpan("my-llm-span-name", "my-llm-model", "my-company", "maybe-ml-app-override", "session-141");
    String chatResponse = ... // user application logic to invoke LLM
    llmSpan.setTags(Map.of(
      "chat_source", "web",
      "users_in_chat", 3
    ));
    llmSpan.setTag("is_premium_user", true);
    llmSpan.finish();
    return chatResponse;
  }
}

Annotation des erreurs

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 produit.

Attacher 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 lors de l’opération :

Arguments
error
requis - booléen
true si le span a rencontré une erreur.

Exemples

import datadog.trace.api.llmobs.LLMObs;

public class MyJavaClass {
  public String invokeChat(String userInput) {
    LLMObsSpan llmSpan = LLMObs.startLLMSpan("my-llm-span-name", "my-llm-model", "my-company", "maybe-ml-app-override", "session-141");
    String chatResponse = "N/A";
    try {
      chatResponse = ... // user application logic to invoke LLM
    } catch (Exception e) {
      llmSpan.addThrowable(e);
      throw new RuntimeException(e);
    } finally {
      llmSpan.finish();
    }
    return chatResponse;
  }
}

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

import datadog.trace.api.llmobs.LLMObs;

public class MyJavaClass {
  public String invokeChat(String userInput) {
    LLMObsSpan llmSpan = 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"
      )
    );
    String chatResponse = ... // user application logic to invoke LLM
    return chatResponse;
  }
}

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 tous les spans auto-instrumentés démarrés pendant que le contexte d’annotation est actif.

La méthode LLMObs.annotation_context() accepte les arguments suivants :

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.
prompt
optionnel - dictionnaire
Un dictionnaire qui représente le prompt utilisé pour un appel LLM. Consultez la documentation de l’objet Prompt pour obtenir le schéma complet et les clés prises en charge. Vous pouvez également importer l’objet Prompt depuis ddtrace.llmobs.utils et le transmettre en tant qu’argument prompt. Remarque: Cet argument s’applique uniquement aux spans LLM.
tags
optionnel - dictionnaire
Un dictionnaire de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent ajouter en tant que tags sur le span. Exemples de clés : session, env, system et version. Pour plus d’informations sur les tags, consultez Getting Started with Tags.

cost_tags a: facultatif - liste de chaînes
Une liste de clés de tag à propager en tant que tags personnalisés sur les métriques de coût et de jetons LLM générées. Chaque entrée doit faire référence à une clé présente dans tags au début du span (fournie au même contexte ou à un contexte parent); les clés de tag ajoutées ultérieurement avec LLMObs.annotate() ne sont pas conservées. Voir Suivi des coûts pour plus de détails.

Exemple

from ddtrace.llmobs import LLMObs
from ddtrace.llmobs.decorators import workflow

@workflow
def rag_workflow(user_question):
    context_str = retrieve_documents(user_question).join(" ")

    with LLMObs.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(...)
    return completion.choices[0].message.content

Le llmobs.annotationContext() du SDK accepte une fonction de rappel qui peut être utilisée pour modifier tous les spans auto-instrumentés démarrés dans le périmètre de la fonction de rappel.

La méthode llmobs.annotationContext() accepte les options suivantes sur le premier argument:

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 - object
Un objet de paires clé-valeur sérialisables en JSON que les utilisateurs peuvent attacher en tant que tags sur le span. Exemples de clés: session, env, system et version. Pour plus d’informations sur les tags, consultez Getting Started with Tags.
costTags
facultatif - tableau de chaînes
Une liste de clés de tag à propager en tant que tags personnalisés sur les métriques de coût et de jetons LLM générées. Chaque entrée doit faire référence à une clé présente dans tags au début du span (fournie au même contexte ou à un contexte parent); les clés de tag ajoutées ultérieurement avec llmobs.annotate() ne sont pas conservées. Voir Suivi des coûts pour plus de détails.

Exemple

const { llmobs } = require('dd-trace');

function ragWorkflow(userQuestion) {
    const contextStr = retrieveDocuments(userQuestion).join(" ");

    const completion = await llmobs.annotationContext({
      tags: {
        retrieval_strategy: "semantic_similarity"
      },
      name: "augmented_generation"
    }, async () => {
      const completion = await openai_client.chat.completions.create(...);
      return completion.choices[0].message.content;
    });
}

Prompt tracking

Attachez des métadonnées de prompt structurées au span LLM afin de pouvoir reproduire les résultats, auditer les modifications et comparer les performances du prompt entre les versions. Lors de l’utilisation de templates, Agent Observability fournit également un version tracking basé sur les modifications du contenu du template.

Utilisez LLMObs.annotation_context(prompt=...) pour attacher des métadonnées de prompt avant l’appel LLM. Pour plus de détails sur l’annotation des spans, voir Enriching spans.

Arguments

prompt
requis - dictionary
Un typed dictionary qui suit le schéma de Prompt ci-dessous.

Clés prises en charge :

  • id (str) : Identifiant logique pour ce prompt. Doit être unique par ml_app. Par défaut à {ml_app}-unnamed_prompt
  • version (str) : Tag de version pour le prompt (par exemple, « 1.0.0 »). Voir version tracking pour plus de détails.
  • variables (Dict[str, str]) : Variables utilisées pour remplir les template placeholders.
  • template (str) : Template string with placeholders (for example, "Translate {{text}} to {{lang}}").
  • chat_template (List[Message]) : Multi-message template form. Fournissez une liste d’objets { "role": "<role>", "content": "<template string with placeholders>" }.
  • tags (Dict[str, str]) : Tags à attacher à l’exécution du prompt.
  • rag_context_variables (List[str]) : Clés de variables contenant le contenu ground-truth/context. Utilisé pour hallucination detection.
  • rag_query_variables (List[str]) : Clés de variable contenant la requête de l’utilisateur. Utilisé pour hallucination detection.

Exemple : invite à modèle unique

from ddtrace.llmobs import LLMObs

def answer_question(text):
    # Attach prompt metadata to the upcoming LLM span using LLMObs.annotation_context()
    with LLMObs.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}"}]
        )
    return completion

Exemple : modèles d’invite LangChain

Lorsque vous utilisez le modèle d’invite de LangChain avec l’auto-instrumentation, assignez des modèles aux 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 Datadog
translation_template = PromptTemplate.from_template("Translate {text} to {language}")
chain = translation_template | llm

Utilisez llmobs.annotationContext({ prompt: ... }, () => { ... }) pour joindre des métadonnées de prompt avant l’appel LLM. Pour plus de détails sur l’annotation des spans, voir Enriching spans.

Arguments

prompt
requis - objet
Un objet qui suit le schéma d’invite ci-dessous.

Propriétés prises en charge :

  • id (chaîne) : Identifiant logique pour cette invite. Doit être unique par ml_app. Par défaut à {ml_app}-unnamed_prompt
  • version (chaîne) : Tag de version pour l’invite (par exemple, « 1.0.0 »). Voir version tracking 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 | List[Message]) : Chaîne de modèle avec des espaces réservés (par exemple, "Translate {{text}} to {{lang}}"). Alternatively, a list of { “role”: “”, “content”: “