批处理允许你并行地在数百或数千个提示词上运行 Hermes 智能体,并生成结构化的轨迹(trajectory)数据。这主要用于 生成训练数据 —— 即产出带有工具使用统计信息的 ShareGPT 格式轨迹,可用于模型微调或评估。
批处理运行器(batch_runner.py)处理 JSONL 格式的提示词(Prompt)数据集,并在具有工具访问权限的完整智能体(Agent)会话中运行每一个提示词。每个提示词都拥有独立的隔离环境。输出结果是结构化的轨迹数据,包含完整的对话历史、工具调用统计以及推理覆盖率指标。
# 基础批处理运行python batch_runner.py \ --dataset_file=data/prompts.jsonl \ --batch_size=10 \ --run_name=my_first_run \ --model=anthropic/claude-sonnet-4.6 \ --num_workers=4
# 恢复中断的运行python batch_runner.py \ --dataset_file=data/prompts.jsonl \ --batch_size=10 \ --run_name=my_first_run \ --resume
# 列出可用的工具集分布(Toolset Distributions)python batch_runner.py --list_distributions输入数据集为一个 JSONL 文件(每行一个 JSON 对象)。每个条目必须包含一个 prompt 字段:
{"prompt": "编写一个查找最长回文子串的 Python 函数"}{"prompt": "使用 Flask 创建一个用于用户身份验证的 REST API 接口"}{"prompt": "调试此错误:TypeError: cannot unpack non-iterable NoneType object"}条目中还可以可选地包含:
image或docker_image:用于该提示词沙箱的容器镜像(支持 Docker、Modal 和 Singularity 后端)。cwd:为该任务的终端会话覆盖指定的工作目录。
| 参数 | 默认值 | 描述 |
|---|---|---|
| —dataset_file | (必填) | JSONL 数据集文件的路径 |
| —batch_size | (必填) | 每一批处理的提示词数量 |
| —run_name | (必填) | 本次运行的名称(用于输出目录和检查点记录) |
| —distribution | ”default” | 用于采样的工具集分布(Toolset distribution) |
| —model | claude-sonnet-4.6 | 使用的模型名称 |
| —base_url | https://openrouter.ai/api/v1 | API 基础 URL |
| —api_key | (环境变量) | 模型的 API 密钥 |
| —max_turns | 10 | 每个提示词允许的最大工具调用迭代次数 |
| —num_workers | 4 | 并行工作进程数 |
| —resume | false | 从检查点恢复运行 |
| —verbose | false | 启用详细日志记录 |
| —max_samples | all | 仅处理数据集中前 N 个样本 |
| —max_tokens | 模型默认值 | 单次模型响应的最大 Token 数 |
提供商路由 (OpenRouter)
Section titled “提供商路由 (OpenRouter)”| 参数 | 描述 |
|---|---|
| —providers_allowed | 允许使用的提供商,以逗号分隔(例如:“anthropic,openai”) |
| —providers_ignored | 忽略的提供商,以逗号分隔(例如:“together,deepinfra”) |
| —providers_order | 优先使用的提供商顺序,以逗号分隔 |
| —provider_sort | 排序依据:“price” (价格), “throughput” (吞吐量), 或 “latency” (延迟) |
推理控制 (Reasoning Control)
Section titled “推理控制 (Reasoning Control)”| 参数 | 描述 |
|---|---|
| —reasoning_effort | 推理强度等级:none, minimal, low, medium, high, xhigh |
| —reasoning_disabled | 完全禁用推理/思考 Token |
| 参数 | 描述 |
|---|---|
| —ephemeral_system_prompt | 执行期间使用的系统提示词,但不会保存到轨迹(Trajectories)数据中 |
| —log_prefix_chars | 日志预览中显示的字符数(默认:100) |
| —prefill_messages_file | 包含预填充消息(prefill messages)的 JSON 文件路径,用于少样本引导(few-shot priming) |
工具集分布 (Toolset Distributions)
Section titled “工具集分布 (Toolset Distributions)”每个提示词都会根据分布(distribution)随机采样一组工具集。这确保了训练数据能够覆盖多样化的工具组合。使用 --list_distributions 可以查看所有可用的分布。
在当前实现中,分布为每个单独的工具集分配一个概率。采样器独立地决定每个工具集的开启或关闭,并确保至少有一个工具集被启用。这与人工编写的预设组合表不同。
所有输出都保存在 data/<run_name>/ 目录下:
data/my_run/├── trajectories.jsonl # 合并后的最终输出(所有批次已合并)├── batch_0.jsonl # 单个批次的结果├── batch_1.jsonl├── ...├── checkpoint.json # 恢复运行的检查点└── statistics.json # 汇总的工具使用统计信息轨迹格式 (Trajectory Format)
Section titled “轨迹格式 (Trajectory Format)”trajectories.jsonl 中的每一行都是一个 JSON 对象:
{ "prompt_index": 42, "conversations": [ {"from": "human", "value": "编写一个函数..."}, {"from": "gpt", "value": "我将创建该函数...", "tool_calls": [...]}, {"from": "tool", "value": "..."}, {"from": "gpt", "value": "这是完成后的函数..."} ], "metadata": { "batch_num": 2, "timestamp": "2026-01-15T10:30:00", "model": "anthropic/claude-sonnet-4.6" }, "completed": true, "partial": false, "api_calls": 3, "toolsets_used": ["terminal", "file"], "tool_stats": { "terminal": {"count": 2, "success": 2, "failure": 0}, "read_file": {"count": 1, "success": 1, "failure": 0} }, "tool_error_counts": { "terminal": 0, "read_file": 0 }}conversations 字段使用类似于 ShareGPT 的格式,包含 from 和 value 字段。工具统计信息经过归一化处理,包含所有可能的工具(默认值为零),以确保 entry 之间 Schema 的一致性,从而兼容 HuggingFace 数据集。
检查点机制 (Checkpointing)
Section titled “检查点机制 (Checkpointing)”批处理运行器具备强大的检查点功能,以实现容错处理:
- 检查点文件: 在每个批次完成后保存,记录哪些提示词索引已完成。
- 基于内容的恢复: 使用
--resume时,运行器会扫描现有的批次文件,并根据实际的文本内容(而不只是索引)匹配已完成的提示词。这使得即使数据集顺序发生变化,也能实现恢复。 - 失败的提示词: 只有成功完成的提示词会被标记为已完成 —— 失败的提示词将在恢复运行时重试。
- 批次合并: 完成后,所有批次文件(包括之前运行产生的文件)都会被合并到一个单一的
trajectories.jsonl中。
恢复运行的工作原理
Section titled “恢复运行的工作原理”- 扫描所有
batch_*.jsonl文件,查找已完成的提示词(通过内容匹配)。 - 过滤数据集,排除已完成的提示词。
- 对剩余的提示词重新分批。
- 仅处理剩余的提示词。
- 将所有批次文件(旧的 + 新的)合并到最终输出中。
质量过滤 (Quality Filtering)
Section titled “质量过滤 (Quality Filtering)”批处理运行器会自动应用质量过滤:
- 无推理过滤: 丢弃所有不包含推理环节的样本(即助手的所有轮次中均未出现
<REASONING_SCRATCHPAD>或原生思考 Token)。 - 损坏条目过滤: 在最终合并期间,会过滤掉包含幻觉工具名称(不在有效工具列表内)的条目。
- 推理统计: 追踪整个运行过程中包含/不包含推理的轮次百分比。
统计信息 (Statistics)
Section titled “统计信息 (Statistics)”完成后,运行器会打印详尽的统计信息:
- 工具使用情况: 每个工具的调用次数、成功/失败率。
- 推理覆盖率: 包含推理过程的助手轮次占比。
- 丢弃样本数: 因缺乏推理而被过滤掉的样本数量。
- 耗时: 总处理时间。
统计信息也会同步保存到 statistics.json 中,以便进行程序化分析。
训练数据生成
Section titled “训练数据生成”生成多样化的工具使用轨迹用于微调:
python batch_runner.py \ --dataset_file=data/coding_prompts.jsonl \ --batch_size=20 \ --run_name=coding_v1 \ --model=anthropic/claude-sonnet-4.6 \ --num_workers=8 \ --distribution=default \ --max_turns=15评估模型在标准化提示词下的工具使用能力:
python batch_runner.py \ --dataset_file=data/eval_suite.jsonl \ --batch_size=10 \ --run_name=eval_gpt4 \ --model=openai/gpt-4o \ --num_workers=4 \ --max_turns=10针对特定提示词的容器镜像
Section titled “针对特定提示词的容器镜像”对于需要特定环境的基准测试,每个提示词都可以指定自己的容器镜像:
{"prompt": "安装 numpy 并计算 3x3 矩阵的特征值", "image": "python:3.11-slim"}{"prompt": "编译并运行此 Rust 程序", "image": "rust:1.75"}{"prompt": "搭建一个 Node.js Express 服务器", "image": "node:20-alpine", "cwd": "/app"}批处理运行器会在运行每个提示词之前验证 Docker 镜像是否可用。