본문으로 건너뛰기

설정

anchor alias
anchor alias
anchor alias
anchor alias
anchor alias
anchor alias
anchor alias

설정

모든 설정 파일은 쉽게 확인하고 백업할 수 있도록 ~/.hermes/ 디렉터리에 저장됩니다.

디렉터리 구조

~/.hermes/
├── config.yaml # 설정값(모델, 터미널, TTS, 압축 등)
├── .env # API 키와 비밀값
├── auth.json # OAuth provider 자격 증명(Nous Portal 등)
├── SOUL.md # 기본 에이전트 정체성(시스템 프롬프트의 1번 슬롯)
├── memories/ # 영구 메모리(MEMORY.md, USER.md)
├── skills/ # 에이전트가 만든 스킬(skill_manage 도구로 관리)
├── cron/ # 예약 작업
├── sessions/ # 게이트웨이 세션
└── logs/ # 로그(errors.log, gateway.log - 비밀값 자동 마스킹)

설정 관리

hermes config              # 현재 설정 보기
hermes config edit # 에디터에서 config.yaml 열기
hermes config set KEY VAL # 특정 값 설정
hermes config check # 업데이트 후 누락된 옵션 확인
hermes config migrate # 누락된 옵션을 대화형으로 추가

# 예:
hermes config set model anthropic/claude-opus-4
hermes config set terminal.backend docker
hermes config set OPENROUTER_API_KEY sk-or-... # .env에 저장됨

hermes config set은 값의 성격에 따라 저장 위치를 자동으로 고릅니다. API 키 같은 비밀값은 .env에, 그 외 설정은 config.yaml에 저장됩니다.

설정 우선순위

설정은 다음 순서로 해석됩니다. 위에 있을수록 우선순위가 높습니다.

  1. CLI 인수 - 예: hermes chat --model anthropic/claude-sonnet-4처럼 실행 단위로 지정한 override
  2. ~/.hermes/config.yaml - 비밀값이 아닌 대부분의 기본 설정 파일
  3. ~/.hermes/.env - 환경 변수 fallback이자 API 키, 토큰, 비밀번호 같은 비밀값의 필수 저장 위치
  4. 내장 기본값 - 아무 설정도 없을 때 사용하는 안전한 기본값
Rule of Thumb

API 키, 봇 토큰, 비밀번호 같은 비밀값은 .env에 둡니다. 모델, 터미널 백엔드, 압축 설정, 메모리 제한, toolset 같은 일반 설정은 config.yaml에 둡니다. 같은 비밀값이 아닌 설정이 양쪽에 있으면 config.yaml 값이 우선합니다.

환경 변수 대체

config.yaml에서는 ${VAR_NAME} 문법으로 환경 변수를 참조할 수 있습니다.

auxiliary:
vision:
api_key: ${GOOGLE_API_KEY}
base_url: ${CUSTOM_VISION_URL}

delegation:
api_key: ${DELEGATION_KEY}

하나의 값 안에 여러 변수를 넣을 수도 있습니다. 예: url: "${HOST}:${PORT}". 참조한 변수가 설정되어 있지 않으면 placeholder가 그대로 유지됩니다. 즉 ${UNDEFINED_VAR}는 그대로 남습니다. ${VAR} 문법만 지원하며, bare $VAR는 확장되지 않습니다.

OpenRouter, Anthropic, Copilot, 사용자 지정 엔드포인트, 자체 호스팅 LLM, fallback 모델 등 AI provider 설정은 AI Providers를 참고하세요.

Provider 타임아웃

providers.<id>.request_timeout_seconds로 provider 전체 요청 타임아웃을 설정할 수 있고, providers.<id>.models.<model>.timeout_seconds로 특정 모델만 override할 수 있습니다. 이 값은 OpenAI-wire, native Anthropic, Anthropic-compatible 전송 방식의 기본 turn client, fallback chain, credential rotation 후 재생성된 client, 그리고 OpenAI-wire의 per-request timeout 인자에 적용됩니다. 따라서 이 설정값은 레거시 HERMES_API_TIMEOUT 환경 변수보다 우선합니다.

비스트리밍 호출이 멈춘 것으로 볼 시간을 providers.<id>.stale_timeout_seconds로 설정할 수 있으며, providers.<id>.models.<model>.stale_timeout_seconds로 모델별 override도 가능합니다. 이 값은 레거시 HERMES_API_CALL_STALE_TIMEOUT 환경 변수보다 우선합니다.

이 값을 설정하지 않으면 레거시 기본값이 유지됩니다. 기본값은 HERMES_API_TIMEOUT=1800s, HERMES_API_CALL_STALE_TIMEOUT=300s, native Anthropic 900s입니다. 현재 AWS Bedrock 경로(bedrock_converse와 AnthropicBedrock SDK)는 boto3 자체 타임아웃 설정을 사용하므로 이 설정에 아직 연결되어 있지 않습니다. 예시는 cli-config.yaml.example의 주석을 참고하세요.

터미널 백엔드 구성

Hermes는 7가지 터미널 백엔드를 지원합니다. 이 설정은 에이전트의 셸 명령이 실제로 어디에서 실행되는지를 결정합니다. 선택지는 로컬 머신, Docker 컨테이너, SSH 원격 서버, Modal 클라우드 샌드박스, Daytona 워크스페이스, Vercel Sandbox, Singularity/Apptainer 컨테이너입니다.

terminal:
backend: local # local | docker | ssh | modal | daytona | vercel_sandbox | singularity
cwd: "." # Gateway/cron working directory (CLI always uses launch dir)
timeout: 180 # Per-command timeout in seconds
env_passthrough: [] # Env var names to forward to sandboxed execution (terminal + execute_code)
singularity_image: "docker://nikolaik/python-nodejs:python3.11-nodejs20" # Container image for Singularity backend
modal_image: "nikolaik/python-nodejs:python3.11-nodejs20" # Container image for Modal backend
daytona_image: "nikolaik/python-nodejs:python3.11-nodejs20" # Container image for Daytona backend

Modal, Daytona, Vercel Sandbox 같은 클라우드 샌드박스에서 container_persistent: true를 사용하면 Hermes는 샌드박스가 다시 만들어질 때 파일 시스템 상태를 최대한 보존하려고 합니다. 다만 같은 라이브 샌드박스, PID 공간, 백그라운드 프로세스가 그대로 유지된다는 뜻은 아닙니다.

백엔드 개요

백엔드명령 실행 위치격리 수준적합한 용도
local현재 머신에서 직접 실행없음개발, 개인 사용
docker세션 전체에서 공유되는 단일 persistent Docker 컨테이너(/new, subagent 포함)높음(namespaces, cap-drop)안전한 샌드박싱, CI/CD
sshSSH로 접속한 원격 서버네트워크 경계원격 개발, 고성능 하드웨어
modalModal 클라우드 샌드박스높음(클라우드 VM)임시 클라우드 컴퓨팅, eval
daytonaDaytona 워크스페이스높음(클라우드 컨테이너)관리형 클라우드 개발 환경
vercel_sandboxVercel Sandbox높음(클라우드 microVM)snapshot 기반 파일 시스템 보존이 필요한 클라우드 실행
singularitySingularity/Apptainer 컨테이너네임스페이스(--containall)HPC 클러스터, 공유 머신

Local 백엔드

기본값입니다. 명령은 별도 격리 없이 현재 머신에서 직접 실행됩니다. 특별한 설치가 필요 없습니다.

terminal:
backend: local
경고

에이전트는 사용자 계정과 같은 파일 시스템 권한을 가집니다. 원하지 않는 도구는 hermes tools로 비활성화하거나, 격리가 필요하면 Docker 백엔드로 전환하세요.

Docker 백엔드

보안 강화를 적용한 Docker 컨테이너 안에서 명령을 실행합니다. 모든 capability를 기본적으로 제거하고, 권한 상승을 막으며, PID 제한을 적용합니다.

명령마다 새 컨테이너를 만드는 방식이 아니라, 하나의 persistent 컨테이너를 재사용합니다. Hermes는 처음 사용할 때 장시간 살아 있는 컨테이너 하나를 시작하고, 모든 terminal, file, execute_code 호출을 docker exec로 같은 컨테이너에 전달합니다. 이 컨테이너는 세션, /new, /reset, delegate_task subagent 사이에서도 Hermes 프로세스가 살아 있는 동안 공유됩니다. 작업 디렉터리 변경, 설치한 패키지, /workspace의 파일은 로컬 셸처럼 다음 도구 호출까지 이어집니다. 종료 시 컨테이너는 중지되고 제거됩니다. 자세한 내용은 아래 컨테이너 수명주기를 참고하세요.

terminal:
backend: docker
docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"
docker_mount_cwd_to_workspace: false # Mount launch dir into /workspace
docker_run_as_host_user: false # See "Running container as host user" below
docker_forward_env: # Env vars to forward into container
- "GITHUB_TOKEN"
docker_volumes: # Host directory mounts
- "/home/user/projects:/workspace/projects"
- "/home/user/data:/data:ro" # :ro for read-only

# Resource limits
container_cpu: 1 # CPU cores (0 = unlimited)
container_memory: 5120 # MB (0 = unlimited)
container_disk: 51200 # MB (requires overlay2 on XFS+pquota)
container_persistent: true # Persist /workspace and /root across sessions

요구 사항: Docker Desktop 또는 Docker Engine이 설치되어 실행 중이어야 합니다. Hermes는 $PATH와 일반적인 macOS 설치 위치(/usr/local/bin/docker, /opt/homebrew/bin/docker, Docker Desktop 앱 번들)를 함께 확인합니다. Podman도 바로 사용할 수 있습니다. Docker와 Podman이 둘 다 설치되어 있을 때 Podman을 강제로 쓰려면 HERMES_DOCKER_BINARY=podman 또는 전체 경로를 지정하세요.

컨테이너 수명주기: Hermes는 docker run -d ... sleep 2h로 만든 단일 장기 실행 컨테이너를 모든 terminal/file-tool 호출에 재사용합니다. 이 재사용은 세션, /new, /reset, delegate_task subagent를 가로질러 Hermes 프로세스가 살아 있는 동안 유지됩니다. 명령은 로그인 셸로 docker exec를 통해 실행되므로 작업 디렉터리 변경, 설치 패키지, /workspace의 파일이 다음 호출까지 남습니다. 컨테이너는 Hermes 종료 시 또는 idle sweep에 의해 회수될 때 중지되고 제거됩니다.

delegate_task(tasks=[...])로 병렬 subagent를 실행해도 이 하나의 컨테이너를 공유합니다. 따라서 동시에 cd를 실행하거나 환경 변수를 바꾸거나 같은 경로에 쓰면 충돌할 수 있습니다. subagent별로 분리된 샌드박스가 필요하다면 register_task_env_overrides()로 작업별 이미지 override를 등록해야 합니다. RL 및 벤치마크 환경(TerminalBench2, HermesSweEnv 등)은 작업별 Docker 이미지를 자동으로 설정합니다.

보안 강화:

  • --cap-drop ALL을 적용하고 DAC_OVERRIDE, CHOWN, FOWNER만 다시 추가
  • --security-opt no-new-privileges
  • --pids-limit 256
  • /tmp(512MB), /var/tmp(256MB), /run(64MB)에 크기 제한 tmpfs 적용

자격 증명 전달: docker_forward_env에 나열한 환경 변수는 먼저 현재 셸 환경에서, 그 다음 ~/.hermes/.env에서 해석됩니다. 스킬이 선언한 required_environment_variables도 자동으로 병합됩니다.

SSH 백엔드

SSH를 통해 원격 서버에서 명령을 실행합니다. 연결 재사용에는 ControlMaster를 사용하며, idle keepalive는 5분입니다. persistent shell은 기본적으로 활성화되어 있어 cwd와 환경 변수 같은 셸 상태가 명령 사이에 유지됩니다.

terminal:
backend: ssh
persistent_shell: true # Keep a long-lived bash session (default: true)

필수 환경 변수:

TERMINAL_SSH_HOST=my-server.example.com
TERMINAL_SSH_USER=ubuntu

선택 옵션:

변수기본값설명
TERMINAL_SSH_PORT22SSH 포트
TERMINAL_SSH_KEY(시스템 기본)SSH 개인 키 경로
TERMINAL_SSH_PERSISTENTtruepersistent shell 활성화

동작 방식: 초기화 시 BatchMode=yesStrictHostKeyChecking=accept-new로 연결합니다. persistent shell은 원격 호스트에서 하나의 bash -l 프로세스를 유지하고 임시 파일을 통해 통신합니다. stdin_data가 필요하거나 sudo를 쓰는 명령은 자동으로 one-shot 모드로 fallback됩니다.

Modal 클라우드 샌드박스에서 명령을 실행합니다. 각 작업은 설정 가능한 CPU, 메모리, 디스크를 가진 격리 VM에서 실행됩니다. 파일 시스템은 세션 사이에 스냅샷으로 저장하고 복원할 수 있습니다.

terminal:
backend: modal
container_cpu: 1 # CPU cores
container_memory: 5120 # MB (5GB)
container_disk: 51200 # MB (50GB)
container_persistent: true # Snapshot/restore filesystem

필수: MODAL_TOKEN_IDMODAL_TOKEN_SECRET 환경 변수, 또는 ~/.modal.toml 설정 파일이 필요합니다.

지속성: 활성화하면 정리 시 샌드박스 파일 시스템을 스냅샷으로 저장하고 다음 세션에서 복원합니다. 스냅샷은 ~/.hermes/modal_snapshots.json에 기록됩니다. 보존되는 것은 파일 시스템 상태이며, 라이브 프로세스, PID 공간, 백그라운드 작업은 보존되지 않습니다.

자격 증명 파일: ~/.hermes/의 OAuth 토큰 등은 자동으로 마운트되며 각 명령 전에 동기화됩니다.

Daytona 백엔드

Daytona 관리형 워크스페이스에서 명령을 실행합니다. 지속성을 위해 stop/resume을 지원합니다.

terminal:
backend: daytona
container_cpu: 1 # CPU cores
container_memory: 5120 # MB → converted to GiB
container_disk: 10240 # MB → converted to GiB (max 10 GiB)
container_persistent: true # Stop/resume instead of delete

필수: DAYTONA_API_KEY 환경 변수.

지속성: 활성화하면 정리 시 샌드박스를 삭제하지 않고 중지했다가 다음 세션에서 다시 시작합니다. 샌드박스 이름은 hermes-{task_id} 패턴을 따릅니다.

디스크 제한: Daytona는 최대 10 GiB를 적용합니다. 그보다 큰 요청은 경고와 함께 상한값으로 조정됩니다.

Vercel 샌드박스 백엔드

Vercel Sandbox 클라우드 microVM에서 명령을 실행합니다. Hermes는 일반 terminal/file 도구 표면을 그대로 사용하며, 모델에 노출되는 Vercel 전용 도구는 없습니다.

terminal:
backend: vercel_sandbox
vercel_runtime: node24 # node24 | node22 | python3.13
cwd: /vercel/sandbox # default workspace root
container_persistent: true # Snapshot/restore filesystem
container_disk: 51200 # Shared default only; custom disk is unsupported

필수 설치: 선택 SDK extra를 설치합니다.

pip install 'hermes-agent[vercel]'

필수 인증: access-token 인증에는 VERCEL_TOKEN, VERCEL_PROJECT_ID, VERCEL_TEAM_ID 세 값이 모두 필요합니다. Render, Railway, Docker 같은 호스트에 배포하거나 장시간 실행되는 일반 Hermes 프로세스에서는 이 방식이 지원되는 설정입니다.

일회성 로컬 개발에서는 짧게 유지되는 Vercel OIDC 토큰도 사용할 수 있습니다.

VERCEL_OIDC_TOKEN="$(vc project token <project-name>)" hermes chat

Vercel 프로젝트에 연결된 디렉터리에서는 프로젝트 이름을 생략할 수 있습니다.

VERCEL_OIDC_TOKEN="$(vc project token)" hermes chat

OIDC 토큰은 수명이 짧으므로 문서화된 배포 경로로 사용하면 안 됩니다.

Runtime: terminal.vercel_runtimenode24, node22, python3.13을 지원합니다. 설정하지 않으면 Hermes는 node24를 기본값으로 사용합니다.

지속성: container_persistent: true이면 Hermes는 정리 중 샌드박스 파일 시스템을 스냅샷으로 저장하고, 같은 작업을 나중에 실행할 때 해당 스냅샷에서 새 샌드박스를 복원합니다. 스냅샷에는 샌드박스로 복사된 Hermes 동기화 자격 증명, 스킬, 캐시 파일이 포함될 수 있습니다. 보존되는 것은 파일 시스템 상태뿐이며, 살아 있는 샌드박스의 정체성, PID 공간, 셸 상태, 실행 중인 백그라운드 프로세스는 보존되지 않습니다.

백그라운드 명령: terminal(background=true)는 Hermes의 일반적인 non-local 백그라운드 프로세스 흐름을 사용합니다. 샌드박스가 살아 있는 동안에는 일반 process 도구로 프로세스를 시작, 폴링, 대기, 로그 확인, 종료할 수 있습니다. 정리 또는 재시작 이후에 Vercel의 detached process를 네이티브로 복구하는 기능은 제공하지 않습니다.

디스크 크기: Vercel Sandbox는 현재 Hermes의 container_disk 리소스 설정을 지원하지 않습니다. container_disk를 설정하지 않거나 공유 기본값 51200으로 두세요. 기본값이 아닌 값은 조용히 무시되지 않고 진단 및 백엔드 생성 실패로 이어집니다.

Singularity/Apptainer 백엔드

Singularity/Apptainer 컨테이너에서 명령을 실행합니다. Docker를 사용할 수 없는 HPC 클러스터와 공유 머신을 위해 설계된 백엔드입니다.

terminal:
backend: singularity
singularity_image: "docker://nikolaik/python-nodejs:python3.11-nodejs20"
container_cpu: 1 # CPU cores
container_memory: 5120 # MB
container_persistent: true # Writable overlay persists across sessions

요구 사항: apptainer 또는 singularity 바이너리가 $PATH에 있어야 합니다.

이미지 처리: Docker URL(docker://...)은 SIF 파일로 자동 변환되어 캐시됩니다. 기존 .sif 파일은 직접 사용할 수 있습니다.

스크래치 디렉터리: 다음 순서로 해석됩니다: TERMINAL_SCRATCH_DIRTERMINAL_SANDBOX_DIR/singularity/scratch/$USER/hermes-agent(HPC convention) → ~/.hermes/sandboxes/singularity.

격리: 호스트 홈 디렉터리를 마운트하지 않고 전체 네임스페이스 격리를 적용하기 위해 --containall --no-home을 사용합니다.

흔한 터미널 백엔드 문제

터미널 명령이 즉시 실패하거나 터미널 도구가 비활성화되었다고 표시되면 다음을 확인하세요.

  • Local - 특별한 요구 사항이 없습니다. 처음 시작할 때 가장 단순하고 안전한 기본값입니다.
  • Docker - docker version으로 Docker 동작을 확인하세요. 실패하면 Docker를 고치거나 hermes config set terminal.backend local로 되돌립니다.
  • SSH - TERMINAL_SSH_HOSTTERMINAL_SSH_USER가 모두 설정되어 있어야 합니다. 누락되면 Hermes가 명확한 오류를 로그에 남깁니다.
  • Modal - MODAL_TOKEN_ID 환경 변수 또는 ~/.modal.toml이 필요합니다. hermes doctor로 점검하세요.
  • Daytona - DAYTONA_API_KEY가 필요합니다. 서버 URL 설정은 Daytona SDK가 처리합니다.
  • Singularity - apptainer 또는 singularity$PATH에 있어야 합니다. HPC 클러스터에서 흔히 사용하는 방식입니다.

원인을 모르겠다면 먼저 terminal.backendlocal로 돌려 명령이 로컬에서 정상 실행되는지 확인하세요.

종료 시 원격-호스트 파일 동기화

SSH, Modal, Daytona 백엔드처럼 에이전트의 작업 트리가 Hermes를 실행하는 호스트와 다른 머신에 있을 때, Hermes는 원격 샌드박스 안에서 에이전트가 건드린 파일을 추적합니다. 세션 종료나 샌드박스 정리 시 수정된 파일은 호스트의 ~/.hermes/cache/remote-syncs/&lt;session-id&gt;/ 아래로 동기화됩니다.

  • 동기화 트리거: 세션 종료, /new, /reset, 게이트웨이 메시지 타임아웃, 원격 백엔드를 사용한 delegate_task subagent 완료.
  • 에이전트가 명시적으로 연 파일만이 아니라, 수정한 전체 트리를 대상으로 합니다. 추가, 편집, 삭제가 모두 캡처됩니다.
  • 확인하러 갔을 때 원격 샌드박스는 이미 정리되었을 수 있습니다. 이 경우 로컬 ~/.hermes/cache/remote-syncs/... 복사본이 에이전트 변경사항의 기준 기록입니다.
  • 모델 체크포인트나 원시 데이터셋 같은 큰 바이너리 출력은 크기 제한을 받습니다. 기본적으로 file_sync_max_mb100이며, 이보다 큰 파일은 동기화에서 제외됩니다. 더 큰 산출물을 예상한다면 값을 올리세요.
terminal:
file_sync_max_mb: 100 # default — sync files up to 100 MB each
file_sync_enabled: true # default — set false to skip the sync entirely

이 기능 덕분에 ephemeral 클라우드 샌드박스가 세션 종료 후 삭제되어도, 에이전트에게 매번 scp나 별도 업로드 명령을 지시하지 않고 결과물을 회수할 수 있습니다.

Docker 볼륨 마운트

Docker 백엔드를 사용할 때 docker_volumes는 컨테이너와 호스트 디렉토리를 공유할 수 있습니다. 각 항목은 표준 도커 -v 구문을 사용합니다. host_path:container_path[:options].

terminal:
backend: docker
docker_volumes:
- "/home/user/projects:/workspace/projects" # Read-write (default)
- "/home/user/datasets:/data:ro" # Read-only
- "/home/user/.hermes/cache/documents:/output" # Gateway-visible exports

이 설정은 다음 상황에 유용합니다.

  • agent에 dataset, config, 참조 코드 같은 입력 파일 제공
  • agent가 만든 코드, 보고서, export 파일 회수
  • 사용자와 agent가 같은 파일에 접근하는 shared workspace 구성

messaging gateway에서 생성된 파일을 보내고 싶다면, agent가 MEDIA:/...를 반환할 수 있도록 export mount를 준비하는 것이 좋습니다. 예를 들어 /home/user/.hermes/cache/documents:/output을 사용할 수 있습니다.

  • Docker 내부에서 파일을 /output/...에 작성합니다.
  • MEDIA:에는 host path를 사용합니다. 예: MEDIA:/home/user/.hermes/cache/documents/report.txt
  • /workspace/.../output/...로만 반환하면 host의 gateway process가 해당 파일을 찾지 못할 수 있습니다.
경고

YAML에서 중복 키가 있으면 앞쪽 값이 조용히 무시될 수 있습니다. 이미 docker_volumes: 블록이 있다면, 파일 뒤쪽에 또 다른 docker_volumes: 키를 추가하지 말고 같은 목록에 새 mount를 병합하세요.

환경 변수를 통해 설정할 수 있습니다: TERMINAL_DOCKER_VOLUMES='["/host:/container"]' (JSON 배열).

도커 Credential 운송

기본적으로 Docker 터미널 세션은 임의 호스트 자격 증명을 상속하지 않습니다. 컨테이너 내부에 특정 토큰이 필요한 경우 terminal.docker_forward_env에 추가하세요.

terminal:
backend: docker
docker_forward_env:
- "GITHUB_TOKEN"
- "NPM_TOKEN"

Hermes는 나열된 각 변수를 현재 shell에서 먼저 찾고, 없으면 ~/.hermes/.env에서 fallback합니다.

경고

docker_forward_env에 나열한 값은 컨테이너 내부에서 실행되는 명령에 노출됩니다. terminal session에 공개해도 괜찮은 값만 전달하세요.

호스트 사용자로 컨테이너를 실행

기본 Docker 컨테이너는 root(UID 0)로 실행됩니다. 이 경우 /workspace나 다른 bind mount에 root 소유 파일이 생겨, 세션 후 host editor에서 수정하려면 sudo chown이 필요할 수 있습니다. terminal.docker_run_as_host_user 플래그로 이 동작을 바꿀 수 있습니다.

terminal:
backend: docker
docker_run_as_host_user: true # default: false

활성화하면 Hermes가 docker run 명령에 --user $(id -u):$(id -g)를 추가합니다. 그러면 /workspace, /root, docker_volumes 같은 bind mount 디렉터리에 작성된 파일이 root가 아니라 host 사용자 소유가 됩니다. 단점은 컨테이너가 더 이상 apt install을 실행하거나 /root/.npm 같은 root 소유 경로에 쓸 수 없다는 점입니다. HOME이 non-root 사용자 소유인 base image를 사용하거나, 필요한 tooling을 image build 시점에 추가하세요.

기존 동작을 유지하려면 false(기본값)로 두세요. workflow가 주로 "mount된 host file 편집"이고 sudo chown -R을 반복하는 것이 번거롭다면 켜는 편이 좋습니다.

선택 사항: 시작 디렉터리를 /workspace에 마운트

Docker sandbox는 기본적으로 격리됩니다. 명시적으로 opt in하지 않는 한 Hermes는 현재 host 작업 디렉터리를 컨테이너에 전달하지 않습니다.

config.yaml에서 사용 가능:

terminal:
backend: docker
docker_mount_cwd_to_workspace: true

활성화하면 다음처럼 동작합니다.

  • ~/projects/my-app에서 Hermes를 실행하면 host directory가 /workspace에 bind mount됩니다.
  • Docker backend가 /workspace에서 시작합니다.
  • file tool과 terminal command가 모두 같은 mounted project를 봅니다.

비활성화하면 docker_volumes로 명시적으로 mount하지 않는 한 /workspace는 sandbox 소유로 유지됩니다.

보안 tradeoff:

  • false는 sandbox boundary를 유지합니다.
  • true는 Hermes를 시작한 directory에 컨테이너가 직접 접근하게 합니다.

컨테이너가 host file에서 직접 작업해야 할 때만 opt in하세요.

Persistent Shell

기본적으로 각 터미널 명령은 별도 subprocess에서 실행됩니다. 작업 디렉터리, 환경 변수, 셸 변수는 명령 사이에 reset됩니다. persistent shell을 활성화하면 하나의 장기 실행 bash process를 execute() 호출 사이에 유지해 상태가 명령 간에 이어집니다.

이 기능은 특히 SSH 백엔드에서 유용합니다. 명령마다 새 연결을 만드는 overhead도 줄일 수 있습니다. persistent shell은 SSH에서 기본 활성화되어 있으며, local backend에서는 비활성화되어 있습니다.

terminal:
persistent_shell: true # default — enables persistent shell for SSH

비활성화하려면:

hermes config set terminal.persistent_shell false

명령 사이에 유지되는 것:

  • 작업 디렉터리(cd /tmp가 다음 명령에도 유지됨)
  • export된 환경 변수(export FOO=bar)
  • 셸 변수 (MY_VAR=hello)

우선순위:

단계변수기본값
Configterminal.persistent_shelltrue
SSH overrideTERMINAL_SSH_PERSISTENTconfig를 따름
Local overrideTERMINAL_LOCAL_PERSISTENTfalse

backend별 환경 변수가 가장 높은 우선순위를 가집니다. local backend에서도 persistent shell을 쓰고 싶다면 다음을 설정합니다.

export TERMINAL_LOCAL_PERSISTENT=true
노트

stdin_data가 필요하거나 sudo를 사용하는 명령은 IPC protocol이 이미 사용 중일 수 있으므로 one-shot mode로 fallback됩니다.

Code ExecutionREADME의 Terminal 섹션을 참고하면 각 backend의 세부 정보를 확인할 수 있습니다.

기술 설정

스킬은 SKILL.md frontmatter를 통해 자신의 구성 설정을 선언할 수 있습니다. ...skills.config 네임스페이스 아래에 저장된 값(paths, preferences, domain settings)입니다.

skills:
config:
myplugin:
path: ~/myplugin-data # Example — each skill defines its own keys

스킬 설정 작업:

  • hermes config migrate는 활성화된 모든 skill을 스캔하고, 아직 설정되지 않은 값이 있으면 입력을 요청합니다.
  • hermes config show는 "Skill Settings" 아래에 모든 skill 설정과 소유 skill을 표시합니다.
  • skill이 로드될 때, 해석된 설정 값은 skill context에 자동으로 주입됩니다.

수동 설정 값:

hermes config set skills.config.myplugin.path ~/myplugin-data

자체 skill에서 설정 항목을 선언하는 방법은 Creating Skills - Config Settings를 참고하세요.

Agent가 생성한 skill 쓰기 보호

agent가 skill_manage를 사용해 skill을 생성, 편집, patch, 삭제할 때 Hermes는 새로 작성되거나 업데이트된 content에서 위험한 keyword pattern을 선택적으로 검사할 수 있습니다(credential harvesting, 명백한 prompt injection, exfiltration 지시 등). 이 scanner는 기본적으로 비활성화되어 있습니다. 실제 agent workflow가 ~/.ssh/를 합법적으로 다루거나 $OPENAI_API_KEY를 언급하는 경우가 많아 오탐이 자주 발생했기 때문입니다. agent의 skill 쓰기 전에 scanner를 실행하려면 다음처럼 설정하세요.

skills:
guard_agent_created: true # default: false

활성화하면 skill_manage가 작성하려는 모든 content chunk가 scanner를 거쳐, 근거가 포함된 승인 prompt로 표시됩니다. 승인된 쓰기만 반영되고, 거부된 쓰기는 설명이 담긴 오류로 agent에게 반환됩니다.

메모리 구성

memory:
memory_enabled: true
user_profile_enabled: true
memory_char_limit: 2200 # ~800 tokens
user_char_limit: 1375 # ~500 tokens

파일 읽기 안전

단일 read_file 호출이 반환할 수 있는 최대 크기를 제어합니다. 한도를 넘는 요청은 offset... 사용을 안내하는 오류로 거부됩니다. 이 설정은 minified JS bundle이나 큰 data file을 한 번에 읽어 context window를 채우는 일을 방지합니다.

file_read_max_chars: 100000  # default — ~25- tokens

큰 context window를 가진 모델에서 큰 파일을 자주 읽는다면 값을 높일 수 있습니다. 작은 text model에서는 값을 낮추는 편이 효율적입니다.

# Large context model (+)
file_read_max_chars: 200000

# Small local model ( context)
file_read_max_chars: 30000

agent는 파일 읽기 결과도 자동으로 dedupe합니다. 같은 파일 영역을 두 번 읽었고 파일이 변경되지 않았다면, content를 다시 반환하는 대신 가벼운 stub을 반환합니다. 이 상태는 context compression 시 reset되므로, 파일 내용이 요약으로 밀려난 뒤에는 agent가 다시 파일을 읽을 수 있습니다.

도구 출력 truncation 한도

세 가지 관련 한도가 Hermes가 도구의 raw output을 자르기 전에 얼마나 많이 반환할 수 있는지를 제어합니다.

tool_output:
max_bytes: 50000 # terminal output cap (chars)
max_lines: 2000 # read_file pagination cap
max_line_length: 2000 # per-line cap in read_file's line-numbered view
  • max_bytesterminal 명령의 stdout/stderr 합산 출력이 이 문자 수를 넘으면, Hermes는 앞 40%와 뒤 60%를 보존하고 [OUTPUT TRUNCATED] 알림을 삽입합니다. 기본값은 50000입니다(일반적으로 약 12k token).
  • max_lines — 단일 read_file 호출에서 반환할 수 있는 최대 줄 수입니다. 이보다 큰 요청은 제한되어, 한 번의 파일 읽기가 context window를 과도하게 채우지 못하게 합니다. 기본값은 2000입니다.
  • max_line_length - read_file이 line-numbered view를 출력할 때 적용되는 줄당 문자 수 제한입니다. 더 긴 줄은 지정된 문자 수 뒤에 ... [truncated]가 붙어 잘립니다. 기본값은 2000입니다.

한 번의 호출에서 더 많은 raw output을 감당할 수 있는 large-context model에서는 이 값을 올릴 수 있습니다. 작은 text model에서는 값을 낮춰 tool result를 compact하게 유지하세요.

# Large context model (+)
tool_output:
max_bytes: 150000
max_lines: 5000

# Small local model ( context)
tool_output:
max_bytes: 20000
max_lines: 500

글로벌 툴킷 Disable

CLI 및 각 gateway 플랫폼에서 특정 toolset을 숨기려면 agent.disabled_toolsets에 이름을 나열하세요.

agent:
disabled_toolsets:
- memory # hide memory tools + MEMORY_GUIDANCE injection
- web # no web_search / web_extract anywhere

이 설정은 hermes tools가 작성한 플랫폼별 tool 설정(platform_toolsets) 이후에 적용됩니다. 따라서 여기에 포함된 toolset은 플랫폼의 저장된 설정에 남아 있어도 항상 제거됩니다. hermes tools UI에서 여러 플랫폼 행을 하나씩 수정하는 대신, "X를 모든 곳에서 끄기" 스위치처럼 사용할 수 있습니다.

목록이 비어 있거나 키가 없으면 아무 동작도 하지 않습니다.

Git Worktree 고립

같은 repository에서 여러 agent를 병렬로 실행하기 위한 격리된 git worktree 설정입니다.

worktree: true    # Always create a worktree (same as hermes -w)
# worktree: false # Default — only when -w flag is passed

활성화하면 각 CLI 세션이 .worktrees/ 아래에 고유 branch의 새 worktree를 만듭니다. agent들은 서로 방해하지 않고 파일 편집, commit, push, PR 생성 작업을 수행할 수 있습니다. 변경사항이 없는 worktree는 종료 시 제거되고, 변경사항이 남은 worktree는 수동 복구를 위해 보존됩니다.

.worktreeinclude를 통해 worktree로 복사할 수 있는 gitignored 파일을 나열할 수 있습니다

#.worktreeinclude.env.venv/
node_modules/

컨텍스트 압축

Hermes는 긴 대화가 모델의 context window 안에 머물 수 있도록 자동 압축을 수행합니다. 압축 summarizer는 별도의 LLM 호출이므로 원하는 provider나 endpoint로 지정할 수 있습니다.

모든 압축 설정은 config.yaml (환경 변수 없음)에 있습니다.

전체 참조

compression:
enabled: true # Toggle compression on/off
threshold: 0.50 # Compress at this % of context limit
target_ratio: 0.20 # Fraction of threshold to preserve as recent tail
protect_last_n: 20 # Min recent messages to keep uncompressed
hygiene_hard_message_limit: 400 # Gateway safety valve — see below

# The summarization model/provider is configured under auxiliary:
auxiliary:
compression:
model: "" # Empty = use main chat model. Override with e.g. "google/gemini-3-flash-preview" for cheaper/faster compression.
provider: "auto" # Provider: "auto", "openrouter", "nous", "codex", "main", etc.
base_url: null # Custom OpenAI-compatible endpoint (overrides provider)
Legacy config migration

compression.summary_model, compression.summary_provider, compression.summary_base_url 의 이전 구성은 auxiliary.compression.* 로 자동 마이그레이션됩니다. 수동 작업이 필요하지 않습니다.

hygiene_hard_message_limit는 gateway 전용 압축 안전장치입니다. 메시지가 수천 개까지 쌓인 장기 세션은 일반적인 context 비율 기반 threshold가 작동하기 전에 모델 context 한도에 먼저 닿을 수 있습니다. 메시지 수가 이 한도를 넘으면 Hermes는 토큰 사용량과 관계없이 압축을 강제합니다. 기본값은 400입니다. 아주 긴 세션이 정상적인 환경이라면 값을 올리고, 더 공격적인 압축이 필요하다면 낮추세요. 실행 중인 gateway에서 이 값을 수정하면 다음 메시지부터 적용됩니다(아래 참고).

Gateway hot-reload of compression and 컨텍스트 length

최근 릴리스에서는 실행 중인 gateway의 config.yaml에서 model.context_length 또는 compression.* 키를 수정하면 다음 메시지부터 적용됩니다. gateway 재시작, /reset, 세션 교체가 필요 없습니다. cached agent signature에 이 키들이 포함되므로, gateway는 변경을 감지하면 투명하게 에이전트를 다시 구성합니다. API 키와 도구/스킬 설정은 여전히 일반 reload 경로가 필요합니다.

일반 설정

기본값(자동 감지) - 별도 설정 불필요:

compression:
enabled: true
threshold: 0.50

기본 설정에서는 메인 provider와 메인 모델을 사용합니다. 기본 채팅 모델보다 저렴한 모델로 압축을 실행하고 싶다면 task별로 override하세요. 예를 들어 auxiliary.compression.provider: openroutermodel: google/gemini-2.5-flash를 함께 설정할 수 있습니다.

특정 제공자 (OAuth 또는 API 키 기반):

auxiliary:
compression:
provider: nous
model: gemini-3-flash

nous, openrouter, codex, anthropic, main 등 어떤 provider든 사용할 수 있습니다.

사용자 정의 엔드포인트 (자체 호스팅, Ollama, Z.ai, DeepSeek 등):

auxiliary:
compression:
model: glm-4.7
base_url: https://api.z.ai/api/coding/paas/v4

사용자 지정 OpenAI 호환 endpoint를 직접 지정합니다. 인증에는 OPENAI_API_KEY를 사용합니다.

3개의 손잡이가 상호 작용하는 방법

auxiliary.compression.providerauxiliary.compression.base_url설명
auto (기본값)설정 안 함가장 적절한 provider를 자동 감지합니다
nous / openrouter설정 안 함지정한 provider를 강제하고 해당 provider의 인증을 사용합니다
무시됨설정함사용자 지정 endpoint를 사용합니다(provider 설정 무시)
Summary model 컨텍스트 length requirement

요약 모델은 메인 agent 모델과 같거나 더 큰 context window를 가져야 합니다. 압축기는 대화의 전체 중간 구간을 요약 모델에 보내므로, 요약 모델의 context window가 메인 모델보다 작으면 요약 호출이 context length 오류로 실패할 수 있습니다. 이 경우 중간 턴이 요약 없이 삭제되어 대화 내용이 조용히 손실됩니다. 모델을 override할 때는 context length가 메인 모델 이상인지 확인하세요.

컨텍스트 엔진

context engine은 대화가 모델의 token limit에 가까워질 때 대화를 관리하는 방식을 제어합니다. 내장 compressor engine은 손실 요약을 사용합니다(Context Compression). plugin engine을 사용하면 다른 전략으로 교체할 수 있습니다.

context:
engine: "compressor" # default — built-in lossy summarization

plugin engine(예: lossless context management를 위한 LCM)을 사용하려면:

context:
engine: "lcm" # must match the plugin's name

plugin engine은 자동으로 활성화되지 않습니다. plugin 이름을 context.engine에 명시적으로 설정해야 합니다. 사용 가능한 engine은 hermes plugins → provider plugin → Context Engine에서 찾아 선택할 수 있습니다.

memory plugin을 위한 유사한 단일 선택 시스템은 Memory Providers를 참고하세요.

Iteration 예산 압력

agent가 많은 tool 호출과 복잡한 작업을 수행하다 보면, context가 부족해지기 전에 iteration budget(기본값: 90 turn)을 먼저 소진할 수 있습니다. budget pressure는 한도에 가까워질 때 모델에 자동으로 경고합니다.

임계값단계모델이 보는 것
70%안내[BUDGET: 63/90. 27 iterations left. Start consolidating.]
90%경고[BUDGET WARNING: 81/90. Only 9 left. Respond NOW.]

경고는 별도 메시지로 추가되지 않고, 마지막 tool result의 JSON에 _budget_warning 필드로 삽입됩니다. 이렇게 하면 prompt caching을 유지하고 대화 구조를 어지럽히지 않습니다.

agent:
max_turns: 90 # Max iterations per conversation turn (default: 90)
api_max_retries: 3 # Retries per provider before fallback engages (default: 3)

budget pressure는 기본적으로 활성화됩니다. agent는 tool result의 일부로 경고를 자연스럽게 확인하고, iteration을 모두 소진하기 전에 작업을 정리해 응답할 수 있습니다.

iteration budget이 완전히 소진되면 CLI는 ⚠ Iteration budget reached (90/90) — response may be incomplete 알림을 표시합니다. 능동 작업 중에 budget이 바닥나면 agent는 멈추기 전에 수행한 작업 요약을 생성합니다.

agent.api_max_retries는 fallback provider로 전환하기 전에 Hermes가 일시적 오류(rate limit, connection drop, 5xx 등)에 대해 provider API 호출을 몇 번 재시도할지 제어합니다. 기본값은 3이며, 최초 호출까지 포함하면 총 4번 시도합니다. fallback provider를 구성했고 빠르게 전환하고 싶다면 0으로 낮추세요. 불안정한 endpoint에 재시도를 몰아넣는 대신, 첫 일시적 오류에서 바로 fallback으로 넘어갑니다.

API 타임아웃

Hermes는 streaming 호출을 위한 별도 timeout 계층과 non-streaming 호출을 위한 stale detector를 제공합니다. stale detector는 기본값을 명시적으로 바꾸지 않았을 때만 local service에 맞춰 자동 조정됩니다.

Timeout기본값Local providerConfig / env
Socket read timeout120s자동으로 1800s로 완화HERMES_STREAM_READ_TIMEOUT
Stale stream detection180s자동 비활성화HERMES_STREAM_STALE_TIMEOUT
Stale non-stream detection300s암시적 기본값일 때 자동 비활성화providers.&lt;id&gt;.stale_timeout_seconds 또는 HERMES_API_CALL_STALE_TIMEOUT
API call (non-streaming)1800s요청 timeoutproviders.&lt;id&gt;.request_timeout_seconds / timeout_seconds 또는 HERMES_API_TIMEOUT

Socket read timeout은 provider에서 다음 데이터 chunk가 올 때까지 얼마나 기다릴지 제어합니다. local LLM은 첫 token을 생성하기 전에 큰 context를 prefill하는 데 몇 분이 걸릴 수 있으므로, Hermes는 local endpoint를 감지하면 이 값을 30분으로 올립니다. HERMES_STREAM_READ_TIMEOUT을 명시적으로 설정하면 endpoint 감지 결과와 관계없이 그 값이 항상 사용됩니다.

Stale stream detection은 SSE keep-alive ping은 계속 오지만 실제 content가 없는 연결을 감지합니다. local provider에서는 긴 prefill 중에 잘못 끊기지 않도록 이 기능이 완전히 비활성화됩니다.

Stale non-stream detection은 지나치게 오래 응답을 만들지 않는 non-streaming 호출을 중단합니다. 기본적으로 Hermes는 긴 prefill 중의 오탐을 막기 위해 local endpoint에서는 이 기능을 비활성화합니다. 다만 providers.&lt;id&gt;.stale_timeout_seconds, providers.&lt;id&gt;.models.&lt;model&gt;.stale_timeout_seconds, 또는 HERMES_API_CALL_STALE_TIMEOUT을 명시적으로 설정했다면 local endpoint에서도 해당 값이 우선합니다.

컨텍스트 압력 경고

반복 예산 압력과 별개로, context pressure는 대화가 compaction threshold에 얼마나 가까운지 추적합니다. 이 threshold에 도달하면 오래된 message를 요약하는 context compression이 실행됩니다. 대화가 길어지는 시점을 사용자와 agent가 이해하는 데 도움이 됩니다.

Threshold단계사용자에게 보이는 것
≥ 60% threshold안내CLI는 cyan progress bar를 보여주고, Gateway는 정보 알림을 보냅니다
≥ 85% threshold경고CLI는 bold yellow progress bar를 보여주고, Gateway는 compaction이 임박했음을 경고합니다

CLI에서, 컨텍스트 압력은 도구 출력 피드의 진행 막대로 나타납니다:

  ◐ context ████████████░░░░░░░░ 62% to compaction  48k threshold (50%) · approaching compaction

메시징 플랫폼에서 일반 텍스트 알림이 전송됩니다

◐ Context: ████████████░░░░░░░░ 62% to compaction (threshold: 50% of window).

auto-compression이 비활성화되어 있으면, 경고는 context가 대신 truncate될 수 있음을 알려줍니다.

context pressure는 자동으로 동작하며 별도 설정이 필요 없습니다. 사용자-facing 알림으로만 표시되고, message stream을 수정하거나 model context에 내용을 주입하지 않습니다.

Credential 풀 전략

동일한 제공자를 위한 다중 API 열쇠 또는 OAuth 토큰이 있을 때, 교체 전략을 구성하세요:

credential_pool_strategies:
openrouter: round_robin # cycle through keys evenly
anthropic: least_used # always pick the least-used key

옵션: fill_first(기본값), round_robin, least_used, random. 전체 문서는 Credential Pool을 참고하세요.

보조 모델

Hermes는 이미지 분석, 웹 페이지 요약, 브라우저 screenshot 분석, 세션 제목 생성, 컨텍스트 압축 같은 side task에 "auxiliary" 모델을 사용합니다. 기본적으로(auxiliary.*.provider: "auto") Hermes는 모든 auxiliary task를 메인 채팅 모델로 보냅니다. 즉 hermes model에서 선택한 동일 provider/model을 사용합니다. 시작할 때는 아무것도 설정할 필요가 없지만, Opus나 MiniMax M2.7처럼 비싼 reasoning 모델을 쓰는 경우 auxiliary task도 의미 있는 비용을 추가할 수 있습니다. 메인 모델과 무관하게 저렴하고 빠른 side task를 원하면 auxiliary.&lt;task&gt;.providerauxiliary.&lt;task&gt;.model을 명시적으로 설정하세요. 예를 들어 vision과 web extraction에 OpenRouter의 Gemini Flash를 사용할 수 있습니다.

Why "auto" uses your main model

이전 build는 aggregator 사용자(OpenRouter, Nous Portal)를 provider 측 저가 기본 모델로 분리했습니다. 하지만 aggregator 구독 비용을 지불한 사용자가 auxiliary traffic에서 다른 모델을 보는 것은 예상하기 어려웠습니다. 이제 auto는 모든 사용자에게 메인 모델을 사용하며, config.yaml의 task별 override는 여전히 우선합니다. 아래 전체 auxiliary 설정 참조를 참고하세요.

auxiliary 모델 구성

YAML을 직접 편집하는 대신 hermes model을 실행하고 메뉴에서 Configure auxiliary models를 선택할 수 있습니다. 그러면 task별 interactive picker가 열립니다.

$ hermes model
→ Configure auxiliary models

vision currently: auto / main model
web_extract currently: auto / main model
session_search currently: openrouter / google/gemini-2.5-flash
title_generation currently: openrouter / google/gemini-3-flash-preview
compression currently: auto / main model
approval currently: auto / main model
triage_specifier currently: auto / main model

작업을 선택하고 provider를 고른 뒤(OAuth flow는 브라우저를 열고, API-key provider는 입력을 요청합니다) 모델을 선택합니다. 변경사항은 config.yamlauxiliary.&lt;task&gt;.*에 저장됩니다. 메인 모델 선택기와 같은 구조이므로 별도 문법을 배울 필요가 없습니다.

비디오 자습서

동영상 보기

범용 설정 패턴

Hermes의 모든 모델 slot(auxiliary task, compression, fallback)은 같은 세 가지 knob을 사용합니다.

역할기본값
provider인증과 routing에 사용할 provider"auto"
model요청할 모델provider 기본값
base_url사용자 지정 OpenAI 호환 endpoint. provider보다 우선합니다.설정하지 않음

base_url이 설정되면 Hermes는 provider를 무시하고 endpoint를 직접 호출합니다(api_key 또는 OPENAI_API_KEY 사용). provider만 설정하면 Hermes는 provider의 내장 인증 흐름과 기본 URL을 사용합니다.

auxiliary task에서 사용할 수 있는 provider는 auto, mainprovider registry에 있는 모든 provider입니다. 예: openrouter, nous, openai-codex, copilot, copilot-acp, anthropic, gemini, google-gemini-cli, qwen-oauth, zai, kimi-coding, kimi-coding-cn, minimax, minimax-cn, minimax-oauth, deepseek, nvidia, xai, xai-oauth, ollama-cloud, alibaba, bedrock, huggingface, arcee, xiaomi, kilocode, opencode-zen, opencode-go, ai-gateway, azure-foundry. custom_providers 목록에 저장한 이름 있는 custom provider도 사용할 수 있습니다. 예: provider: "beans".

MiniMax OAuth

minimax-oauth는 browser OAuth로 로그인합니다. API key는 필요 없습니다. hermes model을 실행하고 **MiniMax (OAuth)**를 선택해 인증하세요. auxiliary task는 MiniMax-M2.7-highspeed를 자동으로 사용합니다. MiniMax OAuth 가이드를 참고하세요.

xAI Grok OAuth

xai-oauth는 SuperGrok 구독자를 위해 browser OAuth로 로그인합니다. API key는 필요 없습니다. hermes model을 실행하고 **xAI Grok OAuth (SuperGrok Subscription)**를 선택해 인증하세요. 같은 OAuth token은 direct-to-xAI 표면(chat, auxiliary task, TTS, image gen, video gen, transcription)에 재사용됩니다. xAI Grok OAuth 가이드를 참고하고, Hermes가 원격 host에 있다면 OAuth over SSH / Remote Hosts도 확인하세요.

"main" is for auxiliary tasks only

"main" provider 옵션은 "메인 에이전트가 쓰는 provider를 그대로 사용"한다는 뜻입니다. 이 값은 auxiliary:, compression:, fallback_model: 설정 안에서만 유효합니다. top-level model.provider 값으로는 사용할 수 없습니다. 사용자 지정 OpenAI 호환 endpoint를 메인 모델로 쓰려면 model: 섹션에서 provider: custom을 설정하세요. 메인 모델 provider 옵션은 AI Providers를 참고하세요.

전체 보조 구성 참조

auxiliary:
# Image analysis (vision_analyze tool + browser screenshots)
vision:
provider: "auto" # "auto", "openrouter", "nous", "codex", "main", etc.
model: "" # e.g. "openai/gpt-4o", "google/gemini-2.5-flash"
base_url: "" # Custom OpenAI-compatible endpoint (overrides provider)
api_key: "" # API key for base_url (falls back to OPENAI_API_KEY)
timeout: 120 # seconds — LLM API call timeout; vision payloads need generous timeout
download_timeout: 30 # seconds — image HTTP download; increase for slow connections

# Web page summarization + browser page text extraction
web_extract:
provider: "auto"
model: "" # e.g. "google/gemini-2.5-flash"
base_url: ""
api_key: ""
timeout: 360 # seconds (6min) — per-attempt LLM summarization

# Dangerous command approval classifier
approval:
provider: "auto"
model: ""
base_url: ""
api_key: ""
timeout: 30 # seconds

# Context compression timeout (separate from compression.* config)
compression:
timeout: 120 # seconds — compression summarizes long conversations, needs more time

# Session search — summarizes past session matches
session_search:
provider: "auto"
model: ""
base_url: ""
api_key: ""
timeout: 30
max_concurrency: 3 # Limit parallel summaries to reduce request-burst 429s
extra_body: {} # Provider-specific OpenAI-compatible request fields

# Skills hub — skill matching and search
skills_hub:
provider: "auto"
model: ""
base_url: ""
api_key: ""
timeout: 30

# MCP tool dispatch
mcp:
provider: "auto"
model: ""
base_url: ""
api_key: ""
timeout: 30

# Kanban triage specifier — `hermes kanban specify <id>` (or the
# dashboard's ✨ Specify button on Triage-column cards) uses this
# slot to expand a one-liner into a concrete spec and promote the
# task to `todo`. Cheap fast models work well here; spec expansion
# is short and doesn't need reasoning depth.
triage_specifier:
provider: "auto"
model: ""
base_url: ""
api_key: ""
timeout: 120

각 auxiliary task에는 초 단위 timeout을 설정할 수 있습니다. 기본값은 vision 120초, web_extract 360초, approval 30초, compression 120초입니다. auxiliary task에 느린 로컬 모델을 사용한다면 이 값을 올리세요. vision에는 HTTP 이미지 다운로드용 download_timeout도 따로 있으며 기본값은 30초입니다. 느린 네트워크나 자체 호스팅 이미지 서버를 사용한다면 이 값도 올릴 수 있습니다.

정보

context compression은 threshold 같은 동작 설정을 compression: 블록에 두고, model/provider 설정은 auxiliary.compression: 블록에 둡니다. 위의 Context Compression을 참고하세요. fallback model은 fallback_model: 블록을 사용합니다. Fallback Model을 참고하세요. 세 경우 모두 같은 provider/model/base_url 패턴을 따릅니다.

세션 검색 Tuning

auxiliary.session_search에 reasoning-heavy 모델을 사용하는 경우 Hermes는 두 가지 내장 제어 옵션을 제공합니다.

  • auxiliary.session_search.max_concurrency: Hermes가 한 번에 요약하는 matching session 수를 제한합니다.
  • auxiliary.session_search.extra_body: 요약 호출에 provider-specific OpenAI 호환 request field를 전달합니다.

예:

auxiliary:
session_search:
provider: "main"
model: "glm-4.5-air"
timeout: 60
max_concurrency: 2
extra_body:
enable_thinking: false

provider가 request burst에 rate limit을 적용한다면 max_concurrency를 사용해 session_search의 병렬성을 낮추고 안정성을 높일 수 있습니다.

extra_body는 해당 task에서 Hermes가 그대로 넘겨주길 원하는 OpenAI-compatible request-body field가 provider 문서에 있을 때만 사용하세요. Hermes는 객체를 그대로 전달합니다.

경고

extra_body는 provider가 실제로 해당 field를 지원할 때만 효과가 있습니다. provider가 native OpenAI-compatible reasoning-off flag를 제공하지 않는다면 Hermes가 대신 만들어낼 수 없습니다.

auxiliary task의 OpenRouter routing과 Pareto Code

auxiliary task가 OpenRouter로 해석될 때, 즉 명시적으로 설정했거나 메인 에이전트가 OpenRouter를 쓰는 상태에서 provider: "main"을 사용했을 때, 메인 에이전트의 provider_routingopenrouter.min_coding_score 설정은 전파되지 않습니다. 각 auxiliary task는 의도적으로 독립적입니다. 특정 aux task에 OpenRouter provider preference를 지정하거나 Pareto Code router를 사용하려면 extra_body로 task별 설정을 넣으세요.

auxiliary:
compression:
provider: openrouter
model: openrouter/pareto-code # use the Pareto Code router for this task
extra_body:
provider: # OpenRouter provider routing prefs
order: [anthropic, google] # try these providers in order
sort: throughput # or "price" | "latency"
# only: [anthropic] # restrict to a specific provider
# ignore: [deepinfra] # exclude specific providers
plugins: # OpenRouter Pareto Code router knob
- id: pareto-router
min_coding_score: 0.5 # 0.0–1.0; higher = stronger coders

이 형태는 OpenRouter가 chat completions request body에서 받는 형태와 같습니다. Hermes는 extra_body 전체를 그대로 전달하므로, openrouter.ai/docs에 문서화된 다른 OpenRouter request-body field도 같은 방식으로 사용할 수 있습니다.

비전 모델 변경

이미지 분석을 위한 Gemini Flash 대신 GPT-4o를 사용하려면:

auxiliary:
vision:
model: "openai/gpt-4o"

또는 환경 변수를 통해 (~/.hermes/.env):

AUXILIARY_VISION_MODEL=openai/gpt-4o

제공자 옵션

이 옵션은 auxiliary task 설정(auxiliary:, compression:, fallback_model:)에 적용됩니다. 메인 model.provider 설정에는 적용되지 않습니다.

Provider설명요구 사항
"auto"사용 가능한 최선의 기본값입니다. vision은 OpenRouter -> Nous -> Codex 순서로 시도합니다.-
"openrouter"OpenRouter를 강제합니다. Gemini, GPT-4o, Claude 등 다양한 모델로 route할 수 있습니다.OPENROUTER_API_KEY
"nous"Nous Portal을 강제합니다.hermes auth
"codex"Codex OAuth(ChatGPT 계정)를 강제합니다. vision도 지원합니다(gpt-5.3-codex).hermes model -> Codex
"minimax-oauth"MiniMax OAuth를 강제합니다. browser login을 사용하며 API key가 필요 없습니다. auxiliary task에는 MiniMax-M2.7-highspeed를 사용합니다.hermes model -> MiniMax (OAuth)
"xai-oauth"xAI Grok OAuth를 강제합니다. SuperGrok 구독자를 위한 browser login 방식이며 API key가 필요 없습니다. 같은 OAuth token이 chat, TTS, image, video, transcription을 커버합니다.hermes model -> xAI Grok OAuth (SuperGrok Subscription)
"main"활성 custom/main endpoint를 사용합니다. OPENAI_BASE_URL + OPENAI_API_KEY 또는 hermes model / config.yaml에 저장된 custom endpoint에서 올 수 있습니다. OpenAI, 로컬 모델, OpenAI-compatible API와 함께 동작합니다. auxiliary task 전용이며 model.provider에는 유효하지 않습니다.custom endpoint credentials + base URL

side task에서 기본 router를 우회하고 싶다면, 메인 provider catalog의 direct API-key provider도 여기서 사용할 수 있습니다. GMI_API_KEY를 설정하면 gmi도 유효합니다.

auxiliary:
compression:
provider: "gmi"
model: "anthropic/claude-opus-4.6"

GMI auxiliary routing에는 GMI의 /v1/models endpoint가 반환하는 정확한 model ID를 사용하세요.

일반 설정

직접 custom endpoint 사용(로컬/자체 호스팅 API에는 provider: "main"보다 명확함):

auxiliary:
vision:
base_url: "http://localhost:1234/v1"
api_key: "local-key"
model: "qwen2.5-vl"

base_urlprovider보다 우선하는 가장 명시적인 방법입니다. direct endpoint override에서는 Hermes가 설정된 api_key를 사용하고, 없으면 OPENAI_API_KEY로 fallback합니다. 이 custom endpoint에 OPENROUTER_API_KEY를 재사용하지 않습니다.

OpenAI API key를 vision에 사용:

# In ~/.hermes/.env:
# OPENAI_BASE_URL=https://api.openai.com/v1
# OPENAI_API_KEY=sk-...

auxiliary:
vision:
provider: "main"
model: "gpt-4o" # or "gpt-4o-mini" for cheaper

OpenRouter를 vision에 사용(다양한 모델로 route 가능):

auxiliary:
vision:
provider: "openrouter"
model: "openai/gpt-4o" # or "google/gemini-2.5-flash", etc.

Codex OAuth(ChatGPT Pro/Plus 계정 - API key 필요 없음):

auxiliary:
vision:
provider: "codex" # uses your ChatGPT OAuth token
# model defaults to gpt-5.3-codex (supports vision)

MiniMax OAuth(browser login, API key 필요 없음):

model:
default: MiniMax-M2.7
provider: minimax-oauth
base_url: https://api.minimax.io/anthropic

hermes model을 실행하고 **MiniMax (OAuth)**를 선택하면 자동으로 설정됩니다. 중국 region에서는 기본 URL이 https://api.minimaxi.com/anthropic입니다. 전체 절차는 MiniMax OAuth 가이드를 참고하세요.

로컬/self-hosted 모델:

auxiliary:
vision:
provider: "main" # uses your active custom endpoint
model: "my-local-model"

provider: "main"은 Hermes가 일반 chat에 사용하는 provider를 그대로 사용합니다. 이름 있는 custom provider(예: beans), openrouter 같은 built-in provider, 또는 legacy OPENAI_BASE_URL endpoint가 여기에 해당합니다.

Codex OAuth를 메인 모델 provider로 사용하는 경우 vision은 자동으로 동작하며 추가 설정이 필요하지 않습니다. Codex는 vision 자동 감지 체인에 포함되어 있습니다.

경고

Vision에는 multimodal 모델이 필요합니다. provider: "main"을 설정했다면 endpoint가 multimodal/vision을 지원하는지 확인하세요. 지원하지 않으면 이미지 분석이 실패합니다.

환경 변수 (legacy)

auxiliary 모델은 환경 변수로도 구성할 수 있습니다. 다만 base_url, api_key를 포함한 모든 옵션을 관리할 수 있는 config.yaml 방식이 권장됩니다.

설정환경 변수
비전 제공자AUXILIARY_VISION_PROVIDER
비전 모델AUXILIARY_VISION_MODEL
비전 endpointAUXILIARY_VISION_BASE_URL
비전 API 키AUXILIARY_VISION_API_KEY
웹 추출 제공자AUXILIARY_WEB_EXTRACT_PROVIDER
웹 추출 모델AUXILIARY_WEB_EXTRACT_MODEL
웹 추출 endpointAUXILIARY_WEB_EXTRACT_BASE_URL
웹 추출 API 키AUXILIARY_WEB_EXTRACT_API_KEY

compression 및 fallback model 설정은 config.yaml에서만 지원됩니다.

hermes config를 실행하면 현재 auxiliary model 설정을 볼 수 있습니다. 기본값과 다를 때만 표시됩니다.

Reasoning Effort

응답하기 전에 모델이 얼마나 많은 "thinking"을 사용할지 제어합니다.

agent:
reasoning_effort: "" # empty = medium (default). Options: none, minimal, low, medium, high, xhigh (max)

설정하지 않으면 기본 reasoning effort는 "medium"입니다. 대부분의 작업에 잘 맞는 균형 수준입니다. 값을 지정하면 이 기본값을 override합니다. 높은 reasoning effort는 복잡한 작업에서 더 나은 결과를 줄 수 있지만 token 사용량과 지연 시간이 늘어납니다.

/reasoning 명령으로 런타임에도 reasoning effort를 바꿀 수 있습니다.

/reasoning           # Show current effort level and display state
/reasoning high # Set reasoning effort to high
/reasoning none # Disable reasoning
/reasoning show # Show model thinking above each response
/reasoning hide # Hide model thinking

도구 사용 강제

일부 모델은 실제 도구 호출 대신 "테스트를 실행하겠습니다..."처럼 의도만 텍스트로 설명할 때가 있습니다. tool-use enforcement는 system prompt 지침을 주입해 모델이 실제 도구를 호출하도록 유도합니다.

agent:
tool_use_enforcement: "auto" # "auto" | true | false | ["model-substring", ...]
동작
"auto"(기본값)gpt, codex, gemini, gemma, grok이 모델명에 포함될 때 활성화됩니다. Claude, DeepSeek, Qwen 등 나머지는 비활성화됩니다.
true모델과 관계없이 항상 활성화합니다. 현재 모델이 작업을 수행하지 않고 설명만 하는 경향이 있을 때 유용합니다.
false모델과 관계없이 항상 비활성화합니다.
["gpt", "codex", "qwen", "llama"]모델명이 나열된 substring 중 하나를 포함할 때만 활성화합니다. 대소문자는 구분하지 않습니다.

주입되는 내용

활성화되면 system prompt에 최대 세 계층의 지침이 추가될 수 있습니다.

  1. 일반 tool-use enforcement(매칭된 모든 모델) - 의도를 설명하는 대신 즉시 도구를 호출하고, 작업이 끝날 때까지 계속하며, 미래 행동 약속으로 턴을 끝내지 말라고 지시합니다.

  2. OpenAI execution discipline(GPT 및 Codex 모델만) - 부분 결과에서 작업을 포기하거나, 선행 조회를 건너뛰거나, 도구 대신 환각하거나, 검증 없이 "done"을 선언하는 GPT 계열 실패 모드를 보정하는 추가 지침입니다.

  3. Google operational guidance(Gemini 및 Gemma 모델만) - 간결성, 절대 경로, 병렬 도구 호출, edit 전 검증 패턴에 대한 지침입니다.

이 설정은 사용자에게 별도로 보이지 않으며 system prompt에만 영향을 줍니다. Claude처럼 이미 도구를 안정적으로 사용하는 모델은 이 지침이 필요하지 않으므로 "auto"에서 제외됩니다.

켜야 하는 경우

기본 auto 목록에 없는 모델을 쓰는데, 실제 수행 대신 무엇을 하겠다고 자주 설명한다면 tool_use_enforcement: true를 설정하거나 목록에 모델 substring을 추가하세요.

agent:
tool_use_enforcement: ["gpt", "codex", "gemini", "grok", "my-custom-model"]

TTS 구성

tts:
provider: "edge" # "edge" | "elevenlabs" | "openai" | "minimax" | "mistral" | "gemini" | "xai" | "neutts"
speed: 1.0 # Global speed multiplier (fallback for all providers)
edge:
voice: "en-US-AriaNeural" # 322 voices, 74 languages
speed: 1.0 # Speed multiplier (converted to rate percentage, e.g. 1.5 → +50%)
elevenlabs:
voice_id: "pNInz6obpgDQGcFmaJgB"
model_id: "eleven_multilingual_v2"
openai:
model: "gpt-4o-mini-tts"
voice: "alloy" # alloy, echo, fable, onyx, nova, shimmer
speed: 1.0 # Speed multiplier (clamped to 0.25–4.0 by the API)
base_url: "https://api.openai.com/v1" # Override for OpenAI-compatible TTS endpoints
minimax:
speed: 1.0 # Speech speed multiplier
# base_url: "" # Optional: override for OpenAI-compatible TTS endpoints
mistral:
model: "voxtral-mini-tts-2603"
voice_id: "c69964a6-ab8b-4f8a-9465-ec0925096ec8" # Paul - Neutral (default)
gemini:
model: "gemini-2.5-flash-preview-tts" # or gemini-2.5-pro-preview-tts
voice: "Kore" # 30 prebuilt voices: Zephyr, Puck, Kore, Enceladus, etc.
xai:
voice_id: "eve" # xAI TTS voice
language: "en" # ISO 639-1
sample_rate: 24000
bit_rate: 128000 # MP3 bitrate
# base_url: "https://api.x.ai/v1"
neutts:
ref_audio: ''
ref_text: ''
model: neuphonic/neutts-air-q4-gguf
device: cpu

이 설정들은 text_to_speech tool과 voice mode 응답(CLI의 /voice tts 또는 messaging gateway)에 모두 적용됩니다.

속도 fallback 계층: provider별 속도(예: tts.edge.speed) → global tts.speed → 기본값 1.0 순서로 적용됩니다. 모든 provider에 동일한 속도를 적용하려면 global tts.speed를 설정하고, provider별 미세 조정이 필요하면 개별 override를 사용하세요.

표시 설정

display:
tool_progress: all # off | new | all | verbose
tool_progress_command: false # Enable /verbose slash command in messaging gateway
platforms: {} # Per-platform display overrides (see below)
tool_progress_overrides: {} # DEPRECATED — use display.platforms instead
interim_assistant_messages: true # Gateway: send natural mid-turn assistant updates as separate messages
skin: default # Built-in or custom CLI skin (see user-guide/features/skins)
personality: "kawaii" # Legacy cosmetic field still surfaced in some summaries
compact: false # Compact output mode (less whitespace)
resume_display: full # full (show previous messages on resume) | minimal (one-liner only)
bell_on_complete: false # Play terminal bell when agent finishes (great for long tasks)
show_reasoning: false # Show model reasoning/thinking above each response (toggle with /reasoning show|hide)
streaming: false # Stream tokens to terminal as they arrive (real-time output)
show_cost: false # Show estimated $ cost in the CLI status bar
tool_preview_length: 0 # Max chars for tool call previews (0 = no limit, show full paths/commands)
runtime_footer: # Gateway: append a runtime-context footer to final replies
enabled: false
fields: ["model", "context_pct", "cwd"]
file_mutation_verifier: true # Append an advisory footer when write_file/patch calls failed this turn
language: en # UI language for static messages (approval prompts, some gateway replies). en | zh | ja | de | es | fr | tr | uk

파일 변경 verifier

display.file_mutation_verifiertrue(기본값)이면, Hermes는 해당 turn에서 write_file 또는 patch 호출이 실패했고 같은 경로에 대한 후속 쓰기로 회복되지 않은 경우 알려줍니다. 이렇게 하면 일부 patch가 조용히 실패했는데도 모델이 성공한 것처럼 요약하는 상황을, 매번 수동으로 git status를 실행하지 않고도 확인할 수 있습니다.

예제 footer:

⚠️ File-mutation verifier: 3 file(s) were NOT modified this turn despite any wording above that may suggest otherwise. Run `git status` or `read_file` to confirm.
• concepts/automatic-organization.md — [patch] Could not find match for old_string
• concepts/lora.md — [patch] Could not find match for old_string
• concepts/rag-pipeline.md — [patch] Could not find match for old_string

footer를 숨기려면 file_mutation_verifier: false 또는 HERMES_FILE_MUTATION_VERIFIER=0을 설정하세요. 이 알림은 turn 종료 시점에 실제 실패가 남아 있을 때만 켜집니다. 실패한 patch를 같은 turn 안에서 재시도해 성공하면 해당 파일에는 표시되지 않습니다.

정적 메시지 UI 언어

display.language 설정은 CLI 승인 prompt, gateway slash-command 응답(예: restart drain 알림, "approval expired", "goal cleared")처럼 사용자가 직접 보는 일부 정적 메시지를 번역합니다. agent 응답, log line, tool output, error trace, slash-command 설명은 번역하지 않습니다. 이러한 항목은 영어로 유지됩니다. agent가 다른 언어로 답하길 원한다면 prompt나 system message에 그렇게 지시하세요.

지원 값: en(기본값), zh(중국어 간체), ja(일본어), de(독일어), es(스페인어), fr(프랑스어), tr(터키어), uk(우크라이나어). 알 수 없는 값은 영어로 fallback됩니다.

HERMES_LANGUAGE 환경 변수로 session별 언어를 설정할 수도 있습니다.

display:
language: zh # CLI approval prompts appear in Chinese
설정값표시 방식
off진행 표시 없음 - 최종 응답만 표시
newtool이 바뀔 때만 tool 표시
all모든 tool 호출을 짧은 preview와 함께 표시(기본값)
verbose전체 args, 결과, 디버그 로그

CLI에서는 /verbose로 이 mode를 순환할 수 있습니다. /verbose를 messaging platform(Telegram, Discord, Slack 등)에서 사용하려면 위의 tool_progress_command: true를 설정하세요. 이 명령은 다음 mode로 전환하고 설정에 저장합니다.

display.runtime_footer.enabled: true이면 Hermes는 gateway의 final 메시지에 작은 runtime context footer를 추가합니다. CLI 상태 표시줄과 비슷하게 모델, context %, cwd, session duration, token, cost 등을 보여줍니다. 기본값은 off이며, 팀이 모든 응답에 provenance를 포함하길 원할 때 gateway별로 켜면 됩니다.

display:
runtime_footer:
enabled: true
fields: ["model", "context_pct", "cwd"] # any of: model, context_pct, cwd, duration, tokens, cost

/footer slash command로 session 실행 중에 이 설정을 전환할 수 있습니다.

Telegram/Discord/Slack 응답에는 다음처럼 덧붙습니다.

— claude-opus-4.7 · 12 tool calls · 2m 14s · $0.042

turn의 final 메시지에만 추가됩니다. 중간 업데이트에는 붙지 않습니다.

Per-platform 진행 오버라이드

플랫폼마다 적절한 verbosity가 다릅니다. 예를 들어 Signal은 메시지 편집을 지원하지 않으므로 진행 업데이트마다 별도 메시지가 생겨 시끄러울 수 있습니다. display.platforms를 사용해 플랫폼별 mode를 설정하세요.

display:
tool_progress: all # global default
platforms:
signal:
tool_progress: 'off' # silence progress on Signal
telegram:
tool_progress: verbose # detailed progress on Telegram
slack:
tool_progress: 'off' # quiet in shared Slack workspace

override가 없는 플랫폼은 global tool_progress 값으로 fallback합니다. legacy display.tool_progress_overrides 키도 하위 호환성을 위해 계속 로드되지만, 처음 로드할 때 deprecated 상태로 표시되고 display.platforms로 migration됩니다.

interim_assistant_messages는 게이트웨이 전용입니다. 활성화되면 Hermes는 완료된 중간 턴 보조 업데이트를 별도의 채팅 메시지로 보냅니다. 이 설정은 tool_progress와 독립적이며 게이트웨이 스트리밍도 필요하지 않습니다.

개인정보 보호

privacy:
redact_pii: false # Strip PII from LLM context (gateway only)

redact_piitrue이면 gateway가 지원 플랫폼에서 LLM으로 보내기 전에 system prompt의 개인 식별 정보를 마스킹합니다.

필드처리
전화번호(WhatsApp/Signal의 사용자 ID)user_<12-char-sha256>로 hash
사용자 IDuser_<12-char-sha256>로 hash
채팅 ID숫자 부분을 hash하고 플랫폼 prefix는 보존(telegram:&lt;hash&gt;)
home channel ID숫자 부분 hash
이름 / username영향 없음. 사용자가 정한 공개 표시 이름입니다.

플랫폼 지원: Redaction는 WhatsApp, Signal 및 Telegram에 적용됩니다. Discord 및 Slack은 언급 시스템 (<@user_id>)이 LLM 컨텍스트에서 실제 ID를 요구합니다.

hash는 deterministic합니다. 같은 사용자는 항상 같은 hash로 매핑되므로, 모델은 group chat 안에서 사용자를 계속 구분할 수 있습니다. routing과 delivery에는 내부적으로 원래 값이 사용됩니다.

Speech-to-Text(STT)

stt:
provider: "local" # "local" | "groq" | "openai" | "mistral"
local:
model: "base" # tiny, base, small, medium, large-v3
openai:
model: "whisper-1" # whisper-1 | gpt-4o-mini-transcribe | gpt-4o-transcribe
# model: "whisper-1" # Legacy fallback key still respected

제공자 행동:

  • localfaster-whisper를 사용합니다. pip install faster-whisper와 별도로 설치하세요.
  • groq는 Groq의 Whisper 호환 엔드포인트를 사용하고 GROQ_API_KEY를 읽습니다.
  • openai는 OpenAI speech API를 사용하고 VOICE_TOOLS_OPENAI_KEY를 읽습니다.

요청한 provider를 사용할 수 없으면 Hermes는 localgroqopenai 순서로 자동 fallback합니다.

Groq 및 OpenAI 모델은 환경 변수로 지정합니다.

STT_GROQ_MODEL=whisper-large-v3-turbo
STT_OPENAI_MODEL=whisper-1
GROQ_BASE_URL=https://api.groq.com/openai/v1
STT_OPENAI_BASE_URL=https://api.openai.com/v1

음성 모드(CLI)

voice:
record_key: "ctrl+b" # Push-to-talk key inside the CLI
max_recording_seconds: 120 # Hard stop for long recordings
auto_tts: false # Enable spoken replies automatically when /voice on
beep_enabled: true # Play record start/stop beeps in CLI voice mode
silence_threshold: 200 # RMS threshold for speech detection
silence_duration: 3.0 # Seconds of silence before auto-stop

마이크 모드는 /voice on으로 활성화합니다. record_key로 녹음을 시작/중지하고, /voice tts로 음성 답변을 toggle할 수 있습니다. End-to-end 설정과 플랫폼별 동작은 Voice Mode를 참고하세요.

스트리밍

전체 응답을 기다리지 않고 token을 terminal 또는 messaging platform으로 streaming합니다.

CLI 스트리밍

display:
streaming: true # Stream tokens to terminal in real-time
show_reasoning: true # Also stream reasoning/thinking tokens (optional)

활성화하면 응답이 streaming box 안에 token 단위로 표시됩니다. tool call은 여전히 조용히 capture됩니다. provider가 streaming을 지원하지 않으면 일반 display로 자동 fallback됩니다.

게이트웨이 스트리밍(Telegram, Discord, Slack)

streaming:
enabled: true # Enable progressive message editing
transport: edit # "edit" (progressive message editing) or "off"
edit_interval: 0.3 # Seconds between message edits
buffer_threshold: 40 # Characters before forcing an edit flush
cursor: " ▉" # Cursor shown during streaming
fresh_final_after_seconds: 60 # Send fresh final (Telegram) when preview is this old; 0 = always edit in place

활성화하면 bot은 첫 token이 도착할 때 message를 보내고, 이후 token이 들어올 때마다 같은 message를 편집합니다. message editing을 지원하지 않는 플랫폼(Signal, Email, Home Assistant)은 첫 시도에서 자동 감지되며, message가 쏟아지지 않도록 해당 session의 streaming이 비활성화됩니다.

progressive token editing 없이 자연스러운 중간 assistant update를 별도 message로 보내고 싶다면 interim_assistant_messages를 사용하세요.

Overflow 처리: streaming text가 platform message length limit을 초과하면(예: 약 4096자), 현재 message를 final 처리하고 새 message를 자동으로 시작합니다.

Fresh final(Telegram): Telegram의 editMessageText는 원래 message timestamp를 보존하므로, 긴 streaming response는 완료 후에도 첫 token의 timestamp를 유지합니다. fresh_final_after_seconds > 0(기본값 60)이면 완료된 답변을 새 message로 다시 보내고 stale preview는 best-effort로 삭제합니다. 이렇게 하면 Telegram에 표시되는 timestamp가 완료 시간을 반영합니다. 짧은 preview는 그대로 edit됩니다. 항상 edit하려면 0으로 설정하세요.

노트

스트리밍은 기본적으로 비활성화됩니다. ~/.hermes/config.yaml에서 스트리밍 UX를 시도할 수 있습니다.

그룹 채팅 세션 격리

공유 대화에서 방마다 하나의 대화를 유지할지, 참가자마다 별도 대화를 둘지 제어합니다.

group_sessions_per_user: true  # true = per-user isolation in groups/channels, false = one shared session per chat
  • true는 기본이며 권장 설정입니다. Discord 채널에서, Telegram 그룹, Slack 채널 및 유사한 공유 컨텍스트, 각 sender는 플랫폼이 사용자 ID를 제공할 때 자신의 세션을 가져옵니다.
  • false는 이전 shared-room 동작으로 되돌립니다. 채널 하나를 하나의 협업 대화로 취급하려는 경우에는 유용할 수 있지만, 사용자들이 context, token cost, interrupt state를 공유하게 됩니다.
  • 직접 메시지는 영향을 받지 않습니다. Hermes는 일반적으로 chat/DM ID를 DM session key로 사용합니다.
  • thread는 어느 설정에서도 parent channel과 분리됩니다. true이면 각 참가자는 thread 안에서도 자신의 session을 갖습니다.

행동 세부 사항 및 예의 경우 SessionsDiscord Guide를 참조하세요.

Unauthorized DM 동작

알 수 없는 사용자가 Hermes에 direct message를 보냈을 때의 동작을 제어합니다.

unauthorized_dm_behavior: pair

whatsapp:
unauthorized_dm_behavior: ignore
  • pair는 기본값입니다. Hermes는 access를 거부하지만, DM에 pairing code를 한 번 응답합니다.
  • ignore는 DM을 조용히 버립니다.
  • 플랫폼별 section은 global 기본값을 override하므로, 한 플랫폼은 조용히 무시하고 다른 플랫폼은 pairing을 허용할 수 있습니다.

빠른 명령

LLM을 호출하지 않고 shell command를 실행하는 custom command를 정의하거나, 하나의 slash command를 다른 command로 alias할 수 있습니다. exec quick command는 Telegram, Discord 같은 messaging platform에서 빠른 서버 점검이나 utility script를 실행할 때 유용합니다.

quick_commands:
status:
type: exec
command: systemctl status hermes-agent
disk:
type: exec
command: df -h /
update:
type: exec
command: cd ~/.hermes/hermes-agent && git pull && pip install -e.
gpu:
type: exec
command: nvidia-smi --query-gpu=name,utilization.gpu,memory.used,memory.total --format=csv,noheader
restart:
type: alias
target: /gateway restart

사용법: CLI 또는 messaging platform에서 /status, /disk, /update, /gpu, /restart를 입력합니다. exec command는 host에서 local로 실행되고 출력을 직접 반환합니다. LLM 호출이 없으므로 token을 사용하지 않습니다. alias command는 지정한 slash command target으로 다시 씁니다.

  • 30초 timeout - 오래 실행되는 command는 오류 메시지와 함께 중단됩니다.
  • Priority - quick command는 skill command보다 먼저 확인되므로 skill 이름을 가릴 수 있습니다.
  • Autocomplete - quick command는 dispatch 시점에 해석되며 built-in slash-command autocomplete table에는 표시되지 않습니다.
  • Type - 지원 type은 execalias입니다. 다른 type은 오류를 표시합니다.
  • 지원 범위 - CLI, Telegram, Discord, Slack, WhatsApp, Signal, Email, Home Assistant에서 동작합니다.

문자열만 있는 prompt shortcut은 quick command로 사용할 수 없습니다. 재사용 가능한 prompt workflow가 필요하다면 skill을 만들거나 기존 slash command에 대한 alias를 사용하세요.

Human Delay

messaging platform에서 사람이 답하는 것 같은 응답 pacing을 시뮬레이션합니다.

human_delay:
mode: "off" # off | natural | custom
min_ms: 800 # Minimum delay (custom mode)
max_ms: 2500 # Maximum delay (custom mode)

코드 실행

execute_code 도구 구성:

code_execution:
mode: project # project (default) | strict
timeout: 300 # Max execution time in seconds
max_tool_calls: 50 # Max tool calls within code execution

**mode**는 script의 작업 디렉터리와 Python interpreter를 제어합니다.

  • project(기본값) - script는 session 작업 디렉터리에서 active virtualenv/conda env의 Python으로 실행됩니다. project dependency(pandas, torch, project package)와 상대 경로(.env, ./data.csv)가 terminal()과 같은 방식으로 자연스럽게 해석됩니다.
  • strict - script는 임시 디렉터리에서 sys.executable(Hermes 자체 Python)로 실행됩니다. 재현성은 가장 높지만 project dependency와 상대 경로는 해석되지 않습니다.

환경 scrub(*_API_KEY, *_TOKEN, *_SECRET, *_PASSWORD, *_CREDENTIAL, *_PASSWD, *_AUTH 제거)과 tool whitelist는 두 mode에 동일하게 적용됩니다. mode를 바꿔도 보안 posture는 바뀌지 않습니다.

웹 검색 백엔드

web_search, web_extract, web_crawl tool은 5개 backend provider를 지원합니다. config.yaml 또는 hermes tools에서 backend를 구성하세요.

web:
backend: firecrawl # firecrawl | searxng | parallel | tavily | exa

# Or use per-capability keys to mix providers (e.g. free search + paid extract):
search_backend: "searxng"
extract_backend: "firecrawl"
BackendEnv VarSearchExtractCrawl
Firecrawl(기본값)FIRECRAWL_API_KEY지원지원지원
SearXNGSEARXNG_URL지원미지원미지원
ParallelPARALLEL_API_KEY지원지원미지원
TavilyTAVILY_API_KEY지원지원지원
ExaEXA_API_KEY지원지원미지원

백엔드 선택: web.backend가 설정되지 않으면 사용 가능한 API key를 기준으로 자동 감지합니다. SEARXNG_URL만 있으면 SearXNG, EXA_API_KEY만 있으면 Exa, TAVILY_API_KEY만 있으면 Tavily, PARALLEL_API_KEY만 있으면 Parallel을 사용합니다. 그 외에는 Firecrawl이 기본값입니다.

SearXNG는 70개 이상의 검색 엔진을 조회하는 무료 self-hosted privacy-respecting metasearch engine입니다. API key는 필요 없고 SEARXNG_URL을 자신의 instance로 설정하면 됩니다. 예: http://localhost:8080. SearXNG는 search-only입니다. web_extractweb_crawl에는 별도 extract provider가 필요합니다(web.extract_backend). Docker 설정은 Web Search setup guide를 참고하세요.

Self-hosted Firecrawl: FIRECRAWL_API_URL을 설정해 자신의 instance를 가리킬 수 있습니다. custom URL이 설정되면 API key는 선택 사항이 됩니다. server에서 USE_DB_AUTHENTICATION=***를 설정해 auth를 비활성화할 수 있습니다.

Parallel 검색 모드: PARALLEL_SEARCH_MODE를 사용하여 검색 행동을 제어합니다. fast, one-shot 또는 agentic (기본값: agentic).

Exa: EXA_API_KEY~/.hermes/.env로 설정하세요. category 필터링 (company, research paper, news, people, personal site, pdf) 및 도메인/날짜 필터를 지원합니다.

브라우저

브라우저 자동화 동작을 설정합니다.

browser:
inactivity_timeout: 120 # Seconds before auto-closing idle sessions
command_timeout: 30 # Timeout in seconds for browser commands (screenshot, navigate, etc.)
record_sessions: false # Auto-record browser sessions as WebM videos to ~/.hermes/browser_recordings/
# Optional CDP override — when set, Hermes attaches directly to your own
# Chrome (via /browser connect) rather than starting a headless browser.
cdp_url: ""
# Dialog supervisor — controls how native JS dialogs (alert / confirm / prompt)
# are handled when a CDP backend is attached (Browserbase, local Chrome via
# /browser connect). Ignored on Camofox and default local agent-browser mode.
dialog_policy: must_respond # must_respond | auto_dismiss | auto_accept
dialog_timeout_s: 300 # Safety auto-dismiss under must_respond (seconds)
camofox:
managed_persistence: false # When true, Camofox sessions persist cookies/logins across restarts
user_id: "" # Optional externally managed Camofox userId
session_key: "" # Optional session key sent when Hermes creates a tab
adopt_existing_tab: false # Reuse an existing tab for this identity before creating one

Dialog 정책:

  • must_respond(기본값) - dialog를 캡처해 browser_snapshot.pending_dialogs에 표시하고, 에이전트가 browser_dialog(action=...)를 호출할 때까지 기다립니다. dialog_timeout_s초 동안 응답이 없으면 page의 JS thread가 영원히 멈추지 않도록 dialog를 자동 dismiss합니다.
  • auto_dismiss - dialog를 캡처한 뒤 즉시 dismiss합니다. 에이전트는 나중에 browser_snapshot.recent_dialogs에서 closed_by="auto_policy"가 포함된 dialog 기록을 볼 수 있습니다.
  • auto_accept - dialog를 캡처한 뒤 즉시 accept합니다. 공격적인 beforeunload prompt가 있는 페이지에 유용합니다.

전체 dialog workflow는 browser feature page를 참고하세요.

브라우저 toolset은 여러 provider를 지원합니다. Browserbase, Browser Use, local Chrome CDP 설정은 Browser 기능 페이지를 참고하세요.

시간대

IANA timezone 문자열로 server-local timezone을 override합니다. 로그, cron scheduling, system prompt 시간 주입의 timestamp에 영향을 줍니다.

timezone: "America/New_York"   # IANA timezone (default: "" = server-local time)

지원 값은 모든 IANA timezone identifier입니다. 예: America/New_York, Europe/London, Asia/Kolkata, UTC. server-local time을 쓰려면 비워 두거나 생략하세요.

Discord

메시징 게이트웨이의 Discord-specific 동작을 설정합니다.

discord:
require_mention: true # Require @mention to respond in server channels
free_response_channels: "" # Comma-separated channel IDs where bot responds without @mention
auto_thread: true # Auto-create threads on @mention in channels
  • require_mention - true (기본값)일 때 봇은 @BotName로 언급될 때 서버 채널에서만 응답합니다. DM은 항상 언급하지 않고 작동합니다.
  • free_response_channels - 봇 mention 없이도 모든 메시지에 응답할 channel ID의 comma-separated 목록입니다.
  • auto_thread - true(기본값)이면 channel mention 시 대화용 thread를 자동 생성해 channel을 깔끔하게 유지합니다. Slack thread와 비슷합니다.

보안

실행 전 보안 검사와 secret redaction을 설정합니다.

security:
redact_secrets: false # Redact API key patterns in tool output and logs (off by default)
tirith_enabled: true # Enable Tirith security scanning for terminal commands
tirith_path: "tirith" # Path to tirith binary (default: "tirith" in $PATH)
tirith_timeout: 5 # Seconds to wait for tirith scan before timing out
tirith_fail_open: true # Allow command execution if tirith is unavailable
website_blocklist: # See Website Blocklist section below
enabled: false
domains: []
shared_files: []
  • redact_secrets - true이면 도구 출력이 대화 context와 로그에 들어가기 전에 API key, token, password처럼 보이는 pattern을 자동 감지해 마스킹합니다. 기본값은 off입니다. 실제 credential이 도구 출력에 자주 등장하고 safety net이 필요할 때 명시적으로 true를 설정하세요.
  • tirith_enabled - true이면 terminal command가 실행 전에 Tirith로 scan됩니다.
  • tirith_path - tirith binary 경로입니다. tirith가 표준 위치가 아닌 곳에 설치되어 있으면 설정하세요.
  • tirith_timeout - tirith scan을 기다릴 최대 초입니다. scan이 timeout되면 명령은 계속 진행합니다.
  • tirith_fail_open - true(기본값)이면 tirith를 사용할 수 없거나 scan이 실패해도 명령 실행을 허용합니다. false로 설정하면 tirith가 확인하지 못한 명령을 차단합니다.

Website Blocklist

에이전트의 web/browser 도구가 접근할 특정 domain을 차단합니다.

security:
website_blocklist:
enabled: false # Enable URL blocking (default: false)
domains: # List of blocked domain patterns
- "*.internal.company.com"
- "admin.example.com"
- "*.local"
shared_files: # Load additional rules from external files
- "/etc/hermes/blocked-sites.txt"

활성화하면 차단 domain pattern과 일치하는 URL은 web/browser 도구 실행 전에 거부됩니다. web_search, web_extract, browser_navigate 및 URL에 접근하는 모든 도구에 적용됩니다.

도메인 규칙 지원:

  • 정확한 domain: admin.example.com
  • wildcard subdomain: *.internal.company.com(모든 하위 domain 차단)
  • TLD wildcard: *.local

공유 파일에는 줄마다 domain rule 하나를 넣습니다. 빈 줄과 # comment는 무시됩니다. 파일이 없거나 읽을 수 없으면 warning을 기록하지만 다른 web 도구를 비활성화하지는 않습니다.

정책은 30초 동안 cache되므로, 재시작 없이도 설정 변경이 빠르게 반영됩니다.

Smart Approvals

Hermes가 잠재적으로 위험한 명령을 어떻게 처리할지 제어합니다.

approvals:
mode: manual # manual | smart | off
모드동작
manual(기본값)flagged command를 실행하기 전에 사용자에게 묻습니다. CLI에서는 interactive approval dialog를 표시하고, 메시징에서는 pending approval request를 queue에 넣습니다.
smartauxiliary LLM으로 flagged command가 실제로 위험한지 평가합니다. low-risk 명령은 session-level persistence로 자동 승인하고, 정말 위험한 명령은 사용자에게 escalate합니다.
off모든 approval check를 건너뜁니다. HERMES_YOLO_MODE=true와 동일합니다. 주의해서 사용하세요.

smart mode는 approval fatigue를 줄이는 데 특히 유용합니다. 에이전트가 안전한 작업은 더 자율적으로 수행하면서, 실제로 파괴적인 명령은 계속 잡아낼 수 있습니다.

경고

approvals.mode: off 설정은 terminal command의 모든 안전 검사를 비활성화합니다. 신뢰할 수 있는 sandboxed 환경에서만 사용하세요.

Checkpoints

파괴적 파일 작업 전에 자동 파일 시스템 snapshot을 만듭니다. 자세한 내용은 Checkpoints & Rollback을 참고하세요.

checkpoints:
enabled: false # Enable automatic checkpoints (also: hermes chat --checkpoints). Default: false (opt-in).
max_snapshots: 20 # Max checkpoints to keep per directory (default: 20)

위임

delegate 도구의 subagent 동작을 설정합니다.

delegation:
# model: "google/gemini-3-flash-preview" # Override model (empty = inherit parent)
# provider: "openrouter" # Override provider (empty = inherit parent)
# base_url: "http://localhost:1234/v1" # Direct OpenAI-compatible endpoint (takes precedence over provider)
# api_key: "local-key" # API key for base_url (falls back to OPENAI_API_KEY)
max_concurrent_children: 3 # Parallel children per batch (floor 1, no ceiling). Also via DELEGATION_MAX_CONCURRENT_CHILDREN env var.
max_spawn_depth: 1 # Delegation tree depth cap (1-3, clamped). 1 = flat (default): parent spawns leaves that cannot delegate. 2 = orchestrator children can spawn leaf grandchildren. 3 = three levels.
orchestrator_enabled: true # Global kill switch. When false, role="orchestrator" is ignored and every child is forced to leaf regardless of max_spawn_depth.

Subagent provider:model override: 기본적으로 subagent는 부모 에이전트의 provider와 model을 상속합니다. delegation.providerdelegation.model을 설정하면 subagent를 다른 provider:model 쌍으로 route할 수 있습니다. 예를 들어 primary agent는 비싼 reasoning model을 쓰고, 좁은 subtask는 저렴하고 빠른 모델에 맡길 수 있습니다.

Direct endpoint override: 명시적인 custom endpoint 경로를 원하면 delegation.base_url, delegation.api_key, delegation.model을 설정하세요. 그러면 subagent가 해당 OpenAI 호환 endpoint로 직접 전송되며 delegation.provider보다 우선합니다. delegation.api_key를 생략하면 Hermes는 OPENAI_API_KEY로 fallback합니다.

delegation provider는 CLI/gateway startup과 같은 credential resolution을 사용합니다. 설정된 provider는 모두 지원됩니다. 예: openrouter, nous, copilot, zai, kimi-coding, minimax, minimax-cn. provider를 설정하면 시스템이 올바른 base URL, API key, API mode를 자동으로 해석하므로 수동 credential wiring이 필요하지 않습니다.

우선순위: delegation.base_url 설정 -> delegation.provider 설정 -> 부모 provider 상속 순입니다. delegation.model 설정은 부모 model 상속보다 우선합니다. provider 없이 model만 설정하면 부모 credential은 유지하고 model name만 바꿉니다. OpenRouter처럼 같은 provider 안에서 모델만 바꿀 때 유용합니다.

너비와 깊이: max_concurrent_children은 batch당 병렬 실행 subagent 수를 제한합니다. 기본값은 3이고 최솟값은 1이며 hard ceiling은 없습니다. DELEGATION_MAX_CONCURRENT_CHILDREN 환경 변수로도 설정할 수 있습니다. 모델이 한도보다 긴 tasks 배열을 제출하면 delegate_task는 조용히 잘라내지 않고 제한을 설명하는 tool error를 반환합니다. max_spawn_depth는 delegation tree depth를 제어합니다(1-3으로 clamp). 기본값 1에서는 delegation이 flat합니다. child는 grandchild를 만들 수 없고 role="orchestrator"leaf로 degrade됩니다. 2로 올리면 orchestrator child가 leaf grandchild를 만들 수 있고, 3은 3단계 tree입니다. agent는 호출마다 role="orchestrator"로 orchestration에 opt in합니다. orchestrator_enabled: false는 depth와 관계없이 모든 child를 leaf로 강제합니다. 비용은 곱으로 늘어납니다. max_spawn_depth: 3, max_concurrent_children: 3이면 tree는 3 x 3 x 3 = 27개의 동시 leaf agent까지 커질 수 있습니다. 사용 패턴은 Subagent Delegation - Depth Limit and Nested Orchestration을 참고하세요.

Clarify

clarification prompt 동작을 설정합니다.

clarify:
timeout: 120 # Seconds to wait for user clarification response

컨텍스트 파일(SOUL.md, AGENTS.md)

Hermes는 두 가지 context scope를 사용합니다.

파일 형식설명위치
SOUL.md개인 agent 정체성 - agent가 누구인지 정의합니다(system prompt의 #1 slot)~/.hermes/SOUL.md 또는 $HERMES_HOME/SOUL.md
.hermes.md / HERMES.md프로젝트별 지침(가장 높은 우선순위)git root까지 검색
AGENTS.md프로젝트별 지침, coding conventiondirectory를 재귀적으로 검색
CLAUDE.mdClaude Code context file(감지 대상)작업 디렉터리만
.cursorrulesCursor IDE rule(감지 대상)작업 디렉터리만
.cursor/rules/*.mdcCursor rule file(감지 대상)작업 디렉터리만
  • SOUL.md는 agent의 기본 정체성입니다. system prompt의 #1 slot을 차지하며 내장 기본 정체성을 완전히 대체합니다. agent를 완전히 custom하려면 이 파일을 편집하세요.
  • SOUL.md가 없거나, 비어 있거나, 로드할 수 없으면 Hermes는 내장 기본 정체성으로 fallback합니다.
  • Project context file 우선순위 - 한 종류만 로드됩니다(처음 일치한 항목 승리): .hermes.mdAGENTS.mdCLAUDE.md.cursorrules. SOUL.md는 항상 별도로 로드됩니다.
  • AGENTS.md는 계층적입니다. 하위 directory에도 AGENTS.md가 있으면 모두 결합됩니다.
  • Hermes는 기본적으로 SOUL.md를 자동 생성합니다.
  • 로드된 모든 context file은 smart truncation을 거쳐 20,000자로 제한됩니다.

참조:

작업 디렉터리

설정기본값
CLI (hermes)command를 실행한 현재 directory
Messaging Gatewayhome directory ~(MESSAGING_CWD로 override 가능)
Docker / Singularity / Modal / SSH컨테이너 또는 원격 machine 내부의 user home directory

작업 디렉터리를 override하려면:

# In ~/.hermes/.env or ~/.hermes/config.yaml:
MESSAGING_CWD=/home/myuser/projects # Gateway sessions
TERMINAL_CWD=/workspace # All terminal sessions