О проекте
Команда: Genov8
Кейс HackAlem.ai: Финансы — Freedom
Стадия: Доведённый продукт
Задача кейса: «Граф денег»: восстановить структуру организованной группы по сети транзакций (AML)
Суть
Объяснимый анализ сети переводов для AML: строит денежный граф, присваивает клиентам роли, кластеры Louvain и приоритет проверки, выдаёт 3 CSV и рабочее место аналитика с интерактивным графом и AI-помощником.
Как устроено
Python-пайплайн загружает три Parquet, строит ориентированный граф NetworkX, считает обороты, удержание средств, быстрое перенаправление (0–2 дня), PageRank, betweenness и связность с seed. Роли (coordinator, distributor, consolidator, transit, terminal, peripheral) назначаются правилами с порогами из thresholds.yaml; priority_score — взвешенная сумма 5 компонентов. FastAPI отдаёт данные, Next.js + Cytoscape.js показывает окружение узла; опциональный OpenAI-помощник отвечает через инструменты чтения графа с журналом вызовов.
Ключевые решения
- NetworkX
- Louvain
- PageRank
- betweenness centrality
- rule-based roles
- weighted priority score
- function calling
Особенности
Отдельные правила для seed (их входящие занижены из-за способа сборки графа) и предупреждения о границе обхода глубины 4. Интерфейс и промпты AI на трёх языках; GID передаются строками, чтобы JS не терял точность.
Стек
Python · pandas · NumPy · PyArrow · SciPy · FastAPI · Next.js · React · TypeScript · Cytoscape.js · Docker · nginx
Модели
gpt-4.1-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-ad15b73e-genov8.
README
README.mdMoneyGraph — граф денег
Объяснимый анализ денежных переводов для HackAlem. MoneyGraph помогает аналитикам финансового мониторинга и AML определить, кого проверить в первую очередь и какие наблюдаемые связи обосновывают эту проверку.
Вместо ручного просмотра тысяч переводов аналитик получает приоритетную очередь клиентов, роли в графе, группы связанных участников и числовые объяснения. Результат — гипотезы для расследования, а не заключение о виновности.
Что реализовано
- Загрузка и проверка трёх Parquet-файлов: клиенты, агрегированные связи и транзакции.
- Построение ориентированного денежного графа; расчёт оборотов, связей, удержания средств, быстрого перенаправления, PageRank, betweenness и связности с исходными клиентами (
seed). - Объяснимая роль для каждого клиента, сообщества Louvain и рейтинг приоритета проверки.
- Три CSV-результата: роли всех клиентов, сводка кластеров и топ-20.
- Веб-интерфейс: очередь приоритетов, поиск по точному GID, интерактивный граф окружения, переход по соседним узлам, карточка с объяснениями и контекст кластера.
- Предупреждения о границе обхода графа и неполных входящих потоках исходных клиентов.
- Опциональный AI-помощник: вопросы к графу на естественном языке, инструменты анализа и журнал их вызовов.
- Переключение интерфейса между русским, казахским и английским. Примеры вопросов и инструкции AI учитывают выбранный язык; помощник получает указание отвечать на нём.
Роли и приоритет
Правила применяются в порядке таблицы: первое подходящее определяет роль. Точные пороги находятся в config/thresholds.yaml, реализация — в backend/app/analysis.
| Роль | Основной сигнал |
|---|---|
coordinator — координатор | Для не-seed: есть входящие и исходящие связи, не менее 3 отправителей и 3 получателей либо степень ≥ 8 и структурный балл ≥ 0,90. Для seed: не менее 8 получателей и структурный балл ≥ 0,90. |
distributor — распределитель | Не менее 5 уникальных получателей при наблюдаемом исходящем потоке. |
consolidator — консолидатор | Для не-seed: не менее 3 отправителей, не более 2 получателей, входящий объём ≥ 100 000 KZT. |
transit — транзит | Для не-seed с входящими и исходящими связями: отношение исходящего к входящему объёму 0,50–1,50; доля быстрого перенаправления ≥ 0,50 в окне 0–2 дня. |
terminal — удержание средств | Для не-seed вне границы наблюдения: входящий и удержанный объём ≥ 100 000 KZT, удержанная доля ≥ 0,80, не более 1 получателя. |
peripheral — периферийный | Остальные узлы; все узлы глубины 4 получают эту роль с предупреждением о границе наблюдения. |
Рейтинг priority_score — сумма пяти компонентов: сила роли 25%, денежная значимость 27%, структурная важность 15%, связь с seed 17%, признаки аномального поведения 16%. Структурная важность объединяет процентильные оценки PageRank, betweenness и степени узла. Аномальные признаки учитывают быстрое перенаправление, дисбаланс потоков и количество транзакций.
role_score и priority_score лежат в диапазоне 0–1 и не являются вероятностями нарушения закона. Краткое evidence содержит наблюдаемые показатели и занимает менее 200 символов.
Как работает решение
- Организатор предоставляет обезличенные Parquet-файлы с GID клиентов и переводами.
- Аналитический pipeline проверяет согласованность файлов, рассчитывает признаки, роли, кластеры и приоритеты, сохраняет CSV.
- Backend загружает данные и результаты, проверяет их согласованность с текущими правилами и предоставляет API.
- Аналитик выбирает клиента из очереди и изучает причины приоритета, направления переводов, соседей и кластер. Поиск по GID позволяет открыть клиента вне топ-20.
- При настроенном OpenAI аналитик задаёт уточняющий вопрос; помощник обращается к инструментам графа и возвращает объяснение. Решение о дальнейшей проверке принимает человек.
Технологии
| Слой | Используется |
|---|---|
| Анализ | Python, pandas, NumPy, PyArrow, NetworkX, SciPy, PyYAML |
| Backend | FastAPI, Uvicorn, Pydantic, python-dotenv |
| Frontend | TypeScript, Next.js 15, React 19, Cytoscape.js |
| Данные | Parquet на входе, CSV на выходе; репозиторий данных в памяти процесса |
| Опциональный AI | Python SDK OpenAI, Responses API; модель по умолчанию gpt-4.1-mini, замена через OPENAI_MODEL |
Роли, кластеры и рейтинги рассчитываются алгоритмами и правилами, без LLM. Собственная обученная ML-модель не используется. Зависимости: backend/requirements.txt и frontend/package.json; для frontend сохранён lockfile.
Архитектура проекта
flowchart LR
D[Parquet: клиенты и переводы] --> P[Python pipeline: проверка и анализ]
Y[thresholds.yaml: правила и веса] --> P
P --> C[CSV: роли, кластеры, топ-20]
D --> B[FastAPI: данные в памяти]
C --> B
B --> F[Next.js: рабочее место аналитика]
F -->|вопрос| A[Опциональный OpenAI-помощник]
A -->|инструменты чтения графа| B
A -->|ответ и журнал инструментов| F
Backend выполняет дорогие расчёты для проверки результатов при старте, затем обслуживает запросы из кешированного репозитория. В браузер передаётся ограниченное окружение выбранного узла, а не весь граф. GID передаются строками, чтобы JavaScript не терял точность длинных идентификаторов.
backend/pipeline.py запуск анализа и проверка CSV
backend/app/analysis/ признаки, роли, кластеры, рейтинг, объяснения
backend/app/api/ репозиторий данных, схемы и HTTP-маршруты
backend/app/agent/ AI-помощник и инструменты графа
frontend/ интерфейс Next.js
config/thresholds.yaml правила и веса
data/ исходные Parquet-файлы
output/ CSV-результаты
starter/starter.py загрузчик и построитель графа организатора
docs/architecture.md подробное описание архитектуры
API: GET /health, GET /api/summary, GET /api/priorities, GET /api/nodes/{gid}, GET /api/nodes/{gid}/graph, GET /api/clusters, GET /api/clusters/{cluster_id}, POST /api/investigator. Все операции анализа работают на чтение; POST не изменяет исходные данные.
Подробная документация: архитектура · локализация интерфейса и AI.
Установка и запуск
Нужны Python, Node.js с npm и Git для получения репозитория. Локальная проверка анализа выполнена на Python 3.14.3; установленная версия Node.js — 24.21.0. Команды ниже выполняются из корня репозитория, где находятся backend/, frontend/ и data/. Данные уже включены в репозиторий. Интернет нужен для установки зависимостей и опциональных запросов к OpenAI.
Windows PowerShell
- Установите зависимости:
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r backend\requirements.txt
Set-Location frontend
npm.cmd ci
Set-Location ..
Если команда python недоступна, но установлен Python Launcher, используйте py -m venv .venv в первой строке. Активация окружения не требуется.
- Рассчитайте результаты и запустите backend:
.\.venv\Scripts\python.exe backend\pipeline.py
.\.venv\Scripts\python.exe -m uvicorn backend.app.main:app --reload
- В другом терминале, также из корня проекта, запустите frontend:
Set-Location frontend
npm.cmd run dev
Linux / macOS
- Установите зависимости и рассчитайте результаты:
python3 -m venv .venv
.venv/bin/python -m pip install -r backend/requirements.txt
cd frontend
npm ci
cd ..
.venv/bin/python backend/pipeline.py
- Запустите backend:
.venv/bin/python -m uvicorn backend.app.main:app --reload
- В другом терминале из корня проекта запустите frontend:
cd frontend
npm run dev
После установки зависимостей, если установлен GNU Make, доступны сокращения make analyze, make backend, make frontend на Windows и Linux/macOS. Makefile выбирает путь к Python в зависимости от ОС. Без Make используйте явные команды выше.
Откройте интерфейс, Swagger API или проверку backend. Дождитесь сообщения Uvicorn об успешном завершении запуска. Для остановки нажмите Ctrl+C в каждом терминале.
Настройка API и AI
Для обычного запуска .env и ключи не нужны. Frontend обращается к http://localhost:8000 по умолчанию.
Для AI создайте в корне репозитория файл .env с собственным ключом:
OPENAI_API_KEY=your-api-key
OPENAI_MODEL=gpt-4.1-mini
Перезапустите backend. Ключ доступен только серверу; .env исключён из Git. Без ключа AI endpoint возвращает HTTP 503 с пояснением, остальные функции доступны.
Если нужен другой адрес backend, задайте его отдельно в frontend/.env.local и перезапустите frontend:
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000
Next.js не загружает корневой .env этого репозитория как конфигурацию frontend. Переменные MONEYGRAPH_* из .env.example сейчас не подключены к выбору путей. Pipeline принимает параметры --data, --config, --out; API использует стандартные data/, config/thresholds.yaml, output/.
Частые проблемы запуска
npmне найден: установите Node.js с npm и откройте новый терминал.ENOENT ... package.json: запускайте npm внутриfrontend/, а не в корне.-mне распознано: перед ним должно быть имя Python, как в командах выше.No module named scipy: повторите установкуbackend/requirements.txtчерез Python из.venv.- Backend сообщает об устаревших CSV: снова выполните pipeline и перезапустите backend.
- Frontend выбрал порт 3001: освободите порт 3000 для этого приложения. CORS backend по умолчанию разрешает только
localhost:3000и127.0.0.1:3000; другие адреса требуют изменения настройки CORS.
Как проверить решение: сценарий для жюри
- Выполните pipeline командой для своей ОС. Для включённого набора и текущих правил ожидаются 2 248 строк клиентов, 91 кластер и 20 строк приоритетов. Pipeline сам проверяет полноту, диапазоны оценок, длину объяснений и сортировку рейтинга.
- Проверьте три файла в
output/:nodes_roles.csv,clusters.csv,top_nodes.csv. Распределение ролей: 91 coordinator, 70 distributor, 83 consolidator, 77 transit, 335 terminal, 1 592 peripheral. - Запустите оба сервера. Откройте
/health: ожидается{"status":"ok"}. В/api/summaryпроверьте 2 248 клиентов, 3 119 связей, 4 840 транзакций и 81 seed. - Откройте MoneyGraph. Проверьте переключение между русским, казахским и английским. В очереди приоритетов (
Priority nodesна английском) выберите первую строку: GID100000004156082100, рольcoordinator, приоритет примерно 0,901633. Изучите компоненты рейтинга, объяснение, входящие и исходящие связи. - Нажмите соседний узел на графе: карточка и окружение должны переключиться на него. Проверьте контекст кластера в карточке.
- Найдите точный GID
100000000404740100. Это узел глубины 4: ожидаются рольperipheralи предупреждение о неполноте исходящих наблюдений. Нулевой наблюдаемый исходящий поток не делает его конечным получателем. - Опционально, с ключом OpenAI, задайте
Почему у GID 100000004156082100 высокий приоритет?. Проверьте журнал вызванных инструментов и сопоставьте ответ с карточкой клиента. Переключите язык, проверьте перевод примеров вопросов и отправьте новый запрос: AI получает инструкцию отвечать на выбранном языке. Формулировка AI-ответа может меняться.
Основной сценарий доступен без OpenAI. Результаты анализа воспроизводятся при одинаковых данных, правилах и версиях библиотек; backend-зависимости не закреплены до точных версий.
Данные и интеграции
| Источник / результат | Содержание |
|---|---|
data/nodes.parquet | 2 248 клиентов с GID, глубиной обхода и признаком seed; 81 seed, 444 узла на границе глубины 4 |
data/edges.parquet | 3 119 направленных связей: отправитель, получатель, сумма KZT и число переводов |
data/transactions.parquet | 4 840 транзакций с датой и суммой |
output/nodes_roles.csv | gid, role, role_score, cluster_id, priority_score, evidence |
output/clusters.csv | Размеры кластеров, число seed, внутренний объём, ключевые GID и гипотеза |
output/top_nodes.csv | Место в очереди, GID, роль, приоритет и причина проверки |
Входные файлы предоставлены организатором; это ограниченная обезличенная выгрузка, а не подключение к банковской системе в реальном времени. Внешние реестры, KYC и данные других банков не подключены.
Единственная опциональная внешняя интеграция — OpenAI. При её использовании сервер отправляет вопрос и результаты вызванных инструментов, включая GID и показатели графа. Доступны node_card, common_receivers, paths, filter_nodes, cluster_summary, what_if_remove, максимум пять вызовов на вопрос. Последний инструмент моделирует удаление узлов из графа; он не блокирует реальные операции.
Ограничения текущей версии
- Наблюдаются внутрибанковские переводы из предоставленной выгрузки; переводы меньше 5 000 KZT отсутствуют. Исходящий обход ограничен глубиной 3, глубина 4 — граница. Входящие потоки seed неполны.
- Даты имеют точность до дня. Быстрое перенаправление — временной признак, а не доказательство движения тех же денег или порядка операций внутри дня.
- Пороги настроены под набор хакатона. Проверка pipeline явно ожидает 2 248 клиентов; для другого набора потребуется адаптация. Расчёты выполняются в памяти, масштабирование на миллионы узлов не проверялось.
- Louvain использует неориентированную проекцию с суммированием встречных объёмов,
resolution=1.0,seed=42. Направления сохраняются в остальных расчётах и отображении графа. - Нет базы данных, авторизации, загрузки файлов через UI, потокового обновления, журнала решений аналитика и сохранения расследований. Интерфейс ориентирован на настольный экран. Машинные коды ролей и полей API/CSV сохраняются на английском независимо от языка интерфейса.
- Обучаемая модель, прогноз недостающих переводов и полноценный временной анализ расследования не реализованы. Архитектурные идеи не следует считать готовыми функциями.
- AI может ошибаться. Код проверяет упомянутые 18-значные GID по результатам инструментов, но не выполняет полную автоматическую проверку всех утверждений и чисел. Ответы следует сверять с данными.
- Это демонстрационный аналитический прототип; оценки обозначают приоритет ручной проверки, а не доказанную противоправную деятельность.
Deployed-версия
Публичная ссылка на развёрнутую версию в репозитории не указана. Для демонстрации используйте локальный запуск: http://localhost:3000. Это локальный адрес, доступный после запуска приложения на вашем компьютере.
Авторы коммитов
История коммитов
- 2026-09-23 17:50chore: prepare nginx for HTTPSGenov8
- 2026-09-23 17:46fix: use explicit Docker network for deploymentGenov8
- 2026-09-23 17:34docs: translate architecture and localization guides into three languagesQuetzzzalcoatl
- 2026-09-23 17:19Merge branch 'codex/frontend-ru-kk'Quetzzzalcoatl
- 2026-09-23 17:15docs: add Russian Kazakh and English README navigationQuetzzzalcoatl
- 2026-09-23 17:08Merge branch 'main' into codex/frontend-ru-kkQuetzzzalcoatl
- 2026-09-23 17:05chore: add production Docker deploymentGenov8
- 2026-09-23 16:49feat: localize AI investigator prompts and responsesQuetzzzalcoatl
Все коммиты (16)
- 2026-09-23 16:48docs: finalize submission and reproducibilityGenov8
- 2026-09-23 16:35Merge branch 'main' into codex/frontend-ru-kkQuetzzzalcoatl
- 2026-09-23 16:28feat: localize frontend in Russian, Kazakh and EnglishQuetzzzalcoatl
- 2026-09-23 16:15feat: add grounded AI investigation copilotGenov8
- 2026-09-23 15:36feat: build MoneyGraph investigation workspaceGenov8
- 2026-09-23 15:06feat: expose MoneyGraph investigation APIGenov8
- 2026-09-23 14:36feat: implement explainable graph analysis pipelineGenov8
- 2026-09-23 13:50chore: initialize MoneyGraph project structureGenov8
Структура репозитория (65 файлов)
.dockerignore .env.example .gitignore Dockerfile.backend Dockerfile.frontend Makefile README.en.md README.kk.md README.md backend/app/__init__.py backend/app/agent/__init__.py backend/app/agent/investigator.py backend/app/agent/localization.py backend/app/agent/tools.py backend/app/analysis/__init__.py backend/app/analysis/clustering.py backend/app/analysis/evidence.py backend/app/analysis/features.py backend/app/analysis/ranking.py backend/app/analysis/roles.py backend/app/api/__init__.py backend/app/api/models.py backend/app/api/repository.py backend/app/api/routes.py backend/app/main.py backend/pipeline.py backend/requirements.txt backend/tests/test_investigator_localization.py config/thresholds.yaml data/.gitkeep data/edges.parquet data/nodes.parquet data/transactions.parquet docs/architecture.en.md docs/architecture.kk.md docs/architecture.md docs/frontend-localization.en.md docs/frontend-localization.kk.md docs/frontend-localization.md frontend/next-env.d.ts frontend/next.config.ts frontend/package-lock.json frontend/package.json frontend/src/app/globals.css frontend/src/app/layout.tsx frontend/src/app/page.tsx frontend/src/components/investigation-workspace.tsx frontend/src/components/investigator-panel.tsx frontend/src/components/language-provider.tsx frontend/src/components/money-graph.tsx frontend/src/lib/api.ts frontend/src/lib/translate-evidence.ts frontend/src/lib/translations.ts frontend/tests/localization.test.cjs frontend/tsconfig.json infra/README.md infra/docker-compose.yml infra/nginx/default.conf output/.gitkeep output/clusters.csv output/nodes_roles.csv output/top_nodes.csv starter/README.md starter/requirements.txt starter/starter.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.