О проекте
Команда: skywhywalker
Кейс HackAlem.ai: Финансы — Freedom
Стадия: Доведённый продукт
Задача кейса: «Граф денег»: восстановить структуру организованной группы по сети транзакций (AML)
Суть
Веб-приложение для AML-аналитика: строит направленный граф переводов, назначает счетам эвристические роли, группирует их, ранжирует очередь проверки с объяснениями и выгружает три CSV. Есть AI-помощник и ограниченный AI-агент.
Как устроено
Данные из CSV, Parquet или ZIP проверяются и превращаются в направленный граф NetworkX. Для каждого счёта считаются PageRank, посредничество, достижимость и сообщества Louvain, необычность оценивается Isolation Forest. Шесть ролей назначаются правилами, а приоритет складывается из графовых признаков, аномалии, паттернов и потоков с весами 35/25/25/15 и перенормировкой при отсутствии компонента. Агент на OpenAI Responses API в цикле вызывает read-only инструменты get_account, get_connections и get_transactions (не больше 5 вызовов и 45 секунд), а сервер сверяет факты перед выдачей.
Ключевые решения
- NetworkX
- PageRank
- betweenness
- Louvain
- Isolation Forest
- rule-based roles
- function calling
- bounded agent loop
- Cytoscape.js
Особенности
Агент ограничен по числу вызовов, обращений к модели и времени, а в интерфейсе виден журнал реальных вызовов инструментов. Следующий счёт попадает в рекомендацию, только если агент уже проверил его инструментом. Длинные GID передаются строками, чтобы JavaScript их не округлял.
Стек
Python · FastAPI · Pandas · NumPy · PyArrow · scikit-learn · NetworkX · React 19 · Vite 7 · Tailwind CSS 4 · Cytoscape.js · pytest
Модели
gpt-4.1-mini (OpenAI Responses API)
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-7c0a290a-skywhywalker.
README
README.mdMoneyGraph AI — кого проверить первым?
Веб-приложение для анализа денежных переводов и подготовки очереди проверки счетов. Проект создан для финансового кейса Freedom «Граф денег» на HackAlem AI.
1. Проблема и решение
AML-аналитик — специалист по противодействию отмыванию денег — получает исходные счета и выгрузку переводов. Ему нужно восстановить связи, найти возможных сборщиков и распределителей средств и решить, кого проверять дальше. Вручную сопоставлять операции, роли и цепочки сложно.
MoneyGraph AI строит направленный граф, рассчитывает признаки счетов, назначает предполагаемые роли и ранжирует счета для ручной проверки. Для каждого вывода можно открыть основания: показатели, правила и исходные операции. Результаты выгружаются в три CSV.
Ценность: аналитик получает не только изображение сети, но и последовательность действий: выбрать счёт → проверить основания → изучить связанные счета → сохранить результаты.
Это аналитический прототип, а не система установления виновности. Роль и приоритет — гипотезы для проверки, не вероятность преступления. Приложение не блокирует счета и не выполняет банковских операций.
2. Что реализовано
- Загрузка данных: встроенный учебный набор, CSV, отдельный Parquet с транзакциями и ZIP с тремя таблицами официального кейса. Проверяются структура, идентификаторы, суммы, даты и согласованность таблиц.
- Интерактивный граф: направление и объём переводов, режимы «Связи счёта» и «Вся сеть», выбор 4 / 8 / 12 крупнейших контрагентов с каждой стороны, фильтры по сумме, роли, паттерну и приоритету, просмотр связей до четырёх переходов.
- Поиск и очередь проверки: поиск по полному идентификатору счёта (GID), карточка показателей, ранжирование. Длинные GID передаются строками без округления в JavaScript.
- Роли и группы: шесть эвристических ролей, группы связанных счетов и сводки по ним. При загрузке полного официального набора учитываются исходные счета (
seed), глубина обхода и изолированные узлы. - Проверяемые основания: компоненты приоритета и их веса, правила назначения роли, исходные операции и выборка путей переводов.
- AI-помощник: объяснение выбранного счёта, сравнение двух счетов, вопросы по данным и сводка по сети. При отсутствии OpenAI доступны явно обозначенные сводки по правилам.
- Ограниченный AI-агент: модель последовательно выбирает инструменты чтения данных, получает результаты и предлагает следующий шаг; в интерфейсе есть журнал фактических вызовов.
- Экспорт: ZIP с
nodes_roles.csv,clusters.csv,top_nodes.csv; тот же расчёт доступен одной командой без веб-интерфейса. - Подсказки для демонстрации: разделы «Обзор за 60 секунд», «Как это работает» и пояснения к критериям оценки проекта.
3. Как работает решение
- Аналитик открывает встроенный набор или загружает файл и нажимает «Построить граф».
- Сервер проверяет данные, строит направленный граф и рассчитывает обороты, контрагентов, графовые признаки, аномалии и паттерны переводов.
- На основе расчётов формируются роли, группы и приоритет проверки. В интерфейсе выбирается счёт из очереди или через поиск.
- Аналитик изучает плательщиков и получателей и открывает основания: показатели, правила и операции, на которых основана оценка.
- При наличии API-ключа можно запустить «AI-проверку». Агент запрашивает дополнительные сведения инструментами и возвращает факты и возможный следующий счёт для проверки.
- Кнопка «Скачать 3 CSV» сохраняет результаты. Решение о дальнейших действиях остаётся за аналитиком.
Откуда берутся роли и приоритет
Роли определяются правилами в backend/roles_engine.py:
| Роль | Интерпретация гипотезы |
|---|---|
consolidator | Собирает средства от нескольких отправителей |
transit | Передаёт значительную часть входящего объёма дальше |
distributor | Распределяет средства между многими получателями |
terminal | Получатель без наблюдаемого внешнего выхода, если это допускают границы выгрузки |
coordinator | Связывает потоки нескольких исходных счетов и занимает посредническое положение |
peripheral | Недостаточно признаков для другой роли либо действуют ограничения наблюдения |
Приоритет объединяет графовые признаки, оценку необычности Isolation Forest, паттерны и доступные показатели движения средств. Базовые веса — 35% / 25% / 25% / 15%. Недоступные компоненты исключаются, остальные веса нормируются. Для исходных счетов и обрезанных узлов четвёртого перехода применяются понижающие коэффициенты. Формула находится в backend/risk_engine.py, фактические веса видны в основаниях.
В интерфейсе приоритет имеет шкалу 0–100, в CSV — 0–1. Это относительная оценка внутри набора. role_score отражает силу правила, а не калиброванную вероятность.
Что здесь является Agentic AI
В отличие от обычного объяснения готовой карточки, агент выполняет цикл запрос модели → выбор инструмента → результат инструмента → следующая проверка или итог. Реализация: backend/investigator.py, endpoint POST /api/ai/investigate.
| Инструмент | Данные |
|---|---|
get_account | Показатели и основания оценки счёта |
get_connections | До восьми крупнейших прямых связей |
get_transactions | До десяти крупнейших операций |
Цикл ограничен пятью попытками вызова инструментов, пятью обращениями к модели и бюджетом 45 секунд с сетевыми таймаутами. Это не строгая гарантия полного времени ответа. Последнее обращение зарезервировано под итог. Агент только читает данные: не меняет оценки, файлы или счета.
Сервер проверяет ссылки на счета и факты; текст подтверждённых фактов собирается из серверных записей. Следующий счёт допускается в рекомендации только после его проверки инструментом. Журнал показывает реальные вызовы, а не скрытые рассуждения модели.
agent / completed— модельный цикл завершён, итог прошёл проверку.agent / limited— достигнут предел или итог не подтверждён; показаны выполненные проверки.rules / unavailable— агент недоступен, например нет ключа; показаны уведомление и стандартные рекомендации, не имитация работы модели. Если до ошибки уже были выполнены проверки, сохраняются полученные факты.
4. Технологии
| Слой | Используемые технологии |
|---|---|
| Интерфейс | JavaScript, React 19, Vite 7, CSS, Tailwind CSS 4, Lucide React |
| Визуализация сети | Cytoscape.js |
| Сервер и API | Python, FastAPI, Uvicorn, Pydantic |
| Обработка данных | Pandas, NumPy, PyArrow; форматы CSV, Parquet и ZIP |
| Графовая аналитика | NetworkX: PageRank, посредничество, достижимость, сообщества Louvain |
| Поиск аномалий | scikit-learn, Isolation Forest; модель обучается на признаках текущего набора |
| Генеративный ИИ | OpenAI Python SDK, Responses API; модель по умолчанию gpt-4.1-mini, настраивается через OPENAI_MODEL |
| Проверки | pytest, FastAPI TestClient, встроенный тестовый модуль Node.js |
Зафиксированные зависимости: requirements-lock.txt и frontend/pnpm-lock.yaml. Два UI-компонента адаптированы из 21st.dev; авторы и источники перечислены в docs/UI_SOURCES.md. Подключение 21st MCP для запуска приложения не требуется. NVIDIA API в текущем коде не используется; GPU для основного расчёта не нужен.
5. Архитектура
CSV / Parquet / ZIP / встроенное демо
│
Проверка и нормализация
│
Граф → признаки → роли, группы, приоритет
│
Единый объект Analysis
┌────┴───────────────┐
FastAPI + React pipeline.py → 3 CSV
│
Основания, граф, экспорт, AI-помощник
│
Read-only инструменты ↔ OpenAI (опционально)
Основные компоненты:
frontend/src/— интерфейс, граф, карточки, основания и журнал агента; обращения к серверу через/api.backend/main.py— HTTP API, наборы данных в памяти и раздача собранного интерфейса.backend/datasets.py— чтение и проверка входных форматов.backend/analysis.pyи модули*_engine.py— общий расчёт графа, признаков, ролей, групп и приоритета.backend/ai_copilot.py,backend/investigator.py— текстовый помощник и агентный цикл.backend/submission.py— формирование трёх CSV для интерфейса и командного запуска.run.py— локальный запуск;pipeline.py— расчёт без веб-интерфейса;tests/— проверки backend.
Отдельная база данных не используется. Загруженные наборы и результаты анализа хранятся в памяти серверного процесса.
6. Установка и запуск
Требования
- Python 3.14 и Node.js 24 — версии, на которых проверялся запуск.
pnpm, доступный в командной строке.- Git для клонирования; интернет для первой установки зависимостей.
- API-ключ OpenAI не нужен для графа, ролей, оснований и экспорта.
Быстрый запуск
git clone https://github.com/BAITC-Hacks/hack-7c0a290a-skywhywalker.git
cd hack-7c0a290a-skywhywalker
python run.py --port 8002
Если Python 3.14 вызывается командой python3, используйте её вместо python.
Запускатор создаёт .venv, при необходимости устанавливает Python-зависимости и собирает frontend, если frontend/dist/index.html отсутствует. После готовности он открывает браузер.
- Приложение: http://127.0.0.1:8002.
- Интерактивная документация API: http://127.0.0.1:8002/docs.
- Проверка сервера: http://127.0.0.1:8002/api/health.
- Остановка:
Ctrl+C. Без--portиспользуется порт8000.
Явная установка по lock-файлам
Из корня репозитория:
python -m venv .venv
Активируйте окружение:
# macOS / Linux
source .venv/bin/activate
# Windows PowerShell
.\.venv\Scripts\Activate.ps1
Затем:
python -m pip install -r requirements-lock.txt
cd frontend
pnpm install --frozen-lockfile
pnpm build
cd ..
python run.py --port 8002
После обновления frontend повторите pnpm build в каталоге frontend. Запускатор не пересобирает уже существующий dist автоматически. При занятом порте выберите другой, например --port 8003.
Необязательно: включить OpenAI
Создайте .env в корне по образцу .env.example и укажите собственный ключ:
OPENAI_API_KEY=your_key_here
OPENAI_MODEL=gpt-4.1-mini
Замените your_key_here реальным ключом и перезапустите сервер. .env исключён из Git; не помещайте ключ в код или frontend. Доступ к модели и расходы на запросы зависят от вашего API-аккаунта. Поле ai_configured в /api/health показывает наличие настройки, а не подтверждает действительность ключа.
Для разработки: запустите python run.py --port 8000, а во втором терминале выполните cd frontend и pnpm dev. Vite проксирует /api на backend по адресу 127.0.0.1:8000.
7. Как жюри проверить решение
Сценарий без ключей и дополнительных файлов
- Запустите приложение и откройте
http://127.0.0.1:8002. - Выберите «Учебный пример». Ожидаются 42 счёта, 172 операции и 43 направленные пары. Все участники и переводы этого набора вымышлены.
- Найдите счёт
Fчерез поиск. Откройте его карточку, посмотрите входящие и исходящие связи, роль и приоритет. - Откройте основания оценки и сопоставьте показатели с таблицей операций. Переключите граф на «Вся сеть», затем вернитесь к связям счёта.
- Нажмите «Скачать 3 CSV». В архиве должны быть
nodes_roles.csv,clusters.csv,top_nodes.csv; для встроенного демо — 42, 5 и 42 строки данных соответственно, без заголовков. - Для проверки собственного ввода загрузите
data/sample_transactions.csvкнопкой «Загрузить данные», нажмите «Построить граф» и повторите просмотр и экспорт.
Дополнительная AI-проверка: с настроенным ключом выберите F, откройте вкладку «AI-проверка» и нажмите «Запустить AI-проверку». Проверьте журнал вызовов, основания фактов и статус завершения. Конкретный следующий счёт и число вызовов могут меняться; результат модели не фиксирован заранее. Без ключа приложение должно явно сообщить о режиме правил.
Проверка расчёта без браузера
В активированном Python-окружении:
python pipeline.py --data data/sample_transactions.csv --out out/demo
Ожидаемая часть вывода:
OK: 42 nodes, 43 pairs, 172 transactions
CSV: 42 roles, 5 clusters, 42 top nodes
Результаты появятся в out/demo/. Для официального набора:
python pipeline.py --data data/official --out out/official
Автоматические тесты
python -m pytest tests -q
node --test frontend/src/components/graph-layout.test.js
При проверке этой версии: 115 Python-тестов прошли, 3 пропущены; 8 Node-тестов прошли. Три пропуска относятся к отсутствующим официальным Parquet-файлам; тесты не требуют реального вызова OpenAI. Проверяются загрузка и валидация, роли и ограничения дат, экспорт, агентный цикл и подготовка графа. Числа встроенного демо выше подтверждены запуском pipeline.py.
Подробнее о проверках: VERIFICATION.md. Сценарий защиты: docs/DEMO.md.
8. Данные и интеграции
Встроенные данные и пользовательские файлы
В репозитории есть data/sample_transactions.csv и генератор data/generate_sample.py. Это синтетические транзакции с точным временем, не официальная выгрузка кейса.
Пользовательский CSV должен быть в UTF-8 с разделителем-запятой и содержать поля:
sender,receiver,amount,timestamp
0001,0002,5000,2026-07-01T10:00:00Z
0002,0003,4500,2026-07-01T10:30:00Z
Также поддерживается схема src,dst,sum_kzt,date. Суммы должны быть положительными конечными числами; даты — в ISO-формате. Время без часового пояса трактуется как UTC. Идентификаторы сохраняются строками, включая ведущие нули. В стандартном CSV валюта не определяется автоматически.
Официальный набор кейса
Исходные Parquet не опубликованы в Git. Для их использования положите предоставленные организаторами файлы в:
data/official/
nodes.parquet # gid, depth, is_seed
edges.parquet # src, dst, sum_kzt, n_tx, depth
transactions.parquet # src, dst, date, sum_kzt
Другую папку задайте переменной окружения MONEYGRAPH_DATA_DIR перед запуском:
# macOS / Linux; замените путь своим
MONEYGRAPH_DATA_DIR="/absolute/path/data" python run.py --port 8002
# Windows PowerShell; замените путь своим
$env:MONEYGRAPH_DATA_DIR = "C:\path\data"
python run.py --port 8002
Если официальный набор найден, приложение выбирает его при старте; иначе открывает демо. Альтернатива — загрузить ZIP с тремя таблицами через интерфейс. Полный набор сохраняет сведения о seed, глубине и изолированных узлах; отдельный файл транзакций этих сведений не содержит. После изменения серверной настройки перезапустите приложение. Для CLI передавайте папку явно через --data.
Согласно описанию кейса в репозитории, официальный набор содержит 2 248 счетов, 3 119 направленных пар и 4 840 операций за июль 2026 года в KZT. Эти числа относятся к внешним данным организаторов, не к встроенному демо.
Выходные данные
| Файл | Содержимое |
|---|---|
nodes_roles.csv | Все счета: gid, role, role_score, cluster_id, priority_score, evidence и дополнительные признаки |
clusters.csv | Группы: cluster_id, n_nodes, n_seed, sum_kzt_internal, top_gids, hypothesis |
top_nodes.csv | До 50 счетов, не отмеченных как seed: rank, gid, role, priority_score, why |
Основание роли ограничено 200 символами. Экспорт охватывает весь проанализированный набор, а не только видимые на экране узлы. Открывая CSV в табличном редакторе, задайте для GID текстовый тип, чтобы редактор не округлил длинные идентификаторы. Названия полей с _kzt сохраняют контракт кейса; для пользовательского CSV суммы остаются в единицах исходного файла, без конвертации валют.
Внешние сервисы
Единственная интеграция с внешней моделью в приложении — OpenAI API. При использовании AI-функций ограниченный контекст счетов, операций и путей передаётся провайдеру. Используйте только данные, разрешённые для такой передачи; для демонстрации подходит учебный набор.
Без AI-функций после установки зависимостей расчёт работает локально. Подключения к банковской системе, внешним реестрам и потокам транзакций в реальном времени нет.
9. Ограничения текущей версии
- Масштаб: до 50 МБ входного файла, 20 000 транзакций и 5 000 узлов; до восьми пользовательских наборов в памяти. Это локальный MVP, не система для миллионов счетов.
- Хранение и доступ: нет авторизации, разграничения прав, постоянного хранилища загрузок, заметок аналитика и истории решений. После перезапуска загруженные пользователем наборы исчезают. Не следует публиковать сервер с конфиденциальными данными без дополнительной защиты.
- Качество выводов: нет эталонной разметки для оценки точности ролей. Эвристики и Isolation Forest выделяют особенности текущей выборки, не доказывают нарушение.
- Неполная сеть: выходы за четвёртый переход и внешние поступления исходных счетов могут быть неизвестны. Отсутствие выхода на границе не означает, что найден конечный получатель.
- Точность времени: для данных только с датой отключены минутные/часовые показатели и FIFO. Совпадение дат не доказывает движение тех же денег. Даже при точном времени FIFO — расчётное сопоставление, не банковское подтверждение.
- Ограниченный просмотр: очередь слева показывает до 100 счетов, поиск работает по всему набору. Граф прямых связей ограничен выбранным числом контрагентов, просмотр цепочек — 80 узлами. Карточка оснований показывает не более 500 операций и выборку путей. Эти ограничения интерфейса не сокращают CSV-выгрузки.
- AI: нужны доступный ключ, интернет и доступ к модели. Ответ может завершиться по лимиту или перейти в режим правил. Текстовые рекомендации требуют проверки человеком; агент не является автономным расследованием.
- Продуктовые интеграции: нет автоматических банковских действий, уведомлений и промышленного развёртывания с мониторингом.
Возможные следующие этапы, пока не реализованные: журнал работы аналитика и роли доступа, сохранение и сравнение версий данных, фоновые расчёты и выдача подграфов для больших наборов. Их полезность и производительность ещё нужно проверять отдельно.
10. Развёрнутая версия
Подтверждённая ссылка на публично развёрнутую версию в репозитории отсутствует. Основной способ проверки — локальный запуск по инструкции выше. http://127.0.0.1:8002 — адрес на компьютере, где запущено приложение, а не публичное демо.
Репозиторий: BAITC-Hacks/hack-7c0a290a-skywhywalker.
Дополнительные материалы: простое объяснение ИИ · требования кейса · сценарий демонстрации · источники UI · работа команды.
Авторы коммитов
История коммитов
- 2026-09-23 17:39docs: write jury-focused Russian project READMEsatkan-satkan
- 2026-09-23 17:13feat: add bounded investigation agent and jury-ready workspacesatkan-satkan
- 2026-09-23 16:24Merge team and MoneyGraph MVPs into one HackAlem applicationspikenstap
- 2026-09-23 15:51Fix Russian statistics layout and verify the working OpenAI integrationspikenstap
- 2026-09-23 15:40Match visual reference with data-backed flow workspace and browser QAsatkan-satkan
- 2026-09-23 15:35Localize MoneyGraph in Russian and add a light green banking-inspired designspikenstap
- 2026-09-23 15:14Redesign investigation workspace from generated visual referencesatkan-satkan
- 2026-09-23 15:06Add MoneyGraph AI as an isolated experimental MVP candidatespikenstap
Все коммиты (12)
- 2026-09-23 14:42Clarify AML workflow and refresh Freedom inspired UIsatkan-satkan
- 2026-09-23 14:23Add optional grounded AI case notesatkan-satkan
- 2026-09-23 14:20Build explainable AML pipeline and investigation web appsatkan-satkan
- 2026-09-23 14:10Initialize MoneyMap project scaffoldsatkan-satkan
Структура репозитория (68 файлов)
.env.example .gitignore AI-EXPLAINED-RU.md README.md Start-MoneyGraph.cmd TEAM.md VERIFICATION.md app.py backend/__init__.py backend/ai_copilot.py backend/analysis.py backend/anomaly_engine.py backend/datasets.py backend/feature_engine.py backend/graph_engine.py backend/investigator.py backend/main.py backend/models.py backend/pattern_engine.py backend/risk_engine.py backend/roles_engine.py backend/submission.py data/generate_sample.py data/official/README.md data/sample_transactions.csv docs/CASE_REQUIREMENTS.md docs/DEMO.md docs/MVP_COMPARISON.md docs/UI_SOURCES.md frontend/index.html frontend/package.json frontend/pnpm-lock.yaml frontend/pnpm-workspace.yaml frontend/public/favicon.svg frontend/src/App.jsx frontend/src/components/AICopilot.jsx frontend/src/components/AgentInvestigator.jsx frontend/src/components/ClustersPanel.jsx frontend/src/components/EvidencePanel.jsx frontend/src/components/HelpPanel.jsx frontend/src/components/InvestigationList.jsx frontend/src/components/JuryGuide.jsx frontend/src/components/MoneyGraph.jsx frontend/src/components/NodeDetails.jsx frontend/src/components/Sidebar.jsx frontend/src/components/StatsBar.jsx frontend/src/components/UploadPanel.jsx frontend/src/components/graph-focus.css frontend/src/components/graph-layout.js frontend/src/components/graph-layout.test.js frontend/src/components/ui/AgentActivity.jsx frontend/src/components/ui/StatsCard.jsx frontend/src/jury-workspace.css frontend/src/main.jsx frontend/src/services/api.js frontend/src/services/labels.js frontend/src/styles.css frontend/vite.config.js pipeline.py requirements-lock.txt requirements.txt run.py tests/test_ai_localization.py tests/test_analysis.py tests/test_datasets.py tests/test_investigator.py tests/test_submission.py tests/test_unified_analysis.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.