제공자 런타임 해석
Hermes에는 다음 경로에서 함께 사용하는 제공자 런타임 해석기가 있습니다.
- CLI
- 게이트웨이
- 크론 작업
- ACP
- 보조 모델 호출
핵심 구현:
hermes_cli/runtime_provider.py— 자격 증명 해석,_resolve_custom_runtime()hermes_cli/auth.py— 제공자 레지스트리,resolve_provider()hermes_cli/model_switch.py— 공유/model스위치 파이프라인(CLI + 게이트웨이)agent/auxiliary_client.py— 보조 모델 라우팅providers/— ABC + 레지스트리 진입점(ProviderProfile,register_provider,get_provider_profile,list_providers)plugins/model-providers/<name>/—api_mode,base_url,env_vars,fallback_models를 선언하고 첫 번째 액세스 시 레지스트리에 등록하는 제공자별 플러그인(번들)입니다.$HERMES_HOME/plugins/model-providers/<name>/의 사용자 플러그인은 같은 이름의 번들 플러그인을 재정의합니다.
providers/의 get_provider_profile()은 지정된 제공자 ID에 대해 ProviderProfile을 반환합니다. runtime_provider.py는 해석 시점에 이를 호출하여 해당 데이터를 여러 파일에 복제할 필요 없이 정식 base_url, env_vars 우선순위 목록, api_mode, fallback_models를 가져옵니다. plugins/model-providers/<your-provider>/(또는 $HERMES_HOME/plugins/model-providers/<your-provider>/) 아래에 register_provider()를 호출하는 새 플러그인을 추가하면 runtime_provider.py가 이를 선택합니다. 해석기 자체에 분기를 추가할 필요는 없습니다.
새로운 최상위 추론 제공자를 추가하려면 이 페이지와 함께 제공자 추가 및 모델 제공자 플러그인 가이드를 읽어보세요.
해석 우선순위
큰 틀에서 제공자 해석은 다음 값을 사용합니다.
- 명시적 CLI/런타임 요청
config.yaml모델/제공자 구성- 환경 변수
- 제공자별 기본값 또는 자동 해결
Hermes는 저장된 모델/제공자 선택을 일반 실행의 단일 기준으로 취급하기 때문에 이 순서가 중요합니다. 이렇게 하면 오래된 셸 export가 사용자가 hermes model에서 마지막으로 선택한 엔드포인트를 자동으로 재정의하는 일을 막을 수 있습니다.
제공자
현재 제공자 제품군에는 다음이 포함됩니다. 전체 번들 세트는 plugins/model-providers/를 참고하세요.
- AI Gateway(Vercel)
- OpenRouter
- Nous Portal
- OpenAI Codex
- Copilot / Copilot ACP
- Anthropic(네이티브)
- Google/Gemini(
gemini,google-gemini-cli) - Alibaba / DashScope (
alibaba,alibaba-coding-plan) - DeepSeek
- Z.AI
- Kimi/Moonshot(
kimi-coding,kimi-coding-cn) - MiniMax(
minimax,minimax-cn,minimax-oauth) - Kilo Code
- Hugging Face
- OpenCode Zen / OpenCode Go
- AWS Bedrock
- Azure Foundry
- NVIDIA NIM
- xAI(Grok)
- Arcee
- GMI Cloud
- StepFun
- Qwen OAuth
- Xiaomi
- Ollama Cloud
- LM Studio
- Tencent TokenHub
- 사용자 정의(
provider: custom) — 모든 OpenAI 호환 엔드포인트를 위한 최상위 제공자 - 이름이 있는 사용자 정의 제공자(
config.yaml의custom_providers목록)
런타임 해석 결과
런타임 해석기는 다음 데이터를 반환합니다.
providerapi_modebase_urlapi_keysource- 만료/갱신 정보와 같은 제공자별 메타데이터
이것이 중요한 이유
이 해석기는 Hermes가 다음 사이에 인증/런타임 로직을 공유할 수 있는 주된 이유입니다.
hermes chat- 게이트웨이 메시지 처리
- 새로운 세션에서 실행되는 크론 작업
- ACP 편집 세션
- 보조 모델 작업
AI Gateway
~/.hermes/.env에 AI_GATEWAY_API_KEY를 설정하고 --provider ai-gateway로 실행합니다. Hermes는 게이트웨이의 /models 엔드포인트에서 사용 가능한 모델을 가져와 도구 사용 지원 여부를 기준으로 언어 모델을 필터링합니다.
OpenRouter, AI Gateway 및 사용자 정의 OpenAI 호환 기본 URL
Hermes에는 여러 제공자 키(예: OPENROUTER_API_KEY, AI_GATEWAY_API_KEY, OPENAI_API_KEY)가 있는 경우 잘못된 API 키가 사용자 정의 엔드포인트에 유출되는 것을 방지하는 로직이 포함되어 있습니다.
각 제공자의 API 키는 자체 기본 URL로 범위가 지정됩니다.
OPENROUTER_API_KEY는openrouter.ai엔드포인트로만 전송됩니다.AI_GATEWAY_API_KEY는ai-gateway.vercel.sh엔드포인트로만 전송됩니다.OPENAI_API_KEY는 사용자 정의 엔드포인트 및 대체 수단으로 사용됩니다.
Hermes는 또한 다음을 구별합니다.
- 사용자가 선택한 실제 사용자 정의 엔드포인트
- 사용자 정의 엔드포인트가 구성되지 않은 경우 사용되는 OpenRouter 대체 경로
이러한 구별은 다음과 같은 경우에 특히 중요합니다.
- 로컬 모델 서버
- 비OpenRouter/비AI Gateway OpenAI 호환 API
- 설정을 다시 실행하지 않고 제공자 전환
OPENAI_BASE_URL을 현재 셸에서 export하지 않은 경우에도 계속 작동해야 하는 저장된 사용자 정의 엔드포인트 구성
네이티브 Anthropic 경로
Anthropic은 더 이상 "OpenRouter를 통한" 것이 아닙니다.
제공자 해석이 anthropic을 선택하면 Hermes는 다음을 사용합니다.
api_mode = anthropic_messages- 네이티브 Anthropic 메시지 API
- 번역용
agent/anthropic_adapter.py
네이티브 Anthropic 자격 증명 해석은 이제 환경 변수 토큰보다 갱신 가능한 Claude Code 자격 증명을 우선합니다. 실제로 이는 다음을 의미합니다.
- Claude Code 자격 증명 파일에 새로 고칠 수 있는 인증이 포함된 경우 기본 소스로 처리됩니다.
- 수동
ANTHROPIC_TOKEN/CLAUDE_CODE_OAUTH_TOKEN값은 여전히 명시적 재정의로 작동합니다. - Hermes는 네이티브 메시지 API 호출 전에 Anthropic 자격 증명을 사전 확인합니다.
- Hermes는 페일오버 경로로 Anthropic 클라이언트를 재구축한 후에도 401에서 한 번 재시도합니다.
OpenAI Codex 경로
Codex는 별도의 Responses API 경로를 사용합니다.
api_mode = codex_responses- 전용 자격 증명 해석 및 인증 저장소 지원
보조 모델 라우팅
다음과 같은 보조 작업:
- 비전
- 웹 추출 요약
- 컨텍스트 압축 요약
- 세션 검색 요약
- 스킬 허브 운영
- MCP 도우미 작업
- 메모리 플러시
기본 대화 모델 대신 자체 제공자/모델 라우팅을 사용할 수 있습니다.
보조 작업이 제공자 main으로 구성되면 Hermes는 일반 채팅과 동일한 공유 런타임 경로를 통해 이를 해결합니다. 실제로 이는 다음을 의미합니다.
- 환경 변수 기반 사용자 정의 엔드포인트는 여전히 작동합니다.
hermes model/config.yaml을 통해 저장된 사용자 정의 엔드포인트도 작동합니다.- 보조 라우팅은 실제 저장된 사용자 정의 엔드포인트와 OpenRouter 페일오버 경로의 차이를 구분할 수 있습니다.
페일오버 모델
Hermes는 기본 모델에 오류가 발생할 때 순서대로 시도되는 (provider, model) 항목 목록인 구성된 대체 제공자 체인을 지원합니다. 레거시 단일 쌍 fallback_model 사전은 여전히 하위 호환용으로 허용됩니다(첫 번째 쓰기 시 마이그레이션됨).
내부적으로 작동하는 방식
-
저장:
AIAgent.__init__은fallback_model사전을 저장하고_fallback_activated = False를 설정합니다. -
트리거 지점:
_try_activate_fallback()은run_agent.py에 있는 기본 재시도 루프의 세 위치에서 호출됩니다.- 유효하지 않은 API 응답에 대한 최대 재시도 후(선택 항목 없음, 콘텐츠 누락)
- 재시도할 수 없는 클라이언트 오류(HTTP 401, 403, 404)
- 일시적인 오류에 대한 최대 재시도 후(HTTP 429, 500, 502, 503)
-
활성화 흐름(
_try_activate_fallback):- 이미 활성화되었거나 구성되지 않은 경우 즉시
False를 반환합니다. auxiliary_client.py에서resolve_provider_client()를 호출하여 적절한 인증을 사용한 새 클라이언트를 구축합니다.api_mode를 결정합니다: OpenAI Codex는codex_responses, Anthropic은anthropic_messages, 그 밖의 경우는chat_completions- 내부 스왑:
self.model,self.provider,self.base_url,self.api_mode,self.client,self._client_kwargs - Anthropic 페일오버의 경우: OpenAI 호환 클라이언트 대신 네이티브 Anthropic 클라이언트를 구축합니다.
- 프롬프트 캐싱을 재평가합니다(OpenRouter의 Claude 모델에 대해 활성화됨)
_fallback_activated = True를 설정해 다시 실행되지 않도록 합니다.- 재시도 횟수를 0으로 재설정하고 루프를 계속합니다.
- 이미 활성화되었거나 구성되지 않은 경우 즉시
-
구성 흐름:
- CLI:
cli.py는CLI_CONFIG["fallback_model"]을 읽고 →AIAgent(fallback_model=...)로 전달합니다. - 게이트웨이:
gateway/run.py._load_fallback_model()은config.yaml을 읽고 →AIAgent로 전달합니다. - 검증:
provider및model키는 모두 비어 있지 않아야 합니다. 그렇지 않으면 페일오버가 비활성화됩니다.
- CLI:
페일오버를 지원하지 않는 것
- 서브에이전트 위임(
tools/delegate_tool.py): 서브에이전트는 상위 제공자를 상속하지만 페일오버 구성은 상속하지 않습니다. - 보조 작업: 자체 독립 제공자 자동 감지 체인을 사용합니다(위의 보조 모델 라우팅 참조).
크론 작업은 페일오버를 지원합니다. run_job()은 config.yaml에서 fallback_providers(또는 레거시 fallback_model)를 읽고 게이트웨이와 같은 AIAgent(fallback_model=...)에 전달합니다. 이는 _load_fallback_model() 패턴과 일치합니다. Cron 내부를 참고하세요.
테스트 범위
지원되는 모든 제공자, 턴 단위 의미 체계, 엣지 케이스를 포괄하는 테스트는 tests/test_fallback_model.py를 참고하세요.