# Boucle de l’agent

Comment l’interface CLI Copilot traite un message utilisateur de bout en bout : de l’invite à session.idle.

<!-- markdownlint-disable GHD046 GHD005 -->

<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->

## Architecture

![Diagramme : diagramme graphique montrant le processus décrit.](/assets/images/help/copilot/copilot-sdk/features-agent-loop-diagram-0.png)

Le **SDK** est une couche de transport : il envoie votre requête au **Copilot CLI** via JSON-RPC et renvoie les événements à votre application.
**L’interface CLI** est l’orchestrateur qui exécute la boucle d’utilisation de l’outil agentique, en effectuant un ou plusieurs appels d’API LLM jusqu’à ce que la tâche soit effectuée.

## Boucle d’utilisation des outils

Lorsque vous appelez `session.send({ prompt })`, le CLI entre dans une boucle :

![Diagramme : Organigramme montrant le processus décrit.](/assets/images/help/copilot/copilot-sdk/features-agent-loop-diagram-1.png)

Le modèle voit **l’historique complet des conversations** sur chaque appel : invite système, message utilisateur et tous les appels et résultats d’outils précédents.

**Informations clés :** Chaque itération de cette boucle est exactement un appel d’API LLM, visible sous la forme d’une `assistant.turn_start` / `assistant.turn_end` paire dans le journal des événements. Il n’y a pas d’appels masqués.

## Tours de conversation : définition

Un **tour** est un seul appel d’API LLM et ses conséquences :

1. L’interface CLI envoie l’historique des conversations au LLM
2. Le LLM répond (éventuellement avec des demandes d’outils)
3. Si des outils ont été demandés, l’interface CLI les exécute
4. `assistant.turn_end` est émis

Un message d’utilisateur unique entraîne généralement **plusieurs tours**. Par exemple, une question telle que « Comment fonctionne X dans cette base de code ? » peut produire :

| Tourner                      | Ce que fait le modèle                                                  | toolRequests ? |
| ---------------------------- | ---------------------------------------------------------------------- | -------------- |
| 1                            | Appelez `grep` et `glob` pour rechercher dans la base de code          |                |
| ✅ Oui                        |                                                                        |                |
| 2                            | Lit des fichiers spécifiques en fonction des résultats de la recherche |                |
| ✅ Oui                        |                                                                        |                |
| 3                            | Lit d’autres fichiers pour un contexte plus approfondi                 |                |
| ✅ Oui                        |                                                                        |                |
| 4                            | Produit la réponse de texte finale                                     |                |
| ❌ Non → la boucle se termine |                                                                        |                |

Le modèle décide de chaque tour s’il faut demander plus d’outils ou produire une réponse finale. Chaque appel voit le **contexte cumulé complet** (tous les appels et résultats d’outils précédents), afin qu’il puisse prendre une décision éclairée quant à la quantité d’informations suffisantes.

## Flux d’événements pour une interaction à plusieurs tours

![Diagramme : Organigramme montrant le processus décrit.](/assets/images/help/copilot/copilot-sdk/features-agent-loop-diagram-2.png)

## Qui déclenche chaque tour ?

| Acteur                | Responsabilité                                                                                                             |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Votre application** | Envoie l’invite initiale via `session.send()`                                                                              |
| **Copilot CLI**       | Exécute la boucle d’utilisation des outils : exécute des outils et alimente les résultats vers le LLM pour le tour suivant |
| **LLM**               | Détermine s’il faut demander des outils (continuer la boucle) ou produire une réponse finale (arrêter)                     |
| **SDK**               | Transmet les événements ; ne contrôle pas la boucle                                                                        |

La CLI est purement mécanique : « le modèle a demandé des outils → exécution → nouvel appel du modèle ». Le **modèle** est le décideur pour quand arrêter.

## Comparaison de `session.idle` et de `session.task_complete`

Il s’agit de deux signaux d’achèvement différents avec des garanties très différentes :

### `session.idle`

* **Toujours émis** lorsque la boucle d’utilisation de l’outil se termine
* **Éphémère** : non conservé sur le disque, non relecturé lors de la reprise de session
* Signifie : « l’agent a arrêté le traitement et est prêt pour le message suivant »
* **Utilisez-le** comme signal fiable « terminé »

La méthode du kit de développement logiciel `sendAndWait()` (SDK) attend cet événement :

```typescript
// Blocks until session.idle fires
const response = await session.sendAndWait({ prompt: "Fix the bug" });
```

### `session.task_complete`

* **Émis éventuellement** : exige que le modèle le signale explicitement
* **Persisté** : enregistré dans le journal des événements de session sur le disque
* Signifie : « l’agent considère la tâche globale remplie »
* Porte un champ facultatif `summary`

```typescript
session.on("session.task_complete", (event) => {
    console.log("Task done:", event.data.summary);
});
```

### Mode pilote automatique : la CLI invite à déclencher `task_complete`

En **mode Autopilot** (opération sans tête/autonome), l’interface CLI suit activement si le modèle a appelé `task_complete`. Si la boucle d’utilisation des outils se termine sans cela, le CLI injecte un message utilisateur synthétique pour inciter le modèle :

> *« Vous n’avez pas encore marqué la tâche comme étant terminée à l’aide de l’outil task\_complete. Si vous planifiez, arrêtez la planification et démarrez l’implémentation. Vous n’avez pas terminé tant que vous n’avez pas terminé la tâche.*

Cela redémarre efficacement la boucle d’utilisation de l’outil : le modèle voit le coup de pouce en tant que nouveau message utilisateur et continue de fonctionner. L’incitation indique également au modèle **de ne pas** appeler `task_complete` prématurément :

* Ne l’appelez pas si vous avez des questions ouvertes : prendre des décisions et continuer à travailler
* Ne l’appelez pas si vous rencontrez une erreur : essayez de le résoudre
* N’appelez-le pas s’il y a des étapes restantes : effectuez-les d’abord

Cela crée un **mécanisme d’achèvement à deux niveaux** dans Autopilot :

1. Le modèle appelle `task_complete` avec un résumé → CLI émet `session.task_complete` → terminé
2. Le modèle s’arrête sans l’appeler → relances de CLI → le modèle continue ou appelle `task_complete`

### Pourquoi `task_complete` peut ne pas apparaître

En **mode interactif** (chat normal), le CLI ne sollicite pas `task_complete`. Le modèle peut l’ignorer entièrement. Raisons courantes :

* **Q\&A conversationnelle** : le modèle répond à une question et s’arrête simplement : il n’y a pas de « tâche » discrète à terminer
* **Discrétion** du modèle : le modèle produit une réponse de texte finale sans appeler le signal complet de la tâche
* **Sessions interrompues** : la session se termine avant que le modèle atteigne un point d’achèvement

Le CLI émet `session.idle` dans tous les cas, car il s’agit d’un signal mécanique (la boucle s’est terminée), et non d’un signal sémantique (le modèle estime avoir terminé).

### Laquelle devez-vous utiliser ?

| Cas d’utilisation                                  | Signal |
| -------------------------------------------------- | ------ |
| « Attendre que l’agent termine le traitement »     |        |
| `session.idle`                                     |        |
| ✅                                                  |        |
|                                                    |        |
| « Savoir quand une tâche de codage est effectuée » |        |
| `session.task_complete` (meilleur effort)          |        |
| « Délai d’expiration/gestion des erreurs »         |        |
| `session.idle`                                     |        |

*

`session.error`
✅
|

## Comptage des appels LLM

Le nombre de paires dans le journal des `assistant.turn_start` / `assistant.turn_end` événements est égal au nombre total d’appels d’API LLM effectués. Il n’y a pas d’appels masqués pour la planification, l’évaluation ou la vérification de l’achèvement.

Pour inspecter le nombre de tour pour une session :

```bash
# Count turns in a session's event log
grep -c "assistant.turn_start" ~/.copilot/session-state/<sessionId>/events.jsonl
```

## Lectures complémentaires

* [Événements de session de streaming](/fr/copilot/how-tos/copilot-sdk/features/streaming-events) : Référence au niveau du champ complet pour chaque type d’événement
* [Reprise de session et persistance](/fr/copilot/how-tos/copilot-sdk/features/session-persistence) : Enregistrement et reprise des sessions
* [Utilisation de crochets](/fr/copilot/how-tos/copilot-sdk/features/hooks) : Interception d’événements dans la boucle (autorisations, outils)