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

# Exécuter Devin Outposts sur des Sandboxes

> Laissez Devin planifier dans Devin Cloud pendant que ses commandes s’exécutent dans une sandbox CoreWeave que vous contrôlez.

Avec [Devin Outposts](https://docs.devin.ai/cloud/outposts/overview), la planification et l’inférence de modèle de Devin restent dans Devin Cloud. Devin exécute des commandes, modifie des fichiers et accède aux dépôts sur une machine que vous gérez. Ce guide fait de cette machine une sandbox CoreWeave : un environnement isolé dont vous choisissez l’image, le CPU, la mémoire, le GPU et la durée de vie.

Un avant-poste est une file d’attente nommée dans Devin Cloud. Un worker est le processus `devin worker` qui se connecte à Devin Cloud en HTTPS sortant, récupère des sessions dans la file d’attente et les exécute localement. Il ne nécessite ni ports entrants, ni adresse IP publique, ni réseau privé virtuel (VPN). Ici, chaque sandbox exécute un worker, qui traite les sessions les unes après les autres pendant toute la durée de vie de la sandbox.

Chaque worker traite une seule session active à la fois. Les sessions supplémentaires attendent qu’un worker se libère. Ce guide démarre un nombre fixe de workers : il ne crée pas de sandboxes supplémentaires lorsque des sessions s’accumulent dans la file d’attente. Démarrez d’autres workers manuellement ou utilisez un orchestrateur pour les provisionner automatiquement.

<h2 id="prerequisites">
  Prérequis
</h2>

Avant de commencer, assurez-vous de disposer des éléments suivants :

* Une organisation Devin dans laquelle les Outposts sont activés. Si **Outposts** n'apparaît pas sous **Settings > Environment** dans Devin Cloud, adressez-vous à votre administrateur Devin.
* Un [jeton d’accès à l’API CoreWeave](/fr/products/sandboxes/placement#choose-and-get-credentials) disposant de l’action `SANDBOX_USER`.
* Pour une utilisation directe du kit de développement logiciel (SDK), Python 3.11 ou version ultérieure avec [`uv`](https://docs.astral.sh/uv/), ou Node.js 22 ou version ultérieure.

Exportez votre jeton d’accès à l’API CoreWeave dans le terminal que vous utilisez pour suivre ce guide :

```bash theme={"system"}
export CWSANDBOX_API_KEY="[API-ACCESS-TOKEN]"
```

<h2 id="create-an-outpost-in-devin-cloud">
  Créer un avant-poste dans Devin Cloud
</h2>

Pour créer un avant-poste et obtenir son jeton, suivez ces étapes :

1. Dans [Devin Cloud](https://app.devin.ai), accédez à **Settings > Environment > Outposts**.
2. Cliquez sur **Create Outpost**, saisissez un nom, puis sélectionnez **Linux**.
3. Copiez le jeton de l’avant-poste. Devin Cloud ne l’affiche qu’une seule fois.

Une fois l’avant-poste prêt, démarrez son worker avec `cws-agent` ou le SDK Sandboxes, puis exécutez la session de vérification.

<h2 id="quick-start-with-cws-agent">
  Démarrage rapide avec cws-agent
</h2>

Suivez les [instructions d’installation de `cws-agent`](https://github.com/coreweave/cws-agent#install). L’outil configure un volume d’instantanés qui permet d’enregistrer et de restaurer votre Workspace à l’aide d’[instantanés du système de fichiers](/fr/products/sandboxes/file-system-snapshots#start-a-sandbox-with-a-snapshot-mount).

Remplacez `[OUTPOST-TOKEN]` par le jeton que vous avez copié, `[OUTPOST-NAME]` par le nom de votre avant-poste et `[SANDBOX-NAME]` par un nom de session `cws-agent` pour ce sandbox. Le nom de session doit comporter de 1 à 40 lettres minuscules, chiffres ou traits d’union, et commencer par une lettre ou un chiffre :

```bash theme={"system"}
export DEVIN_OUTPOSTS_TOKEN="[OUTPOST-TOKEN]"
cws-agent launch [SANDBOX-NAME] --outpost [OUTPOST-NAME]
```

L’outil transmet le jeton à la sandbox et démarre un worker.

Pour afficher le terminal du worker, exécutez :

```bash theme={"system"}
cws-agent connect [SANDBOX-NAME] --cmd 'tmux attach -t outpost-0'
```

Détachez la session avec **Ctrl-b**, puis **d**, et passez à la section [Exécuter et vérifier une session Devin](#run-and-verify-a-devin-session). Ce worker se connecte à Devin Cloud. Il est distinct de l'interface de ligne de commande (CLI) interactive de Devin, lancée avec `--agent devin`.

<h2 id="set-up-with-the-sandbox-sdk">
  Configurer avec le SDK Sandboxes
</h2>

Utilisez cette méthode alternative pour lancer directement un worker, sans passer par `cws-agent`. Elle ne configure pas de stockage persistant.

Exécutez les extraits de code Python dans l’environnement virtuel créé à l’étape [Configurer les identifiants et installer le client](#configure-credentials-and-install-the-client). Enregistrez les extraits de code TypeScript dans des fichiers `.mts` au sein du projet dans lequel vous avez installé le client, puis exécutez-les avec `npx tsx [FILENAME].mts`.

<h3 id="configure-credentials-and-install-the-client">
  Configurer les identifiants et installer le client
</h3>

Dans le terminal où vous exécutez le script, exportez le jeton que vous avez copié lors de la création de l’avant-poste :

```bash theme={"system"}
export DEVIN_OUTPOSTS_TOKEN="[OUTPOST-TOKEN]"
```

Choisissez un client et installez-le en local :

<Tabs>
  <Tab title="Python">
    Utilisez Python 3.11 ou une version ultérieure, ainsi que `uv` :

    ```bash theme={"system"}
    uv venv --python 3.11
    source .venv/bin/activate
    uv pip install 'cwsandbox>=1.14.2'
    ```
  </Tab>

  <Tab title="TypeScript">
    Utilisez Node.js 22 ou une version ultérieure. Installez le client et l’exécuteur TypeScript dans votre projet :

    ```bash theme={"system"}
    npm install @coreweave/cwsandbox@0.5.0-beta.0 tsx
    ```
  </Tab>
</Tabs>

<h3 id="start-the-worker">
  Démarrer le worker
</h3>

<Tip>
  Pour réduire le temps de démarrage du worker, utilisez votre propre image dans laquelle la CLI Devin, Git, les environnements d’exécution des langages et les dépendances du projet sont préinstallés. Indiquez cette image dans `container_image` en Python ou dans `containerImage` en TypeScript. Si elle inclut déjà Git et les certificats d’autorité de certification (CA), supprimez les commandes `apt-get` de l’exemple.
</Tip>

Le script suivant crée une sandbox à partir de l’image de worker officielle de Cognition et exécute `devin worker` comme commande principale de la sandbox. Le client lit `DEVIN_OUTPOSTS_TOKEN` dans votre environnement local et transmet sa valeur dans la requête de création de la sandbox afin de définir la variable d’environnement du worker. La sortie du worker constitue le journal de la sandbox. Si le worker se termine sur une erreur, la plateforme redémarre le conteneur, dans la limite d’un nombre maximal de redémarrages.

<Tabs>
  <Tab title="Python">
    ```python title="start_outpost_worker.py" theme={"system"}
    import os
    import sys

    from cwsandbox import ResourceOptions, Sandbox

    outpost = sys.argv[1]

    # L’image du worker inclut la CLI Devin mais pas git, dont Devin a besoin pour
    # cloner les dépôts. Installez-le, puis confiez le processus au worker.
    command = """
    apt-get update -qq
    DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git ca-certificates >/dev/null
    mkdir -p /workspace
    cd /workspace
    exec devin worker start --outpost="$DEVIN_OUTPOST"
    """

    sandbox = Sandbox.run(
        "bash", "-ec", command,
        container_image="public.ecr.aws/e0h8a4b6/devin-cli:stable",
        environment_variables={
            "DEVIN_OUTPOSTS_TOKEN": os.environ["DEVIN_OUTPOSTS_TOKEN"],
            "DEVIN_OUTPOST": outpost,
        },
        max_lifetime_seconds=8 * 3600,
        resources=ResourceOptions(
            requests={"cpu": "2", "memory": "4Gi"},
            limits={"cpu": "2", "memory": "4Gi"},
        ),
        tags=["devin-outpost-worker"],
    )
    try:
        sandbox.wait()
    except BaseException:
        sandbox.stop().result()
        raise

    print(f"Worker sandbox ID: {sandbox.sandbox_id}")
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript title="start_outpost_worker.mts" theme={"system"}
    import { createSandboxClientFromEnv } from "@coreweave/cwsandbox/node";

    const token = process.env.DEVIN_OUTPOSTS_TOKEN;
    if (!token) throw new Error("Set DEVIN_OUTPOSTS_TOKEN.");
    const outpost = process.argv[2];
    if (!outpost) throw new Error("Pass an outpost name.");

    const command = `
    apt-get update -qq
    DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git ca-certificates >/dev/null
    mkdir -p /workspace
    cd /workspace
    exec devin worker start --outpost="$DEVIN_OUTPOST"
    `;

    const client = createSandboxClientFromEnv();
    const sandbox = await client.run(["bash", "-ec", command], {
      containerImage: "public.ecr.aws/e0h8a4b6/devin-cli:stable",
      environmentVariables: {
        DEVIN_OUTPOSTS_TOKEN: token,
        DEVIN_OUTPOST: outpost,
      },
      resources: { cpu: "2", memory: "4Gi" },
      maxLifetimeSeconds: 8 * 3600,
      waitUntilRunning: false,
      tags: ["devin-outpost-worker"],
    });
    try {
      await sandbox.wait();
    } catch (error) {
      await sandbox.stop();
      throw error;
    }
    console.log(`Worker sandbox ID: ${sandbox.sandboxId}`);
    ```
  </Tab>
</Tabs>

Exécutez-le en indiquant le nom de l’avant-poste créé à l’étape [Créer un avant-poste dans Devin Cloud](#create-an-outpost-in-devin-cloud) :

<Tabs>
  <Tab title="Python">
    ```bash theme={"system"}
    python start_outpost_worker.py [OUTPOST-NAME]
    ```
  </Tab>

  <Tab title="TypeScript">
    ```bash theme={"system"}
    npx tsx start_outpost_worker.mts [OUTPOST-NAME]
    ```
  </Tab>
</Tabs>

En Python, `sandbox.wait()` rend la main dès que la sandbox est en cours d’exécution ou qu’elle s’est déjà terminée. L’installation et l’authentification du worker peuvent alors être encore en cours ; vérifiez donc l’état du worker avant de soumettre une tâche. Le worker démarre dans `/workspace`. Une session pour `your-org/app` extrait son dépôt dans `/workspace/repos/app`.

Le script n’utilise pas de bloc `with` : une sandbox en cours d’exécution continue donc de tourner une fois le script terminé.

<Warning>
  `max_lifetime_seconds` est un plafond strict qui ne peut pas être prolongé par la suite. Une fois ce délai écoulé, la plateforme met fin à la sandbox, ce qui interrompt l’exécution de toute session utilisant le worker. Ce script ne configure aucun instantané ni aucun volume persistant. Un redémarrage du conteneur réinitialise son système de fichiers accessible en écriture, y compris les fichiers situés sous `/workspace`. Conservez les résultats en dehors de la sandbox, par exemple dans un dépôt vers lequel Devin téléverse ses modifications.
</Warning>

<h3 id="optional-use-a-secret-store">
  Facultatif : utiliser un magasin de secrets
</h3>

Vous pouvez transmettre une [référence de secret Forge](/fr/products/sandboxes/secrets) à la place de la valeur du jeton de l’avant-poste. Cette option nécessite une authentification Forge et un placement sans serveur. Stockez le jeton de l’avant-poste dans le Secret Manager de votre équipe Forge, puis exportez les identifiants d’authentification de cette équipe :

```bash theme={"system"}
export FORGE_API_KEY="[FORGE-API-KEY]"
export FORGE_TEAM="[FORGE-TEAM]"
```

Configurez explicitement le SDK avec ces identifiants d’authentification. `FORGE_API_KEY` et `FORGE_TEAM` ne sont que des exemples de noms de variables d’environnement : le SDK ne les détecte donc pas automatiquement.

<Tabs>
  <Tab title="Python">
    Importez `AuthHeaders` et définissez `auth` avant de créer la sandbox :

    ```python theme={"system"}
    import os

    from cwsandbox import AuthHeaders

    auth = AuthHeaders(
        headers={
            "x-wandb-api-key": os.environ["FORGE_API_KEY"],
            "x-entity-id": os.environ["FORGE_TEAM"],
        },
        strategy="wandb_api_key",
    )
    ```

    Passez `auth=auth` à `Sandbox.run()`. Dans les exemples Python suivants, incluez également cette configuration et passez aussi `auth=auth` à chaque appel de `Sandbox.from_id()`.
  </Tab>

  <Tab title="TypeScript">
    Remplacez l’importation et l’initialisation du client par le code suivant. Utilisez également cette configuration du client dans les exemples TypeScript suivants :

    ```typescript theme={"system"}
    import { createSandboxClient } from "@coreweave/cwsandbox/wandb";

    const client = createSandboxClient({
      apiKey: process.env.FORGE_API_KEY,
      entity: process.env.FORGE_TEAM,
    });
    ```
  </Tab>
</Tabs>

Remplacez `[SECRET-NAME]` par le nom du secret de l’équipe :

<Tabs>
  <Tab title="Python">
    Importez `Secret` depuis `cwsandbox`, supprimez `DEVIN_OUTPOSTS_TOKEN` de `environment_variables`, puis ajoutez `secrets=[Secret(store="wandb", name="[SECRET-NAME]", env_var="DEVIN_OUTPOSTS_TOKEN")]` à `Sandbox.run()`.
  </Tab>

  <Tab title="TypeScript">
    Supprimez la déclaration `const token` ainsi que sa vérification `if (!token)`. Supprimez `DEVIN_OUTPOSTS_TOKEN` de `environmentVariables`, puis ajoutez `secrets: [{ store: "wandb", name: "[SECRET-NAME]", envVar: "DEVIN_OUTPOSTS_TOKEN" }]` aux options passées à `client.run()`.
  </Tab>
</Tabs>

Il n’est plus nécessaire d’exporter localement le jeton de l’avant-poste. La plateforme résout la référence et définit elle-même la variable d’environnement du worker.

<h2 id="run-and-verify-a-devin-session">
  Exécuter et vérifier une session Devin
</h2>

Pour ce test, utilisez un avant-poste qui ne contient que ce worker et aucune autre session active ou mise en file d’attente. Choisissez une valeur unique et non secrète pour ce test, puis remplacez `[PROOF-VALUE]` dans la tâche ci-dessous. Dans Devin Cloud, démarrez une nouvelle session et sélectionnez votre avant-poste sous **Configuration > Virtual environment**. Soumettez la tâche ci-dessous, qui commence par `Write the exact text`. Vous pouvez aussi envoyer le message complet dans Slack :

```text theme={"system"}
@Devin !outpost [OUTPOST-NAME] Write the exact text [PROOF-VALUE] to /workspace/outpost-proof.txt and read the file back. Report its contents.
```

Une fois que Devin a signalé l’achèvement de la tâche, lisez le fichier depuis votre propre terminal à l’aide de la commande correspondant à votre configuration. Remplacez `[SANDBOX-NAME]` par le nom de votre Workspace `cws-agent` ou `[SANDBOX-ID]` par l’ID affiché par le script du SDK :

<Tabs>
  <Tab title="cws-agent">
    ```bash theme={"system"}
    cws-agent exec [SANDBOX-NAME] 'cat /workspace/outpost-proof.txt'
    ```
  </Tab>

  <Tab title="SDK Sandboxes">
    <Tabs>
      <Tab title="Python">
        ```python theme={"system"}
        from cwsandbox import Sandbox

        sandbox = Sandbox.from_id("[SANDBOX-ID]").result()
        result = sandbox.exec(["cat", "/workspace/outpost-proof.txt"], check=True).result()
        print(result.stdout, end="")
        ```
      </Tab>

      <Tab title="TypeScript">
        ```typescript theme={"system"}
        import { createSandboxClientFromEnv } from "@coreweave/cwsandbox/node";

        const client = createSandboxClientFromEnv();
        const sandbox = await client.fromId("[SANDBOX-ID]");
        const result = await sandbox.commands.run(["cat", "/workspace/outpost-proof.txt"], { check: true });
        process.stdout.write(result.stdout);
        ```
      </Tab>
    </Tabs>
  </Tab>
</Tabs>

Vérifiez que la sortie correspond à votre valeur unique. Le fait de lire le fichier via l’ID de cette sandbox permet d’attribuer l’écriture effectuée par la session à la sandbox que vous avez créée. Le chemin absolu évite de dépendre du répertoire de travail de la session.

Si la session reste en file d’attente, consultez le journal du worker comme indiqué dans la section suivante. Un worker occupé par une session précédente ne peut pas en prendre une autre tant que celle-ci n’est pas terminée ou suspendue. Si vous n’avez plus besoin de la session précédente, mettez-y fin dans Devin Cloud. Vous pouvez aussi démarrer un autre worker.

<h2 id="check-the-worker-and-stop-it">
  Vérifier le worker et l’arrêter
</h2>

Pour `cws-agent`, connectez-vous au terminal du worker comme indiqué dans le démarrage rapide. Si vous utilisez le SDK, examinez son statut et ses journaux récents. Remplacez `[SANDBOX-ID]` par l’ID affiché :

<Tabs>
  <Tab title="Python">
    ```python theme={"system"}
    from cwsandbox import Sandbox

    sandbox = Sandbox.from_id("[SANDBOX-ID]").result()
    print("Sandbox status:", sandbox.get_status())
    for container in sandbox.container_statuses:
        print(container.name, container.state, container.exit_code, container.restart_count)
    for line in sandbox.stream_logs(tail_lines=100):
        print(line, end="")
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"system"}
    import { createSandboxClientFromEnv } from "@coreweave/cwsandbox/node";

    const client = createSandboxClientFromEnv();
    const sandbox = await client.fromId("[SANDBOX-ID]");
    console.log("Sandbox status:", sandbox.status, "Exit code:", sandbox.exitCode);
    for (const line of await sandbox.logs.read({ tailLines: 100 })) {
      process.stdout.write(line);
    }
    ```
  </Tab>
</Tabs>

Relancez cette vérification pour récupérer des journaux plus récents. Le client Python indique également l’état, le code de sortie et le nombre de redémarrages de chaque conteneur. Le client TypeScript n’expose pas ces informations.

Si le journal indique que l’API Outposts a rejeté le jeton du worker, vérifiez que vous avez bien utilisé le jeton copié lors de la création de l’avant-poste, et que ce jeton appartient au compte propriétaire de l’avant-poste. Si vous utilisez plutôt le jeton API v3 d’un utilisateur de service, son rôle doit accorder **Outposts write** (`account.outposts.write`). Corrigez l’identifiant d’authentification, puis recréez la sandbox.

Une sandbox peut afficher l’état `running` alors que son worker s’arrête et redémarre en boucle. Examinez ses journaux et, avec le client Python, les détails par conteneur présentés dans l’exemple précédent.

Arrêtez tout worker dont l’authentification échoue de manière répétée avant de créer son remplaçant. Si le démarrage échoue sans motif exploitable, conservez l’ID de la sandbox et les journaux pour le [Support CoreWeave](/support/contact).

Arrêtez la sandbox lorsque vous n’avez plus besoin du worker. Pour la configuration sans serveur, consultez [Premiers pas](/fr/products/sandboxes/get-started).

Attendez que la session Devin active se termine et enregistre ses résultats, puis arrêtez les ressources de calcul à l’aide de la commande correspondant à votre configuration :

<Tabs>
  <Tab title="cws-agent">
    ```bash theme={"system"}
    cws-agent down [SANDBOX-NAME]
    ```

    `down` crée un instantané du Workspace avant l’arrêt. Si la capture échoue, examinez l’erreur signalée ainsi que la sortie de `cws-agent status [SANDBOX-NAME]`, puis corrigez le problème avant de réessayer. Si vous pouvez abandonner les modifications non enregistrées, utilisez `cws-agent down [SANDBOX-NAME] --no-snapshot`.
  </Tab>

  <Tab title="SDK Sandboxes">
    <Tabs>
      <Tab title="Python">
        ```python theme={"system"}
        from cwsandbox import Sandbox

        sandbox = Sandbox.from_id("[SANDBOX-ID]").result()
        sandbox.stop().result()
        ```
      </Tab>

      <Tab title="TypeScript">
        ```typescript theme={"system"}
        import { createSandboxClientFromEnv } from "@coreweave/cwsandbox/node";

        const client = createSandboxClientFromEnv();
        const sandbox = await client.fromId("[SANDBOX-ID]");
        await sandbox.stop();
        ```
      </Tab>
    </Tabs>

    Cet exemple n’utilise aucun montage persistant. Avant l’arrêt, copiez vos fichiers hors de la sandbox ou téléversez vos modifications vers votre dépôt.
  </Tab>
</Tabs>

Mettre fin à une session Devin n’arrête pas la sandbox de ce worker. Pour restaurer un Workspace `cws-agent`, consultez le [guide Devin Outposts](https://github.com/coreweave/cws-agent/blob/main/docs/self-hosted.md#devin-outposts) de `cws-agent`.

<h2 id="optional-customize-the-environment">
  Facultatif : personnaliser l’environnement
</h2>

Vous pouvez personnaliser l’environnement du worker de plusieurs façons :

* **Utilisez votre propre image.** L’image officielle contient la CLI `devin` et presque rien d’autre. Compilez à partir de celle-ci une image qui ajoute votre chaîne d’outils, puis transmettez-la via `container_image` en Python ou `containerImage` en TypeScript. Devin nécessite `git`. L’enregistrement d’écran nécessite `ffmpeg`, et les outils de navigateur et d’utilisation de l’ordinateur nécessitent un binaire de navigateur compatible.

  Pour les images amd64 basées sur l’image Ubuntu officielle, installez Google Chrome. Le paquet `chromium` d’Ubuntu n’est qu’un stub snap qui ne fonctionne pas dans les conteneurs. Voir la [configuration du conteneur Devin](https://docs.devin.ai/cloud/outposts/quickstart). L’utilisation de l’ordinateur nécessite également un affichage graphique actif, tel que Xvfb, avec la variable `DISPLAY` définie pour le worker.

  Le worker effectue sa recherche dans les emplacements d’installation standard. S’il ne trouve pas votre binaire, définissez `DEVIN_CHROME_PATH` sur son chemin absolu. Voir la [référence Devin Outposts](https://docs.devin.ai/cloud/outposts/reference).
* **Configurez des GPU.** Pour connaître les options disponibles, voir la [configuration GPU des sandbox](/fr/products/sandboxes/client/guides/sandbox-configuration#gpu). L’exemple de worker de ce guide utilise uniquement des ressources CPU.
* **Exécutez davantage de workers.** Un worker ne sert qu’une session à la fois. Exécutez de nouveau le script avec le même nom d’avant-poste pour démarrer un autre worker sur la file d’attente.
* **Créez une sandbox par session.** Ici, le worker réutilise sa sandbox d’une session à l’autre. Pour obtenir une nouvelle sandbox à chaque session, consultez le [guide d’orchestration](https://docs.devin.ai/cloud/outposts/orchestration) de Devin.
