Datasets documentation

Charger les tâches d'évaluation des agents

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Charger les tâches d'évaluation des agents

Un jeu de données Harbor 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 :

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

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 pour exécuter réellement les tâches.

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 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 également la définition de l'environnement, le vérificateur et une solution oracle :

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 trouvé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 :

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

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

ColonneTypeDescription
namestring[task].name de task.toml (généralement org/name), ou le nom du répertoire de la tâche.
descriptionstring[task].description de task.toml.
instructionstringContenu de instruction.md : ce que l'agent doit faire.
keywordslist de string[task].keywords de task.toml.
schema_versionstringschema_version déclaré par task.toml.
configdictL'ensemble du task.toml, en tant qu'objet JSON : [task], [metadata], [verifier], [agent], [environment], [steps]…
metadatadictLa section [metadata] libre de task.toml.
fileslist de stringTous les fichiers de la tâche, avec des chemins relatifs au répertoire de la tâche.
locationstringEmplacement du répertoire de la tâche dans le jeu de données.
>>> 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 colonne dédiée :

>>> 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() et map() :

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

>>> 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 : son environnement, son vérificateur et ses fichiers 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 :

>>> 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 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 envoie à 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 :

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

Voir aussi

Update on GitHub