AAYMA
RU
Войти

Граф денег — EpiQ

AML-инструмент строит граф транзакций, назначает участникам объяснимые роли (аккумулятор, распределитель, транзит, координатор и др.) и приоритет…

Доведённый продукт
Команда «EPIQ» 4💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: EPIQ
Кейс HackAlem.ai: Финансы — Freedom
Стадия: Доведённый продукт

Задача кейса: «Граф денег»: восстановить структуру организованной группы по сети транзакций (AML)

Суть

AML-инструмент строит граф транзакций, назначает участникам объяснимые роли (аккумулятор, распределитель, транзит, координатор и др.) и приоритет проверки. Результаты показываются в Streamlit с визуализацией маршрутов денег и AI-ассистентом.

Как устроено

Три Parquet-файла (узлы, связи, транзакции) проходят валидацию, затем строится направленный взвешенный граф NetworkX. Для узлов считаются оборот, связность, PageRank, приближённое посредничество и достижимость от seed-узлов. Кластеры выделяются алгоритмом Louvain внутри слабосвязных компонент. Роли назначаются правилами, priority_score взвешивает охват seed 30%, оборот 25%, посредничество 20%, связность 15% и силу роли 10%. Дополнительно ищутся повторяющиеся цепочки A→B→C с задержкой 1–2 дня и отношением выхода ко входу 0,8–1,2, циклы через сильносвязные компоненты и проводится стресс-тест удаления топ-узлов. AI-ассистент на GPT-5 mini вызывает только разрешённые функции чтения графа.

Ключевые решения

  • NetworkX
  • Louvain
  • PageRank
  • betweenness centrality
  • SCC cycles
  • rule-based roles
  • weighted priority score
  • repeated A→B→C chains
  • robustness stress-test
  • function calling

Особенности

Для каждой позиции в рейтинге видна разбивка приоритета на пять слагаемых и сравнение с другим кандидатом. Для подозрительных связей показываются даты и суммы. Примеры для защиты выбираются из результатов автоматически. Всё запускается одной командой python run.py. LLM видит только результаты разрешённых функций, аргументы проверяются по JSON Schema.

Стек

Python · pandas · NumPy · PyArrow · DuckDB · NetworkX · SciPy · Streamlit · PyVis · OpenAI SDK · pytest · GitHub Actions

Модели

GPT-5 mini


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-144ec83b-epiq.

README

README.md

Граф денег — EpiQ

CI

От исходных клиентов — к цепочке переводов и обоснованному списку проверок.

О проекте

MVP для кейса Freedom на HackAlem AI. Инструмент помогает AML-аналитику исследовать обезличенную транзакционную сеть до четырёх колен: найти точки сбора и распределения денег, изучить связи и выбрать участников для углублённой проверки.

Аналитик получает приоритетный список, числовое обоснование роли, историю операций и рекомендации следующего запроса. Результаты — гипотезы по наблюдаемым данным, а не установление личности, виновности или фактического руководства группой. Это прототип команды, а не официальный сервис банка.

Что реализовано

  • Проверка трёх Parquet-файлов: обязательные поля, уникальность узлов и пар связей, положительные суммы, наличие участников, согласованность сумм и числа операций.
  • Направленный взвешенный граф; признаки оборота, связности, PageRank, приближённого посредничества и достижимости из исходных узлов — seed.
  • Кластеры Louvain внутри слабосвязных компонент.
  • Шесть объяснимых ролей: аккумулятор, распределитель, транзит, конечный узел, координатор, периферия. Приоритет и краткое обоснование для каждого узла.
  • Топ-20 в CSV; до 200 кандидатов после фильтров в интерфейсе; поиск по gid.
  • Фильтры ролей, приоритета и сигналов; сценарии поиска сборщиков, дальнейшего движения денег и границы наблюдения.
  • Восемь представлений: «Сеть», «След денег», «Общие получатели», «Операции», «Маршруты», «Устойчивость», «Связи», «Кластеры».
  • Граф окружения на один или два шага, до 60 связей, масштабирование и перемещение. Цвет узлов обозначает роль; связи с сигналами подсвечиваются и имеют пояснения.
  • Маршруты A→B→C с примерами дат, сумм и задержек; неизвестный порядок операций одного дня явно отмечается.
  • Общие получатели для 2–5 выбранных seed: направленные пути до четырёх переходов из каждого исходного клиента, суммы связей и экспорт доказательных путей.
  • Повторяющиеся цепочки: минимум два непересекающихся эпизода A→B→C, задержка 1–2 дня, отношение выхода ко входу 0,8–1,2; даты и суммы каждого эпизода.
  • Разбор места в рейтинге: вклады пяти факторов и сравнение с другим кандидатом из топ-20.
  • Три примера для защиты автоматически выбираются из результатов и сохраняются в out/demo_cases.md.
  • Временные сигналы, синхронные плательщики, дневные всплески, аномальность относительно своего колена и участие в сильносвязных группах с циклами.
  • Стресс-тест связности после удаления топ-1, 5, 10 и 20 узлов.
  • Карточка участника с пробелами данных и рекомендацией следующего запроса.
  • Перечень клиентов для проверки и/или запроса в правоохранительные органы, который аналитик формирует вручную и скачивает в CSV.
  • AI-ассистент OpenAI: вопросы обычным языком, контекст выбранного узла, короткая история диалога и ссылки на результаты разрешённых функций анализа. Локальный режим по ключевым словам доступен без API.

Как работает решение

  1. Организатор предоставляет узлы, агрегированные связи и отдельные транзакции.
  2. Пайплайн проверяет вход, строит граф и рассчитывает признаки.
  3. Правила назначают роли, кластеры, приоритеты и объяснения.
  4. Результаты сохраняются в CSV; сайт читает их и историю транзакций.
  5. Аналитик выбирает сценарий и участника, изучает граф, путь от seed и операции.
  6. Для связей с сигналами видит суммы и даты, проверяет ограничения.
  7. Принимает решение, добавляет участника в перечень и выгружает его.

Система не отправляет запросы в правоохранительные органы и не блокирует счета.

Правила и приоритет

priority_score лежит в диапазоне 0–1 и объединяет охват seed (30%), оборот (25%), посредничество (20%), связность (15%) и силу роли (10%). Изолированным узлам назначается нулевой приоритет. В карточке «Почему такое место в топе» показаны слагаемые, их максимумы и разница с выбранным кандидатом. Охват ограничен пятью seed; остальные структурные признаки нормируются по перцентилям среди положительных значений. При одинаковом приоритете применяется порядок по gid. Слагаемые сохранены в node_features.csv.

РольОсновные условия допуска
АккумуляторНе менее 3 разных плательщиков
РаспределительНе менее 5 разных получателей
ТранзитЕсть вход и выход; выход/вход 0,8–1,2; не seed и не depth=4
Конечный узелВыход до 10% входа; ещё 2 дня наблюдения после последнего входа; не seed и не depth=4
КоординаторДостижим из 2+ seed, верхние 10% по посредничеству, связывает 2+ соседних кластера
ПериферияНи одно содержательное правило не выполнено

Это условия допуска: при нескольких подходящих ролях учитывается сила правил. Формулы находятся в scoring.py, пояснения — в архитектуре.

Технологии

КомпонентНазначение
Python 3.10+Расчётное ядро и запуск
pandas, NumPyОбработка таблиц и вычисления
PyArrow, DuckDBЧтение Parquet; DuckDB — резервный способ чтения в ядре
NetworkX, SciPyГрафовые алгоритмы и расчётная поддержка
Streamlit 1.64+Локальный веб-интерфейс
PyVis / vis-networkИнтерактивный граф и свечение связей
OpenAI SDK / Responses API, GPT-5 miniОпциональный AI-ассистент с вызовом локальных функций анализа
JSON SchemaПроверка аргументов инструментов, типов и лимитов
pytestАвтоматические проверки
GitHub ActionsCI с pytest на Python 3.12 / Ubuntu

Диапазоны версий: requirements.txt, pyproject.toml. Роли и приоритеты рассчитываются правилами, модели на данных проекта не обучались. Для AI-ассистента используется gpt-5-mini через OpenAI Responses API; нужен отдельный API-ключ, интернет и доступные кредиты. Расчёт, граф и локальный режим помощника работают без ключа и внешних API.

Архитектура

flowchart LR
    A[Три Parquet-файла] --> B[Проверка входных данных]
    B --> C[Граф и признаки]
    C --> D[Кластеры и правила ролей]
    C --> E[Маршруты и устойчивость]
    D --> F[CSV и отчёты JSON]
    E --> F
    F --> G[Streamlit]
    A --> G
    G --> H[Решение аналитика и CSV перечня]
    G --> I[AI-ассистент OpenAI]
    I --> J[Разрешённые функции чтения графа]
    F --> J
    J --> I

Расчёт отделён от сайта. Интерфейс читает готовые результаты и дополнительно проверяет временные сигналы на маршрутах показанного окружения для подсветки связей.

run.py                           подготовка окружения, расчёт и запуск сайта
app.py                           интерфейс аналитика
.streamlit/config.toml           тема интерфейса
src/money_graph/
  io_validation.py               чтение, валидация и хеши входных файлов
  graph_features.py              граф, признаки, кластеры
  scoring.py                     роли, приоритеты, обоснования
  advanced_analysis.py           двухшаговые маршруты и устойчивость
  route_evidence.py              проверка пар операций и сигналы связей
  repeated_routes.py             повторения цепочек с независимыми окнами дат
  investigations.py              общие получатели и ограниченный обход от seed
  investigation_ui.py            интерфейс общих получателей и повторений
  demo_cases.py                  выбор проверяемых примеров из текущих данных
  assistant_tools.py             проверяемые функции чтения графа для AI
  ai_assistant.py                ограниченный цикл вызовов OpenAI Responses API
  assistant_ui.py                диалог, разрешение передачи данных, источники ответов
  pipeline.py                    оркестрация и запись результатов
  cli.py                         командный интерфейс расчёта
tests/                           проверки правил, результатов и маршрутов
docs/                            архитектура, аудит ТЗ и сценарий защиты

Установка и запуск

1. Подготовьте окружение и репозиторий

Нужны Python 3.10+ с pip и venv, файлы данных организатора и интернет для первой установки зависимостей. Git нужен только для клонирования; вместо него можно скачать и распаковать ZIP репозитория.

git clone https://github.com/BAITC-Hacks/hack-144ec83b-epiq.git
cd hack-144ec83b-epiq

2. Подготовьте данные

Создайте папку data и распакуйте в неё три файла. Ниже показана структура, это не команды терминала:

data/
  nodes.parquet
  edges.parquet
  transactions.parquet

3. Запустите одной командой

Из папки репозитория:

python run.py

Скрипт проверит наличие данных и свободного порта, создаст .venv при необходимости, установит недостающие зависимости, рассчитает результаты и запустит сайт. Активация окружения не нужна. Откройте локальное приложение. Остановка — Ctrl+C. На Linux/macOS при необходимости используйте python3.

Повторный запуск использует установленные пакеты, если их версии подходят, и заново рассчитывает результаты. После установки пакетов расчёт работает без интернета. Установка зависимостей и расчёт проверены в отдельной копии без .venv и без готовых результатов на Windows / Python 3.14.7. Использовался тот же компьютер и доступный кэш pip; это не проверка на отдельной чистой ОС. Подробности — в отчёте проверки.

Дополнительные команды

# Только расчёт, без сайта
python run.py --no-ui

# Свои каталоги данных и результатов
python run.py --data "C:/dataset" --out "C:/results"

# Если порт 8501 занят
python run.py --port 8502

Если приложение уже работает на 8501, откройте его вместо запуска второй копии. Сообщение Missing data означает, что нужно проверить папку data или --data. При ошибке установки проверьте доступ к пакетам и совместимость версии Python.

Подключение AI-ассистента — необязательно

Создайте локальный .streamlit/secrets.toml по примеру secrets.toml.example:

OPENAI_API_KEY = "ваш_API_ключ"
OPENAI_MODEL = "gpt-5-mini"

secrets.toml исключён из Git. Также поддерживаются переменные окружения с теми же именами; они имеют приоритет. Код активации API-кредитов не является API-ключом. Официальная процедура — в OpenAI Quickstart.

Откройте «Ассистент аналитика» → «AI · OpenAI». После разрешения передачи данных введите вопрос, например «Почему выбранный участник в топе и что запросить дальше?». OpenAI получает вопрос, последние сообщения диалога, выбранный gid и ограниченные результаты функций — идентификаторы, суммы, даты и пути. Полные файлы не загружаются. При отсутствии разрешения поле AI-вопроса отключено; локальный режим остаётся доступен.

Ответ содержит ссылки [D1] и раскрываемые данные. Модель не выполняет произвольный код, не меняет граф и не отправляет запросы в другие организации. Подробнее: устройство и проверка AI-ассистента.

Как проверить решение — сценарий для жюри

  1. Подготовьте данные и выполните python run.py.
  2. Проверьте out/nodes_roles.csv, out/clusters.csv, out/top_nodes.csv. Для исходной поставки кейса ожидается 2 248 узлов и 20 строк топа; на другом наборе количество узлов определяется входом.
  3. На сайте выберите «Кто собирает деньги», затем участника из списка. Проверьте обоснование, число плательщиков, роль и приоритет.
  4. Откройте «След денег» и «Операции». Для достижимого из seed участника будет показан путь; если пути нет или выбран сам seed, появится пояснение.
  5. В «Сети» наведите на подсвеченную связь, если она есть. Янтарный означает операции в окне 0–2 дня, коралловый — также известный порядок по дням и сопоставимые суммы. Для операций одного дня порядок неизвестен.
  6. Раскройте «Почему такое место в топе»: сумма пяти вкладов должна совпадать с итогом, а сравнение — объяснять разницу с другим кандидатом.
  7. Откройте out/demo_cases.md: там находятся реальные gid, seed и даты для трёх примеров. В «Общих получателях» выберите 2–5 указанных seed, найдите сборщика и проверьте пути из каждого seed.
  8. В «Маршрутах» выберите повторяющуюся цепочку из демо и сравните даты и суммы её эпизодов с «Операциями». В «Устойчивости» изучите изменение связности.
  9. Выберите решение в карточке, нажмите «Добавить в перечень» и скачайте CSV.
  10. Откройте run_manifest.json: время расчёта, версии и SHA-256 входа. Лимит ТЗ — менее пяти минут на исходном наборе; оценивается фактический расчёт, без времени установки зависимостей.

При пустом списке ослабьте фильтры. Наличие сигнала зависит от данных. Тайминг защиты — в сценарии демо.

Автоматические тесты

После подготовки .venv, в Windows PowerShell:

.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
.\.venv\Scripts\python.exe -m pytest -q

Linux/macOS:

.venv/bin/python -m pip install -r requirements-dev.txt
.venv/bin/python -m pytest -q

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

После расчёта на реальных данных можно также проверить все восемь экранов, вклады рейтинга, выбор seed, эпизоды и добавление решения:

.\.venv\Scripts\python.exe scripts/smoke_ui.py

На Linux/macOS используйте .venv/bin/python scripts/smoke_ui.py.

Отдельная проверка настоящего API на полностью вымышленных данных (расходует кредиты):

.\.venv\Scripts\python.exe scripts/smoke_ai.py --live --synthetic

Обычные pytest и smoke_ui.py не вызывают платный API.

Данные и интеграции

Вход — локальная обезличенная выгрузка организатора. Parquet-файлы и результаты исключены из Git через .gitignore.

ФайлОбязательные поля
nodes.parquetgid, depth, is_seed
edges.parquetsrc, dst, sum_kzt, n_tx, depth
transactions.parquetsrc, dst, date, sum_kzt

gid — идентификатор участника; src / dst — отправитель / получатель; sum_kzt — сумма в тенге; n_tx — число операций; depth — колено; is_seed — исходный клиент. Пары связей и суммы должны совпадать с агрегацией транзакций. Совпадающие строки операций сохраняются с предупреждением: без transaction_id нельзя доказать, что это технические дубли.

Выходной файлСодержание
nodes_roles.csvgid, role, role_score, cluster_id, priority_score, evidence
clusters.csvРазмер, seed, внутренний оборот, лидеры и гипотеза кластера
top_nodes.csvПервые 20 узлов или все узлы, если их меньше 20
node_features.csv, edges.csvПризнаки и связи для интерфейса
route_patterns.csvДо 200 крупнейших структурных маршрутов с проверкой примеров операций
repeated_routes.csv, route_episodes.csvПовторяющиеся маршруты и отдельные датированные эпизоды, без лимита топ-200
resilience.csvРезультаты удаления топовых узлов
demo_cases.md, demo_cases.jsonПримеры сборщика, повторяющегося маршрута и границы наблюдения, если они есть в данных
quality_report.jsonПроверки входа, предупреждения и сводные показатели
run_manifest.jsonВерсия правил, SHA-256 входа, версии библиотек и длительность

Банковские API и внешнее обогащение клиентов не подключены. OpenAI — опциональная внешняя интеграция помощника; включается пользователем. Ресурсы PyVis встраиваются в HTML. Локальный запуск не является интеграцией с инфраструктурой Freedom.

Ограничения текущей версии

  • Наблюдение ограничено выгрузкой: четвёртое колено обрывается, вход seed неполон, отсутствующие переводы не восстанавливаются.
  • Порог исключения переводов ниже 5 000 KZT описан для исходной поставки кейса; приложение само такой фильтр при загрузке не применяет.
  • Нет размеченных ролей: точность, полнота обнаружения и снижение потерь не измерены. Оценки правил не являются вероятностями виновности.
  • Путь от seed структурный: хронология всей цепочки не проверяется. Проверка времени реализована для A→B→C и не доказывает движение одной и той же суммы.
  • Порядок внутри дня неизвестен. Сопоставимость 80–120% — экспертная эвристика; разбиение и объединение нескольких платежей не сопоставляются.
  • Повторения считаются консервативно: один и тот же маршрут, непересекающиеся окна дат, без увеличения счётчика от совпадающих строк. Одна операция может поддерживать разные альтернативные маршруты; их суммы нельзя складывать.
  • Общий получатель определяется по направленной достижимости из каждого seed. Это не доказательство совместного управления счетами или хронологии всей цепочки.
  • cycle_size — размер сильносвязной группы, а не длина одного простого цикла. Хронология полного кольца не проверяется.
  • Граф показывает ограниченное окружение; подсветка проверяет только его двухшаговые маршруты. Отсутствие подсветки не означает безопасность.
  • Локальный помощник понимает ключевые слова. AI-режим использует LLM и семь ограниченных функций чтения; неподдерживаемые фильтры требуют уточнения. Ответы модели могут ошибаться и должны сверяться с раскрываемыми данными. Автоматически проверяются полные gid и ссылки на источники, но не вся семантика текста.
  • AI отправляет часть данных внешнему провайдеру после разрешения пользователя. До трёх вызовов функций и четырёх API-запросов на вопрос; ошибки не повторяются автоматически. История хранится только в текущей сессии.
  • Решения хранятся в сессии Streamlit; перечень нужно выгружать в CSV. Нет постоянного хранилища дел, авторизации, разграничения прав и журнала действий.
  • Нет потоковой обработки, банковских интеграций и автоматической отправки запросов.
  • Миллионы узлов не тестировались. Зависимости заданы диапазонами версий, полноценного lock-файла окружения нет.

Развёрнутая версия

Публичный адрес deployed-версии в репозитории не указан. Доступен локальный сайт, который работает только на компьютере, где запущен проект.

Переход к миллиону узлов

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

Дополнительные материалы

В обзоре источников отделены идеи от собственной реализации. Использование стандартных алгоритмов и библиотек не означает подтверждённый результат проверки на антиплагиат.

Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
17
Авторы
1
Файлы
41
Ветки
2

Авторы коммитов

lowqrst 17

История коммитов

  • 2026-09-23 17:21feat: connect analyst assistant to OpenAI graph toolslowqrst
  • 2026-09-23 16:45feat: add evidence-based investigations and reproducible jury demolowqrst
  • 2026-09-23 16:18fix: render node tooltips with plain text line breakslowqrst
  • 2026-09-23 16:08docs: write complete Russian README for hackathon jurylowqrst
  • 2026-09-23 16:02feat: add one-command environment setup analysis and app launchlowqrst
  • 2026-09-23 15:58feat: glow suspicious graph edges with dated transaction evidencelowqrst
  • 2026-09-23 15:54style: redesign graph with Obsidian-inspired muted palettelowqrst
  • 2026-09-23 15:51feat: adapt Freedom-inspired theme and investigation scenarioslowqrst
Все коммиты (17)
  • 2026-09-23 15:45feat: validate route evidence and document open-source researchlowqrst
  • 2026-09-23 15:39feat: complete specification audit and graph analysislowqrst
  • 2026-09-23 15:15feat: add transaction tracing investigation toolslowqrst
  • 2026-09-23 15:01feat: add analyst review shortlist workflowlowqrst
  • 2026-09-23 14:52style: apply industrial dashboard design systemlowqrst
  • 2026-09-23 14:46feat: redesign Streamlit investigation dashboardlowqrst
  • 2026-09-23 14:17fix: preserve large gids in dashboard tableslowqrst
  • 2026-09-23 14:12test: validate analysis outputs and app runtimelowqrst
  • 2026-09-23 14:00feat: implement explainable money graph MVPlowqrst
Структура репозитория (41 файлов)
.github/workflows/ci.yml
.gitignore
.streamlit/config.toml
.streamlit/secrets.toml.example
README.md
app.py
docs/ai-assistant.md
docs/architecture.md
docs/demo-script.md
docs/freedom-product-fit.md
docs/open-source-review.md
docs/release-verification.md
docs/tz-compliance.md
pyproject.toml
requirements-dev.txt
requirements.txt
run.py
scripts/smoke_ai.py
scripts/smoke_ui.py
src/money_graph/__init__.py
src/money_graph/advanced_analysis.py
src/money_graph/ai_assistant.py
src/money_graph/assistant_tools.py
src/money_graph/assistant_ui.py
src/money_graph/cli.py
src/money_graph/demo_cases.py
src/money_graph/graph_features.py
src/money_graph/investigation_ui.py
src/money_graph/investigations.py
src/money_graph/io_validation.py
src/money_graph/pipeline.py
src/money_graph/repeated_routes.py
src/money_graph/route_evidence.py
src/money_graph/scoring.py
tests/test_advanced_analysis.py
tests/test_ai_assistant.py
tests/test_ai_ui.py
tests/test_investigations.py
tests/test_pipeline.py
tests/test_route_evidence.py
tests/test_scoring.py
Ветки (2)

Обсуждение 0 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.