О проекте
Команда: KörAI
Кейс HackAlem.ai: Финансы — Freedom
Стадия: Рабочий MVP
Задача кейса: «Граф денег»: восстановить структуру организованной группы по сети транзакций (AML)
Суть
Система анализа сети транзакций «Граф денег»: pipeline назначает узлам роли (distributor, consolidator, transit, coordinator, terminal), выделяет кластеры Louvain и ранжирует приоритетные узлы. Результаты показываются в Next.js-визуализации графа с AI-агентом.
Как устроено
pipeline.py читает nodes/edges/transactions.parquet и строит направленный взвешенный DiGraph (NetworkX). Считаются степени, обороты, PageRank и pass-through, роли задаются объяснимыми if-порогами (20+ получателей, 8+ отправителей, pass-through 0.8–1.2 и т.д.), вычисляются role_score и priority_score. Кластеры находит louvain_communities(seed=42), результат выгружается в CSV и graph.json. FastAPI отдаёт /api/graph, /api/node, /api/ask (LLM) и /api/resilience, фронт на Next.js рисует граф и панель агента.
Ключевые решения
- NetworkX DiGraph
- Louvain
- PageRank
- pass-through ratio
- rule-based role classification
- priority scoring
- resilience analysis
Особенности
Отдельно обработаны ловушки данных: узлы глубины 4 без исходящих помечены is_cutoff, у 81 seed-курьера не считается pass-through, потому что их входящий поток занижен. Есть план масштабирования на миллион узлов (igraph, Leiden, графовая БД). Роли намеренно сделаны объяснимыми правилами, чтобы их можно было защитить числами.
Стек
Python · FastAPI · NetworkX · SciPy · Parquet · Next.js · TypeScript
Модели
OpenAI
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-3306dd18-k-rai.
README
README.mdЗапуск
pip install -r requirements.txt
python start.py
Нужны Python и Node.js с npm. Откройте http://localhost:8000.
start.py установит отсутствующие npm-зависимости, соберёт Next.js с реальным API,
пересчитает граф и запустит FastAPI. Фронтенд и API работают на одном адресе.
Ключ OPENAI_API_KEY читается из корневого .env; во фронтенд он не передаётся.
Для повторного запуска без изменения фронта: python start.py --skip-build.
После изменения файлов фронта запускайте без --skip-build.
pipeline.py читает nodes.parquet, edges.parquet и transactions.parquet, а затем создаёт out/nodes_roles.csv, out/clusters.csv, out/top_nodes.csv и out/graph.json. API: GET /api/graph, GET /api/node/{gid}, POST /api/ask, POST /api/resilience.
Схема решения
данные → метрики → роли → Louvain-кластеры → graph.json → API/фронт. Граф направленный и взвешенный. Роли — объяснимые if-правила, поэтому результат можно защитить по числам.
| Роль | Стартовый порог |
|---|---|
| distributor | 20+ разных получателей |
| consolidator | 8+ разных отправителей |
| transit | pass-through 0.8–1.2 и не более 8 связей |
| coordinator | 3+ разных upstream courier |
| terminal | вход есть, выход не более 10%, но is_cutoff=false |
| peripheral | всё остальное |
role_score нормирован по силе превышения порога, priority_score объединяет роль, оборот, отправителей и upstream-курьеров. Кластеры считаются networkx.community.louvain_communities(..., seed=42). Узлы глубины 4 без исходящих получают is_cutoff=true; курьеры не получают pass-through, потому что их вход в выгрузке занижен.
Ограничения
В предоставленном датасете нет отдельной колонки is_courier: 81 seed-клиент трактуется как известный upstream-курьер из условия кейса. Поэтому для seed входящий поток считается заниженным, а pass_through для них не используется. upstream_couriers — число уникальных seed-курьеров среди всех предков узла.
Это гипотезы по структуре переводов, не доказательство нарушения. Неполная выгрузка может превращать реального получателя в cutoff. Если parquet не содержит явного is_courier/courier, upstream-couriers будут нулевыми. Транзакции используются как источник агрегаций edges; временной latency оставлен расширением для следующей итерации.
Что изменится при миллионе узлов
networkx заменяется на igraph, Louvain — на Leiden, а весь граф и запросы — на графовую БД или потоковые агрегации. Нельзя держать все Python-объекты в памяти; нужны columnar/partitioned parquet, предварительные индексы и асинхронные тяжёлые расчёты.
Раскрытие стартового кода
В starter/starter.py сохранены загрузка parquet, sanity-check, направленный DiGraph, базовые степени, обороты, PageRank и pass-through. Этот pipeline расширяет его ролями, cutoff/courier-ловушками, Louvain, приоритетом, CSV и контрактным graph.json.
Авторы коммитов
История коммитов
- 2026-09-23 17:43Front added, final versionme11r
- 2026-09-23 17:08Fina verison of LLM + not final READMEme11r
- 2026-09-23 16:25new commit LLM api keygwinnnnp
- 2026-09-23 15:58new commit for TZgwinnnnp
- 2026-09-23 15:35TZ 1 Meiirgwinnnnp
- 2026-09-23 15:01Add scipy dependencygwinnnnp
- 2026-09-23 14:43Implement backend and AI agentgwinnnnp
Структура репозитория (64 файлов)
.gitignore AGENTS.md DEPLOY.md README.md api.py data/edges.parquet data/nodes.parquet data/transactions.parquet docs/TZ_graf_deneg.md frontend/.env.example frontend/.gitignore frontend/AGENTS.md frontend/CLAUDE.md frontend/README.md frontend/app/favicon.ico frontend/app/globals.css frontend/app/layout.tsx frontend/app/page.tsx frontend/components/AgentPanel.tsx frontend/components/AnswerText.tsx frontend/components/GraphCanvas.tsx frontend/components/Legend.tsx frontend/components/NodeCard.tsx frontend/components/PriorityList.tsx frontend/components/ResilienceCard.tsx frontend/components/SidePanel.tsx frontend/eslint.config.mjs frontend/lib/api.ts frontend/lib/format.ts frontend/lib/graph.ts frontend/lib/mock.ts frontend/lib/normalize.ts frontend/lib/resilience.ts frontend/lib/rng.ts frontend/lib/roles.ts frontend/lib/types.ts frontend/lib/useReducedMotion.ts frontend/next.config.ts frontend/package-lock.json frontend/package.json frontend/postcss.config.mjs frontend/public/file.svg frontend/public/globe.svg frontend/public/next.svg frontend/public/vercel.svg frontend/public/window.svg frontend/scripts/check-frontend.ts frontend/scripts/check-markdown.tsx frontend/scripts/check-mock.ts frontend/scripts/check-real-api.ts frontend/scripts/check-resilience.ts frontend/scripts/serve-with-api.mjs frontend/tsconfig.json out/clusters.csv out/graph.json out/nodes_roles.csv out/top_nodes.csv pipeline.py requirements.txt start.py starter/README.md starter/requirements.txt starter/starter.py tests/test_regressions.py
Ветки (2)
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.