graph LR
%% ОБЪЯВЛЕНИЕ УЗЛОВ СТРОГО СЛЕВА НАПРАВО (PIPELINE LAYOUT)
classDef transport fill:#E3F2FD,stroke:#0D47A1,stroke-width:1px;
classDef coreEngine fill:#FFF9C4,stroke:#FBC02D,stroke-width:1px;
classDef storage fill:#D9EAD3,stroke:#274E13,stroke-width:2px;
subgraph Слой_1_Шкалы ["1. Пассивный контур шкал"]
IDLE["STATE: IDLE<br>Пассивное время"]:::transport
HUNGRY["STATE: HUNGRY<br>hunger и stress растут"]:::transport
end
subgraph Слой_2_Выбор ["2. Марковское ядро Маршрутизации"]
Roulette["Roulette Wheel Selection<br>Модификация и нормализация весов"]:::coreEngine
end
subgraph Слой_3_Действия ["3. Дискретные состояния модели"]
COOKING["STATE: COOKING"]:::coreEngine
CONSUMPTION["STATE: CONSUMPTION"]:::coreEngine
PURCHASE["STATE: PURCHASE"]:::coreEngine
WASTE["STATE: WASTE"]:::coreEngine
end
subgraph Слой_4_Задержка ["4. Временное сглаживание"]
Weibull["Weibull Delay Engine<br>Расчет смещения Virtual Time + Delay"]:::coreEngine
end
subgraph Слой_5_Шина ["5. Первичная фиксация интентов"]
T_Intent["topic: agent-intents<br>Буфер намеренно совершенных действий"]:::storage
end
%% ПОТОКИ ДАННЫХ КОНВЕЙЕРА СХЕМЫ 1
IDLE -->|Инкремент шкал каждый час| HUNGRY
HUNGRY -->|Триггер EvaluateBehavior| Roulette
Roulette -->|Сектор COOK| COOKING
Roulette -->|Сектор CONSUME| CONSUMPTION
Roulette -->|Сектор SHOP| PURCHASE
Roulette -->|Сектор WASTE| WASTE
COOKING & CONSUMPTION & PURCHASE & WASTE -->|Действие отличается от IDLE| Weibull
Weibull -->|Асинхронный пуш намерения с таймингом| T_Intent
SIM: Событийная модель симулятора (Event-Driven Simulation Model)
В открытом доступе представлена демонстрационная версия метода. В настоящей публичной документации отображены не все шаги, технические сценарии и приватные эндпоинты для системы цифровых симуляторов бизнес-процессов.
- Полная спецификация метода: Будет доступна только во внутреннем контуре разработки (Confluence / Swagger Enterprise).
Основа цифрового симулятора процессов. Сам этот термин описывает математический или логический подход, алгоритм и принцип работы симулятора. Он указывает на то, что симуляция двигается не по фиксированному времени (таймеру), а реагирует на конкретные события (Discrete Event Simulation). Генерируются случайные величины, выстроена причинно-следственная связь событий и бизнес-правила.Каждое изменение состояния системы генерирует событие, которое мы и публикуем.
1. Архитектура Цифрового Двойника (Digital Twin Persona)
В основе алгоритмов вычисления лежит концепция Событийного моделирования (Discrete Event Simulation). Симулятор двигается по временной шкале фиксированными шагами, но внутри каждого шага поведение цифрового двойника или агента полностью стохастично и определяется его персональными характеристиками.
Примечание: Для примеров оспользовали приложение FoodTracker.
Каждый агент описывается двумя изолированными слоями данных:
- Статический профиль (
StaticProfile): Неизменяемая анкета, определяющая социально-экономический класс двойника, его характер, диету и базовые привычки (класс дохода, чувствительность к ценам, склонность к накопительству). - Динамическое состояние (
DynamicState/TwinFoodState): Постоянно меняющиеся физиологические и психологические метрики (текущий уровень голода, стресса, время без покупок и моментальный снимок содержимого холодильника).
Схема архитектуры компонента (Simulation Model State Machine)
Ниже представлен поведенческий стохастический граф переходов (State Machine) цифрового двойника. Схема отражает логику циклической эволюции состояний агента на основе марковских вероятностей, условий сглаживания шкал и триггеров генерации ИИ-событий.
graph LR
%% ОБЪЯВЛЕНИЕ УЗЛОВ СТРОГО СЛЕВА НАПРАВО (PIPELINE LAYOUT)
classDef transport fill:#E3F2FD,stroke:#0D47A1,stroke-width:1px;
classDef coreEngine fill:#FFF9C4,stroke:#FBC02D,stroke-width:1px;
classDef storage fill:#D9EAD3,stroke:#274E13,stroke-width:2px;
classDef external fill:#F3E5F5,stroke:#7E57C2,stroke-width:1px;
subgraph Слой_1_Очередь ["1. Шина Интентов"]
T_Intent["topic: agent-intents<br>JSON: user_id, action_type, virtual_time"]:::storage
end
subgraph Слой_2_Оркестратор ["2. Планировщик Симулятора (Scheduler)"]
Scheduler["Virtual Time Scheduler<br>Вычитка при наступлении virtual_time"]:::coreEngine
Profiles["StaticProfile Cache<br>Данные анкеты твина"]:::storage
end
subgraph Слой_3_Синтез ["3. Семантическое обогащение"]
Prompt["PromptBuilder<br>Сборка промпта из параметров профиля"]:::coreEngine
end
subgraph Слой_4_Инференс ["4. Распределенный ИИ-Контур (Ubuntu)"]
Ollama["Ollama Runtime Nodes<br>Модели: Llama Vision / Qwen"]:::external
end
subgraph Слой_5_Аналитика ["5. Выходной контур телеметрии"]
T_Hist["topic: twin-history-events<br>Финальный JSON для ClickHouse DWH"]:::storage
end
%% ПОТОКИ ДАННЫХ КОНВЕЙЕРА СХЕМЫ 2
T_Intent -->|PollFetches| Scheduler
Scheduler -->|Запрос характеристик по user_id| Profiles
Profiles -->|Анкетные метрики: hoarding_tendency| Prompt
Scheduler -->|Тип действия и контекст| Prompt
Prompt -->|Семантический PromptRequest JSON| Ollama
Ollama -->|Сгенерированный контекстный production JSON| T_Hist
2. Механика эволюции шкал и марковские цепи
На каждом тике времени (равном 1 часу) движок производит расчет поведения агента, состоящий из трех последовательных фаз: Линейный рост шкал -> Оценка марковских вероятностей -> Расчет задержки.
graph LR
Tick[Новый час симуляции] --> Advance[1. AdvanceState: Линейный рост голода и стресса]
Advance --> Eval[2. EvaluateBehavior: Модификация базовых весов]
Eval --> Markov[3. MarkovEngine: Выбор действия рулеткой]
Markov --> Weibull[4. WeibullEngine: Расчет длительности действия]
2.1 Линейное приращение (AdvanceState)
Модель симулирует непрерывную жизнедеятельность. За каждый час пассивного времени показатели агента детерминированно увеличиваются:
- Голод (
current_hunger): Увеличивается на +0.05 за шаг (Clamped до1.0). - Стресс (
current_stress): Увеличивается на +0.01 за шаг (Clamped до1.0). - Время без закупок (
time_since_last_shop): Инкрементируется на +1.
2.2 Динамическая модификация весов Маркова
В системе определена базовая матрица вероятностей для пяти состояний:
IDLE(0.45),COOKING(0.20),CONSUMPTION(0.20),PURCHASE(0.10),WASTE(0.05).
Перед выбором действия модель накладывает на базовую матрицу динамические модификаторы, отражающие текущее состояние шкал твина и контекст времени:
- Фактор критического голода (
hunger > 0.75): Подавляет бездействие (IDLE -0.40), стимулирует готовку (COOKING +0.25) и еду (CONSUMPTION +0.15). - Фактор компульсивного шоппинга (
stress > 0.80): Увеличивает вероятность закупки, масштабируя её на личную склонность к накопительству (PURCHASE +0.25 * hoarding_tendency). - Фактор ночного времени (с 1 до 5 утра): Базово усыпляет твина (
IDLE +0.50), но если зафиксирован высокий стресс (>0.75) и низкая чувствительность к ценам (<0.40), активируется паттерн ночного стресс-шоппинга:PURCHASEполучает +0.35, аIDLEштрафуется на -0.45.
2.3 Математическая нормализация и Алгоритм Рулетки
Для защиты математической модели от ухода в отрицательные вероятности после применения отрицательных значений или штрафов, MarkovEngine выполняет нормализацию:
- Если итоговый вес действия
< 0, он принудительно заменяется на минимальный порог безопасности:w = 0.01. - Выбор действия происходит по алгоритму рулетки (Roulette Wheel Selection): генерируется случайное число
roll = rand.Float64() * totalWeight, итеративно накапливается сумма весов, и выбирается сектор, в который попало число. При полном обнулении весов возвращается дефолтное значение (IDLE).
3. Распределение Вейбулла: Генерация задержек времени
После выбора дискретного действия (например, COOKING) модель должна определить временную координату виртуального календаря — через сколько времени это событие произойдет. Вместо однородного распределения модель использует распределение Вейбулла, которое наиболее реалистично описывает человеческое поведение и время выполнения задач.
Плотность вероятности рассчитывается на основе параметров формы (shape, α) и масштаба (scale, β). Метод GenerateNextEventDelay преобразует случайное число методом обратной функции:
\[ \text{hours} = \beta \cdot (-\ln(1 - u))^{\frac{1}{\alpha}} \]
Стабилизация наносекундного смещенеия: Для предотвращения рассинхронизации часов между предположим 50 000+ параллельных воркеров, вычисленное дробное время в часах сразу переводится в минуты и округляется до минутных границ:
totalMinutes := hours * 60.0 return time.Duration(totalMinutes) * time.Minute
4. Генеративный AI-в-контуре (LLM Semantic Synthesis)
Если марковский процесс выбирает активное действие, в контур симуляции включается генеративный модуль PromptBuilder. Он переводит сухие математические параметры агента в семантический контекст (Промпт) для Large Language Model, заставляя ИИ-сервис генерировать приближенные к реальности, контекстные JSON-данные.
4.1 Трансляция параметров в промпт
- Параметр
HoardingTendency > 0.8транслируется для LLM как: “Ты склонен закупаться впрок огромными объемами (опт, мешки, коробки, килограммы)”. - Параметр
PriceSensitivity > 0.7транслируется как: “Ты крайне чувствителен к ценам, выбираешь только дешевые базовые товары”.
4.2 Схемы данных генеративного слоя (Примеры выходных JSON)
В зависимости от ActionType, LLM обязана вернуть строго валидный JSON-объект без markdown-разметки. Разработчикам ИИ-модуля необходимо настроить парсинг под следующие структуры:
Пример для действия PURCHASE (Чек покупки)
Учитывает диету, доход и склонность к опту.
{
"receipt_no": "BILL-2026-X901",
"total_price": 600.0,
"items": [
{
"item_id": "a1b2-c3d4-e5f6",
"name": "Хлеб Бородинский",
"category": "Выпечка",
"units": 2.0,
"weight_grams": 800.0,
"price": 100.0
},
{
"item_id": "f8e7-d6c5-b4a3",
"name": "Масло сливочное 82%",
"category": "Молочные продукты",
"units": 1.0,
"weight_grams": 200.0,
"price": 400.0
}
]
}Пример для действия COOKING (Приготовление блюда)
Утилизирует ингредиенты из холодильника, создавая новое виртуальное блюдо.
{
"dish_item_id": "dish-992-uuid",
"dish_name": "Суп домашний",
"yield_portions": 4.0,
"yield_weight_grams": 1500.0,
"ingredients": [
{
"source_item_id": "a1b2-c3d4-e5f6",
"used_units": 0.5,
"used_weight_grams": 200.0
},
{
"source_item_id": "8b5c4112-9c3a-4a6c-b26a-123456789abc",
"used_portions": 2.0,
"used_weight_grams": 200.0
},
{
"source_item_id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"used_portions": 1.0,
"used_weight_grams": 250.0
}
]
}Пример для действия CONSUMPTION (Поедание порции)
Уменьшает количество порций готового блюда.
{
"item_id": "dish-992-uuid",
"portions": 1.0,
"weight_grams": 350.0
}Пример для действия WASTE (Утилизация испорченной еды)
{
"item_id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"portions": 0.5,
"weight_grams": 125.0,
"reason": 1
}Что модель дает проекту? (Аналитика данных)
Выстроенная по бизнес-процессам модель помогает набирать датасет синтетических данных, когда естественно собираемых данных еще нет. В зависимости от точности и сложности модели, мы заранее можем увидеть как сравнительно большие данные будут работать на репортинг, процесс майнинг и построенние гипотез. В анализе данных например тоже есть бутстрап, который по сути тоже явялется синтетическким. Также модель используется симулятором при нагрузочном тестировании и тестирует user story use cases, а еще сбор ошибок так называемый слой observability. В примерах мы показали одно српаниельно небольшое приложение, а в документации приложений два для демонстрации применния симуляттора для разных моделей или универсатльности.