О проекте
Команда: 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.mdTRACE — Граф денег
Локальное рабочее место 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-снимок для интерфейса.
- Запись параметров, версий библиотек, времени расчёта и хешей исходников; отдельная проверка согласованности выгрузок.
Как работает решение
- Аналитик помещает выданные Parquet-файлы в
data/. - Запускает расчёт. Пайплайн валидирует данные, строит граф, вычисляет признаки, роли, кластеры и рейтинг.
- Получает CSV, JSON и HTML в
artifacts/. - Открывает TRACE через локальный сервер либо импортирует JSON в интерфейс без сервера.
- Выбирает клиента из рейтинга или ищет его по
gid, изучает переводы, основания роли и ограничения наблюдения. - Использует результат для дальнейшей ручной проверки. Роли и оценки не пересчитываются в браузере.
Технологии
| Компонент | Технологии и назначение |
|---|---|
| Аналитика | Python; в документации main рекомендованы Python 3.11/3.12 |
| Таблицы и вычисления | pandas 2.3.3, NumPy 2.3.3 |
| Чтение Parquet | PyArrow 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.csv | gid,role,role_score,cluster_id,priority_score,evidence |
clusters.csv | cluster_id,n_nodes,n_seed,sum_kzt_internal,top_gids,hypothesis |
top_nodes.csv | rank,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; фиксированный результат и скорость на любом ноутбуке не гарантируются.
Сценарий демо на пять минут
- 30 секунд: объясните задачу и неполноту наблюдаемой сети.
- 60 секунд: покажите запуск и три CSV, затем результат
moneygraph.verify. - 90 секунд: откройте TRACE, выберите клиента из рейтинга и покажите основания роли и вклады в приоритет.
- 60 секунд: найдите второго клиента по полному
gid, покажите его связи, кластер и операции. - 60 секунд: покажите клиента с границей
depth=4или изолят; объясните, почему отсутствие связей не доказывает конечное получение средств.
Проверьте точный поиск длинного ID, направление стрелок, фильтры и совпадение карточки с экспортом. Для проверки без сети используйте локальный импорт graph.json.
Данные и интеграции
Источник — обезличенная выгрузка организаторов:
| Файл | Обязательные поля |
|---|---|
nodes.parquet | gid, depth, is_seed |
edges.parquet | src, dst, sum_kzt, n_tx, depth |
transactions.parquet | src, 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.
Авторы коммитов
История коммитов
- 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
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.