Пакетная обработка
Пакетная обработка позволяет запускать агента Hermes на сотнях или тысячах промптов параллельно, генерируя структурированные данные траекторий. Это в первую очередь используется для генерации обучающих данных — создания траекторий в формате ShareGPT со статистикой использования инструментов, которые можно использовать для тонкой настройки или оценки.
Обзор
Пакетный раннер (batch_runner.py) обрабатывает JSONL-датасет промптов, запуская каждый через полную сессию агента с доступом к инструментам. Каждый промпт получает свою изолированную среду. На выходе получаются структурированные данные траекторий с полной историей диалога, статистикой вызовов инструментов и метриками охвата рассуждений.
Быстрый старт
# Basic batch run
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
# Resume an interrupted run
python batch_runner.py \\
--dataset_file=data/prompts.jsonl \\
--batch_size=10 \\
--run_name=my_first_run \\
--resume
# List available toolset distributions
python batch_runner.py --list_distributions
Формат датасета
Входной датасет — это JSONL-файл (один JSON-объект на строку). Каждая запись должна содержать поле prompt:
{"prompt": "Write a Python function that finds the longest palindromic substring"}
{"prompt": "Create a REST API endpoint for user authentication using Flask"}
{"prompt": "Debug this error: TypeError: cannot unpack non-iterable NoneType object"}
Записи могут дополнительно включать:
-
imageилиdocker_image: образ контейнера для песочницы этого промпта (работает с бэкендами Docker, Modal и Singularity) -
cwd: переопределение рабочей директории для терминальной сессии задачи
Параметры конфигурации
| Параметр | По умолчанию | Описание |
|---|---|---|
--dataset_file |
(обязательно) | Путь к JSONL-датасету |
--batch_size |
(обязательно) | Промптов в батче |
--run_name |
(обязательно) | Название запуска (используется для директории вывода и контрольных точек) |
--distribution |
"default" |
Распределение наборов инструментов для выборки |
--model |
claude-sonnet-4.6 |
Используемая модель |
--base_url |
https://openrouter.ai/api/v1 |
Базовый URL API |
--api_key |
(переменная окружения) | API-ключ для модели |
--max_turns |
10 |
Максимальное количество итераций вызова инструментов на промпт |
--num_workers |
4 |
Параллельные рабочие процессы |
--resume |
false |
Возобновить с контрольной точки |
--verbose |
false |
Включить подробное логирование |
--max_samples |
все | Обработать только первые N образцов из датасета |
--max_tokens |
по умолчанию модели | Максимальное количество токенов в ответе модели |
Маршрутизация провайдеров (OpenRouter)
| Параметр | Описание |
|---|---|
--providers_allowed |
Провайдеры, разделённые запятыми, которые разрешены (например, "anthropic,openai") |
--providers_ignored |
Провайдеры, разделённые запятыми, которые игнорируются (например, "together,deepinfra") |
--providers_order |
Порядок предпочтительных провайдеров через запятую |
--provider_sort |
Сортировка по "price", "throughput" или "latency" |
Управление рассуждениями
| Параметр | Описание |
|---|---|
--reasoning_effort |
Уровень усилий: none, minimal, low, medium, high, xhigh |
--reasoning_disabled |
Полностью отключить токены рассуждений/размышлений |
Дополнительные параметры
| Параметр | Описание |
|---|---|
--ephemeral_system_prompt |
Системный промпт, используемый во время выполнения, но НЕ сохраняемый в траектории |
--log_prefix_chars |
Символы для отображения в предпросмотре логов (по умолчанию: 100) |
--prefill_messages_file |
Путь к JSON-файлу с предзаполненными сообщениями для few-shot прайминга |
Распределения наборов инструментов
Каждый промпт получает случайно выбранный набор инструментов из распределения. Это гарантирует, что обучающие данные покрывают различные комбинации инструментов. Используйте --list_distributions для просмотра всех доступных распределений.
В текущей реализации распределения присваивают вероятность каждому отдельному набору инструментов. Сэмплер независимо активирует каждый набор инструментов, гарантируя, что хотя бы один набор включён. Это отличается от таблицы заранее собранных комбинаций.
Формат вывода
Все выходные данные сохраняются в data/<run_name>/:
data/my_run/
├── trajectories.jsonl # Combined final output (all batches merged)
├── batch_0.jsonl # Individual batch results
├── batch_1.jsonl
├── ...
├── checkpoint.json # Resume checkpoint
└── statistics.json # Aggregate tool usage stats
Формат траекторий
Каждая строка в trajectories.jsonl — это JSON-объект:
{
"prompt_index": 42,
"conversations": [
{"from": "human", "value": "Write a function..."},
{"from": "gpt", "value": "I'll create that function...",
"tool_calls": [...]},
{"from": "tool", "value": "..."},
{"from": "gpt", "value": "Here's the completed function..."}
],
"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. Статистика инструментов нормализована, чтобы включать все возможные инструменты с нулевыми значениями по умолчанию, обеспечивая согласованную схему для всех записей и совместимость с датасетами HuggingFace.
Контрольные точки
Пакетный раннер имеет надёжную систему контрольных точек для отказоустойчивости:
-
Файл контрольной точки: сохраняется после завершения каждого батча, отслеживая, какие индексы промптов обработаны
-
Возобновление по содержимому: при
--resumeраннер сканирует существующие файлы батчей и сопоставляет завершённые промпты по их фактическому текстовому содержимому (а не только по индексам), что позволяет восстановиться даже при изменении порядка датасета -
Неудачные промпты: только успешно завершённые промпты помечаются как выполненные — неудачные промпты будут повторно запущены при возобновлении
-
Слияние батчей: после завершения все файлы батчей (включая предыдущие запуски) объединяются в один
trajectories.jsonl
Как работает возобновление
-
Сканирование всех
batch_*.jsonlфайлов на предмет завершённых промптов (по содержимому) -
Фильтрация датасета для исключения уже завершённых промптов
-
Перегруппировка оставшихся промптов в батчи
-
Обработка только оставшихся промптов
-
Слияние всех файлов батчей (старых + новых) в финальный вывод
Фильтрация качества
Пакетный раннер применяет автоматическую фильтрацию качества:
-
Фильтр отсутствия рассуждений: образцы, в которых ни один из шагов ассистента не содержит рассуждений (нет
<REASONING_SCRATCHPAD>или нативных токенов размышления), отбрасываются -
Фильтр повреждённых записей: записи с вымышленными названиями инструментов (не входящими в список допустимых) отфильтровываются при финальном слиянии
-
Статистика рассуждений: отслеживает процент шагов с рассуждениями и без них по всему запуску
Статистика
После завершения раннер выводит подробную статистику:
-
Использование инструментов: количество вызовов, показатели успеха/неудач для каждого инструмента
-
Охват рассуждений: процент шагов ассистента, содержащих рассуждения
-
Отброшенные образцы: количество образцов, отфильтрованных из-за отсутствия рассуждений
-
Длительность: общее время обработки
Статистика также сохраняется в statistics.json для программного анализа.
Варианты использования
Генерация обучающих данных
Генерация разнообразных траекторий использования инструментов для тонкой настройки:
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
Индивидуальные образы контейнеров для промптов
Для бенчмарков, требующих специфических сред, каждый промпт может указать свой образ контейнера:
{"prompt": "Install numpy and compute eigenvalues of a 3x3 matrix", "image": "python:3.11-slim"}
{"prompt": "Compile this Rust program and run it", "image": "rust:1.75"}
{"prompt": "Set up a Node.js Express server", "image": "node:20-alpine", "cwd": "/app"}
Пакетный раннер проверяет доступность Docker-образов перед запуском каждого промпта.