English translation is not available yet. Showing Russian content.

Настроить cost attribution per feature

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить cost attribution per feature

1. Цель задачи

Научиться размечать и отслеживать затраты на каждую фичу в AI-системе (RAG, reranking, агент, вызовы инструментов). Необходимо внедрить механизм сбора метрик стоимости (токены, задержки, количество вызовов) в разрезе фич и визуализировать их в дашборде. Это позволит выявить самые дорогие компоненты и принять решения по оптимизации.

Ключевой результат Работающий дашборд Grafana, показывающий затраты на каждую фичу за последние 7 дней, с возможностью детализации до одного запроса.


2. Исходные данные

Перед началом необходимо иметь:

Что нужноОткуда взять
Работающая AI-система с несколькими фичамиПет-проект (например, RAG + агент на LangChain) или production-система
Доступ к логам вызовов LLM-провайдераAPI Key OpenAI / Anthropic / локальная LLM
Хранилище для метрикPostgreSQL / ClickHouse / Prometheus (на выбор)
Дашборд-инструментGrafana (обязательно)
Код фичВаш репозиторий

Если нет реального инструмента — симулируем:

  1. Разверните тестовую RAG-систему с помощью LangChain (создайте 3 фичи: retrieval_only, rag_with_rerank, agent_with_tools).
  2. Используйте OpenAI API (или бесплатный эмулятор Ollama) для генерации ответов.
  3. Создайте таблицу в PostgreSQL: feature_usage_logs для записи метрик.
  4. Настройте Prometheus для сбора пользовательских метрик (Python-клиент).

3. Технологический стек

КомпонентИнструментыНазначение
Язык программированияPython 3.10+Реализация логики фич и сбора метрик
Фреймворк для AILangChain / LlamaIndexПостроение RAG, reranking, агентов
Коллекция метрикpython-json-logger, prometheus_clientЛогирование и экспорт метрик
Хранилище метрикPostgreSQL / ClickHouseДолгосрочное хранение логов затрат
ДашбордыGrafanaВизуализация cost attribution
LLM-провайдерOpenAI API (gpt-3.5-turbo / gpt-4o-mini)Генерация ответов (дёшево для тестов)
Эмуляция (опционально)Ollama с llama3.2Локальная LLM без затрат, но метрики имитируем

4. Этапы выполнения

Этап 1: Проектирование схемы сбора метрик (1 час)

Действия

  1. Определите, какие метрики собирать для каждой фичи:

    • input_tokens — токены запроса
    • output_tokens — токены ответа
    • total_latency_ms — общее время выполнения фичи
    • llm_calls — количество вызовов LLM за один запрос
    • retrieval_docs — количество извлечённых документов (для RAG)
    • tool_calls — количество вызовов инструментов (для агента)
    • cost_usd — ориентировочная стоимость (на основе прайсинга провайдера)
  2. Спроектируйте структуру таблицы для логов

    CREATE TABLE feature_usage_logs (
        id SERIAL PRIMARY KEY,
        timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
        request_id UUID NOT NULL,
        feature_name TEXT NOT NULL,          -- 'rag', 'rerank', 'agent', 'tools'
        input_tokens INT,
        output_tokens INT,
        total_latency_ms INT,
        llm_calls INT,
        retrieval_docs INT,
        tool_calls INT,
        cost_usd NUMERIC(10,6)
    );
    CREATE INDEX idx_feature_usage_ts ON feature_usage_logs(timestamp);
    CREATE INDEX idx_feature_usage_name ON feature_usage_logs(feature_name);
    
  3. Определите прайсинг-лист для расчёта cost_usd

    • Например: gpt-3.5-turbo — $0.0015 / 1K input tokens, $0.002 / 1K output tokens
    • Для тестов можно использовать фиксированные ставки: $0.002 за 1K токенов.

Ожидаемый результат этапа Схема таблицы и метрик утверждены, прайсинг зафиксирован.

Этап 2: Инструментирование кода фич (2-3 часа)

Действия

  1. Создайте единый декоратор / контекстный менеджер для замера стоимости:

    import time
    from uuid import uuid4
    import json_logger
    
    logger = json_logger.getLogger()
    
    class CostTracker:
        def __init__(self, feature_name):
            self.feature_name = feature_name
            self.start = None
            self.request_id = uuid4()
    
        def __enter__(self):
            self.start = time.time()
            return self
    
        def __exit__(self, *args):
            latency = int((time.time() - self.start) * 1000)
            # Логируем в JSON-логи
            logger.info("feature_usage", extra={
                "request_id": str(self.request_id),
                "feature": self.feature_name,
                "latency_ms": latency,
                # остальные метрики собираются отдельно
            })
    
  2. В каждой фиче (RAG, reranking, agent) оберните основной вызов в CostTracker:

    with CostTracker("rag"):
        # вызов RAG-цепочки
        ...
    
  3. Добавьте сбор детальных метрик (токены, вызовы):

    • Для LangChain используйте callbacks (LangChainTracer или кастомный CallbackHandler).
    • Пример callback для подсчёта токенов:
      class TokenCounterCallback(BaseCallbackHandler):
          def __init__(self):
              self.input_tokens = 0
              self.output_tokens = 0
          def on_llm_end(self, response, **kwargs):
              self.input_tokens += response.llm_output.get("token_usage", {}).get("prompt_tokens", 0)
              self.output_tokens += response.llm_output.get("token_usage", {}).get("completion_tokens", 0)
      
  4. Объедините данные из CostTracker и callback-ов, запишите в БД:

Ожидаемый результат этапа Код всех фич инструментирован, данные пишутся в PostgreSQL.

Этап 3: Настройка Prometheus и метрик в реальном времени (1 час)

Действия

  1. Добавьте Prometheus-метрики (Histogram для latency, Counter для вызовов и стоимости):

    from prometheus_client import Histogram, Counter, Gauge, start_http_server
    
    feature_latency = Histogram(
        'feature_latency_ms',
        'Latency per feature in ms',
        ['feature'],
        buckets=[100, 500, 1000, 2000, 5000]
    )
    feature_cost = Counter(
        'feature_cost_usd',
        'Cumulative cost per feature',
        ['feature']
    )
    
  2. Обновите CostTracker, чтобы по окончании он обновлял Prometheus-метрики.

  3. Запустите HTTP-сервер Prometheus на порту 8000:

    start_http_server(8000)
    
  4. Настройте Prometheus для сбора метрик (добавьте target в prometheus.yml).

Ожидаемый результат этапа Prometheus получает метрики, Grafana может их визуализировать.

Этап 4: Построение дашборда в Grafana (1-2 часа)

Действия

  1. Подключите источники данных

    • Prometheus (для real-time метрик)
    • PostgreSQL (для исторических данных и детализации)
  2. Создайте дашборд "Cost Attribution per Feature" со следующими панелями:

    ПанельТипЗапрос (PromQL/SQL)
    Total Cost by Feature (7d)Bar chartsum by(feature) (increase(feature_cost_usd[7d]))
    Cost Breakdown TodayPie chartsum by(feature) (increase(feature_cost_usd[24h]))
    Latency p50/p95 by FeatureTime serieshistogram_quantile(0.5, sum(rate(feature_latency_ms_bucket[5m])) by (le, feature))
    Top-5 Most Expensive RequestsTableSQL: SELECT request_id, feature, cost_usd FROM feature_usage_logs WHERE ... ORDER BY cost_usd DESC LIMIT 5
    Calls per FeatureStatincrease(feature_cost_usd_count[24h]) (используйте _count метрику)
  3. Настройте переменные дашборда

    • feature — мультивыбор (все фичи, можно выбрать одну).
    • time_range — стандартный диапазон.
  4. Добавьте алерты

    • Если дневная стоимость какой-либо фичи превышает порог (например, $100 для теста — установите $0.01).

Ожидаемый результат этапа Дашборд показывает затраты по фичам, работает фильтрация, алерты включены.

Этап 5: Анализ и оптимизация (1 час)

Действия

  1. Запустите тестовые сценарии: генерируйте по 100 запросов для каждой фичи (RAG, rerank, agent, tools).
  2. Изучите дашборд: какая фича самая дорогая? Где узкие места?
  3. Предложите оптимизации
    • Для дорогого reranking: уменьшить модель (например, с gpt-4 на gpt-3.5).
    • Для агента: сократить количество шагов, добавить кэширование.
    • Для RAG: уменьшить top_k или использовать дешевый embedding.
  4. Примените одну оптимизацию, повторите тест и сравните затраты.

Ожидаемый результат этапа Текстовый отчёт с выводами и изменениями в конфигурации.


5. Критерии приемки (Definition of Done)

  • Спроектирована и создана таблица feature_usage_logs с индексами.
  • Все фичи (минимум 3: RAG, reranking, агент) инструментированы и пишут метрики в БД.
  • Prometheus экспортирует метрики feature_latency_ms и feature_cost_usd с лейблом feature.
  • Grafana дашборд содержит минимум 4 панели, включая Total Cost per Feature и Top-5 дорогих запросов.
  • Дашборд позволяет фильтровать по фичам и временному диапазону.
  • Настроен алерт на превышение дневной стоимости по любой фиче.
  • Проведён тестовый запуск (100 запросов на фичу) и видно явное разделение затрат.
  • Написана краткая документация по тому, как добавить новую фичу в мониторинг.

6. Ожидаемый результат

Основной артефакт Дашборд Grafana с именем "Cost Attribution per Feature", доступный по URL.

Сопутствующие файлы

  • Скрипты инструментирования (cost_tracker.py, callbacks.py).
  • Конфигурация Prometheus (prometheus.yml).
  • SQL-скрипт создания таблицы.
  • Отчёт об оптимизации (Markdown / PDF).

Опционально Пуш метрик в Prometheus через pushgateway, если приложение не всегда запущено.


7. Возможные сложности и их решение

СложностьРешение
Токены от LLM приходят не всегда (например, локальная модель)Использовать оценку через длину текста: len(text) * 1.3 для приблизительного подсчёта
Нет реального агента с инструментамиСоздать минимальную имитацию агента: один LLM-вызов + симуляция вызова API с фиксированной задержкой
Много фич — сложно дебажитьСделать логгирование каждого шага с request_id и связывать через trace_id
Prometheus метрики теряются при перезапуске приложенияИспользовать Pushgateway для пакетной отправки, или сохранять в БД и вычислять агрегаты в PromQL
Стоимость вызовов LLM меняется (обновление прайсинга)Вынести прайсинг в конфигурационный файл, обновлять при изменении, перезагружать дашборд

8. Бюджет времени (оценка)

ЭтапВремя
Этап 1: Проектирование схемы1 час
Этап 2: Инструментирование кода2.5 часа
Этап 3: Настройка Prometheus1 час
Этап 4: Построение дашборда1.5 часа
Этап 5: Анализ и оптимизация1 час
Итого7 часов

Примечание Для первого раза может потребоваться 8-9 часов из-за настройки окружения. При наличии готового стека (PostgreSQL, Grafana) — 5-6 часов.


9. Связанные вопросы из базы знаний

ВопросТема
13Основы cost engineering в ML-системах
42Мониторинг вызовов LLM
56Логирование метрик с Prometheus
78Построение дашбордов Grafana для ML
123Оптимизация затрат на LLM (кэширование, дешевые модели)
234Агентные архитектуры: метрики и стоимость
345Cost analysis для RAG-пайплайнов
456Инструментирование Python-приложений
567Прайсинг OpenAI и альтернатив
678Алертинг на основе метрик стоимости

10. Чек-лист самопроверки

  • Я спроектировал таблицу для логов и создал её в БД.
  • Я реализовал CostTracker и встроил его во все целевые фичи.
  • Я настроил Prometheus-клиент и экспортирую feature_cost_usd, feature_latency_ms.
  • Я подключил Prometheus и PostgreSQL к Grafana и создал дашборд с нужными панелями.
  • Я протестировал сценарий: запустил 100 запросов, убедился, что данные отображаются, алерты работают.
  • Я написал документацию по добавлению новой фичи (скопировать шаблон + добавить метки).
  • Я выполнил хотя бы одну оптимизацию на основе данных дашборда.