Поступающий в колл-центр звонок должен быть переадресован одному из свободных консультантов, которых на профессиональном сленге принято называть агентами. Эта функциональность реализуется подсистемой маршрутизации входящих звонков, обычно входящей  в пакет услуг для корпоративных клиентов операторов IP телефонии. Правильная маршрутизация это то начало от которого начинается непростой путь к компании, умеющей работать с клиентами.
В статье мы представляем модель дискретно-временного типа, предназначенную для сравнения трех базовых стратегий маршрутизации:

  • Sequential - последовательный индексный перебор свободных агентов от начала до конца.

  • Round Robin - циклический обход с запоминанием последнего ответившего  и пропуском занятых агентов.

  • Longest Idle - выбор агента по максимуму времени простоя (idle_time).

Сравнение проводится по ключевым показателям производительности (KPI) и справедливости распределения нагрузки на агентов - fairness-метрикам.

Варианты использования модели

1. На стороне разработчиков систем маршрутизации

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

2. На стороне тестировщиков для валидации и стресс-тестирования

Она позволяет:

  • Сравнивать поведение симуляции с данными из реальной системы, создавая "цифрового двойника" для проверки точности.

  • Генерировать экстремальные сценарии (резкий всплеск звонков, внезапный выход из строя части операторов), чтобы найти узкие места и пределы прочности системы.

3. На стороне конечных пользователей (клиентов) системы маршрутизации

 Модель может использоваться как  сервис, который позволяет клиентам (например, руководителям колл-центров) проводить "What if?" анализ и подбирать оптимальную стратегию маршрутизации под свои нужды:

  • "Что будет, если мы переключимся на стратегию X? Сократится ли время ожидания?"

  • "Как справится система, если мы наймём ещё 10 операторов?"

  • "Как изменится равномерность нагрузки операторов для разных стратегий  в условиях различной интенсивности звонков?"

Предлагая клиенту такой инструмент, компания оператор предоставляет дополнительную услугу по оптимизации клиентских бизнес-процессов с наглядной демонстрацией эффекта от внедрений новых стратегий, что может быть дополнительным конкурентным преимуществом.

Описание модели

Ключевые особенности

  • Сравнительный анализ: Модель одновременно оценивает три базовые стратегии: Sequential, Round Robin и Longest Idle и позволяет напрямую сравнить их влияние на систему при идентичных входящих потоках звонков.

  • Гибкость и воспроизводимость: Все параметры симуляции (интенсивность звонков, число агентов, длительность вызовов и т.д.) вынесены в единый конфигурационный файл config.py. Использование фиксированного seed для разных генераторов обеспечивает воспроизводимость экспериментов.

  • Комплексные метрики: Собираются как стандартные KPI (уровень обслуживания (SLA), среднее время ожидания, длина очереди), так и метрики справедливости (индекс Джини, коэффициент вариации, эффективное число агентов). Метрики справедливости рассчитываются раздельно для двух показателей:

    • общего количества звонков принятых агентом и

    • суммарного времени загрузки агента.

    Это позволяет оценить не только общую эффективность, но и равномерность загрузки операторов, что важно для планирования ресурсов и мотивации персонала.

  • Архитектура для Colab и локальной разработки: Проект изначально спроектирован для запуска в Google Colab, где все модули создаются в сессионном хранилище при первом запуске. Это позволяет развертывать его и без установки среды Python. При этом структура проекта соответствует  подходу src-layout, что делает его легко переносимым в среды разработки.

Краткое описание модулей и элементов архитектуры

Проект имеет модульную структуру, где каждый компонент отвечает за свою часть логики:

  • src/ccsim/config.py: Центральный модуль для всех настроек симуляции. Использует dataclass со строгой типизацией параметров моделирования и включает методы для сериализации/десериализации в JSON, что удобно для сохранения конфигурации каждого запуска.

  • src/ccsim/agents.py: Определяет класс Agent  с его состояниями (свободен, занят, недоступен) и поведением. Здесь же реализованы функции для генерации стохастических событий, таких как поступление звонков (на основе пуассоновского процесса) и их длительности.

  • src/ccsim/strategies.py: Реализует логику выбора оператора. Все стратегии наследуются от абстрактного базового класса RoutingStrategy, что позволяет легко добавлять новые стратегии без изменения основного кода симуляции. Это ключевой элемент, обеспечивающий расширяемость модели.

  • src/ccsim/simulation.py: Ядро проекта. Содержит основной цикл дискретно-временного моделирования. На каждом шаге  симуляции обрабатываются события: поступление новых звонков, проверка освободившихся операторов, распределение вызовов из очереди и сбор промежуточных данных.

  • src/ccsim/metrics.py: Вычисляет метрики справедливости и вариабельности по собранным данным (индекс Джини, коэффициент вариации и др.).

  • src/ccsim/visualization.py: Отвечает за создание всех графиков: распределения нагрузки, динамики очереди, времени ожидания. Визуализации создаются как для отдельных прогонов, так и для сводного сравнения стратегий.

  • main.py: Точка входа, которая оркестрирует весь процесс. Она инициализирует симуляцию, запускает ее для каждой стратегии, собирает и сохраняет все артефакты (данные в CSV, графики в PNG, конфигурацию в JSON) в уникальную папку для каждого запуска runs/<timestamp>, обеспечивая  прослеживаемость экспериментов.

  • tests/test_strategies.py: Набор модульных тестов для pytest, проверяющих корректность работы каждой стратегии маршрутизации в различных сценариях, включая граничные случаи (нет свободных операторов, пустой список агентов и т.д.).

  • pyproject.toml: Задаёт систему сборки через setuptools, хранит метаданные по PEP 621, включает автопоиск пакетов под src‑layout и минимальные опции pytest для запуска тестов из каталога tests. Такой конфигурационный файл делает проект устанавливаемым (в том числе в editable‑режиме) и предотвращает «теневые» импорты.

  • Запуск проекта в Colab: Editable-установка  пакета и запуск main.py из корня проекта, с сохранением артефактов в runs/<timestamp>.

  • Запуск pytest: формируются отчеты покрытия в консоли и  HTML/JUnit.

Рабочий процесс

  • Загрузка и запуск блокнота "HABR_call_center_simulation_Python_Project.ipynb" в Google Colab. В результате осуществляется генерация структуры и исходников из блокнота Colab с записью файлов в сессионное хранилище, последующей установкой пакета и запуском сценария main.py из корня проекта. Если хотите сохранить свои изменения - сделайте копию загруженного блокнота и работайте с ней.

  • Запуск тестов - запуск ячейки Запуск pytest.

  • Мульти‑прогоны с разными параметрами из модуля конфигурации и сравнением стратегий по  fairness-метрикам  и SLA, включая комбинированные визуализации и отчёты в runs/<timestamp>.

    • Для повторных запусков с измененным набором параметров достаточно перезапустить ячейку модуля конфигурации src/ccsim/config.pyи ячейку Запуск проекта в Colab.

    • В качестве примера можно выполнить три цикла моделирования последовательно задавая значения параметра  lambda_rate из списка [0.65, 0.75, 0.85] в модуле config.py. Для  дефолтного набора значений остальных параметров это соответствует низкой,  пороговой и чрезмерной нагрузке на систему.

    • Видно, что в варианте с низкой нагрузкой стратегии имеют существенные различия в распределениях времени занятости агентов и fairness-метриках, для пороговой нагрузки — разница меньше, при чрезмерной — разница минимальна.

    • Для рассматриваемого примера  из fairness-метрик лучшую чувствительность демонстрирует коэффициент вариации.

    • Наиболее наглядно разница между стратегиями видна на графиках распределений времени суммарной занятости агентов: combined_busy_times_kde.png.

Параметры моделирования

Параметры в src/ccsim/config.py описывают поток вызовов, поведение агентов, ограничения очереди и критерии SLA, а также управляют длиной и детальностью симуляции для воспроизводимых экспериментов. Они заданы в dataclass SimulationConfig и  сериализуются в JSON для фиксации настроек каждого прогона.

Параметры модели

  • seed: инициализация генераторов случайных чисел NumPy и Python.

  • lambda_rate: интенсивность поступления звонков (ед/сек) для пуассоновской генерации времени поступления звонка.

  • num_agents: количество операторов, участвующих в маршрутизации вызовов.

  • num_calls: общее число синтетически сгенерированных звонков за прогон симуляции.

  • max_idle_time: верхняя граница времени простоя агента в модели, используемая для начальной инициализации агентов.

  • min_call_duration, max_call_duration: минимальная и максимальная длительность разговора в секундах для дискретной генерации продолжительностей.

  • agent_logout_prob, agent_login_prob: вероятности выхода агента «в офлайн» и возвращения «в онлайн» на каждом шаге симуляции.

  • agent_response_prob: вероятность того, что выбранный стратегией агент примет назначенный вызов.

  • max_queue_size: максимальный размер очереди ожидания; при превышении входящий вызов фиксируется как пропущенный.

  • service_level_threshold: SLA‑порог по времени ожидания (в секундах), в который должен уложиться ответ, чтобы быть засчитанным.

  • max_wait_before_abandonment: максимальное время ожидания до сброса вызова клиентом.

  • max_simulation_steps: ограничение длины симуляции по шагам; если не задано, устанавливается автоматически как num_calls × 10 в post_init - предотвращение бесконечного цикла.

  • verbose: флаг включения подробных визуализаций и отчётных графиков в ходе симуляции.

Что дальше

В статье описана модель начального уровня. Она может быть расширена в нескольких направлениях:

Повышение реалистичности:

  • Более сложные модели поведения: Добавить неоднородность агентов (разные уровни, графики работы, усталость, агенты-роботы),  более сложное поведение клиентов (повторные звонки, разные уровни терпения, интенсивность входящих звонков с учетом различных цикличностей и влияния экзогенных факторов).

  •  Новые стратегии маршрутизации: Реализовать skill-based routing (маршрутизация на основе навыков), predictive routing (с использованием прогностических моделей для предсказания времени обработки) или гибридные подходы.

Интеграция и инструменты:

  • CLI (Command-Line Interface): Перейти от гибридного варианта Colab  к  полноценному интерфейсу командной строки для запуска симуляций с параметрами, что упростит автоматизацию и интеграцию в CI/CD пайплайны.

  • Интерактивный дашборд: Разработать веб-дашборд (например, с помощью Dash или Streamlit) для интерактивного анализа результатов, где пользователи могли бы менять параметры и сразу видеть "what-if" сценарии.

  • Интеграция с СУБД: Для масштабных экспериментов  можно настроить сохранение результатов не в CSV-файлы, а в колоночную базу данных (например,  DuckDB)  для более эффективного быстрого анализа.

Углубленный анализ:

  • Статистическая значимость: Добавить расчеты для оценки статистической значимости различий между метриками разных стратегий (например, с помощью t-тестов или бутстрэпа).

  • Оптимизация параметров: Использовать методы оптимизации (например, байесовскую оптимизацию) для автоматического подбора наилучших параметров колл-центра (число операторов, размер очереди) для достижения заданных KPI.

Смена парадигмы моделирования:

  • От Дискретно-временной перейти к Дискретно-событийной: Использовать в качестве основы один из фреймворков дискретно‑событийного (DES) моделирования.

Заключительные соображения

В русском языке термин "Моделирование" обладает полисемией. В зависимости от контекста он может обозначать и этап построения модели и этап ее применения. Статья ограничена только первым из них.

Ссылка на блокнот Colab

Открыть блокнот Colab


Владимир Сюр, Сергей Сюр

Комментарии (0)