Настроить token economics для агентов
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить token economics для агентов
1. Цель задачи
Разработать и внедрить систему контроля затрат токенов для AI-агентов, работающих в production-среде. Решение должно включать выделение бюджета на каждого агента, динамические лимиты на вызовы и аудит расходов для предотвращения неконтролируемого роста затрат (runaway costs). Ключевой результат Работающая инфраструктура, которая автоматически ограничивает потребление токенов агентом в пределах заданного бюджета и предоставляет прозрачную отчётность по всем расходам.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| Два-три AI-агента (или их симуляция) | Самостоятельная реализация на Python с вызовами LLM (OpenAI, Anthropic, локальная модель) |
| API-ключи к LLM-провайдеру | OpenAI / Anthropic / локальный эндпоинт (vLLM, Ollama) |
| Тестовые сценарии использования агентов | Набор промптов, имитирующих реальные диалоги (минимум 10 различных вызовов) |
| Хранилище для логов (ClickHouse / SQLite / Prometheus) | Локальная установка или облачный сервис (ClickHouse Cloud, Grafana Cloud) |
| Система мониторинга (опционально) | Grafana + Prometheus (можно развернуть через Docker Compose) |
Если нет реального инструмента — симулируем:
- Создать трёх агентов с разными задачами:
support_agent— отвечает на вопросы пользователей (средняя длина ответа ~200 токенов)analytics_agent— генерирует SQL-запросы и объяснения (средняя длина ~500 токенов)creative_agent— пишет тексты (средняя длина ~1000 токенов)
- Написать простой скрипт, который будет циклически вызывать агентов в случайном порядке, имитируя нагрузку.
- Использовать SQLite как simplestore для логов и бюджета (схема:
agent_id, timestamp, model, prompt_tokens, completion_tokens, cost, action). - Если нет Prometheus/Grafana — выводить метрики в консоль и сохранять CSV-файл для последующего анализа в Jupyter.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Агенты | Python, langchain / openai / anthropic | Реализация логики агентов и вызовов LLM |
| Счётчик токенов | tiktoken (OpenAI), anthropic[tokenizer] | Подсчёт токенов до и после вызова |
| Бюджетирование и лимиты | Python + Redis / SQLite | Хранение и проверка лимитов, сброс по времени |
| Логирование | SQLite / ClickHouse | Фиксация каждого вызова с метаданными |
| Мониторинг (базовый) | Python logging + Prometheus (client) + Grafana | Сбор метрик (total tokens, cost per agent, limit hits) |
| Аудит | SQL-запросы, Pandas / Jupyter | Анализ затрат, выявление аномалий, отчёт |
| CI/развёртывание | Docker Compose (опционально) | Быстрое развертывание стека (Prometheus + Grafana + SQLite) |
4. Этапы выполнения
Этап 1: Проектирование модели бюджета (30 минут)
Действия
-
Определить единицы бюджета
- Дневной лимит токенов на агента (например,
support_agent: 100000 tkn/day) - Месячный лимит расходов в $ (например,
$5/месна агента) - Дополнительно: лимит на один вызов (max_prompt + max_completion)
- Дневной лимит токенов на агента (например,
-
Спроектировать структуру данных для хранения бюджета:
{ "agent_id": "support_agent", "daily_token_limit": 100000, "monthly_cost_limit": 5.00, "current_day_tokens": 0, "current_month_cost": 0.0, "reset_day_at": "00:00 UTC", "reset_month_at": "first day of month", "overage_policy": "BLOCK" } -
Решить, как сбрасывать счётчики:
- Дневной сброс — по UTC-полуночи (можно хранить последний день сброса и сбрасывать при первом запросе нового дня)
- Месячный — по первому числу месяца
-
Определить пороги оповещения
- 80% от лимита — WARNING (логирование + алерт)
- 100% — BLOCK (лимит исчерпан, агент не отвечает)
Ожидаемый результат этапа Документ с описанием модели бюджета (Markdown) и JSON-схема конфигурации.
Этап 2: Реализация счётчика и хранилища (1 час)
Действия
-
Написать модуль
token_counter.py- Функция
count_tokens(text, model="gpt-4o")— используетtiktokenдля OpenAI,anthropic.get_tokenizer()для Claude. - Функция
estimate_cost(prompt_tokens, completion_tokens, model)— по ценам из документации провайдера.
- Функция
-
Создать хранилище с SQLite
- Таблица
usage_log:CREATE TABLE usage_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, agent_id TEXT NOT NULL, request_id TEXT UNIQUE, model TEXT, prompt_tokens INTEGER, completion_tokens INTEGER, total_tokens INTEGER, cost REAL, timestamp TEXT DEFAULT (datetime('now')), status TEXT -- 'success', 'blocked', 'warning' ); - Таблица
budget_config:CREATE TABLE budget_config ( agent_id TEXT PRIMARY KEY, daily_token_limit INTEGER, monthly_cost_limit REAL, policy TEXT DEFAULT 'BLOCK', updated_at TEXT ); - Таблица
budget_state:CREATE TABLE budget_state ( agent_id TEXT PRIMARY KEY, current_day_tokens INTEGER DEFAULT 0, current_month_cost REAL DEFAULT 0.0, last_reset_day TEXT, last_reset_month TEXT );
- Таблица
-
Написать функции для атомарного обновления состояния бюджета:
check_and_deduct(agent_id, prompt_tokens, completion_tokens)— проверяет лимиты, если можно — вычитает и записывает лог, иначе возвращает ошибку.- Использовать SQLite транзакции с
BEGIN IMMEDIATEдля избежания гонок.
Ожидаемый результат этапа Модуль budget_controller.py с функциями check_and_deduct, reset_budgets, log_usage, и get_budget_status.
Этап 3: Интеграция с агентами (1 час)
Действия
-
Обернуть вызов LLM в декоратор/функцию-посредник
def with_budget(agent_id: str, model: str): def decorator(func): def wrapper(*args, **kwargs): # 1. Измерить prompt_tokens (через tiktoken) prompt_text = ... # получить из args/kwargs prompt_tokens = count_tokens(prompt_text, model) # 2. Проверить бюджет budget_ok = pre_check(agent_id, prompt_tokens) if not budget_ok: log_block(agent_id, prompt_tokens) raise BudgetExceededError("Daily/monthly limit reached") # 3. Вызвать LLM result = func(*args, **kwargs) # 4. Измерить completion_tokens completion_text = result["choices"][0]["message"]["content"] completion_tokens = count_tokens(completion_text, model) # 5. Списать и залогировать check_and_deduct(agent_id, prompt_tokens, completion_tokens, model) return result return wrapper return decorator -
Создать трёх агентов с разными бюджетами:
support_agent— daily 50k tkn, monthly $2analytics_agent— daily 100k tkn, monthly $5creative_agent— daily 200k tkn, monthly $10- Все с политикой
BLOCK(блокировать при превышении).
-
Написать тестовый скрипт, имитирующий нагрузку:
- Цикл из 50 итераций, на каждой случайный выбор агента и случайный запрос (несколько шаблонов).
- После каждых 10 итераций вызывать
print_status(agent_id)для вывода остатков бюджета.
Ожидаемый результат этапа Работающие агенты, которые при исчерпании бюджета возвращают ошибку и не тратят токены.
Этап 4: Мониторинг и алертинг (30 минут)
Действия
-
Настроить Prometheus-метрики (если есть Prometheus):
from prometheus_client import Counter, Gauge, Histogram, generate_latest tokens_total = Counter('llm_tokens_total', 'Total tokens consumed', ['agent', 'model']) cost_total = Counter('llm_cost_total', 'Total cost in USD', ['agent']) budget_remaining = Gauge('llm_budget_remaining_tokens', 'Remaining daily tokens', ['agent']) blocked_requests = Counter('llm_blocked_requests_total', 'Blocked requests due to budget', ['agent']) -
Или, для упрощения, логировать алерты в файл:
budget_warning.log— запись при превышении 80% лимитаbudget_blocked.log— запись при блокировке
-
Создать простой дашборд (если Grafana):
-
Добавить алерт при блокировке
Ожидаемый результат этапа Скрипт мониторинга, который в реальном времени показывает состояние бюджета и оповещает о превышениях.
Этап 5: Аудит и отчёт (30 минут)
Действия
-
Написать скрипт
audit_report.py -
Сгенерировать отчёт в формате Markdown
# Отчёт аудита token economics ## Сводка | Agent | Total tokens | Total cost $ | Requests | Avg tokens/req | ... ## Аномалии - Выбросы: 3 запроса > 2x стандартного отклонения - Блокировки: 2 раза (support_agent превысил дневной лимит) ## Рекомендации - Увеличить лимит support_agent на 20% -
Сохранить отчёт в файл
audit_report_YYYY-MM-DD.md
Ожидаемый результат этапа Файл с аудит-отчётом, содержащим наглядную статистику и рекомендации.
5. Критерии приемки (Definition of Done)
- Реализован модуль бюджетирования, который хранит лимиты и текущее состояние в SQLite.
- При вызове агента с превышением дневного или месячного лимита возвращается ошибка и запись в логе типа
blocked. - Счётчик токенов корректно считает как промпт, так и completion (с использованием tiktoken/anthropic tokenizer).
- Каждый вызов агента фиксируется в таблице
usage_logс полными метриками (tokens, cost, timestamp, agent). - Мониторинг выводит текущее состояние бюджетов в консоль (или дашборд) в реальном времени.
- Сгенерирован аудит-отчёт с анализом затрат и аномалий.
- Политика
BLOCKработает атомарно: не происходит списания, если лимит уже исчерпан. - Тестовый сценарий с 50+ вызовами успешно демонстрирует блокировку хотя бы одного агента (для проверки можно искусственно занизить лимит).
6. Ожидаемый результат
Основной артефакт репозиторий с кодом, содержащий:
budget_controller.py— логика бюджета и хранилища.token_counter.py— подсчёт токенов и стоимости.agents.py— агенты с декоратором бюджета.load_simulator.py— скрипт симуляции нагрузки.monitor.py/dashboard.py— мониторинг (консольный или Prometheus).audit_report.py— генерация отчёта.config.yaml— конфигурация лимитов.- Сгенерированный отчёт
audit_report_*.md. - SQLite база данных (или
.dbфайл в папкеdata/) с логами тестового прогона.
Дополнительные результаты (опционально):
- Docker Compose файл с Prometheus + Grafana (если включён).
- Скрипт для сброса бюджета вручную.
- Документация в README.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Гонки при проверке и списании бюджета | Использовать транзакции с уровнем изоляции IMMEDIATE в SQLite или блокировки Redis (WATCH/MULTI/EXEC) |
| Неточность подсчёта токенов | Использовать официальные токенизаторы (tiktoken, anthropic tokenizer) и обновлять их версии при смене модели |
| Сброс бюджета в полночь при разных часовых поясах | Всегда использовать UTC; хранить последнюю дату сброса в БД |
| Пакетная обработка без проверки бюджета | Внедрить middleware/декоратор на уровне каждого вызова, а не на уровне пакета |
| Переполнение счётчика (int64) | В SQLite INTEGER — 8 байт (до 9e18), достаточно. При больших значениях можно хранить как REAL |
| Отсутствие Prometheus | Заменить на вывод в CSV + простой парсер для визуализации через matplotlib |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| Этап 1: Проектирование модели бюджета | 0.5 часа |
| Этап 2: Реализация счётчика и хранилища | 1 час |
| Этап 3: Интеграция с агентами | 1 час |
| Этап 4: Мониторинг и алертинг | 0.5 часа |
| Этап 5: Аудит и отчёт | 0.5 часа |
| Итого (чистое время) | 3.5 часа |
| Примечание для первого раза | +1 час на отладку и настройку окружения (Docker, зависимости) |
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 1 | Какие метрики cost-per-agent считаются стандартными? |
| 8 | Как настроить бюджет на уровне tenant? |
| 12 | Каковы best practices для лимитов rate limiting и token bucket? |
| 23 | Как интегрировать мониторинг LLM с Prometheus? |
| 45 | Как написать postmortem для инцидента runaway costs? |
| 67 | Как считать стоимость запроса для различных провайдеров? |
| 89 | Как реализовать алерты при превышении бюджета в Grafana? |
| 112 | Какие стратегии троттлинга применять для агентов? |
| 156 | Как аудировать токены в multi-agent системе? |
| 203 | Как тестировать бюджетные ограничения без реальных API? |
10. Чек-лист самопроверки
- Я реализовал атомарную проверку и списание бюджета (без race condition).
- Я протестировал сценарий, когда лимит исчерпан — агент возвращает ошибку и не тратит деньги.
- Я убедился, что счётчик токенов считает промпт и completion раздельно и суммарно.
- Я сгенерировал аудит-отчёт, который показывает хотя бы одну аномалию.
- Я задокументировал конфигурацию бюджетов в отдельном файле (YAML/JSON) и могу легко менять лимиты.
- Я добавил логирование предупреждений при 80% лимита.
- Я проверил, что при сбросе (новый день/месяц) бюджет корректно обнуляется.