# Charger les tâches d'évaluation des agents

Un jeu de données [Harbor](https://harborframework.com/docs) est une collection de *tâches* utilisée pour évaluer les agents IA : chaque tâche fournit à un agent une instruction, un environnement sandboxé dans lequel travailler et un vérificateur qui évalue son travail.

Contrairement aux jeux de données tabulaires, un jeu de données Harbor n'est pas un fichier avec une ligne par exemple : **chaque tâche est un répertoire**. Le constructeur `harbor` lit un tel dépôt et produit une ligne par tâche, de sorte qu'un benchmark peut être exploré, filtré et partagé comme n'importe quel autre jeu de données :

```py
>>> from datasets import load_dataset
>>> dataset = load_dataset("harborframework/terminal-bench")
>>> dataset
DatasetDict({
    test: Dataset({
        features: ['name', 'instruction', 'description', 'keywords', 'schema_version', 'config', 'metadata', 'files', 'location'],
        num_rows: 66
    })
})
```

> [!TIP]
> Charger un jeu de données Harbor ne fait que *lire* les tâches : il ne lance jamais d'agent, ne construit pas d'image et n'exécute pas de vérificateur, et il n'exige pas que Harbor soit installé. Utilisez la bibliothèque [Harbor](https://harborframework.com/docs) pour exécuter réellement les tâches.

> [!WARNING]
> Les configurations de tâches Harbor sont des fichiers TOML. Python 3.11 et les versions ultérieures les lisent à l'aide de la bibliothèque standard (`tomllib`) ; sur Python 3.10, vous devez installer un parseur TOML en tant que dépendance supplémentaire. Consultez le guide d'[installation](./installation#harbor) pour savoir comment l'installer.

## Structure du dépôt

Un répertoire de tâche est identifié par deux fichiers, `task.toml` et `instruction.md`, et contient généralement la définition de l'environnement, le vérificateur et une solution oracle :

```text
my-harbor-dataset/
├── README.md
└── tasks/
    ├── task-a/
    │   ├── task.toml          # configuration: metadata, resources, timeouts...
    │   ├── instruction.md     # what the agent is asked to do
    │   ├── README.md          # optional human-readable description
    │   ├── environment/       # Dockerfile / docker-compose.yaml + files of the sandbox
    │   ├── tests/             # verifier
    │   └── solution/          # oracle solution
    └── task-b/
        └── ...
```

Un répertoire est reconnu comme un jeu de données Harbor dès qu’un de ses sous-répertoires, quelle que soit sa profondeur, est un répertoire de tâche (un fichier `task.toml` et un fichier `instruction.md` côte à côte) : les tâches sont détectées automatiquement, sans avoir à lister de fichier.

## Charger les tâches

Les jeux de données Harbor étant constitués de répertoires plutôt que de fichiers de données, ils sont chargés par *chemin* — sans argument `data_files` :

```py
>>> from datasets import load_dataset

>>> # a dataset repository on the Hub
>>> dataset = load_dataset("harborframework/terminal-bench")
>>> # a local directory of tasks
>>> dataset = load_dataset("/path/to/my-harbor-dataset")
>>> # the tasks of a repository that are in a sub-directory
>>> dataset = load_dataset("harborframework/terminal-bench", data_dir="tasks")
```

Le passage explicite de `data_files` est également pris en charge, à condition que le motif inclue les fichiers `task.toml` et `instruction.md` — une paire de fichiers correspondants donne une ligne :

```py
>>> dataset = load_dataset(
...     "/path/to/my-harbor-dataset",
...     data_files={"test": ["my-tasks-dir/*/task.toml", "my-tasks-dir/*/instruction.md"]},
... )
```

## Colonnes

Chaque ligne décrit une tâche :

| Colonne | Type | Description |
|--------|------|-------------|
| `name` | `string` | `[task].name` de `task.toml` (généralement `org/name`), ou le nom du répertoire de la tâche. |
| `description` | `string` | `[task].description` de `task.toml`. |
| `instruction` | `string` | Contenu de `instruction.md` : ce que l'agent doit faire. |
| `keywords` | `list` de `string` | `[task].keywords` de `task.toml`. |
| `schema_version` | `string` | `schema_version` déclaré par `task.toml`. |
| `config` | `dict` | L'ensemble du `task.toml`, en tant qu'objet JSON : `[task]`, `[metadata]`, `[verifier]`, `[agent]`, `[environment]`, `[steps]`... |
| `metadata` | `dict` | La section `[metadata]` libre de `task.toml`. |
| `files` | `list` de `string` | Tous les fichiers de la tâche, avec des chemins relatifs au répertoire de la tâche. |
| `location` | `string` | Emplacement du répertoire de la tâche dans le jeu de données. |

```py
>>> dataset = load_dataset("harborframework/terminal-bench", split="test")
>>> dataset[0]["name"]
'terminal-bench/atrx-vep-crispr'
>>> dataset[0]["instruction"][:90]
'You are provided with a region of genomic DNA representing the human ATRX locus plus sequence'
>>> dataset[0]["config"]["task"]["authors"]
[{'name': 'ScaleAI', 'email': 'tbench@scale.com'}]
>>> dataset[0]["metadata"]["category"]
'Science'
>>> dataset[0]["config"]["environment"]
{'build_timeout_sec': 1800.0, 'cpus': 2, 'memory_mb': 4096, 'storage_mb': 10240, 'gpus': 0}
>>> dataset[0]["files"][:4]
['LICENSE.md', 'README.md', 'environment/Dockerfile', 'environment/data/CDS-information.txt']
>>> dataset[0]["location"]
'tasks/atrx-vep-crispr'
```

L’ensemble du `task.toml` est disponible dans `config`, de sorte qu’aucune information n’est perdue lorsqu’une tâche utilise des champs qui ne sont pas promus en colonnes distinctes :

```py
>>> dataset = dataset.map(lambda task: {"timeout_min": task["config"]["verifier"]["timeout_sec"] / 60})
>>> sorted(set(dataset["timeout_min"]))[:6]
[1.0, 2.0, 3.0, 4.0, 5.0, 7.0]
```

## Filtrer un benchmark

Comme les métadonnées de la tâche sont chargées sous forme de dictionnaire, un benchmark peut être exploré à l'aide des méthodes habituelles [filter()](/docs/datasets/v5.2.0/fr/package_reference/main_classes#datasets.Dataset.filter) et [map()](/docs/datasets/v5.2.0/fr/package_reference/main_classes#datasets.Dataset.map) :

```py
>>> security_tasks = dataset.filter(lambda task: task["metadata"].get("category") == "Security")
>>> [task["name"] for task in security_tasks]
['terminal-bench/formal-crypto', 'terminal-bench/html-js-filter', 'terminal-bench/interleaved-vigenere', 'terminal-bench/shadow-relay', 'terminal-bench/uefi-bootkit']
```

La colonne `files` répertorie tout ce que la tâche fournit, ce qui est pratique pour voir comment une tâche est vérifiée :

```py
>>> pytest_verifiers = dataset.filter(lambda task: any(f.startswith("tests/") and f.endswith(".py") for f in task["files"]))
>>> pytest_verifiers.num_rows
63
```

## Lire les autres fichiers d'une tâche

Seules l'instruction et la configuration d'une tâche sont chargées en tant que colonnes : ses fichiers d'environnement, de vérification et de solution sont répertoriés dans la colonne `files`, sous forme de chemins relatifs au répertoire de la tâche. Combinez `task_id` et `files` pour ouvrir l'un d'entre eux avec `fsspec` :

```py
>>> from huggingface_hub import hffs
>>> dataset_path = "hf://datasets/harborframework/terminal-bench"
>>> with hffs.open(f"{dataset_path}/tasks/cumulative-layout-shift/environment/Dockerfile", "r") as f:
...     print(f.read()[:20])
'# harbor-canary GUID
```

## Configuration

[HarborConfig](/docs/datasets/v5.2.0/fr/package_reference/loading_methods#datasets.packaged_modules.harbor.HarborConfig) accepte quelques arguments en plus de ceux habituels de `load_dataset` :

- `strip_canary` (par défaut `True`) : supprime les lignes de commentaire « benchmark data canary » en tête des instructions, de la même manière que le fait Harbor lorsqu’il les transmet à un agent. Définissez-le sur `False` pour conserver le contenu original du fichier.
- `include_files` (par défaut `True`) : liste tous les fichiers de chaque tâche dans la colonne `files`. Définissez-le sur `False` pour ignorer l’énumération des répertoires des tâches, ce qui est plus rapide lorsque le jeu de données se trouve sur un système de fichiers distant ou contient des milliers de fichiers par tâche.

Les tâches peuvent également être diffusées en continu, ce qui évite de télécharger l'intégralité du benchmark à l'avance :

```py
>>> from datasets import load_dataset
>>> dataset = load_dataset("harborframework/terminal-bench", streaming=True)
>>> for task in dataset["test"]:
...     print(task["name"])
```

## Voir aussi

- La documentation de référence de [Harbor](/docs/datasets/v5.2.0/fr/package_reference/loading_methods#datasets.packaged_modules.harbor.Harbor) et [HarborConfig](/docs/datasets/v5.2.0/fr/package_reference/loading_methods#datasets.packaged_modules.harbor.HarborConfig).
- La [documentation de Harbor](https://harborframework.com/docs) pour *exécuter* les tâches d'un benchmark avec des agents et des vérificateurs.

