О проекте
Команда: DOFP
Кейс HackAlem.ai: Финансы — Freedom
Стадия: Доведённый продукт
Задача кейса: «Граф денег»: восстановить структуру организованной группы по сети транзакций (AML)
Суть
Локальное рабочее место AML-аналитика: из трёх Parquet-файлов Freedom строит направленный граф переводов, определяет роли и сообщества и выдаёт очередь «кого проверить первым» с объяснениями. Результат доступен в интерфейсе с цепочками до четырёх переводов и дневной активностью, выгружается в CSV и Excel.
Как устроено
Загрузка и валидация трёх Parquet → направленный граф (суммы в целых тиынах, повторные операции сохраняются) → графовые признаки, сообщества, временная активность → объяснимый скоринг ролей и приоритета с учётом границы выгрузки (4-е колено, изоляты) → неизменяемый снимок расчёта с параметрами и хешами → API и React-интерфейс (очередь, карточка, граф с окрестностью в 1–2 шага, путь, операции, заметки). Опциональный AI-помощник (OpenAI) даёт объяснения со ссылками на данные и по умолчанию выключен.
Ключевые решения
- направленный граф транзакций
- детекция сообществ
- rule-based скоринг ролей
- ранжирование приоритета
- сохранённые пути до 4 переводов
- снимки с хешами
- экспорт в Excel
Метрики
2248/2248 клиентов с ролью и приоритетом; 4840 операций, 3119 связей; 105 групп; топ-30 к проверке; полный расчёт 2,346 с
Особенности
Правила учитывают артефакты выгрузки: у 444 клиентов на 4-м колене исходящие связи могли быть обрезаны, и это влияет на назначение ролей. Деньги считаются в целых тиынах, длинные ID передаются без потери цифр, снимок воспроизводим по хешам. Есть сравнение позиционирования с Neo4j Bloom, Linkurious и i2.
Стек
Python · React · TypeScript · Vite · Parquet · pytest
Модели
OpenAI (опционально)
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-6d0b8f9a-dofp.
README
README.mdTRACE · Граф денег
От 81 исходного клиента — к приоритетам проверки сети из 2 248 участников.
HackAlem AI · трек «Финансы» · кейс Freedom.
Когда AML-аналитик видит нижний уровень цепочки переводов, главный вопрос — кто выше собирает, передаёт и распределяет деньги. Чтобы ответить, нужно связать тысячи операций, определить значимых участников и проверить, что стоит за каждой гипотезой. От выбора первого клиента зависит, куда пойдёт расследование.
TRACE показывает, кого проверить первым, почему этот клиент важен и какими переводами это подтверждается. Аналитик загружает три файла и получает очередь проверки, предполагаемые роли, группы связанных клиентов и направленную карту движения средств. Из карточки он переходит к цепочке, отдельным операциям и активности по дням, фиксирует заметку и выгружает результат.
Ценность для банка — сосредоточить время специалиста на проверке обоснованных гипотез. TRACE собирает структуру сети и основания приоритета в одном рабочем месте. Следующий шаг виден сразу: изучить точку сбора денег, проверить массовое распределение или разобраться в участнике, связывающем несколько исходных клиентов.
| Что уже получено на наборе Freedom | Результат |
|---|---|
| Клиенты с ролью, приоритетом и объяснением | 2 248 из 2 248 |
| Переводы, учтённые при построении сети | 4 840 операций · 3 119 связей |
| Структурные группы для исследования | 105 |
| Клиенты в готовом списке первоочередной проверки | 30 |
| Полный расчёт в контрольном Linux-прогоне | 2,346 секунды |
Время относится к описанному ниже контрольному прогону, без установки и открытия браузера. Экономию времени аналитика и точность гипотез предстоит измерить в пилоте.
Запустить проект · Пройти демо за 5 минут · Наши преимущества · Проверить методику

Работающее приложение на синтетическом демо. Числа в таблице выше относятся к отдельному расчёту предоставленного набора Freedom.
Почему наш подход полезен
1. Приоритет превращается в понятное действие. В очереди «Кого проверить первым» рядом с клиентом указана конкретная причина внимания. Карточка раскрывает факты и вклад признаков в оценку. Аналитик может начать с верхних позиций и обосновать свой выбор коллеге; поддержка роли и приоритет проверки показаны отдельно.
2. Каждое объяснение можно проверить по данным. Сохранённый путь до четырёх переводов, участники цепочки, суммы на связях, отдельные операции и дневная активность доступны из карточки. Это связывает гипотезу с наблюдаемыми фактами и помогает обнаружить противоречие до принятия решения.
3. Особенности выгрузки учтены в самих правилах. В наборе 444 клиента находятся на четвёртом колене: их исходящие связи могли остаться за границей выгрузки. TRACE учитывает эту границу при назначении ролей. Сохраняются и 19 изолятов; неполные входящие потоки исходных клиентов учитываются при оценке. Аналитик видит, где данные позволяют сделать предположение, а где нужна дополнительная информация.
4. Финансовый результат сохраняет точность и происхождение. Суммы сверяются и рассчитываются в целых тиынах, повторные операции сохраняются, длинные ID передаются без потери цифр. Карточки и обязательные CSV используют один завершённый снимок с параметрами и хешами. Результат можно повторно открыть и сверить с исходным расчётом.
5. Решение легко проверить и включить в рабочий сценарий аналитика. Основной продукт запускается локально на CPU, без графовой СУБД, GPU и API-ключа. Готовый интерфейс, загрузка файлов, заметки, статусы проверки, копирование резюме и Excel с русскими пояснениями сокращают число отдельных инструментов, необходимых для разбора кейса. Основной расчёт и интерфейс не отправляют финансовые данные во внешние API.
Один сценарий от загрузки до результата
Три файла → очередь проверки → карточка и цепочка → операции и дни → заметка и отчёт.
Например, в предоставленных данных есть структура 13 плательщиков → один клиент → 1 получатель. Аналитик может проверить гипотезу сбора средств, открыть путь от исходного клиента и изучить подтверждающие операции. Другой участник переводит деньги 116 получателям — это повод проверить распределение. TRACE даёт факты и инструменты для такого разбора; вывод о дальнейших действиях принимает специалист.
Критерий полезности для будущего пилота — время от загрузки данных до обоснованного решения о проверке клиента, доля подтверждённых экспертом гипотез и число необходимых ручных переходов. Текущий прототип уже позволяет провести такую оценку на едином воспроизводимом результате.
Наше место среди инструментов анализа
TRACE объединяет готовые правила кейса Freedom, учёт неполной выгрузки и полный сценарий проверки в одном локальном приложении. Универсальные системы полезны для широкого круга расследований; наше преимущество для этого кейса — возможность сразу перейти от трёх Parquet к объяснимому списку клиентов и требуемым отчётам.
| Решение или подход | Что оно даёт | Отличие TRACE в этом кейсе |
|---|---|---|
| Таблицы и ручное сопоставление | Просмотр и фильтрацию отдельных операций | Связи, группы, роли и очередь рассчитываются вместе; из карточки можно перейти к пути и операциям |
| Neo4j Bloom | Универсальное исследование данных в графовой базе, поиск и визуальные действия | Наш сценарий запускается из Parquet без подготовки Neo4j и запросов аналитиком; правила кейса и три требуемых CSV уже включены |
| Linkurious | Графовые расследования, дела, комментарии, назначения и статусы | Мы предлагаем компактный однопользовательский MVP для конкретного набора; полноценного командного управления делами у нас пока нет |
| i2 Analyst’s Notebook | Развитый анализ связей, событий и временных последовательностей | Мы сфокусированы на воспроизводимом расчёте заданных ролей и ограничений выгрузки; не заявляем замену универсальной системе расследований |
Сравнение относится к назначению и организации работы, а не к качеству детекции или производительности: общего бенчмарка с этими продуктами мы не проводили. Официальные источники: Neo4j Bloom, Linkurious, i2.
Что реализовано
| Возможность | Что получает аналитик |
|---|---|
| Загрузка через браузер | Выбор трёх Parquet и периода; проверка, расчёт и открытие результата |
| Очередь проверки | «Кого проверить первым»: первые 10 с конкретной причиной, остальные страницы и быстрые вопросы; отдельный экспорт топ-30 |
| Карточка клиента | «Почему этот клиент в очереди?», факты, отдельные пояснения приоритета и поддержки роли, переход к операциям |
| Карта связей | Направленные стрелки, окраска по ролям или сообществам, поиск точного ID, окрестность в 1–2 шага |
| Полная цепочка | Отдельный просмотр сохранённого пути до четырёх переводов без обрезки окрестностью; суммы и количества на связях |
| Активность по дням | Полная история клиента, нулевые дни, точная таблица; различаются отсутствующая история и известное отсутствие операций |
| Сообщества | Состав, исходные клиенты, внутренние и межгрупповые потоки, гипотеза назначения |
| Экспорт | Обязательные CSV и Excel с листами «Как читать», «Клиенты», «Группы», «Проверить сначала» |
| Резюме и работа аналитика | Копирование резюме клиента; локальные статус и заметка по клиенту и расчёту, отдельно от снимка |
| Повторная проверка | Завершённый снимок расчёта с параметрами, версиями, исходными хешами и проверкой целостности |
При ошибке импорта предыдущий успешно загруженный результат сохраняется. Демо включается только явно; приложение не подменяет ошибку настоящего расчёта синтетическими данными.
Итоговая версия: ветка
main. Объединены данные и граф, скоринг, API и интерфейс, цепочки, дневная активность, заметки, экспорт, новый контраст и экспериментальный AI-помощник. Внешние AI-вызовы по умолчанию выключены. Живые записки пока не прошли приёмку; основное расследование работает независимо от AI. Запуск и отключение AI.
Запуск с чистого компьютера
1. Что понадобится
- Python 3.12.x, 64-bit. Python 3.11 и 3.13+ не входят в объявленный диапазон проекта.
- Git для клонирования или ZIP-архив репозитория.
- Современный браузер на компьютере. Для проверки используется Chrome/Chromium; интерфейс рассчитан прежде всего на ноутбук.
- Интернет для получения кода и установки зависимостей. После установки основные функции работают локально.
Node.js, pnpm, Docker, GPU и ключи AI для запуска не нужны: готовый frontend лежит в frontend/dist. Дополнительные настройки .env не требуются.
Для Windows/macOS доступны официальные установщики Python 3.12. Git: инструкция установки. После установки откройте новое окно терминала.
Для чистой Ubuntu 24.04 можно установить необходимые системные пакеты:
sudo apt update
sudo apt install -y git python3.12 python3.12-venv
На другом Linux способ установки Python 3.12 зависит от дистрибутива. Не заменяйте системный Python глобально.
2. Получить проверяемую версию
В терминале выполните:
git clone --branch main https://github.com/BAITC-Hacks/hack-6d0b8f9a-dofp.git moneygraph
cd moneygraph
Репозиторий команды требует предоставленного GitHub-доступа. Если видите Repository not found или ошибку авторизации, проверьте аккаунт и доступ у команды/организаторов. Обычный пароль GitHub не используется для Git-операций; не вставляйте токены в команды или переписку.
Без Git: откройте ветку main в GitHub → Code → Download ZIP, распакуйте архив и откройте терминал в папке, где находятся README.md, pyproject.toml, moneygraph/ и frontend/.
Все дальнейшие команды выполняются из этой папки. Активация окружения не нужна: команды явно используют его Python. Это также обходится без изменения политики выполнения PowerShell.
3. Установить и открыть демо без датасета
macOS / Linux:
python3.12 --version
python3.12 -m venv .venv
.venv/bin/python -m pip install ".[serve]"
.venv/bin/python -m pip check
.venv/bin/python -m moneygraph.api --demo
Windows PowerShell:
py -3.12 --version
py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install ".[serve]"
.\.venv\Scripts\python.exe -m pip check
.\.venv\Scripts\python.exe -m moneygraph.api --demo
Откройте http://127.0.0.1:8000. Терминал должен оставаться открытым. Ожидаются 24 синтетических клиента, граф и заметный баннер «Демонстрационный снимок». Роли демо заданы для показа интерфейса; их нельзя использовать как доказательство качества анализа.
Остановка сервера — Ctrl+C в его терминале. Если порт занят, добавьте --port 8001 к команде запуска и откройте http://127.0.0.1:8001.
4. Проверить настоящий датасет через интерфейс
Получите у организаторов три файла одного набора: nodes.parquet, edges.parquet, transactions.parquet. Они намеренно не включены в Git. Для полноценной проверки расчёта нужен этот набор; встроенного демо достаточно только для знакомства с интерфейсом.
В уже открытом приложении:
- Нажмите «Новые данные».
- Выберите одновременно все три Parquet-файла. Если в архиве есть вложенная папка
data, выбирайте файлы именно из неё. - Для набора кейса укажите 01.07.2026–31.07.2026.
- Нажмите «Загрузить и рассчитать» и дождитесь завершения.
- Проверьте, что баннер DEMO исчез, а число клиентов стало 2 248.
Можно начать сразу с пустого приложения: замените --demo на --empty в команде запуска. Загрузка локальная. XLSX и CSV на вход не поддерживаются. Указанный период должен охватывать все операции: он не служит фильтром, автоматически отбрасывающим неподходящие строки.
5. Один запуск от Parquet до CSV и интерфейса — основной сценарий ТЗ
Положите три файла в папку data в корне проекта. Проверьте, что путь до первого файла — data/nodes.parquet, а не data/data/nodes.parquet. Остановите предыдущий сервер через Ctrl+C.
macOS / Linux:
.venv/bin/python -m moneygraph run --data ./data --out ./out --serve
Windows PowerShell:
.\.venv\Scripts\python.exe -m moneygraph run --data ./data --out ./out --serve
Откройте http://127.0.0.1:8000. Команда печатает run_id, каталог результатов и время расчёта. Без --serve она только рассчитывает и сохраняет результат, затем завершается. Данные можно хранить вне проекта: замените ./data на свой путь в кавычках.
Период по умолчанию — июль 2026. Для совместимого набора другого периода добавьте --period-start YYYY-MM-DD --period-end YYYY-MM-DD. Параметры кластеризации: --resolution 1.0 --seed 42; размер топа: --top-limit 30.
6. Открыть сохранённый результат без пересчёта
После пакетного запуска последний run_id записан в out/current.json.
macOS / Linux:
run_id=$(.venv/bin/python -c 'import json; print(json.load(open("out/current.json"))["run_id"])')
.venv/bin/python -m moneygraph.api --snapshot "./out/runs/$run_id"
Windows PowerShell:
$runId = (Get-Content .\out\current.json | ConvertFrom-Json).run_id
.\.venv\Scripts\python.exe -m moneygraph.api --snapshot ".\out\runs\$runId"
Для расчёта, загруженного через браузер, используйте каталог out/imports/runs/<run_id>: его ID виден в интерфейсе. В --snapshot передаётся папка конкретного завершённого расчёта, а не файл-указатель current.json.
Сценарий проверки за 5 минут
После установки и расчёта настоящего набора:
| Время | Действие жюри | Что проверяется |
|---|---|---|
| 0:00–0:40 | Посмотреть сводку: 2 248 клиентов, 3 119 связей, 105 групп | Загружен настоящий расчёт, а не демонстрационный экран |
| 0:40–1:40 | Открыть клиента из очереди; прочитать «Что видно по переводам» и «Подробности расчёта» | Приоритет и роль имеют основания; это разные оценки |
| 1:40–2:40 | Найти клиента по полному ID; открыть «Показать цепочку на графе» у сохранённого примера | Направления, участники и весь путь видны; можно вернуться к сети |
| 2:40–3:30 | Переключить «Переводы» и «По дням», раскрыть точную таблицу | Объяснение связано с операциями и историей за весь период |
| 3:30–4:15 | Посмотреть группу и предупреждения клиента на четвёртом колене или изолята | Ограничения выгрузки не превращаются в ложный уверенный вывод |
| 4:15–5:00 | «Экспорт результатов»: скачать Excel и три CSV | Результат пригоден для дальнейшей проверки и соответствует схемам ТЗ |
Для воспроизводимых примеров команда подготовила локальный подбор пяти сценариев: сбор, распределение, связь нескольких исходных клиентов, четвёртое колено, изолят.
macOS/Linux:
.venv/bin/python tests/graph/review_graph.py --data ./data --out ../moneygraph-defense-local
Windows:
.\.venv\Scripts\python.exe tests/graph/review_graph.py --data ./data --out ../moneygraph-defense-local
В demo-scenarios.local.json — выбранные ID, ожидаемые факты и шаги; в stability.json — чувствительность кластеров. Выбор делается по данным, ID не зашиты в правила. Для повторного запуска выберите новый --out: отчёты не перезаписываются. Не добавляйте эти локальные файлы в Git.
Как читать результаты
| Термин | Значение |
|---|---|
| Клиент / узел / gid | Участник сети и его исходный идентификатор |
| Исходный клиент / seed | Точка, от которой организаторы собирали исходящие связи |
| Стрелка | Перевод от плательщика к получателю; одна связь может объединять несколько операций |
| Глубина / depth | Шаг обнаружения при выгрузке, а не должность участника |
| Сообщество / группа | Структурная группа связанных клиентов, не доказанная организованная группа |
| Приоритет | Кого полезнее проверить раньше по выбранной формуле |
| Поддержка роли | Насколько признаки поддерживают роль с учётом ограничений |
| Сохранённый путь | Пример направленной связи от исходного клиента; не доказательство перемещения одной суммы |
В CSV оценки лежат в диапазоне 0–1, в интерфейсе и Excel показываются как 0–100. Ни одна из этих шкал не является вероятностью преступления. Все суммы в интерфейсе — KZT. Разница поступлений и отправлений не равна остатку счёта.
Как получаются роли и приоритет
От входных данных к объяснению
flowchart TD
A["Три Parquet-файла"] --> B["Проверка схемы, дат и денежных сумм"]
B --> C["Направленный граф, признаки и сообщества"]
C --> D["Правила ролей и очередь проверки"]
D --> E["Завершённый снимок с проверкой целостности"]
E --> F["Карточки, цепочки и активность по дням"]
E --> G["Три CSV и Excel-отчёт"]
- Проверяем вход. Уникальность клиентов и пар рёбер, существование концов связей, типы, период, суммы и согласованность агрегированных рёбер со всеми операциями. При расхождении расчёт останавливается.
- Строим ориентированный граф. Изолированные клиенты и повторные операции сохраняются. Суммы переводятся в целые тиыны.
- Считаем признаки. Плательщики/получатели, суммы, число операций и активных дней, PageRank, betweenness, достижимость от разных исходных клиентов, примеры путей до четырёх шагов.
- Находим сообщества. Louvain внутри слабосвязных компонент, на неориентированной проекции с весом суммы встречных направлений;
resolution=1.0,seed=42. Изоляты образуют отдельные группы. - Применяем объяснимые правила. Сохраняем принятые и отклонённые кандидаты, ограничения и вклад каждого фактора в приоритет.
- Публикуем целый результат. Снимок включает параметры, версии и SHA-256 артефактов. API использует проверенный результат, а не отдельный повторный скоринг.
Шесть ролей
in_degree/out_degree — разные плательщики/получатели без самого клиента. Самопереводы входят в денежные суммы и число операций. Для допуска роли также нужна поддержка правила не ниже 0,5.
| Код роли | Понятное название | Основной критерий допуска по умолчанию |
|---|---|---|
consolidator | Сбор денег | Не менее 3 плательщиков; их минимум вдвое больше получателей либо достижимы связи от минимум 2 исходных клиентов |
distributor | Распределение денег | Не менее 5 получателей и минимум вдвое больше, чем плательщиков |
transit | Передача дальше | Есть вход и выход, отношение наблюдаемого выхода ко входу 0,8–1,2; не исходный и не граничный клиент |
terminal | Возможный конец цепочки | Есть вход, нет исходящих операций, глубина меньше 4, не исходный клиент; последнее поступление минимум за 2 дня до конца периода |
coordinator | Связующий участник | Достижим от минимум 2 исходных клиентов; есть вход и выход, высокий betweenness и связи минимум с 2 другими сообществами |
peripheral | Роль не определена | Ни один кандидат не прошёл правила; это не признак безопасности |
При сравнении чисел контрагентов нулевой знаменатель заменяется на 1. Для terminal также должны быть известны число дней поступлений и дата последнего входа. «Высокий betweenness» означает процентиль не ниже 0,9 среди положительных значений. Точные формулы поддержки, разрешение равенств и ограничения оценок опубликованы в правилах скоринга.
Приоритет = 0,35 × S + 0,25 × M + 0,25 × B + 0,15 × V, где S — нормированное число достижимых исходных клиентов, M — поддержка принятой роли, B — процентиль betweenness, V — процентиль максимума наблюдаемого входящего/исходящего объёма. При равенстве приоритета первым идёт меньший ID.
Приоритет использует поддержку сигнала до ограничений уверенности в конкретном ярлыке. Поэтому клиент может заслуживать ранней проверки при неоднозначной роли. Это явный методический выбор: замена поддержки на ограниченную оценку меняет 13 из 20 участников топа. Проверка чувствительности описывает последствия; мы не скрываем эту зависимость.
Результаты на предоставленном наборе
| Показатель | Результат |
|---|---|
| Клиентов / исходных клиентов | 2 248 / 81 |
| Направленных связей / отдельных операций | 3 119 / 4 840 |
| Сумма наблюдаемых переводов | 365 890 012,01 KZT |
| Сообществ при настройках по умолчанию | 105 |
Клиентов в nodes_roles.csv / строк в top_nodes.csv | 2 248 / 30 |
| Сохранённых изолятов | 19 |
| Клиентов на глубине 4 | 444 |
| Сохранённых повторных строк операций | 97 |
| Сохранённых примеров путей / из них четырёхшаговых | 3 800 / 1 311 |
Сумма по графу — оборот всех наблюдаемых переводов, не объём уникальных денег и не сумма незаконных средств. Слабосвязных компонент 35 с учётом 19 изолятов, или 16 без них.
При resolution=0.8/1.0/1.2 получены 99/105/123 сообщества. ARI относительно разбиения 1.0 — 0,942 / 1,000 / 0,883. Это проверка чувствительности к масштабу группировки при фиксированном seed, не доказательство истинности состава групп. Методология и воспроизведение.
Размеченных истинных ролей нет. Accuracy, precision и recall на этом наборе не заявляются. Воспроизводимость и прохождение тестов доказывают согласованность реализации, но не правильность всех AML-гипотез.
Файлы результата
После пакетного запуска: out/runs/<run_id>/. out/current.json указывает на последний завершённый расчёт.
| Файл | Содержимое |
|---|---|
nodes_roles.csv | gid, role, role_score, cluster_id, priority_score, evidence — все клиенты, объяснение до 200 символов |
clusters.csv | cluster_id, n_nodes, n_seed, sum_kzt_internal, top_gids, hypothesis |
top_nodes.csv | rank, gid, role, priority_score, why — первые 30 клиентов по умолчанию |
features.parquet | Полные рассчитанные признаки |
transactions.parquet | Нормализованные операции, включая повторы и ссылки на исходные строки |
explanations.jsonl | Подробные правила, кандидаты, ограничения и вклады в приоритет |
graph.json | Клиенты, направленные связи и результаты анализа |
quality.json | Сверки и ограничения данных |
manifest.json | Параметры, версии, идентификатор расчёта и хеши артефактов |
Excel формируется по кнопке «Экспорт результатов → Открыть в Excel — рекомендуется». Он дополняет обязательные CSV, не заменяя их. Для CSV в Excel импортируйте ID клиента как текст: автоматическое распознавание длинных чисел может изменить последние цифры.
Данные, технологии и AI
Данные: обезличенный набор организаторов, внутрибанковские исходящие связи на четыре колена за 1–31 июля 2026, операции от 5 000 KZT. Внешнего обогащения нет. Схема входа:
| Файл | Обязательные поля |
|---|---|
nodes.parquet | gid int64, depth целое 0–4, is_seed bool |
edges.parquet | src, dst int64, sum_kzt, n_tx целое, depth 1–4 |
transactions.parquet | src, dst int64, date дата без времени, sum_kzt |
Входные суммы положительные, в KZT, с точностью не более двух десятичных знаков. Пары и агрегаты операций должны совпадать с edges. Изменение периода не позволяет автоматически использовать произвольную выгрузку другой схемы.
Стек: Python 3.12, pandas 2.2.3, PyArrow 25.0.1, NumPy 2.3.5, NetworkX 3.7, SciPy 1.17.0; FastAPI 0.141.1, Uvicorn 0.53.0, Pydantic 2.13.5; React, TypeScript, Vite и Cytoscape.js. Основные Python-версии закреплены в pyproject.toml, frontend — в frontend/pnpm-lock.yaml.
AI в разработке: команда использовала Codex для реализации, тестирования и проверки решений. Основной продукт выполняет графовые алгоритмы и объяснимые правила, а не вызов LLM и не обученную модель классификации.
AI-агент: что начали и не успели завершить. Мы начали разработку AI-агента, который суммирует данные о клиенте, его переводах и связях и готовит краткую сводку для аналитика со ссылками на исходные факты. За время хакатона успели реализовать backend-модуль, подключить API и вкладку в карточке клиента. Времени на полноценную доводку и проверку качества ответов реальной модели не хватило. Живой запрос выполнен, однако полученные записки отклонены проверкой утверждений или формата; проверка фактов не ослаблялась. Поэтому функция остаётся экспериментальной, а внешние AI-вызовы по умолчанию выключены. Основное расследование — граф, роли, приоритеты, операции и отчёты — работает независимо от AI. Внешняя передача в OpenAI разрешена пользователем; ключ вводится локально. Запуск и быстрое отключение.
Что проверено
На объединённой версии совместно прошли 259 тестов и 36 подслучаев: основной набор ниже плюс 92 проверки AI и его API. В браузере на синтетическом ответе проверены записка, исходный факт, кэш, операции, ошибка провайдера и смена клиента. Живые ответы модели проходят отдельную приёмку; отклонённая записка не показывается. Подробнее — приёмка AI.
Проверка выполнена в новом Python-окружении без системных Python-пакетов и без дополнительного PYTHONPATH. Установлен проект с зависимостями из репозитория, выполнены pip check, расчёт, автоматические проверки, настоящий HTTP-запуск и проверка браузера. Детальный протокол и границы проверки — docs/jury-verification.md.
| Среда | Статус |
|---|---|
| Ubuntu 24.04.3 x86_64, Python 3.12.14 | Установка, полный расчёт, API, тесты и браузер проверены при подготовке README |
| Windows x64 | Командный запуск описан в протоколе C; дополнительно проверен подбор всех бинарных зависимостей Python 3.12 |
| macOS 12+ Apple Silicon / Intel | Проверен подбор бинарных зависимостей Python 3.12; полный запуск интерфейса на этих ОС в этой проверке не выполнялся |
В проверяемой сборке прошли 167 тестов и 36 подслучаев с подключёнными настоящими данными и файловым снимком. В браузере проверены граф, карточка, полная цепочка, дневная активность, операции, Excel и загрузка настоящих Parquet; ошибок JavaScript не обнаружено. Дополнительно проверены понятная очередь, пять сценариев A, копирование резюме и сохранение заметок на синтетическом стенде.
Контрольный Linux-прогон объединённой сборки завершил полный расчёт за 2,346 с. В Windows-прогоне команды — 8,563 с. Оба замера исключают установку и открытие браузера; они не гарантируют время любого компьютера. Требование ТЗ — менее пяти минут на выданном объёме.
Мы не обещаем запуск на любой ОС, телефоне, 32-битном устройстве или произвольной версии Python. Приведённые инструкции относятся к указанным настольным средам.
Автоматическая проверка
Для обычных тестов установите дополнительные зависимости и запустите:
macOS/Linux:
.venv/bin/python -m pip install ".[serve,dev]"
.venv/bin/python -m pytest -q
Windows:
.\.venv\Scripts\python.exe -m pip install ".[serve,dev]"
.\.venv\Scripts\python.exe -m pytest -q
Без переменных окружения проверки выданного набора пропускаются. Для полной приёмки сначала выполните пакетный запуск с --data ./data --out ./out, затем:
macOS/Linux:
export MONEYGRAPH_DATA_DIR="$PWD/data"
export MONEYGRAPH_API_TESTS=1
run_id=$(.venv/bin/python -c 'import json; print(json.load(open("out/current.json"))["run_id"])')
export MONEYGRAPH_SNAPSHOT_DIR="$PWD/out/runs/$run_id"
.venv/bin/python -m pytest -q
Windows PowerShell:
$env:PYTHONUTF8 = "1"
$env:MONEYGRAPH_DATA_DIR = (Resolve-Path .\data).Path
$env:MONEYGRAPH_API_TESTS = "1"
$runId = (Get-Content .\out\current.json | ConvertFrom-Json).run_id
$env:MONEYGRAPH_SNAPSHOT_DIR = (Resolve-Path ".\out\runs\$runId").Path
.\.venv\Scripts\python.exe -m pytest -q
Тесты сверяют суммы, роли и ограничения, все карточки настоящего снимка, направления путей, повторные операции, дневную активность, импорты и соответствие экспортов. Реальный HTTP-тест использует отдельный свободный локальный порт.
Если запуск не получился
| Симптом | Что сделать |
|---|---|
python3.12 или py не найден | Установить Python 3.12, открыть новый терминал и проверить версию. На macOS при сбое Homebrew Python использовать официальный установщик |
| Ошибка версии Python при pip install | Создать окружение именно Python 3.12, а не системным 3.11/3.13 |
venv / ensurepip отсутствует на Ubuntu | Установить пакет python3.12-venv, затем заново создать окружение |
ModuleNotFoundError | Использовать Python из .venv и повторить -m pip install ".[serve]" из корня проекта |
data/nodes.parquet не найден | Распаковать данные; проверить отсутствие лишнего уровня data/data; передать правильную папку через --data |
| Период или суммы не проходят проверку | Использовать три файла одного набора и период, охватывающий все операции; не удалять строки для обхода сверки |
| Адрес не открывается | Убедиться, что сервер ещё работает; открыть именно http://127.0.0.1:8000, без HTTPS |
| Порт занят | Добавить --port 8001 и открыть адрес с этим портом |
| Frontend отсутствует / ответ 503 | Запускать из полного checkout с frontend/dist; при отдельной установке wheel передать --static-dir с абсолютным путём к этой папке |
| Не удаётся скачать зависимости | Проверить доступ к PyPI и интернет; офлайн-установка без заранее подготовленных пакетов не заявляется |
| Обновлён код, но поведение старое | Повторить установку -m pip install ".[serve]" и перезапустить сервер |
| ID клиента испортился в Excel | Использовать дополнительный XLSX-отчёт либо импортировать колонку ID из CSV как текст |
Ограничения и дальнейшее развитие
- Наблюдения неполные: один месяц, один банк, порог 5 000 KZT, исходящий обход. Внешние потоки и меньшие суммы отсутствуют.
- Четвёртое колено обрезано: отсутствие выхода не доказывает удержания средств; вход исходных клиентов также неполон.
- Роли — эвристики: нет размеченной истины, статистической калибровки и автоматического юридического вывода. Пороговые правила требуют пилота.
- Время — только день: дневные суммы и структурные пути не доказывают мгновенный транзит или прохождение одной суммы через всю цепочку.
- Локальный MVP: браузерный импорт ограничен 40 МиБ на файл, 10 000 клиентов, 50 000 связей и 200 000 операций. Один импорт одновременно. Нет банковской интеграции и потокового мониторинга.
- Визуализация ограничивает объём: обычный граф показывает до 250 узлов; скрытая часть обозначается. Поиск работает по всему снимку, отдельный путь показывается целиком.
- Нет командного управления делами: локальные статусы и заметки уже сохраняются отдельно от расчёта в
out/reviews.sqlite3; общие дела, назначение ответственных, авторизация и аудит действий пользователей — следующие этапы. Сервер слушает loopback; публиковать его как банковский сервис без этих механизмов нельзя. - Хеши защищают согласованность: они выявляют повреждение и рассогласование файлов, но не являются цифровой подписью.
Следующие шаги: пилот с AML-аналитиками и измерение времени проверки; калибровка правил на экспертной разметке; приёмка AI-объяснений в отдельной тестовой ветке; командное управление расследованиями; проверка устойчивости при изменении данных и масштабирование.
Что изменится при росте до миллиона узлов
Это план масштабирования, предусмотренный ТЗ, а не заявление о поддержке такого объёма текущим MVP. Помимо числа узлов важны число рёбер, операций и исходных клиентов, а также размер крупнейшей компоненты. Простого увеличения лимита загрузки недостаточно.
| Участок | Изменение подхода |
|---|---|
| Загрузка и денежные сверки | Читать Parquet порциями и только нужные столбцы; агрегировать операции по частям, сохраняя точные суммы в целых тиынах и проверку итогов. Не держать исходные байты, таблицы и все копии графа одновременно в памяти |
| Представление графа | Перейти от Python-объектов NetworkX к компактным массивам и разреженному представлению; исходные int64 ID хранить отдельно от внутренних индексов |
| Центральности | Уже сейчас betweenness оценивается по min(128, N) источникам. На большом объёме выбирать размер выборки по бюджету времени и проверять устойчивость топа; PageRank считать над разреженным графом с явными условиями остановки |
| Достижимость и примеры путей | Сохранить смысл исходящего обхода до четырёх шагов; ограничивать число сохраняемых примеров, кэшировать востребованные пути. Неполный расчёт достижимости явно маркировать: его нельзя незаметно подставлять в скоринг как полный |
| Сообщества | Обрабатывать независимые компоненты параллельно в пределах памяти. Для одной большой компоненты использовать подходящий движок и измерять время отдельно; произвольное разрезание её на куски может изменить найденные группы |
| Хранение и API | Хранить результаты с индексами по клиенту, группе и приоритету; читать карточки и операции по запросу. Большой JSON и все операции не загружать целиком при каждом запуске сервера |
| Интерфейс | Сначала показывать агрегаты сообществ и очередь, затем раскрывать локальный подграф. Сохранять глобальный поиск, пагинацию и предупреждение об ограниченном отображении |
При переходе сохраняются контракты трёх CSV, объяснения правил, хеши и параметры снимка. Приёмка включает сверку сумм и количества строк, сравнение ролей и состава топа на контрольном наборе, оценку чувствительности сообществ и замеры времени/пиковой памяти при росте узлов и рёбер. Распределённую инфраструктуру следует добавлять только по результатам этих замеров. Требование текущего кейса «менее пяти минут» проверено на выданном наборе, на миллион узлов оно автоматически не переносится.
Материалы проекта
- Техническое задание Freedom
- Качество данных и методология графа
- Правила ролей и чувствительность очереди
- Расчёт и снимки, API и интерфейс
- Полные цепочки: контракт и проверки
- Проверка установки для жюри
Публичная развёрнутая версия не предоставляется: демонстрация запускается локально по инструкции выше. Исходные финансовые файлы, результаты с ID клиентов, API-ключи и пароли в репозиторий не включаются. Данные используются в рамках условий организаторов; в публичных иллюстрациях — только синтетическое демо.
Авторы коммитов
История коммитов
- 2026-09-23 17:56style(ui): replace paper aesthetic with cool surfaces and vivid violetnaki707
- 2026-09-23 17:53Merge pull request #4 from BAITC-Hacks/codex/readme-pitchNura
- 2026-09-23 17:52docs: lead README with product pitch and disclose unfinished AI acceptanceCurtisEllese
- 2026-09-23 17:52style(ui): give Freeman an editorial dossier layout and distinctive palettenaki707
- 2026-09-23 17:48Merge all team components and contrast improvements into mainnurasylnurasyl380
- 2026-09-23 17:42Merge remote-tracking branch 'origin/main' into codex/ai-assistant-testnurasylnurasyl380
- 2026-09-23 17:42Connect optional AI assistant to client card in test branchnurasylnurasyl380
- 2026-09-23 17:28Update README.mdCurtisEllese
Все коммиты (43)
- 2026-09-23 17:28style(ui): improve contrast and clarify action and warning coloursnaki707
- 2026-09-23 17:18Document AI test branch and combined acceptance resultsnurasylnurasyl380
- 2026-09-23 17:18Prepare isolated AI acceptance branch and resolve test module collisionnurasylnurasyl380
- 2026-09-23 17:12Merge AI assistant into isolated acceptance branchnurasylnurasyl380
- 2026-09-23 17:12Document main release and separate AI acceptance branchnurasylnurasyl380
- 2026-09-23 17:09Merge verified application and jury README into mainnurasylnurasyl380
- 2026-09-23 17:07Merge pull request #2 from BAITC-Hacks/codex/release-readme-fixesNura
- 2026-09-23 17:03Merge remote-tracking branch 'origin/codex/api-ui' into codex/api-uinurasylnurasyl380
- 2026-09-23 17:02Guide analyst workflow from priority queue to evidencenurasylnurasyl380
- 2026-09-23 17:02docs: fix deleted clone branch and document million-node scalingCurtisEllese
- 2026-09-23 16:58fix(ai): handle completed HTTP responses without false validation failuresnaki707
- 2026-09-23 16:56Merge pull request #1 from BAITC-Hacks/codex/jury-readmeNura
- 2026-09-23 16:52docs: add complete jury pitch and verified clean-install guideCurtisEllese
- 2026-09-23 16:31Connect complete saved path evidence viewernurasylnurasyl380
- 2026-09-23 16:29feat(ai): add explicit OpenAI preset and safe connection checknaki707
- 2026-09-23 16:22Merge complete saved path evidence into API UI branchnurasylnurasyl380
- 2026-09-23 16:19Connect daily activity chart to client cardsnurasylnurasyl380
- 2026-09-23 16:17feat(graph): materialize complete saved seed paths for investigationCurtisEllese
- 2026-09-23 16:17feat(ai): add cited AML explanations with bounded provider calls and factual reviewnaki707
- 2026-09-23 16:09Merge daily client activity into API UI branchnurasylnurasyl380
- 2026-09-23 16:07feat(graph): add exact daily client activity and local chart reviewCurtisEllese
- 2026-09-23 16:03Add local dataset uploads and readable Excel reportsnurasylnurasyl380
- 2026-09-23 15:25Complete integrated UI acceptance and explain role uncertaintynurasylnurasyl380
- 2026-09-23 15:16Integrate final graph validation and defense scenariosnurasylnurasyl380
- 2026-09-23 15:16Integrate scoring pipeline and shared serving commandnurasylnurasyl380
- 2026-09-23 15:14test(graph): prepare five verifiable defense scenariosCurtisEllese
- 2026-09-23 15:09feat(pipeline): serve verified snapshots through the team APInaki707
- 2026-09-23 15:00Integrate verified pipeline snapshots with API and real-data UInurasylnurasyl380
- 2026-09-23 14:54test(data-graph): verify community stability and finalize scoring handoffCurtisEllese
- 2026-09-23 14:44Add read-only investigation API and local graph interfacenurasylnurasyl380
- 2026-09-23 14:44feat(pipeline): integrate team graph and publish reproducible analysis snapshotsnaki707
- 2026-09-23 14:24Verify graph-to-scoring contract on the provided datasetnaki707
- 2026-09-23 14:10Document scoring progress, VS Code workflow and integration next stepsnaki707
- 2026-09-23 14:04Add explainable role scoring and priority ranking with graph feature adapternaki707
- 2026-09-23 13:54feat(data-graph): validate money flows and compute deterministic graph featuresCurtisEllese
Структура репозитория (106 файлов)
.gitignore README.md docs/ai-assistant.md docs/data-quality.md docs/graph-methodology.md docs/handoff-to-c.md docs/images/demo-overview.png docs/jury-verification.md docs/pipeline.md docs/scoring-decisions.md docs/scoring-progress.md docs/scoring-sensitivity.md docs/scoring.md docs/ui.md frontend/.gitignore frontend/index.html frontend/package.json frontend/pnpm-lock.yaml frontend/pnpm-workspace.yaml frontend/public/trace.svg frontend/src/AIAssistant.tsx frontend/src/App.tsx frontend/src/DailyActivity.tsx frontend/src/ImportData.tsx frontend/src/InvestigationIntro.tsx frontend/src/NetworkGraph.tsx frontend/src/PathView.tsx frontend/src/ReviewEditor.tsx frontend/src/api.ts frontend/src/main.tsx frontend/src/styles.css frontend/src/tokens.css frontend/src/types.ts frontend/tsconfig.json frontend/vite.config.ts moneygraph/__main__.py moneygraph/ai/__init__.py moneygraph/ai/check.py moneygraph/ai/config.py moneygraph/ai/context.py moneygraph/ai/errors.py moneygraph/ai/models.py moneygraph/ai/prompt.py moneygraph/ai/provider.py moneygraph/ai/service.py moneygraph/ai/validation.py moneygraph/analytics/communities.py moneygraph/analytics/explanations.py moneygraph/analytics/features.py moneygraph/analytics/graph.py moneygraph/analytics/ranking.py moneygraph/analytics/roles.py moneygraph/analytics/temporal.py moneygraph/api/.gitignore moneygraph/api/__init__.py moneygraph/api/__main__.py moneygraph/api/ai.py moneygraph/api/app.py moneygraph/api/demo.py moneygraph/api/excel.py moneygraph/api/imports.py moneygraph/api/models.py moneygraph/api/presentation.py moneygraph/api/requirements.txt moneygraph/api/reviews.py moneygraph/api/service.py moneygraph/api/snapshot.py moneygraph/config.py moneygraph/io/exports.py moneygraph/io/load.py moneygraph/io/snapshots.py moneygraph/io/validate.py moneygraph/pipeline.py pyproject.toml scripts/start-ai-preview.ps1 tests/ai/conftest.py tests/ai/test_ai_validation.py tests/ai/test_api_boundary.py tests/ai/test_context.py tests/ai/test_openai.py tests/ai/test_provider.py tests/ai/test_service.py tests/ai/test_ui_api.py tests/api/.gitignore tests/api/test_analyst_workflow.py tests/api/test_api.py tests/api/test_daily_activity.py tests/api/test_imports_reports.py tests/api/test_path_view.py tests/api/test_snapshot.py tests/data/test_provided_dataset.py tests/data/test_validation.py tests/graph/PATH-EVIDENCE.md tests/graph/review_daily_activity.py tests/graph/review_graph.py tests/graph/review_path_evidence.py tests/graph/test_graph.py tests/graph/test_path_evidence.py tests/graph/test_review_graph.py tests/graph/test_temporal.py tests/integration/test_serving.py tests/pipeline/test_pipeline.py tests/pipeline/test_snapshots.py tests/scoring/test_graph_contract.py tests/scoring/test_scoring.py tests/scoring/validate_features.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.