第 8 章

第 8 章:数据集——本地、Hub 与 Git 仓库

第 8 章:数据集——本地、Hub 与 Git 仓库

单个 task 只能回答一个场景的问题,成体系地评测一个 agent 需要一批 task。本章介绍 Harbor 数据集的三种来源——本地目录/dataset.toml 清单、Harbor Hub 发布版、Git 仓库——各自的运行命令、dataset.toml 的日常操作、registry.json 的 schema,以及如何组织并发布自己的数据集。

数据集是什么,从哪里来

回顾一下:一个 Harbor task = instruction + 沙箱环境 + 判分脚本;数据集就是 task 的集合,还可以定义自定义指标(metrics)来聚合各 task 的 reward。三种使用方式如下:

来源 选择方式 典型命令
本地目录或 dataset.toml 清单 --path / -p harbor run -p "<path/to/dataset>" ...
Harbor Hub 发布版 --dataset / -d harbor run -d "<org/name@version>" ...
Git 仓库 --repo harbor run --repo org/repo-name ...

三者共享同一批 task 格式,区别只在"task 从哪里来"。

本地数据集:目录与 dataset.toml

隐式数据集(implicit dataset)

最简单的组织方式:把一组 task 目录并置在同一目录下即可:

my-dataset/
├── task1/
├── task2/
└── task3/

然后直接运行:

harbor run -p ./my-dataset -a "" -m ""

-p 的取值既可以是一个 task 目录的父目录,也可以是一个 dataset.toml 清单文件。

显式数据集(explicit dataset):dataset.toml

当你想从同一批 task 中切分出多个数据集(比如按难度、按类别取子集)时,复制粘贴 task 目录既笨重又难维护。更好的做法是创建 dataset.toml 清单——它只保存指向各 task 目录的指针,而非拷贝。

dataset.toml 的常用操作

# 在当前目录生成 dataset.toml 清单
harbor dataset init ""

# 添加 / 移除一个 task 目录
harbor dataset add ""
harbor dataset remove ""

# 整批导入 / 移除另一个数据集的全部 task
harbor dataset add ""
harbor dataset remove ""

# 运行清单
harbor run -p ""

<org> 通常是你的公司/团队名,<name> 是数据集名。从另一个 dataset.toml 整批增删,让"主数据集 + 派生子集"的维护变得非常轻。

发布到 Harbor Hub

写好的数据集可以分享给团队成员或公开发布到 Harbor Hub:

harbor publish ""

官方给了一个贴切的类比:Harbor Hub 更像 PyPI 或 NPM,而不是 GitHub。因为 task 本质上是软件——开发过程发生在版本控制的仓库里,而"版本"被发布到 Hub 供人安装使用。发布完成后,任何有权限的人都能直接运行 harbor run -d "<org/name>",也可以钉住版本 -d "<org/name@version>"。

Git 仓库数据集

第三种方式是从任意 Git 仓库直接解析并运行数据集,支持 GitHub、GitLab 和 Hugging Face:

harbor run --repo "" -a "" -m ""

Harbor 会克隆仓库,默认运行其中 tasks/ 目录下的任务。

--repo 的写法

# GitHub 简写(默认 github.com),可钉住分支、tag 或 commit
--repo ""
--repo "@"
--repo "@"
--repo "@"

# 完整 URL,可通过 /tree/ 路径指定子目录
--repo "https://github.com/"
--repo "https://github.com//tree//"

# Hugging Face 与 GitLab
--repo "https://huggingface.co/datasets/"
--repo "https://gitlab.com/"

未指定 @ref 时,使用仓库的默认分支。

在仓库内选择数据集

  • 仓库相对路径:用 -p 把仓库内某个目录当作隐式数据集: harbor run --repo "<org/repo-name>" -p "<path/to/tasks>" -a "<agent>" -m "<model>"
  • 默认 registry:用 -d 选择仓库根目录 registry.json 中定义的数据集,可带版本:-d "<dataset>" 或 -d "<dataset>@<version>"。
  • 自定义 registry 路径:registry.json 不在根目录时,用 --registry-path "<path/to/registry.json>" 指明。

既不给 -p 也不给 -d 时,Harbor 把仓库的 tasks/ 目录当作隐式数据集。标准数据集 flag 与 --repo 通用:-i "<task-a>" -i "<task-b>" 只包含指定 task,-l "<count>" 限制 task 数量。但注意:--repo 不能与 --registry-url 或 --task / --task-git-url 组合使用。

认证方面,公开仓库无需任何配置;私有仓库复用你环境中已有的 Git 凭证(SSH key、credential helper、GIT_ASKPASS 等)——只要 git ls-remote 能访问到仓库,--repo 就能工作。

registry.json:自定义 registry 的 schema

registry.json 是一个 JSON 数组,每个条目定义数据集的一个版本,必填 name、version、description、tasks,metrics 可选:

[
  {
    "name": "",
    "version": "",
    "description": "",
    "tasks": [
      {
        "name": "",
        "git_url": "https://github.com//.git",
        "git_commit_id": "",
        "path": ""
      }
    ],
    "metrics": [
      {
        "type": "mean",
        "kwargs": {}
      }
    ]
  }
]

数据集级字段:

字段 类型 默认值 说明
name string 必填 配合 --dataset 使用的数据集名
version string 必填 数据集版本;其他版本另写一个顶层条目
description string 必填 人类可读的描述
tasks list[Task] 必填 包含的 task 列表
metrics list[Metric] [] 可选的 reward 聚合方式

task 级字段(每个 task 必须有 name 和 path,Git 字段可选):

字段 类型 默认值 说明
name string 必填 task 名称
path string 必填 task 目录路径;有 git_url 时相对仓库根目录,否则为本地路径
git_url string | null null task 所在 Git 仓库;省略即表示本地路径
git_commit_id string | null null task 所在 commit;省略时解析仓库默认分支

metric 级字段:type 取值 "sum" / "min" / "max" / "mean" / "uv-script"(默认 "mean"),指定聚合各 task reward 的指标实现;kwargs(默认 {})是传给指标实现的关键字参数。

一个便利规则:通过 --repo 加载 registry 时,Harbor 会用所选仓库及解析出的 commit 自动补全缺失的 git_url 和 git_commit_id。两条官方最佳实践:数据集的 name + version 组合要唯一;远程 task 要钉住完整 commit SHA,保证 run 可复现。默认 registry 是 Harbor Hub;用 --registry-url 或 --registry-path 可以指向任何人都能自建的 registry。

如何组织并发布自己的数据集

把本章内容串成一条可操作的路径。推荐用 Git 仓库承载开发过程,按标准布局组织:

my-repo/
├── registry.json        # 可选;要用 -d 时必需
└── tasks/
    ├── task-a/
    │   ├── task.toml
    │   ├── instruction.md
    │   ├── environment/
    │   └── tests/
    └── task-b/
        └── ...

日常迭代与发布流程:

flowchart LR
    A[编写 task 目录] --> B{如何组织?}
    B -->|临时/本地| C[目录并置
implicit dataset] B -->|需要子集| D[dataset.toml 清单] C --> E[本地验证
harbor run -p ...] D --> E E --> F[harbor publish org/name
发布到 Harbor Hub] E --> G[Git 仓库 + registry.json
harbor run --repo ...]

几条经验法则:

  • 开发在 Git,发布在 Hub:把 task 仓库当作源码,把 Hub 上的版本当作发布物(PyPI 模式)。
  • 子集用清单表达,不要拷贝目录:dataset.toml 的指针机制让"同一批 task、多个数据集"零维护成本。
  • 对外分享首选 --repo:合作方克隆即用;想要稳定的"版本化数据集"再走 harbor publish。
  • 远程 task 一律钉 SHA:git_commit_id 写完整 commit SHA,配合唯一 name + version,run 才可复现。

本章小结

  • 数据集是 task 的集合,可定义 metrics 聚合 reward;三种来源对应三种选择方式:本地 -p、Hub -d、Git 仓库 --repo。
  • 隐式数据集只需把 task 目录并置后 harbor run -p ./my-dataset;需要子集时改用 dataset.toml 清单(存指针而非拷贝)。
  • harbor dataset init 创建清单,dataset add / dataset remove 增删单个 task 目录或整批另一个 dataset.toml 的 task。
  • harbor publish "<org/name>" 发布到 Harbor Hub;Hub 类比 PyPI/NPM——开发在仓库、版本在 Hub,运行用 -d "<org/name@version>"。
  • --repo 支持 GitHub/GitLab/Hugging Face、shorthand 与完整 URL、@ref 钉住分支/tag/commit、/tree/ 指定子目录;默认运行仓库的 tasks/ 目录。
  • 仓库内用 -p(相对路径)、-d(根级 registry.json)或 --registry-path 选择数据集;-i 筛选、-l 限量;--repo 不能与 --registry-url、--task/--task-git-url 同用。
  • registry.json 条目必填 name、version、description、tasks,可选 metrics;task 必填 name 与 path;metric 的 type 默认 "mean";--repo 加载时会自动补全缺失的 Git 字段。
  • 数据集 name + version 要唯一,远程 task 钉完整 commit SHA;私有仓库复用环境中的 Git 凭证,git ls-remote 能通即可。

延伸阅读