AAYMA
RU
Войти

TRACE — Граф денег

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

Рабочий MVP
Команда «LLM-Solo» 11💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: LLM-Solo
Кейс HackAlem.ai: Финансы — Freedom
Стадия: Рабочий MVP

Задача кейса: «Граф денег»: восстановить структуру организованной группы по сети транзакций (AML)

Суть

Локальное рабочее место AML-аналитика: по трём Parquet-файлам строится граф переводов, узлам назначаются роли, выделяются кластеры и формируется рейтинг из 50 клиентов для ручной проверки.

Как устроено

Пайплайн moneygraph проверяет схемы Parquet и строит направленный взвешенный граф в NetworkX. Затем считает признаки (степени, betweenness, достижимость от seed, сопоставление входящих и исходящих объёмов в окне 0–2 дня) и назначает 6 ролей правилами с порогами из config/roles.json в фиксированном порядке. Сообщества ищутся Louvain на неориентированной проекции. Приоритет считается формулой 0.30·seed_reach + 0.25·flow + 0.20·bridge + 0.15·fan + 0.10·role_support. Результаты выгружаются в CSV, JSON и самодостаточный HTML-отчёт для интерфейса TRACE на Canvas.

Ключевые решения

  • NetworkX
  • Louvain
  • betweenness centrality
  • rule-based roles
  • flow matching 0-2 days
  • motif detection
  • weighted priority score

Особенности

В run.json записываются хеши исходников и версии библиотек, отдельная команда moneygraph.verify перепроверяет выгрузки по исходным данным. Суммы хранятся в целых сотых KZT, чтобы избежать ошибок округления. Чат «След» заложен через AI_CONTRACT.md, но сервер модели не подключён.

Стек

Python · pandas · NumPy · PyArrow · NetworkX · HTML/CSS/JS Canvas · Node.js

Модели

OpenAI Responses API


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-7a019b2e-llm-solo.

README

README.md

TRACE — Граф денег

Локальное рабочее место AML-аналитика: от переводов к объяснимой структуре финансовых связей.

Проект для финансового кейса Freedom на хакатоне HackAlem AI. Помогает аналитику, который начинает проверку с известных клиентов, увидеть связи, найти узлы сбора и распределения средств, выделить сообщества и выбрать порядок ручной проверки.

Результаты — структурные гипотезы по наблюдаемой сети, а не доказательства преступления или виновности. Основной сценарий работает локально, без API-ключей и внешних сервисов.

Этот README описывает ветку main репозитория BAITC-Hacks/hack-7a019b2e-llm-solo, проверенную на коммите e747bc26663dcbc67ca5c12c3f9727db5e4b293d. Команды ниже относятся к её структуре (moneygraph/, frontend/, корневой requirements.txt).

Что реализовано

  • Чтение трёх Parquet-файлов с проверкой схем, идентификаторов, денежных сумм, дат и согласованности рёбер с транзакциями.
  • Направленный взвешенный граф со всеми входными узлами, включая изолированные.
  • Шесть ролей клиентов, числовые основания и оценка соответствия эвристике.
  • Кластеризация Louvain: состав сообществ, число seed, внутренний оборот, ведущие узлы и гипотеза.
  • Рейтинг до 50 клиентов для ручной проверки с объяснением вклада признаков.
  • Сопоставление входящих и исходящих объёмов в окне 0–2 календарных дней без повторного использования одного входящего объёма.
  • Интерфейс TRACE: поиск точного gid, граф, фильтры, окраска по роли или кластеру, карточки клиентов, просмотр операций и CSV-экспорт.
  • Экспериментальная панель чата «След» с привязкой к выбранному клиенту; сервер модели пока не подключён, без него ответы не генерируются.
  • Самодостаточный HTML-отчёт и полный JSON-снимок для интерфейса.
  • Запись параметров, версий библиотек, времени расчёта и хешей исходников; отдельная проверка согласованности выгрузок.

Как работает решение

  1. Аналитик помещает выданные Parquet-файлы в data/.
  2. Запускает расчёт. Пайплайн валидирует данные, строит граф, вычисляет признаки, роли, кластеры и рейтинг.
  3. Получает CSV, JSON и HTML в artifacts/.
  4. Открывает TRACE через локальный сервер либо импортирует JSON в интерфейс без сервера.
  5. Выбирает клиента из рейтинга или ищет его по gid, изучает переводы, основания роли и ограничения наблюдения.
  6. Использует результат для дальнейшей ручной проверки. Роли и оценки не пересчитываются в браузере.

Технологии

КомпонентТехнологии и назначение
АналитикаPython; в документации main рекомендованы Python 3.11/3.12
Таблицы и вычисленияpandas 2.3.3, NumPy 2.3.3
Чтение ParquetPyArrow 21.0.0
Граф и сообществаNetworkX 3.5, Louvain, betweenness centrality
ИнтерфейсHTML, CSS, JavaScript, Canvas; готовые файлы включены в Git, CDN не используется
Локальная раздача файловPython-сервер на 127.0.0.1
ПроверкиPython unittest и Node.js test runner
Дополнительный LLM-примерNode.js 22+, OpenAI Responses API; отдельно от аналитики и сайта

Версии Python-зависимостей закреплены в requirements.txt. База данных, Docker и GPU для основного сценария не нужны. В репозитории указано использование Codex при разработке; работающий аналитический пайплайн не вызывает LLM.

Архитектура

nodes.parquet + edges.parquet + transactions.parquet
                         |
                  Чтение и валидация
                         |
                  Направленный граф
                         |
              Признаки + сообщества Louvain
                         |
                 Роли + приоритет проверки
                         |
          CSV + metrics.json + graph.json + run.json
                         |
               report.html / интерфейс TRACE
ПутьОтветственность
moneygraph/__main__.pyОбщий запуск, параметры, хеши, время и запуск сервера
moneygraph/io.pyЗагрузка и проверка исходных данных, денежные суммы в целых сотых KZT
moneygraph/analysis.pyПостроение графа, признаки, роли, сообщества и рейтинг
moneygraph/report.pyПроверка выходных контрактов и экспорт
moneygraph/snapshot.pyЕдиный JSON-снимок с точными строковыми ID
moneygraph/verify.pyПроверка записанных результатов по исходным данным
moneygraph/server.pyРаздача разрешённых файлов на локальном адресе
moneygraph/viewer.htmlШаблон самостоятельного графового отчёта
frontend/Интерфейс TRACE, локальный импорт и просмотр операций
frontend/build.cjsСборка исходников приложения и панели чата в готовые app.js и styles.css
AI_CONTRACT.mdКонтракт будущего серверного подключения чата
config/roles.jsonПороги и веса аналитики
tests/Тесты Python
src/, test/Отдельный Node.js LLM-каркас и его тесты
starter/Сохранённая стартовая заготовка; основная точка входа в main — moneygraph

Роли и объяснимость

Порядок правил: coordinator → distributor → consolidator → transit → terminal → peripheral. Первая подходящая роль становится основной; интерфейс может показать все сработавшие правила.

Здесь входящая/исходящая степень означает число уникальных контрагентов без самопереводов; seed — исходный клиент обхода.

РольОсновное правило по умолчанию
coordinatorСуммарная степень ≥4, положительная betweenness не ниже 90-го перцентиля активных узлов, связи с ≥2 другими кластерами и достижимость от ≥3 seed
distributor≥5 получателей; исходящая степень ≥2 × max(входящая степень, 1)
consolidator≥5 плательщиков и достижимость от ≥2 seed
transitНе seed и не обрезанный узел; положительный вход, входящие и исходящие связи; отношение выхода к входу 0,8–1,2; сопоставленный объём покрывает ≥80% входа и выхода в окне 0–2 дня
terminalНе seed и не обрезанный узел; положительный наблюдаемый вход и отсутствие исходящих контрагентов
peripheralОстальные случаи, включая недостаточность наблюдений

role_score — сила соответствия правилу: базовые 0,60 и по 0,10 за три дополнительных признака в classify; максимум 0,90. Для обрезанных узлов максимум 0,60; для peripheral — 0,20. Это не вероятность виновности.

Приоритет рассчитывается по формуле 0,30 × seed_reach + 0,25 × flow + 0,20 × bridge + 0,15 × fan + 0,10 × role_support: нормированный охват seed, перцентиль оборота, посредничества, числа контрагентов и поддержка роли. Для peripheral поддержка роли равна нулю; для изолятов весь приоритет равен нулю. Равенства разрешаются сортировкой по gid по возрастанию.

Louvain работает на неориентированной проекции; внутренний оборот считается по направленным рёбрам исходного графа. Параметры и случайный seed задаются в config/roles.json. Betweenness по умолчанию точная; предусмотрен режим approximate.

Установка и запуск

1. Получить код main

Для новой копии проекта:

git clone --branch main https://github.com/BAITC-Hacks/hack-7a019b2e-llm-solo.git trace-main
cd trace-main

Если уже работаете в другой ветке, используйте отдельную папку: эти команды не требуют переключать существующую рабочую копию.

2. Создать окружение и установить зависимости

Windows PowerShell, Python 3.12:

py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt

Linux/macOS с установленным Python 3.12:

python3.12 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt

Интернет нужен для получения кода и зависимостей. Далее основной сценарий работает локально. Используйте Python из созданного окружения при каждом запуске.

3. Добавить данные

Распакуйте данные организаторов, сохранив структуру:

data/
  nodes.parquet
  edges.parquet
  transactions.parquet

Датасет не поставляется в Git. CSV не являются поддерживаемым входом текущего moneygraph/io.py.

4. Рассчитать результаты

Из корня проекта:

.\.venv\Scripts\python.exe -m moneygraph --data data --out artifacts

Для Linux/macOS замените .\.venv\Scripts\python.exe на .venv/bin/python.

5. Открыть интерфейс

Расчёт и запуск локального сервера:

.\.venv\Scripts\python.exe -m moneygraph --data data --out artifacts --serve

Откройте http://127.0.0.1:8765/frontend/ для TRACE или http://127.0.0.1:8765/report.html для самостоятельного отчёта. Остановка сервера — Ctrl+C; другой порт задаётся, например, --port 8766.

Без сервера можно открыть artifacts/report.html. Для TRACE откройте artifacts/frontend/index.html, нажмите «Импорт данных» и выберите artifacts/graph.json.

При установленном Node.js 22+ доступны npm run analyze и npm start; они вызывают Python через вспомогательный скрипт. Для статического интерфейса npm install и сборка не нужны.

Готовые файлы фронтенда уже включены в репозиторий. После изменения frontend/app-source.js, agent*.js, styles-source.css или agent.css пересоберите их командой node frontend/build.cjs. Проверка актуальности сборки: node frontend/build.cjs --check.

Выходные файлы

Файл в artifacts/Поля или назначение
nodes_roles.csvgid,role,role_score,cluster_id,priority_score,evidence
clusters.csvcluster_id,n_nodes,n_seed,sum_kzt_internal,top_gids,hypothesis
top_nodes.csvrank,gid,role,priority_score,why
graph.jsonПолный снимок узлов, связей, операций, кластеров и рейтинга
metrics.jsonПризнаки и ограничения наблюдаемости узлов
run.jsonКонфигурация, версии, хеши и время выполнения
report.htmlСамодостаточный отчёт со встроенными данными
frontend/Копия интерфейса TRACE для просмотра результата

Как проверить решение

Автоматическая проверка

После расчёта выполните:

.\.venv\Scripts\python.exe -m moneygraph.verify --data data --out artifacts
.\.venv\Scripts\python.exe -m unittest discover -s tests -v

Успешная проверка экспортов возвращает JSON с status: "ok" и код завершения 0. Проверяются схемы, покрытие узлов, операции и повторы, суммы, кластеры, рейтинг, согласованность CSV/JSON, хеши и ограничение времени 300 секунд. При использовании собственного конфига передайте одинаковый --config в расчёт и проверку.

Для тестов JavaScript при установленном Node.js:

node --test frontend/*.test.cjs
npm test

Наличие тестов в репозитории не означает, что они уже прошли в вашем окружении. Время текущего расчёта смотрите в artifacts/run.json; фиксированный результат и скорость на любом ноутбуке не гарантируются.

Сценарий демо на пять минут

  1. 30 секунд: объясните задачу и неполноту наблюдаемой сети.
  2. 60 секунд: покажите запуск и три CSV, затем результат moneygraph.verify.
  3. 90 секунд: откройте TRACE, выберите клиента из рейтинга и покажите основания роли и вклады в приоритет.
  4. 60 секунд: найдите второго клиента по полному gid, покажите его связи, кластер и операции.
  5. 60 секунд: покажите клиента с границей depth=4 или изолят; объясните, почему отсутствие связей не доказывает конечное получение средств.

Проверьте точный поиск длинного ID, направление стрелок, фильтры и совпадение карточки с экспортом. Для проверки без сети используйте локальный импорт graph.json.

Данные и интеграции

Источник — обезличенная выгрузка организаторов:

ФайлОбязательные поля
nodes.parquetgid, depth, is_seed
edges.parquetsrc, dst, sum_kzt, n_tx, depth
transactions.parquetsrc, dst, date, sum_kzt

Денежные суммы валидируются с точностью до сотых KZT. edges уже агрегирует транзакции: два источника не складываются как независимый оборот. Совпадающие строки операций сохраняются, поскольку без банковского ID нельзя объявить их дублями.

Идентификаторы сохраняются точными целыми в Python и строками на границе JSON/браузера. При импорте CSV в Excel выбирайте текстовый тип для ID. HTML и JSON содержат данные сети: режим доступа должен соответствовать режиму исходного датасета.

API-ключ и отдельный LLM-пример

Основной графовый анализ и TRACE не требуют ключа. Клиентская панель «След» уже есть в интерфейсе, но для реальных ответов ей нужен серверный POST /api/ai/analyze, описанный в AI_CONTRACT.md. В текущем Python-сервере этот endpoint не реализован; панель сообщает «ИИ пока не подключён». Создание .env само по себе чат не подключит.

В src/ сохранён отдельный консольный пример: классификация текста как приветствия, запроса помощи или неизвестного сообщения. Он не определяет финансовые роли и не подключён как чат сайта.

Пример без API:

npm run llm:demo -- --offline "Привет"

Для необязательного вызова API в копии main создайте .env из шаблона:

Copy-Item .env.example .env

Заполните OPENAI_API_KEY в .env. Модель по умолчанию в коде — gpt-4.1-mini, параметр OPENAI_MODEL; наличие доступа к модели определяется вашим API-проектом. Запуск npm run llm:demo -- "Привет" может отправить текст во внешний API и расходовать средства аккаунта. Ключ не помещается в HTML или Git; .env исключён из отслеживания. Подключение к реальному API при подготовке README не проверялось.

Ограничения

  • Сеть ограничена исходящей выгрузкой до четырёх переходов; в описании набора указан один месяц и переводы от 5 000 KZT внутри банка. Полная финансовая активность клиентов неизвестна.
  • У seed вход неполон; отсутствие выхода на границе depth=4 не означает конечного получателя. Разность входа и выхода не является балансом счёта.
  • Даты не задают порядок внутри дня. Временное сопоставление — допущение; в признаках предусмотрен и вариант без внутридневных совпадений.
  • Достижимость от seed не доказывает движение конкретных денег или руководство группой. Кластер — структурная гипотеза.
  • Нет ground truth ролей, обучения модели и подтверждённой accuracy. Пороги и оценки требуют предметной проверки.
  • Онлайн-поток транзакций и внешнее обогащение не реализованы. У чата сайта готова клиентская часть, но отсутствует серверная интеграция модели. Отдельной БД нет: расчёт ведётся в памяти, результат хранится в файлах.
  • NetworkX, точная центральность и полный JSON рассчитаны на локальный MVP. Миллион узлов потребует компактного графового хранения, приближённых вычислений, пакетной обработки и выдачи подграфов. Такая масштабная реализация не заявляется.
  • После сбоя старые результаты нельзя считать свежими: повторите расчёт и проверку выгрузок.

Развёрнутая версия

Публичная deployed-версия в проверенном репозитории не указана. Предусмотрен локальный запуск на http://127.0.0.1:8765/frontend/; этот адрес доступен только на компьютере, где запущен сервер.

Исходный код: репозиторий команды, ветка main.

Звёзды
⭐ 2
Форки
0
Язык
JavaScript
Последний push
в прошлом месяце
Коммиты
16
Авторы
4
Файлы
84
Ветки
5

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

Aslzhasl 10Tabyldy Zhansultan 3akadirku 2Ad1kon 1

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

  • 2026-09-23 20:05Add transaction witnesses, observed motifs and role sensitivityAslzhasl
  • 2026-09-23 17:55docs: describe TRACE setup, architecture and jury verificationakadirku
  • 2026-09-23 17:52feat(trace): integrate Zhans frontend with final Muha backendTabyldy Zhansultan
  • 2026-09-23 19:40Finalize local submission checks and restrict export servingAslzhasl
  • 2026-09-23 19:30Add observable motif detection and the local server moduleAslzhasl
  • 2026-09-23 17:16feat(trace): add lion assistant chat and backend handoffTabyldy Zhansultan
  • 2026-09-23 19:14Claim the P1 motif work in AGENTS.md so the two agents do not collideAslzhasl
  • 2026-09-23 19:06Validate Python backend inputs and verify delivery exportsAslzhasl
Все коммиты (16)
  • 2026-09-23 18:42Document verified Python TRACE integration and temporal role changesAslzhasl
  • 2026-09-23 18:37Remove every trace of Go from the repositoryAslzhasl
  • 2026-09-23 18:20Drop Go, correct the README, record team decisionsAslzhasl
  • 2026-09-23 18:04Add QA data study, research scripts and work-in-progress frontendAslzhasl
  • 2026-09-23 15:59Work done so far: including a bit of frontakadirku
  • 2026-09-23 15:24feat(frontend): add TRACE dossier UI and backend contractTabyldy Zhansultan
  • 2026-09-23 14:17docs: add AGENTS.md project instructionsAd1kon
  • 2026-09-23 16:13Implement explainable money graph pipeline and resolve QA defectsAslzhasl
Структура репозитория (84 файлов)
.env.example
.gitignore
AGENTS.md
AI_CONTRACT.md
BACKEND_CONTRACT.md
FOR_MUHA.md
QA-REPORT.md
README.md
config/roles.json
docs/ACCEPTANCE.md
docs/BACKEND-HANDOFF-REVIEW.md
docs/BACKEND-READY.md
docs/DATA-STUDY.md
docs/HACKATHON_AUDIT.md
docs/QA-RESOLUTION.md
docs/SOLUTION_PLAN.md
docs/SUBMISSION-CHECK.md
frontend/DESIGN.md
frontend/README.md
frontend/agent-answer.schema.json
frontend/agent-ui.js
frontend/agent-ui.test.cjs
frontend/agent.css
frontend/agent.js
frontend/agent.test.cjs
frontend/app-source.js
frontend/app.js
frontend/backend.test.cjs
frontend/build.cjs
frontend/data.js
frontend/data.test.cjs
frontend/index.html
frontend/package.json
frontend/packaging.test.cjs
frontend/styles-source.css
frontend/styles.css
moneygraph/__init__.py
moneygraph/__main__.py
moneygraph/analysis.py
moneygraph/files.py
moneygraph/io.py
moneygraph/motifs.py
moneygraph/report.py
moneygraph/server.py
moneygraph/snapshot.py
moneygraph/verify.py
moneygraph/viewer.html
package.json
requirements.txt
scripts/check-reproducibility.py
scripts/qa-smoke-openai.mjs
scripts/research_component_profiles.py
scripts/research_data_signals.py
scripts/research_paths.py
scripts/research_robustness.py
scripts/research_role_assumptions.py
scripts/review_data_study.py
scripts/review_smoke_offline.mjs
scripts/review_terminal_proxy.py
scripts/review_transit_definitions.py
scripts/run-python.mjs
src/app.js
src/cli.js
src/memory.js
src/openai-client.js
src/rules.js
src/validator.js
starter/README.md
starter/requirements.txt
starter/starter.py
test/app.test.js
test/cli.test.js
test/qa-memory.test.js
test/qa-openai-client.test.js
test/qa-resilience.test.js
test/qa-validator.test.js
test/regression.test.js
tests/test_backend_validation.py
tests/test_file_safety.py
tests/test_moneygraph.py
tests/test_roles_v2.py
tests/test_server.py
tests/test_snapshot.py
tests/test_verify.py
Ветки (5)

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

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

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