
Поступающий в колл-центр звонок должен быть переадресован одному из свободных консультантов, которых на профессиональном сленге принято называть агентами. Эта функциональность реализуется подсистемой маршрутизации входящих звонков, обычно входящей в пакет услуг для корпоративных клиентов операторов 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