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

# Threads

> Effectuez des tâches agentiques en utilisant le système de threads

<Info>
  Cette documentation concerne la version **Wise Wolf** (février 2026) et ultérieures.
  Si vous êtes sur **Unique Urchin** (décembre 2025) ou **Victorious Vicuna** (janvier 2026), veuillez consulter [la documentation héritée des threads agentiques](/fr/developer-resources/chat-and-ai-models/agent-api).
</Info>

## Motivation

L'API Thread vous permet d'engager des conversations en s'appuyant sur des capacités de raisonnement multi-outils et en utilisant des [agents](/fr/developer-resources/agents-and-threads/agents) spécialisés. C'est la méthode recommandée pour interagir avec les outils Paradigm.

## Terminologie

### Tour (Turn)

Une interaction unique entre un utilisateur et le modèle, comprenant une question utilisateur, un raisonnement en plusieurs étapes, des appels d'outils et la réponse finale du modèle.

### Fil (Thread)

Une conversation composée d'une séquence de tours.

### Parties (Parts)

Un composant de la réponse de l'agent dans un tour. Il peut être de type `reasoning`, `tool_call` ou `text` (réponse finale à l'utilisateur).
Les parties d'un message d'agent au sein d'un tour sont structurées dans l'ordre suivant :

* une partie `reasoning` expliquant le raisonnement sur le fait que l'agent choisisse ou non d'utiliser un outil ou de renvoyer directement la réponse finale ;
* une partie `tool_call` contenant les informations sur l'outil appelé ainsi que le résultat brut de l'outil ;
* répéter les deux premières étapes jusqu'à ce que l'agent choisisse de renvoyer la réponse finale ou que le budget de raisonnement soit atteint ;
* une partie `text` contenant la réponse finale.

### Message

Un ensemble de parties correspondant, au sein d'un tour, soit à la réponse de l'agent soit à la question de l'utilisateur. Un **tour est donc principalement composé d'une liste de 2 messages** : la question utilisateur et la réponse de l'agent.

### Source

Une source utilisée par un outil pour générer la réponse finale du tour ; elle peut être de type `web` ou `document`.

### Artefact (Artifact)

Un fichier généré par un outil, attaché à un tour.

## Démarrage rapide

Vous pouvez initialiser un nouveau fil de conversation à l'aide de l'endpoint [POST /api/v3/threads/turns](/api-reference-v3/threads/create-a-conversation-thread-with-initial-turn).

<Warning>
  Le champ `chat_setting_id` du payload est déprécié et l'utilisation de `agent_id` est désormais préférée. Pour des raisons de rétrocompatibilité, `chat_setting_id` est toujours supporté. Notez que si vous spécifiez à la fois `agent_id` et `chat_setting_id`, le champ `agent_id` prendra le dessus.
</Warning>

```py theme={null}
import os
import requests

# Récupérer la clé API depuis l'environnement
api_key = os.getenv("PARADIGM_API_KEY")
# Récupérer l'URL de base depuis l'environnement (par défaut : instance publique)
base_url = os.getenv("PARADIGM_BASE_URL", "https://paradigm.lighton.ai/api/v3")

response = requests.post(
    f"{base_url}/threads/turns",
    headers={"Authorization": f"Bearer {api_key}"},
    json={
        "agent_id": 1,
        "query": "What is the capital of France?"
    }
).json()
```

En précisant :

* `agent_id` (*optionnel*) : l'identifiant de l'[Agent](/fr/developer-resources/agents-and-threads/agents) à utiliser pour cette requête. Si laissé vide, l'agent par défaut de votre organisation sera utilisé. Vous pouvez lister les agents disponibles via l'endpoint \[GET /api/v3/agents]\([api-reference-v3/threads/](/api-reference-v3/agents/list-all-agents).
* `query` : la question de l'utilisateur.

<Accordion title="Exemple de réponse">
  ```json theme={null}
  {
    "id": "9339cf12-8530-421d-8dda-79cd3016a182",
    "object": "turn",
    "thread": "783b089b-0ecc-496b-b0c3-70d0f327d9b8",
    "status": "completed",
    "messages": [
      {
        "id": "2951681d-9477-4e8d-889b-0f63bef890f6",
        "object": "message",
        "role": "user",
        "parts": [
          {
            "type": "text",
            "text": "What is the capital of France?"
          }
        ],
        "created_at": "2025-12-16T16:01:53.806331Z"
      },
      {
        "id": "5ec22b40-ba6c-40ab-b94d-97fc05d5c142",
        "object": "message",
        "role": "assistant",
        "parts": [
          {
            "type": "reasoning",
            "reasoning": "Basic factual question - no tools needed."
          },
          {
            "type": "text",
            "text": "La capitale de la France est Paris."
          }
        ],
        "created_at": "2025-12-16T16:01:56.210968Z"
      }
    ],
    "created_at": "2025-12-16T16:01:53.804779Z"
  }
  ```
</Accordion>

Dans ce cas, la réponse de l'agent sur ce tour est composée de deux parties :

* une partie **reasoning** expliquant le raisonnement derrière la réponse ;
* une partie **text** contenant la réponse finale.

Notez que **la dernière partie de la réponse de l'agent est toujours de type `text` et constitue la réponse finale** et que **la réponse de l'agent est toujours le second et dernier message**.

<Warning>
  Si le tour met trop de temps à être généré, vous recevrez une réponse **HTTP 202** avec l'**ID du fil** (`tread`) et l'**ID du tour** (`turn_id`) dans le payload. Vous pouvez ensuite utiliser l'endpoint [GET /api/v3/threads/:id/turns/:turn\_id](/api-reference-v3/threads/retrieve-a-conversation-thread) pour sonder le champ `status` jusqu'à ce qu'il soit à l'état `completed`, puis récupérer la réponse finale.
</Warning>

<Tip>
  Vous pouvez également éviter l'attente et utiliser le [Mode Arrière-plan](#mode-arriere-plan) pour générer le tour en arrière-plan.
</Tip>

Vous pouvez accéder à la réponse finale de l'agent comme ceci :

```py theme={null}
# Exemple minimal pour illustrer le schéma d'accès
response = {
    "messages": [
        {"parts": []},
        {"parts": [{"type": "text", "text": "Paris"}]}
    ]
}
answer: str = response["messages"][-1]["parts"][-1]["text"]
```

Vous pouvez également récupérer le `thread_id` comme ceci :

```py theme={null}
response = {"thread": "783b089b-0ecc-496b-b0c3-70d0f327d9b8"}
thread_id: str = response["thread"]
```

Vous pouvez ensuite continuer dans la même conversation avec l'endpoint [POST /api/v3/threads/:id/turns](/api-reference-v3/threads/create-a-conversation-turn-in-a-thread) pour créer un nouveau tour.

## Recettes

Pour les recettes suivantes, vous pouvez soit utiliser :

* l'endpoint [POST /api/v3/threads/turns](/api-reference-v3/threads/create-a-conversation-thread-with-initial-turn) pour créer un tour dans un nouveau fil ;
* l'endpoint [POST /api/v3/threads/:id/turns](/api-reference-v3/threads/create-a-conversation-turn-in-a-thread) pour créer un tour dans un fil existant et ainsi bénéficier du contexte déjà présent si nécessaire.

<Warning>
  Bien que l'endpoint [POST /api/v3/threads/turns](/api-reference-v3/threads/create-a-conversation-thread-with-initial-turn) fournisse un raccourci pour créer directement un fil avec un tour, **il ne supporte pas le mode streaming**. Si vous souhaitez utiliser le streaming, créez un fil via l'endpoint [POST /api/v3/threads](/api-reference-v3/threads/create-a-conversation-thread) puis créez un tour dans ce fil via l'endpoint [POST /api/v3/threads/:id/turns](/api-reference-v3/threads/create-a-conversation-turn-in-a-thread) en spécifiant `stream=true`.
</Warning>

Dans ces exemples nous utiliserons la méthode impliquant un nouveau fil, mais les deux endpoints acceptent le même payload et renvoient le même schéma de réponse.
On suppose également que vous parsez la réponse de l'API en dictionnaire Python, comme dans la section [Démarrage rapide](#demarrage-rapide).

<Tip>
  Pour les usages unitaires au sein de workflows, il est recommandé d'utiliser le premier endpoint et de créer un fil frais par tour.
</Tip>

### Restreindre par fichier, espaces de travail ou tags

Vous pouvez restreindre une requête à une liste de **Workspaces** et/ou de **Tags** ou de **Fichiers** (documents) en utilisant les paramètres `workspace_ids`, `tag_ids` ou `file_ids` dans le payload. Par exemple, via l'endpoint [POST /api/v3/threads/turns](/api-reference-v3/threads/create-a-conversation-thread-with-initial-turn) pour restreindre aux fichiers dans les workspaces d'id `1` **ou** `2` **et** qui sont attachés aux tags d'id `4` **ou** `5` :

```json theme={null}
{
  "agent_id": 1,
  "query": "What is the conclusion of the last quaterly meeting note?",
  "workspace_ids": [1, 2],
  "tag_ids": [4, 5],
}
```

De même, pour restreindre une requête aux fichiers d'id `8` et `9` :

```json theme={null}
{
  "agent_id": 1,
  "query": "What is the conclusion of the last quaterly meeting note?",
  "file_ids": [8, 9],
}
```

<Warning>
  Bien que vous puissiez combiner `workspace_ids` et `tag_ids`, vous **ne pouvez pas combiner l'un ou l'autre avec** `file_ids`.
</Warning>

<Info>
  Le champ `agent_id` est optionnel. S'il est omis, l'agent par défaut de votre organisation sera utilisé. Vous pouvez lister les [agents](/fr/developer-resources/agents-and-threads/agents) disponibles via l'endpoint [GET /api/v3/agents](/api-reference-v3/agents/list-all-agents).
</Info>

<Tip>
  Il est recommandé de ne pas forcer un outil lors d'un scoping : le routage automatique sélectionnera l'outil optimal pour votre(vos) fichier(s).
</Tip>

* Vous pouvez récupérer la liste des **workspaces** disponibles pour un agent spécifique en appelant l'endpoint [GET /api/v3/agents/:id](http://localhost:3001/api-reference-v3/agents/retrieve-a-single-agent) et en utilisant le champ `workspaces` du composant.

* Vous pouvez récupérer la liste des **fichiers** disponibles pour un agent spécifique en appelant l'endpoint [GET /api/v3/agents/:id/files](http://localhost:3001/api-reference-v3/agents/list-files-scoped-to-an-agent).

* Vous pouvez récupérer la liste des **tags** disponibles pour un agent spécifique en appelant l'endpoint [GET /api/v3/agents/:id/tags](/api-reference-v3/agents/list-tags-used-in-workspaces-for-an-agent).

<Tip>
  Si vous ne spécifiez pas d'agent particulier, vous utilisez l'agent par défaut de votre organisation. Vous pouvez le récupérer en appelant l'endpoint [GET /api/v3/agents?is\_default=true](/api-reference-v3/agents/list-all-agents) (si vous êtes sys-admin vous pouvez utiliser le paramètre de requête additionnel `&company_id=:id` avec l'identifiant de votre organisation).
</Tip>

### Utiliser un outil spécifique

Appelez l'endpoint [POST /api/v3/threads/turns](/api-reference-v3/threads/create-a-conversation-thread-with-initial-turn), en précisant le nom de l'outil à utiliser dans le payload comme ceci :

```json theme={null}
{
  "agent_id": 1,
  "query": "What is the conclusion of the last quaterly meeting note?",
  "force_tool": "document_search"
}
```

<Info>
  Le champ `agent_id` est optionnel. S'il est omis, l'agent par défaut de votre organisation sera utilisé. Vous pouvez lister les [agents](/fr/developer-resources/agents-and-threads/agents) disponibles via l'endpoint [GET /api/v3/agents](/api-reference-v3/agents/list-all-agents).
</Info>

<Warning>
  Forcer un outil lorsqu'on travaille avec des documents n'est pas recommandé. Préférez restreindre (scoper) des fichiers/espaces de travail à votre requête et laissez le routage automatique décider de l'outil le plus adapté.
</Warning>

Vous pouvez lister les outils natifs disponibles pour l'agent que vous utilisez via l'endpoint [GET /api/v3/agents/:id/tools]().

<Warning>
  Assurez-vous que l'outil natif sélectionné est activé pour l'agent que vous utilisez. Vous pouvez vérifier en appelant l'endpoint [GET /api/v3/agents/:id](). Si vous ne spécifiez pas d'agent, vous pouvez vérifier via l'endpoint [GET api/v3/agents?is\_default=true]() (si vous avez un rôle sys-admin vous pouvez utiliser le paramètre `?company_id=:id` avec l'identifiant de votre organisation).
</Warning>

Comme vu dans la section [Démarrage rapide](#demarrage-rapide), la réponse de l'agent est le dernier message du tour.

Vous pouvez ensuite récupérer la réponse finale comme ceci :

```py theme={null}
# Exemple minimal pour illustrer le schéma d'accès
response = {
    "messages": [
        {"parts": []},
        {"parts": [{"type": "text", "text": "Paris"}]}
    ]
}
answer: str = response["messages"][-1]["parts"][-1]["text"]
```

Dans ce scénario la première partie de la réponse de l'agent est une partie **tool\_call**. Elle contient les informations sur l'outil appelé ainsi que le résultat brut de l'outil.

<Info>
  Notez que puisque l'outil a été forcé à une valeur spécifique, ce tour ne contiendra pas de partie de type « reasoning ».
</Info>

Vous pouvez la récupérer comme ceci :

```
tool_call: dict = response["messages"][-1]["parts"][0]
```

### Utiliser un serveur MCP spécifique

Si vous souhaitez restreindre le routage d'outils aux outils fournis par un serveur MCP spécifique, appelez l'endpoint [POST /api/v3/threads/turns](/api-reference-v3/threads/create-a-conversation-thread-with-initial-turn) en précisant le nom du serveur MCP dans le payload comme ceci :

<Warning>
  Assurez-vous que le serveur MCP sélectionné est activé dans la section **Agent MCP Servers** de vos [Paramètres de Chat](/fr/administration/agent-management/agent-settings).
</Warning>

```json theme={null}
{
  "agent_id": 1,
  "query": "What are the latest news about LightOn ?",
  "force_mcp_server": "websearch-linkup"
}
```

<Info>
  Le champ `agent_id` est optionnel. S'il est omis, l'agent par défaut de votre organisation sera utilisé. Vous pouvez lister les [agents](/fr/developer-resources/agents-and-threads/agents) disponibles via l'endpoint [GET /api/v3/agents](/api-reference-v3/agents/list-all-agents).
</Info>

Cela restreindra le routage des outils aux outils fournis par le serveur MCP nommé `websearch-linkup` attaché à l'organisation liée à la clé API utilisée.

<Tip>
  Notez que même lorsqu'un serveur MCP spécifique est forcé, le modèle peut toujours choisir de n'utiliser aucun de ses outils s'il pense connaître la réponse.
</Tip>

### Étendre le prompt système

Vous pouvez étendre le prompt système le temps d'une requête et fournir des instructions spécifiques via le paramètre `system_prompt_suffix` du payload. Par exemple, en utilisant l'endpoint [POST /api/v3/threads/turns](/api-reference-v3/threads/create-a-conversation-thread-with-initial-turn) :

```json theme={null}
{
  "agent_id": 1,
  "query": "What is the conclusion of the last quaterly meeting note?",
  "force_tool": "document_search",
  "system_prompt_suffix": "Rephrase technical term into more accessible language."
}
```

<Info>
  Le champ `agent_id` est optionnel. S'il est omis, l'agent par défaut de votre organisation sera utilisé. Vous pouvez lister les [agents](/fr/developer-resources/agents-and-threads/agents) disponibles via l'endpoint [GET /api/v3/agents](/api-reference-v3/agents/list-all-agents).
</Info>

<Tip>
  Utiliser cette méthode plutôt qu'ajouter plus d'instructions dans votre requête permet d'ajuster le comportement de l'agent tout en garantissant une précision de recherche optimale pour votre requête dans le cas des outils `document_search` ou `document_analysis`.
</Tip>

### Demander une sortie structurée

Vous pouvez demander une sortie structurée de l'agent en spécifiant le paramètre `response_format` dans le payload. Par exemple, via l'endpoint [POST /api/v3/threads/turns](/api-reference-v3/threads/create-a-conversation-thread-with-initial-turn) :

```json theme={null}
{
  agent_id: 1,
  "query": "What is the capital of France?",
  "response_format": {
    "type": "object",
    "properties": {
      "capital": {
        "type": "string"
      },
      "country": {
        "type": "string"
      }
    },
    "required": [
      "capital",
      "country"
    ]
  }
}
```

<Info>
  Le champ `agent_id` est optionnel. S'il est omis, l'agent par défaut de votre organisation sera utilisé. Vous pouvez lister les [agents](/fr/developer-resources/agents-and-threads/agents) disponibles via l'endpoint [GET /api/v3/agents](/api-reference-v3/agents/list-all-agents).
</Info>

Pour plus d'informations sur `response_format`, veuillez consulter la documentation [Guided JSON](/fr/developer-resources/chat-and-ai-models/structured-output#guided-json).

### Générer des artefacts

Certains outils comme `code_execution` peuvent générer des artefacts téléchargeables par la suite. Par exemple, en utilisant l'endpoint [POST /api/v3/threads/turns](/api-reference-v3/threads/create-a-conversation-thread-with-initial-turn) :

```json theme={null}
{
  "agent_id": 1,
  "query": "Draw me a graph of a sinusoidal function.",
  "force_tool": "code_execution"
}
```

<Info>
  Le champ `agent_id` est optionnel. S'il est omis, l'agent par défaut de votre organisation sera utilisé. Vous pouvez lister les [agents](/fr/developer-resources/agents-and-threads/agents) disponibles via l'endpoint [GET /api/v3/agents](/api-reference-v3/agents/list-all-agents).
</Info>

Cela se traduira par une réponse d'agent composée de 2 parties :

* une partie `tool_call` dans laquelle vous pouvez trouver les artefacts générés ;
* une partie `text` contenant la réponse finale.

Vous pouvez ensuite récupérer les artefacts comme ceci :

```python theme={null}
artifacts: list[dict] = response["messages"][-1]["parts"][0]["tool_call"]["result"]["file_artifacts"]
```

Chaque artefact de fichier contient les champs suivants :

* `id` : l'identifiant de l'artefact ;
* `thumbnail_base64` : une miniature webp 256x256 encodée en base64 de l'artefact si celui-ci est une image.

Une fois l'identifiant de l'artefact obtenu, vous pouvez récupérer le contenu de l'artefact en utilisant l'endpoint [GET /api/v3/artifacts/:id/content](/api-reference-v3/artifacts/retrieve-an-artifact-content).

## Mode arrière-plan

Pour les requêtes lourdes devant être traitées de manière asynchrone, vous pouvez utiliser l'endpoint [POST /api/v3/threads/turns](/api-reference-v3/threads/create-a-conversation-thread-with-initial-turn) avec le paramètre `background` réglé à `true`. Par exemple :

```json theme={null}
{
    "agent_id": 1,
    "query": "What is the capital of France?",
    "background": true
}
```

<Info>
  Le champ `agent_id` est optionnel. S'il est omis, l'agent par défaut de votre organisation sera utilisé. Vous pouvez lister les [agents](/fr/developer-resources/agents-and-threads/agents) disponibles via l'endpoint [GET /api/v3/agents]().
</Info>

Vous recevrez une réponse **HTTP 200** avec l'objet du fil mais ne contenant que la question utilisateur ; notez que le champ `status` est positionné à `running` :

<Accordion title="Exemple de réponse">
  ```json theme={null}
  {
      "id": "6d0d54c3-a87b-4c66-8af2-8ef59418358e",
      "object": "turn",
      "thread": "12df8e86-e8b0-49ee-8634-f5ce8944591c",
      "status": "running",
      "messages": [
        {
          "id": "22461762-afd8-4533-8cf2-2e7d516a38d6",
          "object": "message",
          "role": "user",
          "parts": [
            {
              "type": "text",
              "text": "What is the capital of France?"
            }
      ],
      "created_at": "2025-12-17T14:46:00.703903Z"
      }
    ],
    "created_at": "2025-12-17T14:46:00.702207Z"
  }
  ```
</Accordion>

Vous pouvez ensuite récupérer l'identifiant du fil de la manière suivante :

```python theme={null}
thread_id: str = response["thread"]
```

Vous pouvez maintenant sonder périodiquement l'endpoint [GET /api/v3/threads/:id](/api-reference-v3/threads/retrieve-a-conversation-thread) jusqu'à ce que le champ `status` soit positionné à `completed`.

Lorsque le fil revient à l'état `completed`, vous pouvez récupérer ses tours via l'endpoint [GET /api/v3/threads/:id/turns](http://localhost:3001/api-reference-v3/threads/list-conversation-turns-in-a-thread).

<Tip>
  Pour ne récupérer que le dernier tour, vous pouvez définir le paramètre de requête `limit` à `1`.
</Tip>
