For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navigation principale
Theme

Shell

Exécutez des commandes shell dans des conteneurs hébergés ou dans votre propre environnement d’exécution local.

L’outil shell permet aux modèles de travailler dans un environnement de terminal complet. L’API Responses prend en charge l’exécution de commandes shell en local ou à distance.

Avec l’outil shell, les modèles peuvent exécuter des commandes dans l’un des environnements suivants :

L’outil shell est disponible via l’API Responses. L’API Chat Completions ne le prend pas en charge.

L’exécution de commandes shell arbitraires peut être dangereuse. Exécutez toujours les commandes dans un bac à sable. Dans la mesure du possible, autorisez ou bloquez des commandes précises. Journalisez l’activité de l’outil à des fins d’audit.

Démarrage rapide avec le shell distant

Le shell distant offre une solution native simple à utiliser pour les tâches qui nécessitent des traitements avancés et déterministes, qu’il s’agisse d’effectuer des calculs ou de manipuler des fichiers multimédias.

Utilisez container_auto pour qu’OpenAI crée et gère un conteneur pour votre requête.

Outil shell avec container_auto
curl -L 'https://api.openai.com/v1/responses' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-6-astra",
    "tools": [
      { "type": "shell", "environment": { "type": "container_auto" } }
    ],
    "input": [
      {
        "type": "message",
        "role": "user",
        "content": [
          { "type": "input_text", "text": "Execute: ls -lah /mnt/data && python --version && node --version" }
        ]
      }
    ],
    "tool_choice": "auto"
  }'

Caractéristiques de l’environnement d’exécution hébergé

  • L’environnement d’exécution repose actuellement sur Debian 12 et peut évoluer.
  • Le répertoire de travail par défaut est /mnt/data.
  • /mnt/data est toujours présent. C’est le répertoire pris en charge pour les fichiers que les utilisateurs peuvent télécharger.
  • Le shell distant ne prend pas en charge les sessions TTY interactives.
  • Les commandes du shell distant s’exécutent sans sudo.
  • Vous pouvez exécuter des services dans le conteneur si votre workflow en a besoin.

Parmi les langages actuellement préinstallés figurent :

  • Python 3.11
  • Node.js 22.16
  • Java 17.0
  • PHP 8.2
  • Ruby 3.1
  • Go 1.23

Réutilisez un conteneur pour plusieurs requêtes

Si vos workflows itératifs nécessitent un environnement qui reste actif sur la durée, créez un conteneur, puis faites-y référence dans vos appels suivants à l’API Responses.

1. Créez un conteneur

Création d’un conteneur réutilisable
curl -L 'https://api.openai.com/v1/containers' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "name": "analysis-container",
    "memory_limit": "1g",
    "expires_after": { "anchor": "last_active_at", "minutes": 20 }
  }'

2. Faites référence au conteneur dans l’API Responses

Utilisation du shell avec container_reference
curl -L 'https://api.openai.com/v1/responses' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-6-astra",
    "tools": [
      {
        "type": "shell",
        "environment": {
          "type": "container_reference",
          "container_id": "cntr_08f3d96c87a585390069118b594f7481a088b16cda7d9415fe"
        }
      }
    ],
    "input": "List files in the container and show disk usage."
  }'

Associez des Skills

Les Skills sont des ensembles de ressources réutilisables et versionnés que vous pouvez monter dans un environnement de shell distant. Vous déterminez ainsi les Skills disponibles. Au moment d’exécuter les commandes shell, le modèle décide de les utiliser ou non.

Consultez le guide des Skills pour savoir comment importer des Skills et gérer leurs versions.

Création d’un conteneur avec des Skills associés
curl -L 'https://api.openai.com/v1/containers' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "name": "skill-container",
    "skills": [
      { "type": "skill_reference", "skill_id": "skill_4db6f1a2c9e73508b41f9da06e2c7b5f" },
      { "type": "skill_reference", "skill_id": "openai-spreadsheets", "version": "latest" }
    ]
  }'

Accès réseau

Par défaut, les conteneurs hébergés ne disposent d’aucun accès réseau sortant.

Pour l’activer :

  1. Un administrateur doit configurer la liste des domaines autorisés par votre organisation dans le tableau de bord.
  2. Dans votre requête, définissez explicitement network_policy pour l’environnement du conteneur.
Outil shell avec une liste de domaines autorisés
curl -L 'https://api.openai.com/v1/responses' \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6-astra",
    "tool_choice": "required",
    "tools": [
      {
        "type": "shell",
        "environment": {
          "type": "container_auto",
          "network_policy": {
            "type": "allowlist",
            "allowed_domains": ["pypi.org", "files.pythonhosted.org", "github.com"]
          }
        }
      }
    ],
    "input": [
      {
        "role": "user",
        "content": "In the container, pip install httpx beautifulsoup4, fetch release pages, and write /mnt/data/release_digest.md."
      }
    ]
  }'

Autoriser des domaines présente des risques de sécurité, notamment l’exfiltration de données à la suite d’une attaque par injection de prompt. Autorisez uniquement des domaines de confiance que des attaquants ne peuvent pas utiliser pour recevoir des données volées. Lisez attentivement la section Risques et sécurité ci-dessous avant d’utiliser cet outil.

Ordre de priorité des règles d’accès réseau

Lorsque plusieurs règles s’appliquent :

  • La liste d’autorisation de votre organisation définit l’ensemble des domaines que peut contenir allowed_domains.
  • Le paramètre network_policy de la requête restreint davantage l’accès.
  • La requête échoue si allowed_domains contient des domaines absents de la liste d’autorisation de votre organisation.

Conservation des données et cycle de vie des conteneurs

Tant qu’un conteneur hébergé utilisé par le shell distant ou l’Interpréteur de code est actif, l’application peut enregistrer son état temporaire dans le système de fichiers du conteneur, qui repose sur un stockage par blocs éphémère. Les données du conteneur sont supprimées à son expiration ou lorsque vous le supprimez explicitement.

Pour en savoir plus sur les contrôles des données, consultez la page ZDR et résidence des données.

Téléchargez les fichiers produits

Le shell distant peut produire des fichiers téléchargeables. Utilisez les mêmes API de gestion des conteneurs et des fichiers que pour l’Interpréteur de code afin de récupérer les fichiers écrits dans /mnt/data.

Contrôles supplémentaires des données

Pour limiter la durée de vie des contenus et des fichiers à celle du conteneur hébergé, vous pouvez inclure les fichiers directement dans la requête et monter dans le conteneur des Skills fournis de la même manière.

Utilisation de fichiers et de Skills inclus directement dans la requête
INLINE_ZIP=$(base64 -i ./csv_insights.zip)
REPORT_CSV=$(base64 -i ./report.csv)

CONTAINER_ID=$(
  curl -sL 'https://api.openai.com/v1/containers' \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -d '{
      "name": "inline-skill-container",
      "skills": [
        {
          "type": "inline",
          "name": "csv-insights",
          "description": "Summarize CSV files and produce a markdown report.",
          "source": {
            "type": "base64",
            "media_type": "application/zip",
            "data": "'"$INLINE_ZIP"'"
          }
        }
      ]
    }' | jq -r '.id'
)

curl -L 'https://api.openai.com/v1/responses' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-6-astra",
    "tools": [
      {
        "type": "shell",
        "environment": {
          "type": "container_reference",
          "container_id": "'"$CONTAINER_ID"'"
        }
      }
    ],
    "input": [
      {
        "role": "user",
        "content": [
          {
            "type": "input_file",
            "filename": "report.csv",
            "file_data": "data:text/csv;base64,'"${REPORT_CSV}"'"
          },
          {
            "type": "input_text",
            "text": "Use the csv-insights skill to summarize report.csv."
          }
        ]
      }
    ]
  }'

Pour les requêtes suivantes, transmettez le même container_id avec container_reference. Les Skills montés et les fichiers déjà présents dans le conteneur restent disponibles tant que celui-ci est actif.

Supprimez un conteneur dès la fin du travail

Une fois le travail terminé, vous pouvez supprimer explicitement le conteneur sans attendre qu’il expire pour cause d’inactivité.

Suppression d’un conteneur
curl -L -X DELETE 'https://api.openai.com/v1/containers/container_id' \
  -H "Authorization: Bearer $OPENAI_API_KEY"

Secrets par domaine

Utilisez domain_secrets lorsqu’un domaine de votre liste allowed_domains exige des en-têtes d’autorisation confidentiels, comme Authorization: Bearer <token>.

Chaque entrée comprend :

  • Le domaine cible
  • Un nom explicite pour le secret
  • La valeur du secret

Lors de l’exécution :

  • Le modèle et l’environnement d’exécution voient des noms de substitution (par exemple $API_KEY) à la place des identifiants réels.
  • Le composant auxiliaire chargé de l’authentification remplace ces noms par les valeurs réelles des secrets uniquement pour les destinations approuvées.
  • Les valeurs réelles des secrets ne sont pas conservées sur les serveurs de l’API et n’apparaissent pas dans le contexte accessible au modèle.

L’assistant peut ainsi appeler des services protégés tout en limitant le risque de fuite de données.

Outil shell avec domain_secrets
curl -L 'https://api.openai.com/v1/responses' \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6-astra",
    "input": [
      {
        "role": "user",
        "content": "Use curl to call https://httpbin.org/headers with header Authorization: Bearer $API_KEY. Tell me what you see in the final text response."
      }
    ],
    "tool_choice": "required",
    "tools": [
      {
        "type": "shell",
        "environment": {
          "type": "container_auto",
          "network_policy": {
            "type": "allowlist",
            "allowed_domains": ["httpbin.org"],
            "domain_secrets": [
              {
                "domain": "httpbin.org",
                "name": "API_KEY",
                "value": "debug-secret-123"
              }
            ]
          }
        }
      }
    ]
  }'

Workflows sur plusieurs échanges

Pour poursuivre le travail dans le même environnement hébergé, réutilisez le conteneur et transmettez previous_response_id.

Poursuite d’un workflow shell
curl -L 'https://api.openai.com/v1/responses' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-6-astra",
    "previous_response_id": "resp_2a8e5c9174d63b0f18a4c572de9f64a1b3c76d508e12f9ab47",
    "tools": [
      {
        "type": "shell",
        "environment": {
          "type": "container_reference",
          "container_id": "cntr_f19c2b51e4a06793d82d54a7be0fc9154d3361ab28ce7f6041"
        }
      }
    ],
    "input": "Read /mnt/data/top5.csv and report the top candidate."
  }'

Sorties du shell dans l’API Responses

Le shell distant et le shell local utilisent les mêmes types d’éléments de sortie. Chaque exécution du shell est représentée par une paire d’éléments de sortie :

  • shell_call : commandes demandées par le modèle.
  • shell_call_output : sortie des commandes et état de fin d’exécution.
Exemple d’élément shell_call
{
  "type": "shell_call",
  "call_id": "call_9d14ac6f2b73485e91c0f4da6e1b27c8",
  "action": {
    "commands": ["ls -l"],
    "timeout_ms": 120000,
    "max_output_length": 4096
  },
  "status": "in_progress"
}

Mode shell local

Vous pouvez également lancer des commandes shell dans votre propre environnement d’exécution local en exécutant les actions shell_call, puis en renvoyant shell_call_output au modèle.

Utilisez ce mode si vous devez garder le contrôle du système de fichiers ou accéder à des outils internes. Choisissez shell comme type d’outil et local comme type d’environnement. Si vous migrez depuis l’ancien outil local_shell, désormais retiré, mettez à jour votre requête et traitez shell_call et shell_call_output dans votre boucle d’exécution.

Requête utilisant le shell local
curl -L 'https://api.openai.com/v1/responses' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-6-astra",
    "instructions": "The local bash shell environment is on Mac.",
    "input": "find me the largest pdf file in ~/Documents",
    "tools": [{ "type": "shell", "environment": { "type": "local" } }]
  }'

Lorsque vous recevez des éléments de sortie shell_call :

  • Examinez chaque commande avant de l’exécuter. Utilisez une liste de commandes autorisées et exigez une approbation pour les commandes destructrices ou celles qui accèdent à des données sensibles.
  • Exécutez les commandes approuvées dans un bac à sable. Limitez explicitement l’accès au système de fichiers et au réseau, la quantité de mémoire utilisable et la durée d’exécution. Appliquez votre propre délai d’expiration, même si le modèle en suggère un.
  • Consignez les commandes et leurs résultats à des fins d’audit.
  • Recueillez stdout, stderr et l’état de fin d’exécution.
  • Renvoyez les résultats sous la forme d’un élément shell_call_output dans la requête suivante.
Exemple d’exécuteur de commandes shell en local
from contextlib import suppress
from dataclasses import dataclass
import os
import signal
import subprocess


@dataclass
class CmdResult:
    stdout: str
    stderr: str
    exit_code: int | None
    timed_out: bool


class ShellExecutor:
    def __init__(self, default_timeout: float = 60):
        self.default_timeout = default_timeout

    def run(self, cmd: str, timeout: float | None = None) -> CmdResult:
        t = self.default_timeout if timeout is None else timeout
        p = subprocess.Popen(
            cmd,
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            start_new_session=True,
        )
        try:
            out, err = p.communicate(timeout=t)
            return CmdResult(out, err, p.returncode, False)
        except subprocess.TimeoutExpired:
            # Stop the shell and its children before draining their output pipes.
            with suppress(ProcessLookupError):
                os.killpg(p.pid, signal.SIGKILL)
            out, err = p.communicate()
            return CmdResult(out, err, p.returncode, True)

Ces exemples nécessitent Linux ou macOS. À l’expiration du délai d’exécution d’une commande, ils arrêtent tout le groupe de processus de cette commande.

Exemple de contenu d’un élément shell_call_output
{
  "type": "shell_call_output",
  "call_id": "call_3ef1b8c79a4d6520f9e3ab7d41c68f25",
  "max_output_length": 4096,
  "output": [
    {
      "stdout": "...",
      "stderr": "...",
      "outcome": {
        "type": "exit",
        "exit_code": 0
      }
    },
    {
      "stdout": "...",
      "stderr": "...",
      "outcome": {
        "type": "timeout"
      }
    }
  ]
}

Si une commande échoue ou dépasse le délai d’exécution, renvoyez son état de fin d’exécution pour que le modèle puisse décider de réessayer ou non. Consultez l’avis de retrait de l’ancien outil.

Utilisez le shell local avec le SDK Agents

Si vous utilisez le SDK Agents, vous pouvez fournir votre propre implémentation de l’exécuteur de commandes shell à la fonction utilitaire de l’outil shell.

Utilisation du shell local avec le SDK Agents
import { Agent, run, withTrace, shellTool } from "@openai/agents";

class LocalShell {
  async run(action) {
    return {
      output: [
        {
          stdout: "Shell is not available. Needs to be implemented first.",
          stderr: "",
          outcome: {
            type: "exit",
            exitCode: 1,
          },
        },
      ],
      maxOutputLength: action.maxOutputLength,
    };
  }
}

const shell = new LocalShell();

const agent = new Agent({
  name: "Shell Assistant",
  model: "gpt-6-astra",
  instructions:
    "You can execute shell commands to inspect the repository. Keep responses concise and include command output when helpful.",
  tools: [
    shellTool({
      shell,
      needsApproval: true,
      onApproval: async (_ctx, _approvalItem) => {
        return { approve: true };
      },
    }),
  ],
});

await withTrace("shell-tool-example", async () => {
  const result = await run(agent, "Show the Node.js version.");
  console.log(`\nFinal response:\n${result.finalOutput}`);
});

Vous trouverez des exemples fonctionnels dans les dépôts du SDK.

Exemple d’utilisation de l’outil shell en TypeScript

Exemple TypeScript utilisant l’outil shell du SDK Agents.

Exemple d’utilisation de l’outil shell en Python

Exemple Python utilisant l’outil shell du SDK Agents.

Gestion des erreurs courantes

  • Si une commande dépasse le délai d’exécution fixé, signalez l’expiration du délai et joignez la sortie partielle recueillie.
  • Si max_output_length figure dans shell_call, incluez-le dans shell_call_output.
  • Évitez les commandes interactives. Les commandes de l’outil shell doivent pouvoir s’exécuter sans intervention.
  • Conservez la sortie des commandes qui se terminent avec un code de sortie non nul afin que le modèle puisse déterminer comment reprendre l’exécution.

Risques et sécurité

Activer l’accès réseau dans l’API Containers élargit considérablement les possibilités des conteneurs, mais présente des risques importants pour la sécurité et la gouvernance des données. L’accès réseau est désactivé par défaut. Si vous l’activez, limitez strictement l’accès sortant aux domaines de confiance nécessaires à la tâche.

Les conteneurs disposant d’un accès réseau peuvent interagir avec des services tiers et des registres de paquets. Ils sont ainsi exposés à des fuites de données, à un détournement des outils à la suite d’une attaque par injection de prompt ou à un accès accidentel à des ressources hors du périmètre prévu. Ces risques augmentent lorsque les règles sont trop larges, restent figées ou sont appliquées de manière inégale.

Identifiez les risques d’attaque par injection de prompt dans les contenus récupérés sur le réseau

Tout contenu externe récupéré sur le réseau peut renfermer des instructions dissimulées visant à manipuler le comportement du modèle. Traitez les contenus réseau provenant de sources non fiables comme potentiellement malveillants et redoublez de prudence pour les actions susceptibles de modifier des données ou des systèmes.

Connectez-vous uniquement à des destinations de confiance

Autorisez uniquement les domaines auxquels vous faites confiance et que vous maintenez activement. Faites preuve de prudence avec les intermédiaires et les agrégateurs qui relaient les requêtes vers d’autres services. Avant de les ajouter à votre liste de domaines autorisés, examinez leurs pratiques de traitement et de conservation des données.

Prévoyez des vérifications avant et après l’exécution des requêtes

Examinez la commande de l’outil shell et sa sortie, toutes deux fournies dans la réponse de l’API Responses. Pour chaque session, consignez les hôtes demandés et les destinations réelles des connexions sortantes. Examinez régulièrement les journaux pour vérifier que les accès correspondent à vos attentes, repérer les écarts au fil du temps et détecter les comportements suspects.

Vérifiez le respect des exigences de résidence et de conservation des données

Les contrôles des données d’OpenAI s’appliquent dans le périmètre d’OpenAI. Les données transmises à des services tiers via le réseau sont toutefois soumises aux politiques de conservation de ces services. Vérifiez que les points de terminaison externes répondent à vos exigences en matière de résidence des données, de conservation et de conformité.