Batch Processing
Batch processing을 사용하면 수백 개 또는 수천 개의 prompt에 대해 Hermes agent를 병렬로 실행하고, 구조화된 trajectory data를 생성할 수 있습니다. 주된 용도는 training data generation입니다. 즉 fine-tuning이나 evaluation에 사용할 수 있는 ShareGPT 형식의 trajectory와 tool usage statistics를 만드는 데 사용됩니다.
개요
batch runner(batch_runner.py)는 prompt가 들어 있는 JSONL dataset을 처리합니다. 각 prompt는 tool access가 있는 완전한 agent session을 통해 실행되며, prompt마다 격리된 환경을 받습니다. 출력은 전체 대화 기록, tool call 통계, reasoning coverage metric을 포함한 구조화된 trajectory data입니다.
빠른 시작
# 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
dataset 형식
입력 dataset은 JSONL 파일입니다. 한 줄에 JSON object 하나가 들어갑니다. 각 entry에는 반드시 prompt field가 있어야 합니다.
{"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"}
entry에는 선택적으로 다음 field를 포함할 수 있습니다.
image또는docker_image: 해당 prompt의 sandbox에 사용할 container image입니다. Docker, Modal, Singularity backend에서 동작합니다.cwd: task의 terminal session에 적용할 working directory override입니다.
설정 옵션
| Parameter | 기본값 | 설명 |
|---|---|---|
--dataset_file | (required) | JSONL dataset 경로 |
--batch_size | (required) | batch당 prompt 수 |
--run_name | (required) | 이번 run의 이름. output dir와 checkpointing에 사용됩니다. |
--distribution | "default" | sample할 toolset distribution |
--model | claude-sonnet-4.6 | 사용할 model |
--base_url | https://openrouter.ai/api/v1 | API base URL |
--api_key | (env var) | model용 API key |
--max_turns | 10 | prompt당 최대 tool-calling iteration |
--num_workers | 4 | 병렬 worker process 수 |
--resume | false | checkpoint에서 재개 |
--verbose | false | verbose logging 활성화 |
--max_samples | all | dataset에서 처음 N개 sample만 처리 |
--max_tokens | model default | model response당 최대 token 수 |
provider routing(OpenRouter)
| Parameter | 설명 |
|---|---|
--providers_allowed | 허용할 provider를 쉼표로 구분해 지정합니다. 예: "anthropic,openai" |
--providers_ignored | 무시할 provider를 쉼표로 구분해 지정합니다. 예: "together,deepinfra" |
--providers_order | 선호 provider 순서를 쉼표로 구분해 지정합니다. |
--provider_sort | "price", "throughput", "latency" 중 하나로 정렬합니다. |
reasoning 제어
| Parameter | 설명 |
|---|---|
--reasoning_effort | effort level: none, minimal, low, medium, high, xhigh |
--reasoning_disabled | reasoning/thinking token을 완전히 비활성화 |
고급 옵션
| Parameter | 설명 |
|---|---|
--ephemeral_system_prompt | 실행 중에는 사용하지만 trajectory에는 저장하지 않는 system prompt |
--log_prefix_chars | log preview에 표시할 문자 수. 기본값은 100입니다. |
--prefill_messages_file | few-shot priming에 사용할 prefill message JSON 파일 경로 |
toolset distribution
각 prompt는 distribution에서 무작위로 sample된 toolset 집합을 받습니다. 이를 통해 training data가 다양한 tool 조합을 포함하게 됩니다. 사용 가능한 모든 distribution을 보려면 --list_distributions를 사용합니다.
현재 구현에서 distribution은 각 개별 toolset에 확률을 할당합니다. sampler는 toolset마다 독립적으로 coin flip을 수행한 뒤, 최소 하나의 toolset이 활성화되도록 보장합니다. 이는 미리 작성된 조합 table에서 하나를 고르는 방식과 다릅니다.
출력 형식
모든 출력은 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
trajectory 형식
trajectories.jsonl의 각 줄은 JSON object입니다.
{
"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 field는 from과 value field를 사용하는 ShareGPT 유사 형식입니다. tool stats는 가능한 모든 tool을 포함하도록 정규화되며, 사용하지 않은 tool은 0을 기본값으로 갖습니다. 이렇게 해야 HuggingFace dataset 호환성을 위해 entry 간 schema가 일관됩니다.
checkpointing
batch runner는 fault tolerance를 위해 견고한 checkpointing을 제공합니다.
- Checkpoint file: 각 batch가 완료될 때 저장되며, 완료된 prompt index를 추적합니다.
- Content-based resume:
--resume을 사용하면 runner가 기존 batch file을 scan하고 prompt의 실제 text content로 완료 여부를 matching합니다. index만 보지 않으므로 dataset 순서가 바뀌어도 복구할 수 있습니다. - Failed prompts: 성공적으로 완료된 prompt만 done으로 표시됩니다. 실패한 prompt는 resume 시 다시 시도됩니다.
- Batch merging: 완료 시 이전 run의 batch file을 포함한 모든 batch file이 하나의
trajectories.jsonl로 병합됩니다.
resume 동작 방식
- 모든
batch_*.jsonlfile에서 완료된 prompt를 scan합니다. content matching을 사용합니다. - 이미 완료된 prompt를 제외하도록 dataset을 filter합니다.
- 남은 prompt를 다시 batch로 나눕니다.
- 남은 prompt만 처리합니다.
- 모든 batch file, 즉 old + new를 최종 출력으로 병합합니다.
quality filtering
batch runner는 자동 quality filtering을 적용합니다.
- No-reasoning filter: assistant turn에 reasoning이 하나도 없는 sample은 버립니다.
<REASONING_SCRATCHPAD>나 native thinking token이 없는 경우입니다. - Corrupted entry filter: 유효한 tool list에 없는 hallucinated tool name이 있는 entry는 final merge 중에 걸러냅니다.
- Reasoning statistics: 전체 run에서 reasoning이 있는 turn과 없는 turn의 비율을 추적합니다.
statistics
완료 후 runner는 종합 통계를 출력합니다.
- Tool usage: tool별 call count와 success/failure rate
- Reasoning coverage: assistant turn 중 reasoning이 있는 비율
- Samples discarded: reasoning 부족으로 filter된 sample 수
- Duration: 전체 처리 시간
통계는 programmatic analysis를 위해 statistics.json에도 저장됩니다.
사용 사례
training data generation
fine-tuning을 위한 다양한 tool-use trajectory를 생성합니다.
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
model evaluation
표준화된 prompt 전반에서 model이 tool을 얼마나 잘 사용하는지 평가합니다.
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별 container image
특정 환경이 필요한 benchmark의 경우, 각 prompt가 자체 container image를 지정할 수 있습니다.
{"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"}
batch runner는 각 prompt를 실행하기 전에 Docker image에 접근할 수 있는지 확인합니다.