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

# API Agent

> Commencez avec l'API Agent

<Info>
  Si vous utilisez **Unique Urchin**, veuillez consulter [cette version](/fr/developer-resources/chat-and-ai-models/agent-api-beta) de la documentation.
</Info>

<Info>
  Cette documentation est obsolète et uniquement valable si vous êtes sur la version **Victorious Vicuna** (janvier 2026). Si vous
  êtes déjà sur la version **Wise Wolf** (février 2026) ou ultérieure, veuillez consulter [cette documentation](/fr/developer-resources/agents-and-threads/threads).
</Info>

<Tip>
  L'API Agent est disponible en disponibilité générale depuis la version **Victorious Vicuna** (janvier 2026) et suivantes.
</Tip>

## Motivation

L'API Agent, qui alimente le nouveau [Mode Agent](/fr/user-guides/chat-features/agents), vous permet d'engager des conversations en s'appuyant sur des capacités de raisonnement multi‑outils. C'est désormais 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).

```py theme={null}
import os
import json
import urllib.request

# 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")

url = f"{base_url}/threads/turns"
payload = {
    "chat_setting_id": 1,
    "ml_model": "alfred-ft5",
    "query": "What is the capital of France?"
}
data = json.dumps(payload).encode("utf-8")

req = urllib.request.Request(
    url,
    data=data,
    headers={
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
    },
    method="POST"
)

with urllib.request.urlopen(req) as resp:
    response = json.load(resp)
```

En précisant :

* `chat_settings_id` : l'identifiant des [Paramètres de Chat](/fr/administration/agent-management/agent-settings) attachés à votre organisation (optionnel, par défaut ceux attachés à votre organisation) ;
* `ml_model` : le nom du modèle IA à utiliser (optionnel, par défaut le modèle par défaut de votre organisation) ;
* `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.

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 à un espace de travail / document

Vous pouvez restreindre une requête à une liste de **Workspaces** et/ou de **Fichiers** (documents) en utilisant les paramètres `workspaces_ids` et/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) :

```json theme={null}
{
  "chat_setting_id": 1,
  "ml_model": "alfred-ft5",
  "query": "What is the conclusion of the last quaterly meeting note?",
  "workspaces_ids": [1, 2]
}
```

<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 utiliser les endpoints suivants pour récupérer la liste des espaces de travail et fichiers disponibles :

* [GET /api/v3/workspaces](/api-reference-v3/workspaces/list-all-workspaces)
* [GET /api/v3/files](/api-reference-v3/files/list-files-accessible-to-the-authenticated-user)

### 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}
{
  "chat_setting_id": 1,
  "ml_model": "alfred-ft5",
  "query": "What is the conclusion of the last quaterly meeting note?",
  "force_tool": "document_search"
}
```

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

Notez que les outils natifs disponibles sont :

* `document_search`
* `document_analysis`
* `code_execution`

<Warning>
  Assurez‑vous que l'outil sélectionné est activé dans la section **Agent Tools** de vos [Paramètres de Chat](/fr/administration/agent-management/agent-settings).
</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}
{
  "chat_setting_id": 1,
  "ml_model": "alfred-ft5",
  "query": "What are the latest news about LightOn ?",
  "force_mcp_server": "websearch-linkup"
}
```

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}
{
  "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."
}
```

<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}
{
  "query": "What is the capital of France?",
  "response_format": {
    "type": "object",
    "properties": {
      "capital": {
        "type": "string"
      },
      "country": {
        "type": "string"
      }
    },
    "required": [
      "capital",
      "country"
    ]
  }
}
```

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}
{
  "query": "Draw me a graph of a sinusoidal function.",
  "force_tool": "code_execution"
}
```

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}
{
    "query": "What is the capital of France?",
    "background": true
}
```

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](/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>
