Настройка мониторинга качества ответов AI-модели

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Настройка мониторинга качества ответов AI-модели
Средняя
от 1 рабочего дня до 3 рабочих дней
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1218
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    854
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1047
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    825

Настройка мониторинга качества ответов AI-модели

Мониторинг качества ответов LLM в production — обнаружение деградации до того, как пользователи начнут жаловаться. Автоматические метрики: длина ответов, токсичность, релевантность, hallucination signals.

Метрики качества для мониторинга

Прокси-метрики (вычисляются автоматически, без LLM):

  • Длина ответа: резкое уменьшение → регрессия в промпте
  • Refusal rate: рост отказов отвечать
  • Incomplete response rate: ответы обрезанные по max_tokens
  • Repetition rate: петли в генерации

LLM-as-judge метрики (дороже, выборочно):

  • Relevance to query
  • Factual consistency
  • Helpfulness score
  • Toxicity / safety
class ResponseQualityMonitor:
    def analyze_response(self, request: str, response: str) -> QualitySignals:
        signals = QualitySignals()

        # Длина
        signals.response_length_tokens = count_tokens(response)
        signals.is_very_short = signals.response_length_tokens < 20

        # Отказ отвечать
        refusal_patterns = ["I cannot", "I'm unable", "I don't have access",
                           "не могу", "не в состоянии", "отказываюсь"]
        signals.is_refusal = any(p.lower() in response.lower() for p in refusal_patterns)

        # Обрезание
        signals.is_truncated = response.endswith(("...", "—", "–"))

        # Повторения (петли)
        words = response.split()
        if len(words) > 20:
            unique_bigrams = len(set(zip(words, words[1:])))
            total_bigrams = len(words) - 1
            signals.repetition_score = 1 - unique_bigrams / total_bigrams
            signals.has_loops = signals.repetition_score > 0.4

        return signals

Дрейф качества со временем

Проблема: LLM API провайдеры обновляют модели без анонсов. Вчерашний gpt-4o — не сегодняшний. Отслеживаем скользящее среднее метрик качества:

def detect_quality_drift(
    metric: str,
    recent_values: list[float],  # последние N запросов
    baseline_values: list[float]  # исторический baseline
) -> DriftDetection:
    from scipy.stats import ks_2samp

    # Kolmogorov-Smirnov тест на изменение распределения
    statistic, p_value = ks_2samp(baseline_values, recent_values)

    # Среднее значение
    recent_mean = np.mean(recent_values)
    baseline_mean = np.mean(baseline_values)
    relative_change = (recent_mean - baseline_mean) / baseline_mean

    return DriftDetection(
        metric=metric,
        is_drifted=p_value < 0.05,
        relative_change=relative_change,
        direction="improvement" if relative_change > 0 else "degradation",
        severity="high" if abs(relative_change) > 0.10 else "medium" if abs(relative_change) > 0.05 else "low"
    )

Алерты и дашборды

Prometheus метрики публикуются из мониторинга:

from prometheus_client import Histogram, Counter, Gauge

RESPONSE_LENGTH = Histogram("llm_response_length_tokens", "Response length distribution",
                            buckets=[10, 50, 100, 200, 500, 1000, 2000])
REFUSAL_COUNT = Counter("llm_refusal_total", "Refusal responses")
QUALITY_SCORE = Gauge("llm_quality_score", "Rolling quality score", ["model"])

# Алерты
# ALERT если refusal_rate за 15 минут > 5%
# ALERT если средняя длина ответа < 50 токенов (была > 150)
# ALERT если quality_score < baseline - 0.1