AAYMA
RU
Войти

TRACE

Локальное рабочее место AML-аналитика: из трёх Parquet-файлов Freedom строит направленный граф переводов, определяет роли и сообщества и выдаёт…

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

О проекте

Команда: 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.md

TRACE · Граф денег

От 81 исходного клиента — к приоритетам проверки сети из 2 248 участников.

HackAlem AI · трек «Финансы» · кейс Freedom.

Когда AML-аналитик видит нижний уровень цепочки переводов, главный вопрос — кто выше собирает, передаёт и распределяет деньги. Чтобы ответить, нужно связать тысячи операций, определить значимых участников и проверить, что стоит за каждой гипотезой. От выбора первого клиента зависит, куда пойдёт расследование.

TRACE показывает, кого проверить первым, почему этот клиент важен и какими переводами это подтверждается. Аналитик загружает три файла и получает очередь проверки, предполагаемые роли, группы связанных клиентов и направленную карту движения средств. Из карточки он переходит к цепочке, отдельным операциям и активности по дням, фиксирует заметку и выгружает результат.

Ценность для банка — сосредоточить время специалиста на проверке обоснованных гипотез. TRACE собирает структуру сети и основания приоритета в одном рабочем месте. Следующий шаг виден сразу: изучить точку сбора денег, проверить массовое распределение или разобраться в участнике, связывающем несколько исходных клиентов.

Что уже получено на наборе FreedomРезультат
Клиенты с ролью, приоритетом и объяснением2 248 из 2 248
Переводы, учтённые при построении сети4 840 операций · 3 119 связей
Структурные группы для исследования105
Клиенты в готовом списке первоочередной проверки30
Полный расчёт в контрольном Linux-прогоне2,346 секунды

Время относится к описанному ниже контрольному прогону, без установки и открытия браузера. Экономию времени аналитика и точность гипотез предстоит измерить в пилоте.

Запустить проект · Пройти демо за 5 минут · Наши преимущества · Проверить методику

TRACE: очередь проверки, направленный граф и объяснение клиента

Работающее приложение на синтетическом демо. Числа в таблице выше относятся к отдельному расчёту предоставленного набора 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. Для полноценной проверки расчёта нужен этот набор; встроенного демо достаточно только для знакомства с интерфейсом.

В уже открытом приложении:

  1. Нажмите «Новые данные».
  2. Выберите одновременно все три Parquet-файла. Если в архиве есть вложенная папка data, выбирайте файлы именно из неё.
  3. Для набора кейса укажите 01.07.2026–31.07.2026.
  4. Нажмите «Загрузить и рассчитать» и дождитесь завершения.
  5. Проверьте, что баннер 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-отчёт"]
  1. Проверяем вход. Уникальность клиентов и пар рёбер, существование концов связей, типы, период, суммы и согласованность агрегированных рёбер со всеми операциями. При расхождении расчёт останавливается.
  2. Строим ориентированный граф. Изолированные клиенты и повторные операции сохраняются. Суммы переводятся в целые тиыны.
  3. Считаем признаки. Плательщики/получатели, суммы, число операций и активных дней, PageRank, betweenness, достижимость от разных исходных клиентов, примеры путей до четырёх шагов.
  4. Находим сообщества. Louvain внутри слабосвязных компонент, на неориентированной проекции с весом суммы встречных направлений; resolution=1.0, seed=42. Изоляты образуют отдельные группы.
  5. Применяем объяснимые правила. Сохраняем принятые и отклонённые кандидаты, ограничения и вклад каждого фактора в приоритет.
  6. Публикуем целый результат. Снимок включает параметры, версии и 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.csv2 248 / 30
Сохранённых изолятов19
Клиентов на глубине 4444
Сохранённых повторных строк операций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.csvgid, role, role_score, cluster_id, priority_score, evidence — все клиенты, объяснение до 200 символов
clusters.csvcluster_id, n_nodes, n_seed, sum_kzt_internal, top_gids, hypothesis
top_nodes.csvrank, 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.parquetgid int64, depth целое 0–4, is_seed bool
edges.parquetsrc, dst int64, sum_kzt, n_tx целое, depth 1–4
transactions.parquetsrc, 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, объяснения правил, хеши и параметры снимка. Приёмка включает сверку сумм и количества строк, сравнение ролей и состава топа на контрольном наборе, оценку чувствительности сообществ и замеры времени/пиковой памяти при росте узлов и рёбер. Распределённую инфраструктуру следует добавлять только по результатам этих замеров. Требование текущего кейса «менее пяти минут» проверено на выданном наборе, на миллион узлов оно автоматически не переносится.

Материалы проекта

Публичная развёрнутая версия не предоставляется: демонстрация запускается локально по инструкции выше. Исходные финансовые файлы, результаты с ID клиентов, API-ключи и пароли в репозиторий не включаются. Данные используются в рамках условий организаторов; в публичных иллюстрациях — только синтетическое демо.

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

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

nurasylnurasyl380 20naki707 11CurtisEllese 9Nura 3

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

  • 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
Ветки (11)

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

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

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