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

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-обучения * Структура директорий