> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tracer vos agents

> Utilisez le SDK Agent Lens pour instrumenter des applications agentiques sur plusieurs tours de conversation et visualiser leur activité dans Agent Lens.

Découvrez comment instrumenter une application agentique sur plusieurs tours de conversation à l’aide du SDK CoreWeave Forge afin de visualiser, de déboguer et d’évaluer le comportement de votre agent. Ce guide s’adresse aux développeurs qui créent ou intègrent des agents et souhaitent bénéficier d’une visibilité structurée sur les conversations, les tours de conversation, les appels LLM et les exécutions d’outils.

Le SDK Agent Lens modélise le cycle de vie complet d’une conversation d’agent sur plusieurs tours de conversation : l’agent, auquel sont rattachées de nombreuses conversations ; la conversation, qui regroupe les tours de conversation ; chaque échange entre l’utilisateur et l’agent (tour de conversation) ; les appels LLM effectués au cours d’un tour de conversation ; et les exécutions d’outils déclenchées par un LLM. Les traces s’affichent dans l’onglet **Conversations** de votre projet CoreWeave Agent Lens. Chaque conversation présente une chronologie sur plusieurs tours de conversation, avec les appels d’outils imbriqués, l’utilisation des jetons et le feedback.

Agent Lens repose sur [OpenTelemetry (OTel)](https://opentelemetry.io/docs/concepts/), la norme ouverte de traçage distribué. Chaque tour de conversation, appel LLM et appel d’outil émet un *span* OTel (un enregistrement structuré d’une opération). Chaque span est tagué avec des attributs issus des [conventions sémantiques GenAI](https://opentelemetry.io/docs/specs/semconv/gen-ai/), tels que `gen_ai.agent.name` et `gen_ai.conversation.id`.

<h2 id="before-you-begin">
  Avant de commencer
</h2>

Pour commencer, installez le SDK Agent Lens et initialisez votre projet. Cette étape enregistre votre entity et votre projet auprès d’Agent Lens afin que le SDK achemine les spans vers le bon emplacement dans l’interface utilisateur. Le SDK lit votre clé API dans la variable d’environnement `WANDB_API_KEY`.

<Tabs>
  <Tab title="Python">
    ```bash lines theme={"system"}
    pip install coreweave
    ```

    Remplacez `[YOUR-TEAM]` par le nom de votre entity Forge et `[YOUR-PROJECT]` par le nom de votre projet. L’entity est requis.

    ```python lines theme={"system"}
    from coreweave.forge.agentlens import tracing

    tracing.init("[YOUR-TEAM]/[YOUR-PROJECT]")
    ```

    Appelez `tracing.init()` avant tout appel à `start_conversation()`, `start_turn()`, `start_llm()`, `start_tool()` ou `start_subagent()`. Avant l’exécution de `init()`, ou après `shutdown()`, les fonctions de traçage n’ont silencieusement aucun effet. Vous pouvez donc laisser l’instrumentation dans le code de production et la piloter par la configuration. Appelez `tracing.shutdown()` à la fin de votre processus pour procéder au vidage des spans encore en mémoire tampon. Cette fonction est également enregistrée auprès d’`atexit`.
  </Tab>

  <Tab title="TypeScript">
    ```bash lines theme={"system"}
    npm install @coreweave/forge-sdk
    ```

    Remplacez `[YOUR-TEAM]` par le nom de votre entity Forge et `[YOUR-PROJECT]` par le nom de votre projet. L’entity est requis.

    ```typescript lines theme={"system"}
    import { tracing } from '@coreweave/forge-sdk/agentlens';

    await tracing.init('[YOUR-TEAM]/[YOUR-PROJECT]');
    ```

    Appelez `tracing.init()` une seule fois avant tout appel à `startConversation()`, `startTurn()`, `startLLM()`, `startTool()` ou `startSubagent()`. En TypeScript, chaque requête ou run d’agent doit également être encapsulé dans `tracing.runIsolated()`, qui conserve l’état de traçage de ce run à travers les `await` et empêche les requêtes simultanées de partager une conversation. Tout span démarré en dehors de `tracing.runIsolated()` lève une erreur. Appelez `tracing.shutdown()` à la fin de votre processus pour procéder au vidage des spans encore en mémoire tampon.
  </Tab>
</Tabs>

<h2 id="the-agent-data-model">
  Le modèle de données des agents
</h2>

Agent Lens modélise le comportement des agents sous la forme d’une hiérarchie de relations un-à-plusieurs. Chaque agent peut avoir plusieurs conversations, chaque conversation peut comporter plusieurs tours de conversation, chaque tour de conversation peut comporter plusieurs appels LLM, et chaque appel LLM peut déclencher plusieurs appels d’outil.

| Concept | Classe du SDK Agent Lens | Type de span OTel | Description | Page de référence |
| - | - | - | - | - |
| Agent | *(aucune classe)* | *(aucun span, regroupement par l’attribut `agent_name`)* | Une application agentique qui contient une ou plusieurs conversations. | |
| Conversation | `Conversation` | *(aucun span, les tours de conversation sont regroupés par l’attribut `conversation_id`)* | Une conversation ou un run qui contient un ou plusieurs tours de conversation. | [Python](/fr/products/agent-lens/reference/python-sdk/conversation) <br /> [TypeScript](/fr/products/agent-lens/reference/typescript-sdk/classes/conversation) |
| Tour de conversation | `Turn` | `invoke_agent` | Un message de l’utilisateur et la réponse complète de l'agent. | [Python](/fr/products/agent-lens/reference/python-sdk/turn) <br /> [TypeScript](/fr/products/agent-lens/reference/typescript-sdk/classes/turn) |
| Appel LLM | `LLM` | `chat` | Un appel à l’API d’un modèle de langage. | [Python](/fr/products/agent-lens/reference/python-sdk/llm) <br /> [TypeScript](/fr/products/agent-lens/reference/typescript-sdk/classes/llm) |
| Appel d’outil | `Tool` | `execute_tool` | Un appel d’outil déclenché par une réponse du LLM. | [Python](/fr/products/agent-lens/reference/python-sdk/tool) <br /> [TypeScript](/fr/products/agent-lens/reference/typescript-sdk/classes/tool) |
| Appel de sous-agent | `SubAgent` | `invoke_agent` | Un appel d’agent imbriqué, généralement lorsqu’un agent délègue une tâche à un autre. | [Python](/fr/products/agent-lens/reference/python-sdk/subagent) <br /> [TypeScript](/fr/products/agent-lens/reference/typescript-sdk/classes/subagent) |

Le diagramme suivant montre comment un agent englobe plusieurs conversations, une conversation plusieurs tours de conversation, et ainsi de suite.

```mermaid theme={"system"}
flowchart TB
    Agent["Agent<br/>agent_name"]

    Agent --> S1 & S2

    S1["Conversation 1<br/>conversation_id<br/>(sans span OTel)"]
    S2["Conversation 2<br/>conversation_id<br/>(sans span OTel)"]

    S1 --> T1 & T2
    S2 --> T3

    T1["Tour de conversation 1<br/>invoke_agent<br/>(span racine, trace distincte)"]
    T2["Tour de conversation 2<br/>invoke_agent<br/>(span racine, trace distincte)"]
    T3["Tour de conversation 1<br/>invoke_agent<br/>(span racine, trace distincte)"]

    T1 --> L1 & L2
    L1["Appel LLM<br/>chat"]
    L2["Appel LLM<br/>chat"]

    L1 --> Tool1["Appel d’outil<br/>execute_tool"]

    classDef agent fill:#DE72FF33,stroke:#454B52,stroke-width:2px
    classDef conversation fill:#FFD95C33,stroke:#454B52,stroke-width:2px
    classDef turn fill:#00CDDB33,stroke:#454B52,stroke-width:2px
    classDef llm fill:#FFCBAD33,stroke:#454B52,stroke-width:2px
    classDef tool fill:#f4f4f5,stroke:#454B52,stroke-width:2px

    class Agent agent
    class S1,S2 conversation
    class T1,T2,T3 turn
    class L1,L2 llm
    class Tool1 tool
```

Une conversation regroupe les tours de conversation au moyen d’un attribut `conversation_id` partagé, et non d’un span parent : chaque tour de conversation démarre donc sa propre trace OTel. Cette conception prend en charge le traçage distribué et l’exécution parallèle. Le client envoie les spans directement au collecteur OTel, sans aucune agrégation côté serveur.

<Tip>
  Pour intégrer Agent Lens à des SDK d’agent ou à des harness tels que le Claude Agent SDK ou Codex, consultez [Choisir une intégration d’agent](/fr/products/agent-lens/get-started/integrations). Ces intégrations définissent `conversation_id` à partir de la session du SDK ou du harness : vous n'avez donc pas besoin de `start_conversation()` pour regrouper leurs tours de conversation. Les intégrations des SDK de fournisseurs de LLM (OpenAI, Anthropic et Google Gen AI) ne créent pas de conversations, et Agent Lens n'affiche que les appels exécutés au sein d'une conversation. Utilisez donc les API décrites sur cette page pour ouvrir une conversation et des tours de conversation autour de ces appels.
</Tip>

<h2 id="agent-tracing-apis">
  API de traçage d’agents
</h2>

Les sections suivantes décrivent chaque fonction de traçage de premier niveau ainsi que les arguments qu’elle accepte. Utilisez ces fonctions pour instrumenter les couches conversation, tour de conversation, appel LLM et appel d’outil du modèle de données présenté dans la section précédente.

Agent Lens expose les fonctions de premier niveau suivantes. Chaque fonction renvoie un objet qui peut s’utiliser comme gestionnaire de contexte (avec `with` en Python, ou `try/finally` en TypeScript) ou que vous pouvez fermer manuellement en appelant `.end()`.

<h3 id="start-a-conversation">
  Démarrer une conversation
</h3>

`start_conversation()` (Python) ou `startConversation()` (TypeScript) ajoute un attribut `conversation_id` à chaque span enfant afin que les tours de conversation soient regroupés dans l’onglet **Conversations**. Si vous transmettez un `conversation_id` / `conversationId`, celui-ci doit rester stable pendant toute la durée de vie de la conversation. Réutilisez le même ID pour ajouter de nouveaux tours de conversation à une conversation existante. Si vous l’omettez, le SDK génère automatiquement un UUID.

La conversation active est stockée dans le contexte (un `ContextVar` Python ou un `AsyncLocalStorage` Node.js). Tout code s’exécutant dans le même contexte asynchrone peut donc la récupérer avec `tracing.get_current_conversation()` / `tracing.getCurrentConversation()` sans avoir à transmettre explicitement l’objet conversation.

<Tabs>
  <Tab title="Python">
    ```python lines theme={"system"}
    conversation = tracing.start_conversation(
        agent_name="my-agent",    # Facultatif : identifie l’agent dans l’interface utilisateur. Si vous l’omettez, la conversation n’est pas regroupée sous un agent nommé.
        conversation_id="",       # Facultatif : ID stable pour regrouper les tours de conversation ; généré automatiquement s’il est vide.
        model="",                 # Facultatif : modèle par défaut pour les tours de cette conversation.
        conversation_name="",     # Facultatif : libellé lisible affiché dans l’interface utilisateur.
        include_content=True,     # Facultatif : définissez sur False pour exclure le corps des messages des spans.
        continue_parent_trace=False,  # Facultatif : se rattacher à une trace OTel existante au lieu d’en démarrer une nouvelle.
    )
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript lines theme={"system"}
    const conversation = tracing.startConversation({
      agentName: 'my-agent',  // Facultatif : identifie l’agent dans l’interface utilisateur. Si vous l’omettez, la conversation n’est pas regroupée sous un agent nommé.
      conversationId: '',     // Facultatif : ID stable pour regrouper les tours de conversation, généré automatiquement s’il est vide.
      model: '',              // Facultatif : modèle par défaut pour les tours de cette conversation.
    });
    ```
  </Tab>
</Tabs>

<h3 id="start-a-turn">
  Démarrer un tour de conversation
</h3>

`start_turn()` (Python) et `startTurn()` (TypeScript) créent un nouveau span `invoke_agent` qui devient la racine d’une nouvelle trace OTel. Agent Lens utilise ce span pour représenter un échange complet entre l’utilisateur et l’agent dans la vue chronologique.

<Tabs>
  <Tab title="Python">
    ```python lines theme={"system"}
    turn = tracing.start_turn(
        user_message="What is the weather in Tokyo?",  # Texte saisi par l’utilisateur.
        agent_name="my-agent",   # Facultatif : redéfinit le nom de l’agent défini au niveau de la conversation.
        model="gpt-4o",          # Facultatif : modèle utilisé pour ce tour de conversation.
    )
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript lines theme={"system"}
    const turn = tracing.startTurn({
      userMessage: 'What is the weather in Tokyo?',  // Texte saisi par l’utilisateur.
      agentName: 'my-agent',  // Facultatif : redéfinit le nom de l’agent défini au niveau de la conversation.
      model: 'gpt-4o',        // Facultatif : modèle utilisé pour ce tour de conversation.
    });
    ```
  </Tab>
</Tabs>

Vous pouvez l’appeler de deux façons :

* **En tant que fonction de premier niveau** (`tracing.start_turn(...)` / `tracing.startTurn(...)`), comme dans les exemples ci-dessous. Elle récupère la conversation active à partir du contexte et hérite de son ID de conversation. Si aucune conversation n’est active, le tour de conversation est créé sans `conversation_id` et n’est regroupé avec aucun autre tour de conversation.
* **En tant que méthode d’instance** d’une conversation dont vous détenez une référence (`conversation.start_turn(...)` / `conversation.startTurn(...)
  `). Cette forme est pratique lorsqu’un objet conversation explicite est disponible dans la portée courante, par exemple à l’intérieur d’un bloc de gestionnaire de contexte. L’exemple [« Gestionnaire de contexte ou
  schéma try-finally »](#context-manager-or-try-finally-pattern), présenté plus loin dans ce guide, utilise cette forme. Consultez le [tableau
  du modèle de données](#the-agent-data-model) présenté plus haut pour accéder directement aux pages de référence `Conversation`, `Turn`, `LLM`, `Tool` et `SubAgent`
  des deux SDK.

<h3 id="start-an-llm-call">
  Démarrer un appel LLM
</h3>

`start_llm()` / `startLLM()` crée un span `chat` imbriqué dans le tour de conversation en cours. Agent Lens utilise ce span pour afficher dans l’interface utilisateur l’utilisation des jetons, le nom du modèle, les messages d’entrée et de sortie, ainsi que le raisonnement.

<Tabs>
  <Tab title="Python">
    ```python lines theme={"system"}
    llm = tracing.start_llm(
        model="gpt-4o",             # L’identifiant du modèle.
        provider_name="openai",     # Facultatif : nom du fournisseur, par exemple "openai", "anthropic". Voir la remarque ci-dessous.
        system_instructions=["Be concise."],  # Facultatif : chaînes du prompt système.
    )
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript lines theme={"system"}
    const llm = tracing.startLLM({
      model: 'gpt-4o',          // L’identifiant du modèle.
      providerName: 'openai',   // Facultatif : nom du fournisseur, par exemple "openai", "anthropic". Voir la remarque ci-dessous.
    });
    ```
  </Tab>
</Tabs>

Une fois l’appel LLM terminé, attribuez les données de la réponse à l’objet `llm` avant sa fermeture :

<Tabs>
  <Tab title="Python">
    ```python lines theme={"system"}
    with tracing.start_llm(model="gpt-4o", provider_name="openai") as llm:
        response = openai_client.chat.completions.create(...)
        llm.input_messages = [Message(role="user", content="...")]
        llm.output_messages = [Message(role="assistant", content=response.choices[0].message.content)]
        llm.usage = Usage(
            input_tokens=response.usage.prompt_tokens,
            output_tokens=response.usage.completion_tokens,
        )
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript lines theme={"system"}
    const llm = tracing.startLLM({ model: 'gpt-4o', providerName: 'openai' });
    try {
      const response = await openaiClient.chat.completions.create({ ... });
      llm.record({
        inputMessages: [{ role: 'user', content: '...' }],
        outputMessages: [{ role: 'assistant', content: response.choices[0].message.content ?? '' }],
        usage: {
          inputTokens: response.usage?.prompt_tokens,
          outputTokens: response.usage?.completion_tokens,
        },
      });
    } finally {
      llm.end();
    }
    ```

    `llm.record()` est un raccourci qui permet d’attribuer `inputMessages`, `outputMessages`, `usage` et `reasoning` en un seul appel. Vous pouvez toujours définir les propriétés une par une si vous le préférez. Le SDK Python expose la même méthode sous la forme `llm.record(...)`, avec des arguments nommés en snake\_case.
  </Tab>
</Tabs>

Indiquez explicitement `provider_name` / `providerName`. Agent Lens ne le déduit pas de la chaîne du modèle.

<h3 id="start-a-tool-call">
  Démarrer un appel d’outil
</h3>

`start_tool()` / `startTool()` crée un span `execute_tool`. Ce span devient l’enfant du span OTel actif dans le contexte (généralement le span `chat` de l’appel LLM qui a généré l’appel d’outil).

<Tabs>
  <Tab title="Python">
    ```python lines theme={"system"}
    tool = tracing.start_tool(
        name="get_weather",                  # Nom de l’outil tel que déclaré au LLM.
        arguments='{"city": "Tokyo"}',       # Chaîne JSON des arguments de l’outil.
        tool_call_id="call_abc123",          # Facultatif : ID de l’appel d’outil issu de la réponse du LLM.
    )
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript lines theme={"system"}
    const tool = tracing.startTool({
      name: 'get_weather',            // Nom de l’outil tel que déclaré au LLM.
      args: '{"city": "Tokyo"}',      // Facultatif : chaîne JSON des arguments de l’outil.
      toolCallId: 'call_abc123',      // Facultatif : ID de l’appel d’outil issu de la réponse du LLM.
    });
    ```
  </Tab>
</Tabs>

Attribuez le résultat de l’outil avant de fermer le span :

<Tabs>
  <Tab title="Python">
    ```python lines theme={"system"}
    with tracing.start_tool(name="get_weather", arguments='{"city": "Tokyo"}') as tool:
        result = get_weather_api("Tokyo")
        tool.result = result  # Accepte un dict, une liste ou une chaîne. Encodé automatiquement en JSON.
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript lines theme={"system"}
    const tool = tracing.startTool({ name: 'get_weather', args: '{"city": "Tokyo"}' });
    try {
      tool.result = await getWeatherApi('Tokyo');
    } finally {
      tool.end();
    }
    ```
  </Tab>
</Tabs>

<h2 id="usage-patterns-for-agent-tracing">
  Modèles d’utilisation pour le traçage d’agents
</h2>

Les sections suivantes décrivent comment combiner ces fonctions selon la structure de votre code d’agent.

Les exemples suivants utilisent deux types du SDK Agent Lens :

* `Message` ([Python](/fr/products/agent-lens/reference/python-sdk/message-types#message) · [TypeScript](/fr/products/agent-lens/reference/typescript-sdk/interfaces/message)) représente une entrée individuelle d’une conversation : une entrée utilisateur, une réponse de l’assistant, un prompt système ou le résultat d’un outil. Attribuez une liste de messages à `llm.input_messages` / `llm.inputMessages` pour enregistrer ce que le modèle a reçu, et à `llm.output_messages` / `llm.outputMessages` pour enregistrer ce qu’il a produit.
* `Usage` ([Python](/fr/products/agent-lens/reference/python-sdk/message-types#usage) · [TypeScript](/fr/products/agent-lens/reference/typescript-sdk/interfaces/usage)) capture le nombre de jetons indiqué dans la réponse du LLM et s’attribue à `llm.usage`.

Agent Lens s’appuie sur ces deux types pour afficher dans l’interface les entrées, les sorties et l’utilisation des jetons de chaque appel LLM.

<h3 id="context-manager-or-try-finally-pattern">
  Gestionnaire de contexte ou schéma try-finally
</h3>

Pour la plupart des agents, utilisez un gestionnaire de contexte en Python ou un schéma try-finally en TypeScript. Le span est fermé et envoyé à la fin du bloc, même si une exception se produit.

Agent Lens stocke dans le contexte la conversation, le tour de conversation et l’appel LLM actifs. Ainsi, toute fonction appelée dans un bloc peut appeler `start_llm()` / `startLLM()` ou `start_tool()` / `startTool()` sans avoir à conserver de référence explicite au parent. Ce mécanisme fonctionne d’un module à l’autre, tant que le code s’exécute dans le même contexte asynchrone. Pour récupérer les objets actifs depuis n’importe quel niveau de la pile d’appels, utilisez `tracing.get_current_conversation()` / `tracing.getCurrentConversation()`, `tracing.get_current_turn()` / `tracing.getCurrentTurn()` et `tracing.get_current_llm()` / `tracing.getCurrentLLM()`.

<Tabs>
  <Tab title="Python">
    ```python lines highlight="13,14,17,25,29" theme={"system"}
    from coreweave.forge.agentlens import tracing
    from coreweave.forge.agentlens.tracing import Message, Usage

    # Fonctions fictives : remplacez-les par vos propres implémentations.
    def call_openai(*args, **kwargs):
        pass  # Remplacez par l’appel à votre client LLM.

    def get_weather_api(city: str) -> str:
        return "24°C, sunny"  # Remplacez par l’appel à votre API météo.

    tracing.init("[YOUR-TEAM]/[YOUR-PROJECT]")

    with tracing.start_conversation(agent_name="weather-bot") as conversation:
        with conversation.start_turn(user_message="What is the weather in Tokyo?") as turn:

            # Premier appel LLM : renvoie un appel d’outil.
            with tracing.start_llm(model="gpt-4o", provider_name="openai") as llm:
                response = call_openai(...)
                llm.input_messages = [Message(role="user", content="What is the weather?")]
                llm.think("User wants weather data, I should call get_weather.")
                llm.output("Let me check the weather for you.")
                llm.usage = Usage(input_tokens=100, output_tokens=20)

                # Appel d’outil : enfant de l’appel LLM qui l’a demandé.
                with tracing.start_tool(name="get_weather", arguments='{"city":"Tokyo"}') as tool:
                    tool.result = get_weather_api("Tokyo")  # Renvoie "24°C, sunny".

            # Second appel LLM : synthétise la réponse finale.
            with tracing.start_llm(model="gpt-4o", provider_name="openai") as llm:
                llm.input_messages = [Message(role="user", content="What is the weather?")]
                llm.output("It is 24°C and sunny in Tokyo today.")
                llm.usage = Usage(input_tokens=150, output_tokens=30)

    tracing.shutdown()
    ```
  </Tab>

  <Tab title="TypeScript">
    Encapsulez le run de l’agent dans `tracing.runIsolated()` afin que son contexte de conversation, de tour de conversation et de LLM soit conservé d’un `await` à l’autre et reste isolé des autres runs exécutés en parallèle.

    ```typescript lines highlight="11,12,14,17,25,36" theme={"system"}
    import { tracing } from '@coreweave/forge-sdk/agentlens';
    import type { Message, Usage } from '@coreweave/forge-sdk/agentlens/tracing';

    // Fonction fictive : remplacez-la par votre propre implémentation.
    async function getWeatherApi(city: string): Promise<string> {
      return '24°C, sunny';  // Remplacez par l’appel à votre API météo.
    }

    await tracing.init('[YOUR-TEAM]/[YOUR-PROJECT]');

    await tracing.runIsolated(async () => {
      const conversation = tracing.startConversation({ agentName: 'weather-bot' });
      try {
        const turn = conversation.startTurn({ userMessage: 'What is the weather in Tokyo?' });
        try {
          // Premier appel LLM : renvoie un appel d’outil.
          const llm = tracing.startLLM({ model: 'gpt-4o', providerName: 'openai' });
          try {
            llm.inputMessages = [{ role: 'user', content: 'What is the weather?' }];
            llm.think('User wants weather data, I should call get_weather.');
            llm.output('Let me check the weather for you.');
            llm.usage = { inputTokens: 100, outputTokens: 20 };

            // Appel d’outil : enfant de l’appel LLM qui l’a demandé.
            const tool = tracing.startTool({ name: 'get_weather', args: '{"city":"Tokyo"}' });
            try {
              tool.result = await getWeatherApi('Tokyo');  // Renvoie "24°C, sunny".
            } finally {
              tool.end();
            }
          } finally {
            llm.end();
          }

          // Second appel LLM : synthétise la réponse finale.
          const llm2 = tracing.startLLM({ model: 'gpt-4o', providerName: 'openai' });
          try {
            llm2.inputMessages = [{ role: 'user', content: 'What is the weather?' }];
            llm2.output('It is 24°C and sunny in Tokyo today.');
            llm2.usage = { inputTokens: 150, outputTokens: 30 };
          } finally {
            llm2.end();
          }
        } finally {
          turn.end();
        }
      } finally {
        conversation.end();
      }
    });

    await tracing.shutdown();
    ```
  </Tab>
</Tabs>

<h3 id="manual-start-and-end-pattern">
  Modèle de démarrage et de fin manuels
</h3>

Appelez `.end()` explicitement lorsque vous ne pouvez pas utiliser de blocs `with` ni `try/finally`, par exemple lorsque vous ouvrez et fermez des spans dans des appels de fonction distincts, ou lorsque vous gérez un cycle de vie asynchrone en dehors d’une coroutine. Il vous incombe d’appeler `.end()` sur chaque objet que vous créez, afin que les spans soient fermés et transmis au collecteur. En TypeScript, terminer un tour de conversation ou une conversation ferme également tous ses descendants encore ouverts.

<Tabs>
  <Tab title="Python">
    ```python lines highlight="1,2,4,9,15" theme={"system"}
    conversation = tracing.start_conversation(agent_name="weather-bot")
    turn = conversation.start_turn(user_message="What is the weather?")

    llm = tracing.start_llm(model="gpt-4o", provider_name="openai")
    llm.input_messages = [Message(role="user", content="What is the weather?")]
    llm.output("Let me check.")
    llm.usage = Usage(input_tokens=100, output_tokens=20)

    tool = tracing.start_tool(name="get_weather", arguments='{"city": "Tokyo"}')
    tool.result = "24°C, sunny"
    tool.end()   # end() est idempotent : il peut être appelé plusieurs fois sans risque.

    llm.end()

    llm2 = tracing.start_llm(model="gpt-4o", provider_name="openai")
    llm2.output("It is 24°C and sunny in Tokyo.")
    llm2.usage = Usage(input_tokens=150, output_tokens=30)
    llm2.end()

    turn.end()
    conversation.end()
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript lines highlight="1,2,3,5,10,16" theme={"system"}
    await tracing.runIsolated(async () => {
      const conversation = tracing.startConversation({ agentName: 'weather-bot' });
      const turn = conversation.startTurn({ userMessage: 'What is the weather?' });

      const llm = tracing.startLLM({ model: 'gpt-4o', providerName: 'openai' });
      llm.inputMessages = [{ role: 'user', content: 'What is the weather?' }];
      llm.output('Let me check.');
      llm.usage = { inputTokens: 100, outputTokens: 20 };

      const tool = tracing.startTool({ name: 'get_weather', args: '{"city": "Tokyo"}' });
      tool.result = '24°C, sunny';
      tool.end();  // end() est idempotent : il peut être appelé plusieurs fois sans risque.

      llm.end();

      const llm2 = tracing.startLLM({ model: 'gpt-4o', providerName: 'openai' });
      llm2.output('It is 24°C and sunny in Tokyo.');
      llm2.usage = { inputTokens: 150, outputTokens: 30 };
      llm2.end();

      turn.end();
      conversation.end();
    });
    ```
  </Tab>
</Tabs>

<h2 id="semantic-conventions">
  Conventions sémantiques
</h2>

Le SDK Agent Lens émet des spans OTel conformes aux [conventions sémantiques GenAI](https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/) et aux [conventions de spans d’agent GenAI](https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-agent-spans/). Agent Lens accepte n’importe quel span OTel, stocke tous ses attributs et permet de les interroger. Vous pouvez ajouter des attributs personnalisés aux spans avec `set_attributes()` / `setAttributes()` sur n’importe quel objet de traçage Agent Lens. Voir [Définir des attributs sur les spans d’agent](/fr/products/agent-lens/tracing/attributes).

Le SDK dispose de son propre fournisseur de traceurs OpenTelemetry privé. Il exporte uniquement les spans créés via Agent Lens: il ne remplace pas le fournisseur global de votre application et n’exporte pas les spans issus d’une instrumentation tierce.

<h2 id="how-data-appears-in-the-agent-lens-ui">
  Affichage des données dans l’interface Agent Lens
</h2>

Une fois votre agent instrumenté à l’aide des modèles précédents, puis exécuté, vos traces apparaissent dans l’onglet **Conversations** de votre projet Agent Lens à l’adresse `https://`.

* L’**onglet Conversations** affiche toutes les conversations, accompagnées d’une mini-carte de l’activité des tours de conversation.
* La **vue détaillée d’une conversation** s’ouvre lorsque vous cliquez sur une conversation. Elle affiche tous ses tours de conversation, ses appels LLM, ses exécutions d’outils, le nombre de jetons ainsi que tout feedback joint.

Pour plus de détails sur la consultation des données capturées dans Agent Lens, voir [Afficher l’activité de l’agent](/fr/products/agent-lens/conversations/view-activity).
