agent-control-center/docs/patterns/CREDENTIAL_POOLS.md

12 KiB
Raw Blame History

Credential Pools & Multi-Account Management

Версия: 0.1.0-draft Дата: 2026-07-20 Статус: Draft Зависит от: SPECIFICATION.md, ARCHITECTURE.md, docs/adapters/HERMES.md

Этот документ описывает паттерны управления пулами API-ключей для провайдеров ИИ-моделей. Реализация запрещена до G0/G1 и утверждения оператором.

1. Обзор

Credential Pool — механизм ротации нескольких API-ключей в рамках одного провайдера, обеспечивающий:

  • Автоматический обход исчерпанных квот
  • Round-robin распределение нагрузки
  • Приоритетное использование ключей
  • Прозрачный failover без ручного вмешательства

2. Архитектура credential pool

┌─────────────────────────────────────────────┐
│               Hermes Agent                   │
│  ┌───────────────────────────────────────┐  │
│  │         Credential Pool Manager       │  │
│  │  ┌─────────┐  ┌─────────┐  ┌───────┐ │  │
│  │  │ Key #1  │  │ Key #2  │  │ Key N │ │  │
│  │  │ (active)│  │ (active)│  │(spare)│ │  │
│  │  └────┬────┘  └────┬────┘  └───┬───┘ │  │
│  │       │            │           │     │  │
│  │       ▼            ▼           ▼     │  │
│  │   ┌──────────────────────────────┐   │  │
│  │   │      Provider API Backend    │   │  │
│  │   └──────────────────────────────┘   │  │
│  └───────────────────────────────────────┘  │
│                                               │
│  ┌───────────────────────────────────────┐   │
│  │       9Router (опционально)           │   │
│  │  • Round-robin распределение          │   │
│  │  • Quota tracking                     │   │
│  │  • OpenAI-формат трансляции           │   │
│  └───────────────────────────────────────┘   │
└─────────────────────────────────────────────┘

3. Hermes Auth Pools

3.1 Конфигурация

Hermes поддерживает несколько ключей на одного провайдера через hermes auth:

# Добавление ключа
hermes auth add opencode-go
hermes auth add fireworks
hermes auth add gemini
hermes auth add nvidia

# Просмотр пула
hermes auth list opencode-go
# Вывод:
# [0] sk-abc...xyz  active   quota: 85%
# [1] sk-def...uvw  active   quota: 42%
# [2] sk-ghi...rst  active   quota: 12%

# Ручной сброс exhausted-статуса
hermes auth reset opencode-go 2

3.2 Стратегии выбора ключа

Стратегия Алгоритм Применение
Round-robin Последовательный перебор активных ключей Равномерное распределение нагрузки
Priority-based Ключи с более высоким приоритетом используются первыми primary/fallback сценарий
Least-loaded Ключ с наименьшим процентом использованной квоты Оптимизация использования квот
Failover-only Второй ключ активируется только при отказе первого Минимизация случайного использования дорогих ключей

3.3 Primary/Fallback паттерн

# ~/.hermes/auth.json (концептуально)
{
  "pools": {
    "opencode-go": {
      "keys": [
        {
          "id": "primary",
          "key": "sk-primary-...",
          "priority": 1,
          "quota_limit": 1000000,
          "status": "active"
        },
        {
          "id": "fallback",
          "key": "sk-fallback-...",
          "priority": 2,
          "quota_limit": 500000,
          "status": "active"
        }
      ],
      "strategy": "priority"
    }
  }
}

3.4 Статусы ключей

Статус Описание Поведение
active Ключ работает Используется согласно стратегии
exhausted Ключ исчерпал квоту Автоматически исключается из ротации
rate_limited Временный rate limit Исключается на cooldown-период (60s)
error Ошибка аутентификации Исключается до ручного сброса
disabled Ручное отключение Никогда не используется

3.5 Обработка ошибок

HTTP-код Интерпретация Действие
401 Неверный ключ status=error; alert
403 Доступ запрещён status=error; alert
429 Rate limit status=rate_limited; retry через cooldown
429 + x-ratelimit-remaining: 0 Квота исчерпана status=exhausted; переключение на следующий ключ
500/502/503 Серверная ошибка Retry до 3 раз; затем fallback ключ
Timeout Сетевой сбой Retry 1 раз; затем fallback ключ

4. Интеграция с 9Router

4.1 Назначение

9Router — внешний агрегатор API-ключей, обеспечивающий:

  • Централизованное управление пулом ключей от разных аккаунтов
  • Round-robin / weighted распределение запросов
  • Отслеживание квот в реальном времени
  • Трансляцию форматов запросов (не-OpenAI → OpenAI-совместимый)
  • Единый endpoint для всех моделей

4.2 Конфигурация Hermes → 9Router

# config.yaml
model:
  provider: opencode-go
  base_url: "https://9router.example.com/v1/opencode-go"  # Проксируется через 9Router
  api_key: "${NINEROUTER_API_KEY}"
# .env
NINEROUTER_API_KEY=nr-...

4.3 Паттерны использования

Round-robin через 9Router

# 9Router конфигурация (на стороне 9Router)
pools:
  opencode-go:
    strategy: round-robin
    keys:
      - account: personal
        key: sk-personal-...
        weight: 1
      - account: team
        key: sk-team-...
        weight: 2
      - account: backup
        key: sk-backup-...
        weight: 1

Quota tracking

9Router отслеживает использование через:

  • Response headers (x-ratelimit-remaining, x-ratelimit-reset)
  • Собственный счётчик токенов из тела ответа
  • Периодический опрос /v1/usage (если доступен)

При достижении 95% квоты ключ помечается low; при 100% — exhausted и исключается из ротации.

4.4 Отказоустойчивость

Если 9Router недоступен, Hermes MUST fallback на прямое подключение к провайдеру с локальным credential pool:

Hermes → [попытка] 9Router → [отказ]
       → [fallback] прямой endpoint провайдера + локальный пул ключей

5. Мониторинг квот

5.1 Метрики

Метрика Источник Обновление
tokens_used Response body usage.total_tokens Каждый запрос
tokens_remaining Response header x-ratelimit-remaining или локальный счётчик Каждый запрос
quota_percent tokens_used / quota_limit * 100 Каждый запрос
request_count Локальный счётчик Каждый запрос
error_count HTTP status != 200 Каждый запрос
latency_p95 Локальный замер Скользящее окно 5 мин

5.2 Пороги и алерты

Порог Условие Действие
WARNING quota_percent > 80% Уведомление оператору
CRITICAL quota_percent > 95% Автоматический failover на следующий ключ + алерт
EXHAUSTED quota_percent >= 100% Исключение ключа из ротации + инцидент
ERROR_BURST > 5 ошибок за 1 мин Отключение ключа на 5 мин + алерт

5.3 Автоматический failover

1. Текущий ключ получает 429 с x-ratelimit-remaining: 0
2. Pool Manager помечает ключ exhausted
3. Выбирается следующий ключ согласно стратегии
4. Запрос повторяется с новым ключом
5. Если все ключи exhausted → возврат ошибки оператору
6. Exhausted-ключи сбрасываются при наступлении reset time

6. Безопасность

Требование Реализация
Ключи NEVER в логах Secret redaction (security.redact_secrets) включён по умолчанию
Ключи NEVER в коде Хранятся только в .env или auth.json
Ключи NEVER в Git .gitignore исключает .env, auth.json
Ротация без простоя Добавление нового ключа в пул + сброс старого после grace period
Аудит использования Все операции с ключами логируются через audit tool

7. Процедуры

7.1 Добавление нового ключа

# 1. Добавить ключ в пул
hermes auth add opencode-go

# 2. Проверить статус
hermes auth list opencode-go

# 3. Проверить health с новым ключом
hermes --profile worker-code doctor

# 4. При необходимости настроить 9Router
# Обновить конфигурацию 9Router с новым ключом

7.2 Замена скомпрометированного ключа

# 1. Немедленно отозвать ключ на стороне провайдера
# 2. Пометить ключ как error в Hermes
hermes auth remove opencode-go 1  # индекс скомпрометированного ключа

# 3. Добавить новый ключ
hermes auth add opencode-go

# 4. Проверить, что старый ключ не используется
# Проверить логи аудита

7.3 Сброс exhausted-статуса

# После сброса квоты (начало нового billing period)
hermes auth reset opencode-go 0
hermes auth reset opencode-go 1

8. Ссылки