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

282 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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`:
```bash
# Добавление ключа
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 паттерн
```yaml
# ~/.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
```yaml
# config.yaml
model:
provider: opencode-go
base_url: "https://9router.example.com/v1/opencode-go" # Проксируется через 9Router
api_key: "${NINEROUTER_API_KEY}"
```
```bash
# .env
NINEROUTER_API_KEY=nr-...
```
### 4.3 Паттерны использования
#### Round-robin через 9Router
```yaml
# 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 Добавление нового ключа
```bash
# 1. Добавить ключ в пул
hermes auth add opencode-go
# 2. Проверить статус
hermes auth list opencode-go
# 3. Проверить health с новым ключом
hermes --profile worker-code doctor
# 4. При необходимости настроить 9Router
# Обновить конфигурацию 9Router с новым ключом
```
### 7.2 Замена скомпрометированного ключа
```bash
# 1. Немедленно отозвать ключ на стороне провайдера
# 2. Пометить ключ как error в Hermes
hermes auth remove opencode-go 1 # индекс скомпрометированного ключа
# 3. Добавить новый ключ
hermes auth add opencode-go
# 4. Проверить, что старый ключ не используется
# Проверить логи аудита
```
### 7.3 Сброс exhausted-статуса
```bash
# После сброса квоты (начало нового billing period)
hermes auth reset opencode-go 0
hermes auth reset opencode-go 1
```
## 8. Ссылки
- [HERMES.md](../adapters/HERMES.md) — спецификация Hermes-адаптера
- [WORKER_ORCHESTRATION.md](WORKER_ORCHESTRATION.md) — оркестрация worker-профилей
- [MONITORING.md](../operations/MONITORING.md) — мониторинг квот и алерты
- [BACKUP.md](../operations/BACKUP.md) — бэкап конфигурации credential pools
- [SPECIFICATION.md](../SPECIFICATION.md) §6.8 — Usage, notifications и audit