Перейти к содержанию

Environments

На этой странице Hermes Agent включает полноценный фреймворк окружений, который связывает возможности вызова инструментов с фреймворком RL-обучения Atropos. Это обеспечивает три рабочих процесса: 1. RL-обучение — обучение языковых моделей на многопользовательских агентных задачах с GRPO 2. Бенчмарки — оценка моделей на стандартизированных агентных бенчмарках 3. Генерация данных — создание SFT-данных для обучения из развёртываний агента

Все три используют одну и ту же основу: класс окружения, который определяет задачи, запускает цикл агента и оценивает результат. Окружения репозитория и инструменты RL-обучения Фреймворк окружений на Python, описанный здесь, находится в директории environments/ репозитория и представляет собой API уровня реализации для интеграции Hermes/Atropos. Он отделён от пользовательских инструментов rl_*, которые работают как оркестрационная оболочка для удалённых процессов RL-обучения. Быстрые ссылки * Хотите запустить бенчмарки? Переходите к Доступные бенчмарки * Хотите обучать с RL? Смотрите Инструменты RL-обучения для агентного интерфейса или Запуск окружений для ручного выполнения * Хотите создать новое окружение? Смотрите Создание окружений

Архитектура​

Система окружений построена на трёхуровневой цепочке наследования:

BaseEnv (Atropos)​

Фундамент из atroposlib. Предоставляет: * Управление сервером — подключение к API, совместимым с OpenAI (VLLM, SGLang, OpenRouter) * Планирование задач — координация параллельных развёртываний * Интеграция с Wandb — логирование метрик и визуализация развёртываний * CLI-интерфейс — три подкоманды: serve, process, evaluate * Логирование оценок — evaluate_log() сохраняет результаты в JSON + JSONL

HermesAgentBaseEnv​

Слой hermes-agent (environments/hermes_base_env.py). Добавляет: * Конфигурация терминального бэкенда — устанавливает TERMINAL_ENV для изолированного выполнения (local, Docker, Modal, Daytona, SSH, Singularity) * Разрешение инструментов — _resolve_tools_for_group() вызывает get_tool_definitions() из hermes-agent для получения правильных схем инструментов на основе включённых/отключённых наборов * Интеграция цикла агента — collect_trajectory() запускает HermesAgentLoop и оценивает результат * Двухфазная работа — Фаза 1 (сервер OpenAI) для eval/SFT, Фаза 2 (VLLM ManagedServer) для полноценного RL с logprobs * Патчи для асинхронной безопасности — monkey-patch для Modal-бэкенда для работы внутри цикла событий Atropos

Конкретные окружения​

Ваше окружение наследуется от HermesAgentBaseEnv и реализует пять методов: Метод| Назначение
---|---
setup()| Загрузка датасета, инициализация состояния
get_next_item()| Возврат следующего элемента для развёртывания
format_prompt(item)| Преобразование элемента в сообщение пользователя
compute_reward(item, result, ctx)| Оценка развёртывания (0.0–1.0)
evaluate()| Периодическая логика оценки

Основные компоненты​

Цикл агента​

HermesAgentLoop (environments/agent_loop.py) — это переиспользуемый движок многопользовательского агента. Он выполняет тот же шаблон вызова инструментов, что и основной цикл hermes-agent: 1. Отправляет сообщения + схемы инструментов в API через server.chat_completion() 2. Если ответ содержит tool_calls, отправляет каждый через handle_function_call() 3. Добавляет результаты инструментов в диалог, возвращается к шагу 1 4. Если tool_calls нет, агент завершает работу

Вызовы инструментов выполняются в пуле потоков (ThreadPoolExecutor(128)), чтобы асинхронные бэкенды (Modal, Docker) не вызывали взаимоблокировку внутри цикла событий Atropos. Возвращает AgentResult: [code] @dataclass
class AgentResult:
messages: List[Dict[str, Any]] # Полная история диалога
turns_used: int # Количество вызовов LLM
finished_naturally: bool # True, если модель остановилась сама
reasoning_per_turn: List[Optional[str]] # Извлечённое содержимое рассуждений
tool_errors: List[ToolError] # Ошибки при выполнении инструментов
managed_state: Optional[Dict] # Состояние VLLM ManagedServer (Фаза 2)

[/code]

Контекст инструментов​

ToolContext (environments/tool_context.py) предоставляет функциям награды прямой доступ к той же песочнице, которую модель использовала во время развёртывания. Область видимости task_id гарантирует сохранение всего состояния (файлы, процессы, вкладки браузера). [code] async def compute_reward(self, item, result, ctx: ToolContext):
# Запуск тестов в терминальной песочнице модели
test = ctx.terminal(\"pytest -v\")
if test[\"exit_code\"] == 0:
return 1.0

    # Проверка, был ли создан файл  
    content = ctx.read_file(\"/workspace/solution.py\")  
    if content.get(\"content\"):  
        return 0.5

    # Загрузка файлов для локальной проверки  
    ctx.download_file(\"/remote/output.bin\", \"/local/output.bin\")  
    return 0.0

[/code] Доступные методы: Категория| Методы
---|---
Терминал| terminal(command, timeout)
Файлы| read_file(path), write_file(path, content), search(query, path)
Передача| upload_file(), upload_dir(), download_file(), download_dir()
Веб| web_search(query), web_extract(urls)
Браузер| browser_navigate(url), browser_snapshot()
Общее| call_tool(name, args) — запасной выход для любого инструмента hermes-agent
Очистка| cleanup() — освобождение всех ресурсов

Парсеры вызовов инструментов​

Для Фазы 2 (VLLM ManagedServer) сервер возвращает неформатированный текст без структурированных вызовов инструментов. Клиентские парсеры в environments/tool_call_parsers/ извлекают tool_calls из необработанного вывода: [code] from environments.tool_call_parsers import get_parser

parser = get_parser(\"hermes\")  # или \"mistral\", \"llama3_json\", \"qwen\", \"deepseek_v3\", и т.д.  
content, tool_calls = parser.parse(raw_model_output)

[/code] Доступные парсеры: hermes, mistral, llama3_json, qwen, qwen3_coder, deepseek_v3, deepseek_v3_1, kimi_k2, longcat, glm45, glm47. В Фазе 1 (тип сервера OpenAI) парсеры не нужны — сервер обрабатывает разбор вызовов инструментов нативно.

Доступные бенчмарки​

TerminalBench2​

89 сложных терминальных задач с индивидуальными Docker-песочницами для каждой задачи. |
---|---
Что тестирует| Способность к выполнению одной задачи (кодинг/сисадмин)
Оценка| Бинарный провал/успех (проверка тестовым набором)
Песочница| Облачные песочницы Modal (индивидуальные Docker-образы для каждой задачи)
Инструменты| terminal \+ file
Задачи| 89 задач из нескольких категорий
Стоимость| ~$50–200 за полную оценку (параллельное выполнение)
Время| ~2–4 часа [code] python environments/benchmarks/terminalbench_2/terminalbench2_env.py evaluate \
--config environments/benchmarks/terminalbench_2/default.yaml

# Запуск конкретных задач  
python environments/benchmarks/terminalbench_2/terminalbench2_env.py evaluate \\  
    --config environments/benchmarks/terminalbench_2/default.yaml \\  
    --env.task_filter fix-git,git-multibranch

[/code]
Датасет: NousResearch/terminal-bench-2 на HuggingFace.

TBLite (OpenThoughts Terminal Bench Lite)​

100 задач с калиброванной сложностью — более быстрый прокси для TerminalBench2. |
---|---
Что тестирует| То же, что и TB2 (кодинг/сисадмин), калиброванные уровни сложности
Оценка| Бинарный провал/успех
Песочница| Облачные песочницы Modal
Инструменты| terminal \+ file
Задачи| 100 задач: Лёгкие (40), Средние (26), Сложные (26), Экстремальные (8)
Корреляция| r=0.911 с полным TB2
Скорость| в 2.6–8× быстрее TB2 [code] python environments/benchmarks/tblite/tblite_env.py evaluate \
--config environments/benchmarks/tblite/default.yaml

[/code]
TBLite — тонкий подкласс TerminalBench2: отличаются только датасет и таймауты. Создан командой OpenThoughts Agent (Snorkel AI + Bespoke Labs). Датасет: NousResearch/openthoughts-tblite.

YC-Bench​

Стратегический бенчмарк с длинным горизонтом — агент играет роль CEO AI-стартапа. |
---|---
Что тестирует| Многопользовательская стратегическая согласованность на сотнях шагов
Оценка| Составная: 0.5 × выживание + 0.5 × нормализованные_средства
Песочница| Локальный терминал (Modal не требуется)
Инструменты| только terminal
Запуски| 9 по умолчанию (3 пресета × 3 сида), последовательно
Стоимость| ~$50–200 за полную оценку
Время| ~3–6 часов [code] # Установка yc-bench (опциональная зависимость)
pip install \"hermes-agent[yc-bench]\"

# Запуск оценки  
bash environments/benchmarks/yc_bench/run_eval.sh

# Или напрямую  
python environments/benchmarks/yc_bench/yc_bench_env.py evaluate \\  
    --config environments/benchmarks/yc_bench/default.yaml

# Быстрый тест с одним пресетом  
python environments/benchmarks/yc_bench/yc_bench_env.py evaluate \\  
    --config environments/benchmarks/yc_bench/default.yaml \\  
    --env.presets '[\"fast_test\"]' --env.seeds '[1]'

[/code]
YC-Bench использует collinear-ai/yc-bench — детерминированную симуляцию с 4 областями навыков (research, inference, data_environment, training), системой престижа, управлением сотрудниками и финансовым давлением. В отличие от бинарной оценки по задачам TB2, YC-Bench измеряет, способен ли агент поддерживать согласованную стратегию на протяжении сотен взаимосвязанных решений.

Учебные окружения​

TerminalTestEnv​

Минимальное самодостаточное окружение со встроенными задачами (без внешнего датасета). Используется для сквозной проверки всего стека. Каждая задача просит модель создать файл по известному пути; верификатор проверяет содержимое. [code] # Режим process (сохраняет развёртывания в JSONL, не требует сервера обучения)
python environments/terminal_test_env/terminal_test_env.py process \
--env.data_path_to_save_groups terminal_test_output.jsonl

# Режим serve (подключается к API Atropos для RL-обучения)  
python environments/terminal_test_env/terminal_test_env.py serve

[/code]

HermesSweEnv​

Учебное окружение в стиле SWE-bench. Модель получает задачу по программированию, использует инструменты terminal + file + web для её решения, а функция награды запускает тесты в той же Modal-песочнице. [code] python environments/hermes_swe_env/hermes_swe_env.py serve \
--openai.model_name YourModel \
--env.dataset_name bigcode/humanevalpack \
--env.terminal_backend modal

[/code]

Запуск окружений​

Каждое окружение — это отдельный Python-скрипт с тремя CLI-подкомандами:

evaluate — Запуск бенчмарка​

Для окружений, предназначенных только для оценки (бенчмарков). Запускает все элементы, вычисляет метрики, логирует в wandb. [code] python environments/benchmarks/tblite/tblite_env.py evaluate \
--config environments/benchmarks/tblite/default.yaml \
--openai.model_name anthropic/claude-sonnet-4.6

[/code] Не требует сервера обучения или run-api. Окружение обрабатывает всё самостоятельно.

process — Генерация SFT-данных​

Запускает развёртывания и сохраняет оценённые траектории в JSONL. Полезно для генерации данных обучения без полного цикла RL. [code] python environments/terminal_test_env/terminal_test_env.py process \
--env.data_path_to_save_groups output.jsonl \
--openai.model_name anthropic/claude-sonnet-4.6

[/code] Формат вывода: каждая строка — это оценённая траектория с полной историей диалога, наградой и метаданными.

serve — Подключение к Atropos для RL-обучения​

Подключает окружение к работающему API-серверу Atropos (run-api). Используется во время активного RL-обучения. [code] # Терминал 1: Запуск API Atropos
run-api

# Терминал 2: Запуск окружения  
python environments/hermes_swe_env/hermes_swe_env.py serve \\  
    --openai.model_name YourModel

[/code] Окружение получает элементы от Atropos, запускает развёртывания агента, вычисляет награды и отправляет оценённые траектории обратно для обучения.

Двухфазная работа​

Фаза 1: Сервер OpenAI (Оценка / SFT)​

Использует server.chat_completion() с параметром tools=. Сервер (VLLM, SGLang, OpenRouter, OpenAI) обрабатывает разбор вызовов инструментов нативно. Возвращает объекты ChatCompletion со структурированными tool_calls. * Используется для: оценки, генерации SFT-данных, бенчмарков, тестирования * Плейсхолдеры токенов создаются для конвейера Atropos (поскольку реальные ID токенов недоступны из API OpenAI)

Фаза 2: VLLM ManagedServer (Полный RL)​

Использует ManagedServer для точных ID токенов + logprobs через /generate. Клиентский парсер вызовов инструментов восстанавливает структурированные tool_calls из необработанного вывода. * Используется для: полного RL-обучения с GRPO/PPO * Реальные токены, маски и logprobs проходят через конвейер * Установите tool_call_parser в конфиге в соответствии с форматом вашей модели (например, \"hermes\", \"qwen\", \"mistral\")

Создание окружений​

Учебное окружение​

[code] from environments.hermes_base_env import HermesAgentBaseEnv, HermesAgentEnvConfig
from atroposlib.envs.server_handling.server_manager import APIServerConfig

class MyEnvConfig(HermesAgentEnvConfig):  
    my_custom_field: str = \"default_value\"

class MyEnv(HermesAgentBaseEnv):  
    name = \"my-env\"  
    env_config_cls = MyEnvConfig

    @classmethod  
    def config_init(cls):  
        env_config = MyEnvConfig(  
            enabled_toolsets=[\"terminal\", \"file\"],  
            terminal_backend=\"modal\",  
            max_agent_turns=30,  
        )  
        server_configs = [APIServerConfig(  
            base_url=\"https://openrouter.ai/api/v1\",  
            model_name=\"anthropic/claude-sonnet-4.6\",  
            server_type=\"openai\",  
        )]  
        return env_config, server_configs

    async def setup(self):  
        from datasets import load_dataset  
        self.dataset = list(load_dataset(\"my-dataset\", split=\"train\"))  
        self.iter = 0

    async def get_next_item(self):  
        item = self.dataset[self.iter % len(self.dataset)]  
        self.iter += 1  
        return item

    def format_prompt(self, item):  
        return item[\"instruction\"]

    async def compute_reward(self, item, result, ctx):  
        # ctx предоставляет полный доступ к инструментам песочницы развёртывания  
        test = ctx.terminal(\"pytest -v\")  
        return 1.0 if test[\"exit_code\"] == 0 else 0.0

    async def evaluate(self, *args, **kwargs):  
        # Периодическая оценка во время обучения  
        pass

if __name__ == \"__main__\":  
    MyEnv.cli()

[/code]

Бенчмарк только для оценки​

Для бенчмарков следуйте шаблону, используемому в TerminalBench2, TBLite и YC-Bench: 1. Создайте в environments/benchmarks/ваш-бенчмарк/ 2. Установите конфиг только для оценки: eval_handling=STOP_TRAIN, steps_per_eval=1, total_steps=1 3. Заглушите методы обучения: collect_trajectories() возвращает (None, []), score() возвращает None 4. Реализуйте rollout_and_score_eval(eval_item) — цикл агента + оценка для каждого элемента 5. Реализуйте evaluate() — оркестрирует все запуски, вычисляет агрегированные метрики 6. Добавьте потоковый JSONL для отказоустойчивого сохранения результатов 7. Добавьте очистку: обработка KeyboardInterrupt, cleanup_all_environments(), _tool_executor.shutdown() 8. Запускайте с подкомандой evaluate

Смотрите environments/benchmarks/yc_bench/yc_bench_env.py как чистый, хорошо документированный эталонный пример.

Справочник по конфигурации​

Поля HermesAgentEnvConfig​

Поле Тип По умолчанию Описание
enabled_toolsets List[str] None (все) Какие наборы инструментов hermes включить
disabled_toolsets List[str] None Наборы инструментов для исключения
distribution str None Имя вероятностного распределения наборов инструментов
max_agent_turns int 30 Максимальное количество вызовов LLM на одно развёртывание
agent_temperature float 1.0 Температура сэмплирования
system_prompt str None Системное сообщение для агента
terminal_backend str \"local\" local, docker, modal, daytona, ssh, singularity
terminal_timeout int 120 Секунд на одну терминальную команду
terminal_lifetime int 3600 Максимальное время жизни песочницы
dataset_name str None Идентификатор датасета HuggingFace
tool_pool_size int 128 Размер пула потоков для выполнения инструментов
tool_call_parser str \"hermes\" Парсер для необработанного вывода Фазы 2
extra_body Dict None Дополнительные параметры для OpenAI API (например, предпочтения провайдера OpenRouter)
eval_handling Enum STOP_TRAIN STOP_TRAIN, LIMIT_TRAIN, NONE
### YAML-конфигурация​
Окружения могут быть настроены через YAML-файлы, передаваемые с --config:
[code]
env:
enabled_toolsets: [\"terminal\", \"file\"]
max_agent_turns: 60
max_token_length: 32000
agent_temperature: 0.8
terminal_backend: \"modal\"
terminal_timeout: 300
dataset_name: \"NousResearch/terminal-bench-2\"
tokenizer_name: \"NousResearch/Hermes-3-Llama-3.1-8B\"
use_wandb: true
wandb_name: \"my-benchmark\"
openai:  
  base_url: \"https://openrouter.ai/api/v1\"  
  model_name: \"anthropic/claude-sonnet-4.6\"  
  server_type: \"openai\"  
  health_check: false

[/code] Значения YAML переопределяют значения по умолчанию из config_init(). Аргументы CLI переопределяют значения YAML: [code] python my_env.py evaluate \
--config my_config.yaml \
--openai.model_name anthropic/claude-opus-4.6 # переопределяет YAML

[/code]

Предварительные требования​

Для всех окружений​

  • Python >= 3.11
  • atroposlib: pip install git+https://github.com/NousResearch/atropos.git
  • Ключ API LLM (OpenRouter, OpenAI или собственный VLLM/SGLang)
  • Аккаунт Modal и CLI: pip install \"hermes-agent[modal]\"
  • Переменные окружения MODAL_TOKEN_ID и MODAL_TOKEN_SECRET

Для YC-Bench​

  • pip install \"hermes-agent[yc-bench]\" (устанавливает CLI yc-bench + SQLAlchemy)
  • Modal не требуется — работает с локальным терминальным бэкендом

Для RL-обучения​

  • TINKER_API_KEY — ключ API для сервиса обучения Tinker
  • WANDB_API_KEY — для отслеживания метрик Weights & Biases
  • Подмодуль tinker-atropos (находится в tinker-atropos/ в репозитории)

Смотрите RL-обучение для агентного рабочего процесса RL.

Структура директорий​

[code] environments/
├── hermes_base_env.py # Абстрактный базовый класс (HermesAgentBaseEnv)
├── agent_loop.py # Движок многопользовательского агента (HermesAgentLoop)
├── tool_context.py # Доступ к инструментам для функций награды (по развёртыванию)
├── patches.py # Патчи асинхронной безопасности для Modal-бэкенда
│
├── tool_call_parsers/ # Клиентские парсеры для Фазы 2
│ ├── hermes_parser.py # Формат Hermes/ChatML
│ ├── mistral_parser.py # Формат Mistral [TOOL_CALLS]
│ ├── llama_parser.py # JSON-вызов инструментов Llama 3
│ ├── qwen_parser.py # Формат Qwen
│ ├── deepseek_v3_parser.py # Формат DeepSeek V3
│ └── ... # + kimi_k2, longcat, glm45/47, и т.д.
│
├── terminal_test_env/ # Проверка стека (встроенные задачи)
├── hermes_swe_env/ # Учебное окружение SWE-bench
│
└── benchmarks/ # Бенчмарки для оценки
├── terminalbench_2/ # 89 терминальных задач, Modal-песочницы
├── tblite/ # 100 калиброванных задач (быстрый прокси TB2)
└── yc_bench/ # Стратегический бенчмарк с длинным горизонтом

[/code] * Архитектура * BaseEnv (Atropos) * HermesAgentBaseEnv * Конкретные окружения * Основные компоненты * Цикл агента * Контекст инструментов * Парсеры вызовов инструментов * Доступные бенчмарки * TerminalBench2 * TBLite (OpenThoughts Terminal Bench Lite) * YC-Bench * Учебные окружения * TerminalTestEnv * HermesSweEnv * Запуск окружений * evaluate — Запуск бенчмарка * process — Генерация SFT-данных * serve — Подключение к Atropos для RL-обучения * Двухфазная работа * Фаза 1: Сервер OpenAI (Оценка / SFT) * Фаза 2: VLLM ManagedServer (Полный RL) * Создание окружений * Учебное окружение * Бенчмарк только для оценки * Справочник по конфигурации * Поля HermesAgentEnvConfig * YAML-конфигурация * Предварительные требования * Для всех окружений * Для бенчмарков с Modal-песочницами (TB2, TBLite) * Для YC-Bench * Для RL-обучения * Структура директорий