О проекте
Команда: TALENTS
Кейс HackAlem.ai: Финансы — Freedom
Стадия: Доведённый продукт
Задача кейса: «Граф денег»: восстановить структуру организованной группы по сети транзакций (AML)
Суть
Локальный AML-инструмент: из трёх Parquet строит направленный граф переводов 2248 клиентов, присваивает каждому роль-гипотезу и приоритет проверки с объяснением, выделяет 88 кластеров и показывает всё в веб-интерфейсе аналитика.
Как устроено
Python-пайплайн (pipeline.py) валидирует Parquet, считает метрики графа и сообщества Louvain, затем вызывает C++17-ядро (engine 1.3.0, JSON-контракт по схеме), которое применяет шесть формальных правил ролей (coordinator, transit, consolidator, peripheral и др.) с открытыми порогами и вкладами в приоритет. Учтены обрыв обхода на depth=4 и неполные входящие у seed. Результат: три CSV, graph.json и манифест с SHA-256; React/Vite UI показывает очередь проверки, карточки клиента и связи, 1–3 следующих действия и восемь сценариев устойчивости (исключение top-N по приоритету или объёму). verify_outputs.py сверяет результат с независимым эталоном на NetworkX.
Ключевые решения
- Louvain
- NetworkX (эталон проверки)
- rule-based role classification
- network resilience top-N removal
- SHA-256 integrity manifest
- JSON Schema contract
Метрики
2248 узлов, 3119 рёбер, 88 кластеров, топ-20; при исключении top-10 крупнейшая компонента 1877→1420 (по приоритету) и 1877→1502 (по объёму)
Особенности
Гибрид Python + C++ с формальным JSON-контрактом между ними и независимой сверкой всех результатов через NetworkX. Отдельно учтена граница наблюдаемости: клиент без исходящих на depth=4 не помечается как terminal. Для жюри готовы контрольные gid с ожидаемыми фактами.
Стек
Python 3.12 · C++17 · CMake · nlohmann/json · React · TypeScript · Vite · Parquet · pytest
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-5886f2d6-talents.
README
README.mdПоток — граф денежных переводов
Кого из 2248 клиентов проверять первым и почему? «Поток» помогает AML-аналитику банка восстановить наблюдаемую структуру переводов: увидеть возможные роли клиентов, сообщества, приоритеты проверки и следующие действия.
Проект команды TALENTS для HackAlem AI. Решение работает локально: Parquet → Python → C++ → веб-интерфейс и три CSV. Каждая роль — гипотеза для проверки человеком, каждый балл сопровождается объяснением.
Кейс: «Граф денег: восстановление финансовой структуры организованной группы по транзакционной сети».
Итоговая поставка: C++ 1.3.0, 2248 клиентов, 3119 направленных связей, 4840 переводов, 88 кластеров, топ-20. Полный рассчитанный пакет находится в frontend/public/data.
Быстрый просмотр · Пересчёт из Parquet · Проверка для жюри · Правила и пороги · Измеренная польза · Ограничения · Документация
Проблема и пользовательский сценарий
Основной пользователь — AML-аналитик / специалист финансового мониторинга банка. По списку исходных клиентов и выгрузке переводов ему нужно определить, какие связи и клиентов исследовать первыми, и объяснить свой выбор.
- Аналитик передаёт три Parquet-файла пайплайну через локальную папку.
- Одна команда проверяет данные, строит граф, выделяет сообщества и вызывает C++.
- Аналитик открывает очередь проверки, находит клиента по
gid, рассматривает входящие и исходящие связи. - Карточка показывает гипотезу роли, причины приоритета, ограничения данных и 1–3 следующих действия: например, запросить продолжение исходящих за границей обхода.
- Аналитик сравнивает структурные сценарии исключения top-N и сохраняет три CSV того же расчёта для дальнейшей проверки.
Загрузка Parquet выполняется через CLI; интерфейс читает подготовленный пакет. Запросы в банк или правоохранительные органы автоматически не отправляются.
Что реализовано
| Требование кейса | Реализация | Где проверить |
|---|---|---|
| Один воспроизводимый запуск | Проверка Parquet, метрики, Louvain, C++, валидация и экспорт без ручного редактирования данных | python pipeline.py |
| Роль для каждого клиента | Все 2248 узлов, включая 19 изолированных seed; роль, две оценки и объяснение до 200 символов | nodes_roles.csv |
| Объяснимые правила | Шесть формальных правил, открытые пороги, альтернативные роли и вклады в приоритет | Правила ниже, карточка клиента |
| Кластеры и гипотезы | Размер, число seed, внутренний оборот, лидеры и гипотеза назначения каждого из 88 кластеров | clusters.csv |
| Топ и визуализация | Топ-20 с причинами, направленный граф, раскраска по ролям/кластерам, поиск и фильтры | top_nodes.csv, интерфейс |
Дополнительно реализованы:
- Учёт обрыва на
depth=4и неполных входящих seed. - Карточка клиента с численными объяснениями и рекомендациями проверки; карточка связи с направлением, суммой и числом переводов.
- Достижимость из разных seed и связи с внешними кластерами.
- Устойчивость наблюдаемой сети: восемь сценариев top-1/3/5/10 по приоритету и объёму переводов, сравнение с исходным графом, переход к карточкам исключённых в модели клиентов.
- Проверка целостности пакета по SHA-256. CSV скачиваются из сохранённых байтов открытого расчёта, поэтому последующий пересчёт не подменяет его экспорт.
Быстрый просмотр
Для просмотра готового результата нужны Git, Node.js 22.14+ и npm. Python и компилятор для этого режима не нужны.
git clone https://github.com/BAITC-Hacks/hack-5886f2d6-talents.git
cd hack-5886f2d6-talents/frontend
npm ci
npm run dev
Открыть http://127.0.0.1:5173. Если репозиторий уже скачан, начните с cd frontend из его корня. Интернет нужен для первоначальной установки зависимостей; после установки расчёт и интерфейс работают без внешних сервисов.
Публичная deployed-версия не опубликована. Поставляется локальное приложение. Сборка для локального просмотра: npm run build, затем npm run preview и http://127.0.0.1:4173. Открывать index.html через file:// не следует.
Установка и полный пересчёт
Для расчёта нужны Python 3.12, CMake ≥3.16 и C++17-компилятор (GCC/Clang/MSVC). nlohmann/json включён в репозиторий. GPU, платные API, база данных, .env и ключи не требуются.
Все следующие команды выполняются из корня репозитория. Установка и сборка выполняются заранее и не входят в замер пакетного расчёта.
1. Python-зависимости
Windows / PowerShell:
py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\Activate.ps1
Если политика PowerShell запрещает активацию, вместо python в дальнейших командах используйте .\.venv\Scripts\python.exe.
Linux / macOS:
python3.12 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
source .venv/bin/activate
Версии зависимостей закреплены в requirements.txt; для установки нужен доступ к PyPI либо заранее подготовленные пакеты.
2. C++-ядро
cmake -S engine -B engine/build -DCMAKE_BUILD_TYPE=Release
cmake --build engine/build --config Release --parallel 2
На Windows есть альтернативный скрипт, который находит инструменты в PATH или установленном CLion:
powershell -ExecutionPolicy Bypass -File engine/build.ps1
Пути бинарника: MinGW/Ninja — engine/build/engine.exe, Visual Studio — engine/build/Release/engine.exe, Linux/macOS — engine/build/engine. Пайплайн автоматически проверяет эти пути. Подробности — engine/README.md.
3. Одна команда от сырых данных до результата
python pipeline.py
Вход по умолчанию: TechTask/data(1)/data. Выход: out/ — три CSV, input.json, result.json, graph.json, отчёт проверки и manifest. Успех: код завершения 0, сообщение status: complete; ожидаются 2248 узлов, 3119 рёбер, 88 кластеров и 20 строк топа.
Чтобы пересчитать и проверить пакет для интерфейса, используйте вместо предыдущей команды:
python prepare_ui_data.py
Она выполняет весь пайплайн, обновляет frontend/public/data/ и дополнительно проверяет результат, исходные файлы и использованный бинарник. Ожидаются complete и passed. После успеха запустите npm run dev в папке frontend или нажмите «Обновить файлы» в открытом UI.
На Windows перед пересчётом остановите Vite через Ctrl+C: ранее наблюдалась блокировка файла. Публикация повторяет временные ошибки Windows 5/32/33 с общим бюджетом до 3 секунд; постоянная ошибка остаётся ошибкой. Для npm run preview после пересчёта требуется новая npm run build, поскольку preview читает копию из dist/data.
Другой вход, выход или конфигурация:
python pipeline.py --data "TechTask/data(1)/data" --core engine/build/engine.exe --out out
python pipeline.py --core-config overrides.json --top 50 --out out-custom
Замените путь бинарника для своей системы. Конфигурация по умолчанию — engine/config/default.json; для данной выгрузки сохраняйте max_depth=4. Указанный в --core-config файл должен существовать.
Как проверить решение
Автоматическая проверка поставки
После установки Python-зависимостей:
python verify_outputs.py --data "TechTask/data(1)/data"
Проверяются все семь хэшей артефактов, исходные Parquet, JSON/CSV, набор клиентов, кластеры, топ и все восемь сценариев устойчивости по независимому эталону NetworkX. Ожидаемый результат: status: passed, engine_version: 1.3.0, resilience_scenarios_checked: 8, is_demo: false.
Для своего нового расчёта добавьте --out out --core engine/build/engine.exe. Хэш локально пересобранного бинарника может отличаться от бинарника опубликованной поставки: --core должен указывать именно на тот файл, которым получен проверяемый комплект. Полную проверку новой поставки с правильным бинарником автоматически делает prepare_ui_data.py.
Сценарий для жюри: около пяти минут
- Выполнить живой пересчёт
python prepare_ui_data.py, затем открыть интерфейс. Проверить 2248 клиентов / 3119 связей / 88 кластеров и топ-20. - Найти следующие
gidи сопоставить карточки с ожидаемыми фактами:
| Клиент | Ожидаемый результат | Смысл проверки |
|---|---|---|
100000000331309100 | coordinator; достижим из 7 seed, связан с 13 внешними кластерами, 5 отправителей и 99 получателей | Почему узел первым попадает в очередь; структурная роль остаётся гипотезой |
100000008692291100 | transit; вход 160 000, выход 156 000 KZT, отношение 0,975 | Близость сумм и необходимость проверки дат; связь к 100000004418967100 — 100 000 KZT, 1 операция |
100000003037476100 | consolidator; depth=4, 3 отправителя, вход 555 000 KZT | Ноль наблюдаемых исходящих на границе не превращает клиента в terminal |
- Открыть «Устойчивость наблюдаемой сети», выбрать N=10 и переключить способы отбора: крупнейшая компонента 1877 → 1420 по приоритету и 1877 → 1502 по объёму. Открыть карточку одного из выбранных клиентов, затем «Показать исходный граф».
- Найти произвольный
gid, предложенный жюри; объяснить роль по числам карточки. Запасной случай —100000000456947100: изолированный seed,peripheral, приоритет 0; он сохранён в графе. - Скачать
nodes_roles.csv,clusters.csv,top_nodes.csv; ожидаются 2248 / 88 / 20 строк данных соответственно, без учёта заголовков.
Эти gid служат примерами проверки; алгоритмы не содержат списков «правильных ответов». Подробный сценарий демо и разбор контрольных клиентов.
Тесты и повторяемость
Из корня, после сборки ядра и установки основных зависимостей:
python -m pip install -r requirements-dev.txt
python -m pytest -q
python engine/tests/test_engine.py engine/build/engine.exe -v
python engine/tests/check_pipeline.py engine/build/engine.exe
Для Visual Studio/Linux/macOS замените путь ядра, как указано выше. Последняя команда заново рассчитывает полный датасет в отдельной папке engine/test-output/pipeline-integration/; ожидаются status: passed, пустые failures и warnings.
Из frontend/:
npm test
npm run build
Подтверждённые проверки финальной версии: 333 теста Python, 43 теста C++ и 35 тестов UI прошли без пропусков; сборка интерфейса успешна. Без собранного C++ реальные интеграционные тесты Python явно пропускаются — такой запуск не заменяет полную приёмку.
Приёмка данных и ядра · Приёмка финального интерфейса · История проверки чистой установки.
Правила ролей и приоритета
Правила применяются ко всем клиентам одинаково. Самопереводы сохраняются в исходных данных, но исключаются из признаков ролей и приоритета.
Обозначения: I/O — наблюдаемые входящие/исходящие суммы без самопереводов; D_in/D_out — число разных внешних отправителей/получателей; V=max(I,O); P — число уникальных внешних контрагентов; S — число других seed, из которых клиент достижим по направлению рёбер; B — число внешних кластеров среди его непосредственных контрагентов.
Q(X) — доля положительных значений признака по всему графу, не превышающих X. Для нуля Q=0. sat(x,t)=min(1,x/t). Seed не засчитывается сам себе даже при цикле.
Выбор основной роли
Первое сработавшее правило в таблице определяет основную роль; остальные сохраняются в role_candidates.
| Порядок | Роль | Условие по умолчанию |
|---|---|---|
| 1 | coordinator — структурно связующий узел | S≥3, B≥2, D_in≥2, D_out≥2, Q(V)≥0.75 |
| 2 | consolidator — признаки сбора средств | D_in≥3, D_in>D_out, I>0, Q(I)≥0.5 |
| 3 | distributor — признаки распределения | D_out≥5, D_out>D_in, O>0, Q(O)≥0.5 |
| 4 | transit — признаки транзита | Не seed, depth<4, обе степени положительны, I>0, 0.8≤O/I≤1.2 |
| 5 | terminal — гипотеза конечного получателя в выгрузке | Не seed, depth<4, D_in>0, I>0, исходящая степень включая петли равна 0 |
| 6 | peripheral — недостаточно признаков | Ни одно предыдущее правило не выполнено |
На depth=4 отключены terminal и transit; у seed не используется отношение входящих/исходящих для этих ролей. peripheral не означает отсутствие риска, а coordinator не устанавливает организатора группы.
Оценки и объяснения
role_score ∈ [0,1] — сила соответствия эвристическому правилу, не калиброванная вероятность. Она зависит от числа контрагентов, достижимости, перцентилей сумм и близости входа/выхода для транзита. Поправка на качество наблюдения: ×0.8 для границы обхода и ×0.85 для seed; при обоих условиях применяются оба множителя. Точные формулы для всех ролей находятся в спецификации ядра.
priority_score ∈ [0,1] рассчитывается отдельно от роли:
priority = 0.35 × sat(S, 5)
+ 0.30 × Q(V)
+ 0.20 × Q(P)
+ 0.15 × sat(B, 3)
Топ сортируется по неокруглённому приоритету, при равенстве — по возрастанию числового gid. evidence объясняет роль, why — очередь проверки, priority_breakdown хранит вклад каждого сигнала. next_actions задаёт 1–3 следующих проверки с учётом недостающих наблюдений. Пороговые значения и веса сохраняются в meta.config каждого расчёта.
Кластеризация
Louvain применяется к неориентированной взвешенной проекции: вес пары равен сумме переводов в двух направлениях. Петли исключаются только из проекции, изолированные клиенты получают отдельные кластеры. seed=42, resolution=1.0, порядок данных фиксирован. Исходный граф, признаки ролей и достижимость сохраняют направление переводов.
Внутренний оборот кластера считается по исходным направленным рёбрам один раз, включая петли. Лидеры — до пяти клиентов по приоритету; hypothesis описывает возможное назначение по составу ролей и ограничениям данных. Кластер не является доказанной организованной группой.
Измеренная польза и отличие подхода
Отбор учитывает не только объём, но и связь нескольких исходных клиентов, внешние кластеры и число контрагентов. Пользователь получает объяснение каждого выбора и может сравнить его с простой альтернативой.
Эксперимент на всех 2248 клиентах: при одинаковом N виртуально исключили выбранные узлы и их связи. Исходная крупнейшая слабая компонента — 1877 клиентов.
| N | Крупнейшая компонента после отбора по приоритету | После отбора по объёму |
|---|---|---|
| 1 | 1782 | 1782 |
| 3 | 1655 | 1705 |
| 5 | 1561 | 1620 |
| 10 | 1420 | 1502 |
Для N=10 наш отбор уменьшает крупнейшую компоненту на 457 клиентов, выбор по объёму — на 375: разница 82 клиента при одинаковом числе выбранных карточек. Одновременно выбор по объёму охватывает больше прошлых операций: 103,37 млн KZT против 88,06 млн KZT. Преимущество по одной метрике не переносится автоматически на другую.
Все восемь сценариев и baseline независимо сверены с Python/NetworkX. Повторить сравнение:
python engine/tests/benchmark_benefit.py --engine engine/build/engine.exe --require-engine-resilience --runs 5
Вновь используйте путь бинарника своей системы. Полная методика, таблица, охват seed и ограничения.
Граница вывода: это структурный эксперимент на неполной наблюдаемой сети. Роли, баллы и кластеры после исключения не пересчитываются. Направление игнорируется только для слабой связности; суммы и рёбра сохраняют направления. Исключение в модели не доказывает прекращение переводов, а прошлый оборот не является предотвращённым ущербом. Новизна продукта — сочетание объяснимой очереди, учёта неполноты и проверяемого сравнения стратегий; мировой новизны графовых алгоритмов не заявляем.
Производительность на предоставленном объёме
| Измерение | Результат | Границы замера |
|---|---|---|
| Полная подготовка пакета 1.3.0 и проверка доставки | 5,660 с | Локальный Windows-запуск Армана, после установки и сборки; отчёт |
| C++ целиком, медиана пяти запусков | 0,648 с | Локальный Windows-запуск Артура: запуск процесса, JSON I/O и анализ; методика |
Требование кейса — полный пересчёт не более 300 секунд. У supervisor установлен общий лимит 300 секунд, у ядра — 120 секунд. Превышение бюджета завершает расчёт ошибкой; принудительное прерывание supervisor возвращает код 124. Это замеры на данном графе и локальных машинах, а не гарантия времени для любого оборудования или миллиона узлов.
Технологии и архитектура
| Компонент | Технологии | Ответственность |
|---|---|---|
| Подготовка и экспорт | Python 3.12, pandas, NumPy, PyArrow, SciPy, NetworkX, jsonschema | Parquet, проверки, базовые метрики, Louvain, запуск ядра, CSV/JSON и manifest |
| Аналитическое ядро | C++17, STL, CMake, nlohmann/json 3.12.0 | Направленная достижимость, роли, приоритет, объяснения, следующие действия, устойчивость |
| Интерфейс | React, TypeScript, Vite, Cytoscape.js, lucide-react | Граф, поиск, карточки, фильтры, сценарии и выгрузки |
| Проверки | pytest, Python unittest, Node test runner/tsx, JSON Schema, независимый NetworkX | Контракты, крайние случаи, согласованность данных и интеграция |
Версии Python закреплены в requirements.txt, версии frontend — в package-lock.json. Код, лицензии и происхождение компонентов раскрыты в THIRD_PARTY.md.
flowchart LR
A["3 исходных Parquet"] --> B["Python: проверки и метрики"]
B --> C["Louvain: кластеры"]
C --> D["input.json"]
D --> E["C++: роли, приоритет, объяснения, устойчивость"]
E --> F["result.json"]
F --> G["Python: валидация и экспорт"]
G --> H["3 CSV + graph.json + manifest"]
H --> I["React: граф и очередь проверки"]
Python вызывает engine input.json result.json. В JSON gid, src, dst — строки канонического int64; соединение результатов идёт по gid, без преобразования в JavaScript Number. UI отображает рассчитанные значения и не пересчитывает роли. Контракты: Python/UI, C++, устойчивость.
Публикация пишет manifest последним, но не является атомарной заменой всего каталога. UI сверяет SHA-256 graph и трёх CSV, а также повторно читает manifest; несогласованный пакет отклоняется. Два процесса с одним --out одновременно запускать нельзя. JSON/CSV опубликованного пакета отмечены в .gitattributes для сохранения байтов и целостного разрешения конфликтов.
AI и внешние сервисы. Все три участника использовали OpenAI Codex как AI-агента при разработке, тестировании и подготовке документации. В работающем продукте используются графовые алгоритмы и открытые эвристики; обученная ML-модель и внешний LLM API не используются. Данные клиентов не обогащаются внешними источниками, облачный кластер и API-ключи не нужны.
Данные, интеграции и выходные файлы
Предоставленные организаторами обезличенные данные находятся в TechTask/data(1)/data/, исходный стартер — в TechTask/starter(1)/starter/, Word-ТЗ — в TechTask. Python развивает функции загрузки, построения графа и базовых метрик из стартера в модуле hackalem/data.py. Обязательные проверки: уникальность gid и направленных пар, концы рёбер, типы, глубины, конечность сумм, точное число транзакций и суммы по каждой паре с допуском 0,01 KZT.
| Источник | Строк | Поля |
|---|---|---|
nodes.parquet | 2248 | gid, depth, is_seed |
edges.parquet | 3119 | src, dst, sum_kzt, n_tx, depth |
transactions.parquet | 4840 | src, dst, date, sum_kzt |
Период — июль 2026; 81 seed; обход только по исходящим переводам на четыре колена; только внутрибанковские операции от 5000 KZT. Все узлы, включая 19 изолированных seed, включены до добавления рёбер. Поэтому полный граф содержит 35 слабых компонент: 16 с рёбрами и 19 одиночных, а не только 16 компонент из описания связанной части. 88 Louvain-кластеров — другой вид разбиения.
Схемы обязательных CSV фиксированы:
| Файл | Строк данных | Колонки в порядке выгрузки |
|---|---|---|
| nodes_roles.csv | 2248 | gid, role, role_score, cluster_id, priority_score, evidence |
| clusters.csv | 88 | cluster_id, n_nodes, n_seed, sum_kzt_internal, top_gids, hypothesis |
| top_nodes.csv | 20 | rank, gid, role, priority_score, why |
CSV: UTF-8, разделитель — запятая; top_gids — JSON-массив строк внутри ячейки. В CSV gid записан точным десятичным int64 без .0; при чтении сохраняйте его строкой или int64, не float. evidence и why — непустые объяснения до 200 Unicode-символов. Для каждого клиента ровно одна основная роль, обе оценки в диапазоне 0–1.
Дополнительные артефакты: input.json — вход ядра; result.json — его исходный ответ; graph.json — данные UI; validation.json — проверка исходных данных; run_manifest.json — конфигурация, версии, времена и SHA-256 исходников, бинарника и артефактов. Локальные логи core.*.log не включены в Git. Данные и синтетические gid предоставлены для хакатона; команда не заявляет авторство датасета.
Ограничения
- У 444 клиентов
depth=4: исходящие за границей выгрузки неизвестны. Входящие seed неполны; полные балансы, другие банки, другие периоды и суммы ниже порога недоступны. - Нет размеченных ролей.
role_scoreне является проверенной вероятностью, accuracy/precision/recall не измерены. Достижимость не устанавливает хронологию и происхождение конкретных денег. - Временной транзит за 1–2 дня, автоматический поиск повторяющихся маршрутов/циклов, отдельная ML-детекция аномалий и чат-ассистент не реализованы. Даты транзакций загружаются, но не используются для подтверждения сквозного движения средств.
- Экономия рабочего времени AML-аналитика не измерена. Автоматические проверки и браузерная приёмка описаны в отчётах; замер с человеком и новое подтверждение сохранения трёх CSV на диск пока не получены.
- Текущая версия рассчитана на пакетную локальную обработку. Нет потокового сервиса, авторизации пользователей и промышленной банковской интеграции; JSON и граф находятся в памяти. Большой JS-бандл даёт предупреждение Vite при сборке.
- Синтетические файлы
examples/используются в тестах и не заменяют полную поставку. Явный режимpython pipeline.py --demo --out out-demoзапускает отдельную Python-эвристику с меткой demo; автоматического переключения на неё при ошибке C++ нет.
Развитие и масштабирование до 1 млн узлов
Текущая сложность направленной достижимости при N клиентах, M рёбрах и S seed — O(S·(N+M)). Новый блок устойчивости добавляет O(N log N + 9·(N+M)). Точные ограничения памяти и сортировок — в описании ядра.
| Ограничение текущей версии | Следующий технический шаг | Как проверять результат |
|---|---|---|
| Parquet/JSON и Python-граф целиком в памяти | Потоковая агрегация Arrow/DuckDB, компактные CSR-массивы и обмен Arrow/Parquet | Время и пиковая RAM на 100 тыс. и 1 млн узлов |
| Отдельный BFS для каждого seed | Битовые наборы достижимости по конденсации сильно связных компонент; при необходимости приближения | Совпадение с точным эталоном на контрольных графах, цена памяти |
| Все узлы загружаются в браузер | Серверная выдача окрестностей, агрегаты сообществ, уровни детализации | Время открытия карточки и объём ответа |
| Эвристики без разметки | Проверка гипотез предметными экспертами, временные признаки, версионирование правил | Размеченная выборка, ошибки и время решения задач аналитика |
| Локальный инструмент | Контроль доступа, аудит действий и подключение к разрешённым банковским выгрузкам | Пилот с AML-командой и проверка требований организации |
Это план развития; миллион узлов и промышленный пилот ещё не испытывались. Предельное время пять минут на новом масштабе требует отдельного подтверждения.
Структура репозитория и команда
TechTask/ исходное ТЗ, данные и стартер организаторов
engine/ C++-ядро, конфигурация, JSON Schema и тесты
hackalem/ Python: данные, экспорт, контракты и эталон
pipeline.py одна команда пакетного расчёта
prepare_ui_data.py пересчёт и проверка пакета для UI
verify_outputs.py независимая проверка опубликованных файлов
frontend/ веб-интерфейс, тесты и public/data
examples/ маленький синтетический пример интеграции
tests/ Python-тесты и проверки настоящего C++
docs/ измерения, навигация и архив прежних отчётов
team/ материалы участников и фактические отчёты приёмки
| Участник | Вклад |
|---|---|
| Артур | C++: признаки, роли, приоритет, объяснения, следующие действия, устойчивость и тесты |
| Арман | Parquet, метрики, Louvain, интеграция, валидация, воспроизводимость и полный пакет |
| Савелий | Интерфейс, граф, карточки, понятные объяснения, устойчивость, CSV и браузерная приёмка |
Все документы · Демо · Результаты эксперимента · Сторонние материалы и использование AI.
Авторы коммитов
История коммитов
- 2026-09-23 17:36Finalize judge-facing README with reproducible workflow and verified resultsArtur
- 2026-09-23 17:22Record frontend acceptance of the published resilience bundleTALANTPMS
- 2026-09-23 17:17Merge remote-tracking branch 'origin/main' into saveliy/frontendTALANTPMS
- 2026-09-23 17:16Refine resilience navigation and validate graph metadata integrationTALANTPMS
- 2026-09-23 17:14Merge repository cleanup and retain completed delivery statusArman
- 2026-09-23 17:13Deliver verified C++ 1.3 resilience bundle with integrated UIArman
- 2026-09-23 17:13Clean repository metadata and consolidate historical reportsArtur
- 2026-09-23 17:06Merge remote-tracking branch 'origin/main' into saveliy/frontendTALANTPMS
Все коммиты (37)
- 2026-09-23 17:06Explain client priorities in plain language and display prepared resilience scenariosTALANTPMS
- 2026-09-23 17:03Record successful integrated C++ and Python acceptanceArtur
- 2026-09-23 17:01Merge remote-tracking branch 'origin/main'Artur
- 2026-09-23 17:01Organize documentation and add validated network resilience experimentsArtur
- 2026-09-23 17:00Validate resilience metadata and bound Windows publication retriesArman
- 2026-09-23 16:44Plan final 80-minute resilience feature and team acceptanceArtur
- 2026-09-23 16:34Merge team documentation with frontend Word auditTALANTPMS
- 2026-09-23 16:32Audit frontend against the original Word requirementsTALANTPMS
- 2026-09-23 16:31Audit integrated delivery against task and judging criteriaArtur
- 2026-09-23 16:25Document Arman final reproduction and integrated C++ 1.2 deliveryArman
- 2026-09-23 16:21Verify retained analyst actions against the original example snapshotArman
- 2026-09-23 16:18Merge analyst UI and keep generated data snapshots atomicArman
- 2026-09-23 16:13Integrate C++ 1.2 analyst actions with verified frontend deliveryTALANTPMS
- 2026-09-23 16:10Merge C++ 1.2.0 and deliver verified analyst next actionsArman
- 2026-09-23 16:06Add directed transfer details and optional analyst next actionsTALANTPMS
- 2026-09-23 16:04Add explainable analyst next actions in C++ 1.2.0Artur
- 2026-09-23 16:01Preserve optional analyst next actions through Python pipelineArman
- 2026-09-23 15:48Verify UI data snapshots and document final team prioritiesArtur
- 2026-09-23 15:28Merge latest analytics and verify frontend compatibilityTALANTPMS
- 2026-09-23 15:15Add Saveliy analyst UI with directed graph, client priorities and CSV exportTALANTPMS
- 2026-09-23 15:07Audit latest pipeline against task requirements and refine cluster explanationsArtur
- 2026-09-23 14:55Deliver verified C++ dataset for UI and document reproducibilityArman
- 2026-09-23 14:50Prepare technical review instructions and verify clean repository buildArtur
- 2026-09-23 14:41Integrate C++ 1.1 with Python pipeline and document team next stepsArtur
- 2026-09-23 14:27Integrate Python pipeline with Arthur C++ engine contractArman
- 2026-09-23 14:09Add Python data pipeline and integration handoff for ArthurArman
- 2026-09-23 13:56Add C++ analytics engine and teammate integration guidesArtur
- 2026-09-23 13:26Include extracted archive metadata filesArtur
- 2026-09-23 13:24Add hackathon brief, dataset, and starter codeArtur
Структура репозитория (130 файлов)
.gitattributes .gitignore CONTRACT.md README.md THIRD_PARTY.md TechTask/HackAlem AI_ Граф денег_ восстановление финансовой структуры организованной группы по транзакционной сети.docx TechTask/README.md TechTask/data(1)/data/edges.parquet TechTask/data(1)/data/nodes.parquet TechTask/data(1)/data/transactions.parquet TechTask/starter(1)/starter/README.md TechTask/starter(1)/starter/requirements.txt TechTask/starter(1)/starter/starter.py demo_core.py docs/EVIDENCE.md docs/README.md docs/archive/engine/CLEAN_CHECK.md docs/archive/engine/INTEGRATION.md docs/archive/engine/TZ_AUDIT.md docs/archive/engine/VALIDATION.md docs/archive/engine/reports/clean-check-c7f7bb4.json docs/archive/engine/reports/full-tz-audit.json docs/archive/frontend/VERIFICATION.md docs/archive/frontend/WORD_TZ_CHECK.md docs/archive/team/Artur.md docs/archive/team/CURRENT_REVIEW.md docs/archive/team/FINISH_PLAN.md docs/archive/team/NEXT_STEPS.md docs/archive/team/TECHNICAL_REVIEW.md docs/archive/team/artur/NEXT_ACTIONS.md engine/CMakeLists.txt engine/CONTRACT.md engine/README.md engine/build.ps1 engine/config/default.json engine/examples/input.json engine/examples/result.json engine/schemas/input.schema.json engine/schemas/result.schema.json engine/src/analysis.cpp engine/src/analysis.hpp engine/src/default_config.hpp.in engine/src/main.cpp engine/src/version.hpp.in engine/tests/benchmark_benefit.py engine/tests/check_dataset.py engine/tests/check_pipeline.py engine/tests/requirements.txt engine/tests/test_engine.py engine/third_party/README.md engine/third_party/nlohmann/LICENSE.MIT engine/third_party/nlohmann/json.hpp examples/clusters.csv examples/graph.json examples/input.json examples/nodes_roles.csv examples/result.json examples/top_nodes.csv frontend/.gitignore frontend/DEMO.md frontend/README.md frontend/RESILIENCE_CHECK.md frontend/index.html frontend/package-lock.json frontend/package.json frontend/public/data/clusters.csv frontend/public/data/graph.json frontend/public/data/input.json frontend/public/data/nodes_roles.csv frontend/public/data/result.json frontend/public/data/run_manifest.json frontend/public/data/top_nodes.csv frontend/public/data/validation.json frontend/public/favicon.svg frontend/src/App.tsx frontend/src/ClientDetails.tsx frontend/src/GraphView.tsx frontend/src/ResiliencePanel.tsx frontend/src/TransferDetails.tsx frontend/src/bundle.test.ts frontend/src/bundle.ts frontend/src/data.test.ts frontend/src/data.ts frontend/src/explanations.test.ts frontend/src/explanations.ts frontend/src/main.tsx frontend/src/resilience.test.ts frontend/src/resilience.ts frontend/src/styles.css frontend/src/transfers.test.ts frontend/src/transfers.ts frontend/src/vite-env.d.ts frontend/tsconfig.json frontend/vite.config.ts hackalem/__init__.py hackalem/data.py hackalem/export.py hackalem/protocol.py hackalem/resilience.py hackalem/resilience_reference.py make_examples.py pipeline.py prepare_ui_data.py pytest.ini requirements-dev.txt requirements.txt team/DEMO_CASES.md team/LAST_80_MINUTES.md team/README.md team/RESILIENCE_CONTRACT.md team/USABILITY_CHECK.md team/arman/DATA_AND_CLUSTERS.md team/arman/FINAL_RUN.md team/arman/LAST_80_MINUTES.md team/arman/NEXT_ACTIONS.md team/arman/README.md team/arman/REPRODUCIBILITY.md team/arman/RESILIENCE_CHECK.md team/artur/DEFENSE.md team/artur/LAST_80_MINUTES.md team/saveliy/LAST_80_MINUTES.md team/saveliy/README.md team/saveliy/graph.example.json tests/test_bundle.py tests/test_cluster_hypotheses.py tests/test_cpp_integration.py tests/test_pipeline.py tests/test_publication.py tests/test_resilience_reference.py verify_outputs.py
Ветки (2)
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.