AAYMA
RU
Войти

OrgTrace

ИИ-агент, сравнивающий редакции положений (.docx) до и после реорганизации: находит созданные/сохранённые/упразднённые подразделения, потерю…

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

О проекте

Команда: Solnik
Кейс HackAlem.ai: Спецтрек — Казахтелеком
Стадия: Доведённый продукт

Задача кейса: Агент, сравнивающий документы оргструктуры до и после реорганизации

Суть

ИИ-агент, сравнивающий редакции положений (.docx) до и после реорганизации: находит созданные/сохранённые/упразднённые подразделения, потерю, перенос и дублирование функций, конфликт интересов и формирует заключение со ссылкой на пункт документа, с выгрузкой в Word.

Как устроено

docparse разбирает .docx (распаковкой OOXML) на пронумерованные пункты, orgmap извлекает состав подразделений и функции по подпунктам руководителей. align считает семантическую близость функций через OpenAI text-embedding-3-small, с резервным лексическим режимом по IDF-весам без сети. compare находит потери, передачи, обобщения, дублирования и конфликты; агент-верификатор перепроверяет каждое подозрение на потерю инструментами search_clauses/get_clause/list_units, а вердикт без ссылки на пункт понижается до «не уверен». Итоговое заключение модель переписывает только из фактов.

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

  • разбор DOCX на пункты
  • эмбеддинги text-embedding-3-small
  • IDF lexical fallback
  • function calling
  • агент-верификатор
  • пороги уверенности
  • экспорт в Word

Метрики

7 из 7 контрольных случаев; 48 выводов, 100% со ссылкой на пункт; разбор ~45 с; 34 теста

Особенности

Агент-верификатор снимает ложные тревоги о потере функций, а цитаты может брать только из инструментов (код отклоняет вердикт без ссылки). Есть офлайн-режим для зала с плохим Wi-Fi и скрипт оценки на контрольном комплекте с ожидаемыми выводами.

Стек

Python 3.10+ · FastAPI · Uvicorn · pytest · Playwright · HTML/JS

Модели

OpenAI text-embedding-3-small · OpenAI chat model


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

README

README.md

OrgTrace

OrgTrace

Трассировка функций при реорганизации. ИИ-агент «Анализ организационной структуры и функционала».

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

Задача: спец-трек Казахтелеком — ИИ-агент «Анализ организационной структуры и функционала» Команда: Solnik


Проблема

При реорганизации подразделений положения, оргструктуры и приложения к распорядительным документам сопоставляют вручную. На комплекте из двух редакций одного положения это 84 тысячи знаков и более трёхсот пунктов в каждом документе. Человек читает их построчно, поэтому функции теряются, дублируются и пересекаются незаметно.

Что делает решение

Пользователь загружает два комплекта документов. Агент разбирает их на пронумерованные пункты, определяет состав подразделений и закреплённые за ними функции, сопоставляет функции семантически и выдаёт:

  • перечень созданных, сохранённых и исчезнувших подразделений;
  • функции, которым не нашлось соответствия в новой редакции — возможная потеря;
  • функции, перешедшие в другое подразделение;
  • близкие формулировки у разных подразделений — дублирование;
  • признаки конфликта интересов, когда одно подразделение и выполняет проверки, и оценивает их качество;
  • итоговое аналитическое заключение.

Для каждого вывода показывается документ, номер пункта и сама цитата.

Как это выглядит

Стартовая страница

Стартовая страница OrgTrace

Сетка возможностей

Блок «Проверьте на своём комплекте»

Сводка по разбору контрольного комплекта. Сайдбар разбит на группы выводов со счётчиками; сверху показатели, ниже состав подразделений (созданные выделены), итоговое заключение и карточки выводов.

Сводка разбора

Работа агента-верификатора. Первичное сопоставление отметило возможную потерю функции. Агент пять раз обратился к документу, нашёл функцию в новой формулировке в п. 2.4.7 и снял ложную тревогу. Раскрывающийся блок показывает каждый вызов инструмента с аргументами и ответом.

Агент снимает ложную тревогу

Конфликт интересов. ДККМ одновременно разрабатывает методические материалы и оценивает качество аудита — вывод подтверждён двумя пунктами.

Конфликт интересов

Рекомендация по устранению дублирования — опциональный пункт ТЗ.

Рекомендация

Подразделения с закреплёнными функциями и ссылками на пункты.

Подразделения

Снимки воспроизводятся скриптом scripts/screenshots.py при запущенном сервере (нужен Playwright: pip install playwright && python -m playwright install chromium).

Проверить за 60 секунд

git clone <URL репозитория> && cd <папка>
python -m venv .venv && .venv\Scripts\activate      # Windows
pip install -r requirements.txt

python -m pytest tests -q                           # тесты, сеть не нужна
python -m src.evaluate                              # проверка на контрольном комплекте с метрикой
python -m src.evaluate --fast                       # то же без агента и без сети
python -m uvicorn src.app:app --port 8000           # веб-интерфейс: http://127.0.0.1:8000

В интерфейсе нажмите «Контрольный комплект» — анализ выполнится на документах из data/samples, загружать ничего не нужно. Личные аккаунты для проверки не требуются.

Python 3.10 и выше. OPENAI_API_KEY не обязателен: без него агент работает в резервном режиме (см. ниже).

Контрольный сценарий и что должно найтись

Комплект data/samples — две редакции Положения о внутреннем аудите (№8 и №9). Заранее известные изменения и ожидаемый результат:

Что произошлоОжидаемый выводПодтверждение
Созданы два департаментаДИТААД и ДОА помечены как созданныеп. 3.4 обеих редакций
Состав вырос с 2 до 4 подразделений4 подразделения после, 2 доп. 3.4
Роль «Директор направления внутреннего аудита» преобразованафункции перешли к директорам ДИТААД и ДОАред.8 п. 5.3 → ред.9 п. 5.3
Часть функций ДНМ и ДККМ перераспределенаfunction_moved между подразделениямип. 5.4–5.7 обеих редакций

Результат прогона python -m src.evaluate

Найдено контрольных случаев: 7 из 7
Выводов всего: 48
Из них со ссылкой на конкретный пункт: 48 (100%)

Разбивка выводов: 24 дублирования, 13 функций, ставших общими, 5 передач между подразделениями, 2 созданных подразделения, 2 сохранённых, 1 конфликт интересов, 1 подозрение на потерю, снятое агентом. Полный разбор двух документов по 300+ пунктов занимает около 45 секунд. Тестов — 34, проходят без сети.

Архитектура

документы .docx
      │
      ▼
docparse.py   разбор на пункты с сохранением номера, раздела и цитаты
      │
      ▼
orgmap.py     состав подразделений (п. «состоит из следующих подразделений»)
              и функции каждого — по подпунктам его руководителя
      │
      ▼
align.py      семантическая близость функций
              режим embeddings (OpenAI) │ резервный lexical (без сети)
      │
      ▼
compare.py    потери, передачи, обобщения, дублирования, конфликты + источники
      │
      ▼
agent.py      агент-верификатор: перепроверяет каждое подозрение на потерю,
              вызывая инструменты search_clauses / get_clause / list_units
      │
      ├──► recommend.py предложения по устранению пересечений функций
      ├──► report.py    заключение (модель переписывает факты, не добавляя своих)
      ├──► export.py    выгрузка заключения в Word
      ├──► evaluate.py  проверка на контрольном комплекте и метрика
      └──► app.py       веб-интерфейс и JSON API

Агентный слой — ядро решения. Сопоставление по близости даёт кандидатов, но не понимает, что функция могла переехать в другой раздел или быть переформулирована. Поэтому каждое подозрение на потерю проходит второй круг: агент сам решает, что искать, вызывает инструменты поиска по документу и выносит вердикт — «потеря подтверждена», «функция найдена в другом пункте» или честное «не уверен, нужна проверка человеком». В интерфейсе раскрывается полная трассировка его вызовов.

Агент не может выдумать источник. Цитаты он получает только из инструментов, а вердикт «функция найдена» без ссылки на пункт отклоняется кодом и понижается до «не уверен».

Ключевое решение: разделение детерминированного и вероятностного. Всё, что однозначно задано документом — номер пункта, принадлежность функции подразделению, состав структуры — извлекается кодом. Модель применяется только там, где нужен смысл: сопоставление разных формулировок одной функции и текст заключения. Поэтому агент не может придумать несуществующий пункт: цитата всегда берётся из разобранного документа.

Порог уверенности. У каждого вывода есть числовая уверенность. Слабое соответствие помечается средним риском, а не выдаётся за факт. Формулировки намеренно осторожны: «возможная потеря функции», а не «функция утрачена».

Резервный режим. Если ключа нет или сеть недоступна, близость считается по взвешенным токенам с IDF, без обращения к сети. Выводы становятся грубее, но продукт остаётся работоспособным — это важно для демонстрации в зале с общим Wi-Fi.

Соответствие требованиям ТЗ

Требование (must have)Где реализовано
1. Определить реорганизованные, сохранённые и созданные подразделенияcompare.compare_units → unit_created / unit_kept / unit_removed
2. Сопоставить функционал и выявить потерю функцийcompare.compare_functions → function_lost, function_moved
3. Выявить дублирование и конфликт интересовcompare.find_duplication, compare.find_conflicts
4. Для каждого вывода показать источник: документ и пунктdocparse.Clause.cite, поле sources у каждого вывода
5. Итоговое аналитическое заключениеreport.render_conclusion, показывается в интерфейсе и выгружается в Word — export.build_docx, кнопка «Скачать заключение»

Пункты раздела «Опционально» из ТЗ:

Опциональное требованиеСостояние
3. Рекомендации по перераспределению функций и устранению пересеченийреализовано: recommend.py предлагает, за кем закрепить функцию, с обоснованием
1. Сверка с законодательством и стандартамине реализовано: корпус нормативных документов подключается тем же парсером
2. Сравнение структур с другими операторамине реализовано: требует внешних данных

Дополнительно к требованиям ТЗ: выявление функций, переставших быть закреплёнными за подразделением (function_generalized) — при реорганизации ответственность нередко размывается в общие разделы, и это отдельный риск; агент-верификатор, снимающий ложные тревоги; скрипт проверки на контрольном комплекте с метрикой.

Технологии

Python 3.10+, FastAPI и Uvicorn, OpenAI API (text-embedding-3-small для близости, чат-модель для заключения), разбор .docx через распаковку OOXML без внешних зависимостей, pytest. Интерфейс — одна страница на чистом HTML и JS, без сборки.

Переменные окружения

Файл .env.example:

ПеременнаяНазначение
OPENAI_API_KEYКлюч OpenAI. Без него — резервный режим
OPENAI_MODELМодель для заключения
OPENAI_EMBED_MODELМодель эмбеддингов, по умолчанию text-embedding-3-small
OPENAI_TIMEOUT_SТаймаут запроса к OpenAI, по умолчанию 40 секунд
ORGTRACE_OFFLINE1 — полностью без сети, резервный режим
ORGTRACE_<РЕЖИМ>_<ПОРОГ>Переопределение порога сходства, например ORGTRACE_EMBEDDINGS_MATCH=0.6

Языки документов

Поддерживаются документы на русском, казахском и смешанные — когда в одном положении чередуются казахские и русские формулировки. Разбор учитывает казахский алфавит (Ә, Ғ, Қ, Ң, Ө, Ұ, Ү, Һ, І) и казахский порядок слов в заголовках пунктов («ОАД директоры:»). Смысловое сопоставление выполняется многоязычными эмбеддингами OpenAI, поэтому функция из русской редакции находит соответствие в казахской и наоборот; в резервном режиме без сети сопоставление работает внутри одного языка.

Развёртывание на сервере

Требования: Linux или Windows, Python 3.10+, около 300 МБ под зависимости. Доступ к api.openai.com нужен для режима с моделью; без него сервис работает в резервном режиме.

git clone <URL репозитория> orgtrace && cd orgtrace
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

cp .env.example .env            # вписать OPENAI_API_KEY; без ключа — резервный режим
python -m pytest tests -q       # проверка окружения, сеть не нужна

python -m uvicorn src.app:app --host 0.0.0.0 --port 8000 --workers 1

После запуска сервис доступен по адресу http://<адрес-сервера>:8000: стартовая страница на /, рабочий экран на /app.

Один рабочий процесс. Результаты разборов для выгрузки заключения хранятся в памяти процесса, поэтому запускайте с --workers 1: при нескольких процессах запрос на выгрузку может попасть не в тот процесс и получить «результат не найден». После перезапуска сервиса результаты прошлых разборов не сохраняются — это осознанное решение прототипа, документы пользователей на диске не остаются.

За обратным прокси (например, nginx) учтите две настройки: разбор занимает до минуты, а файл может весить до 20 МБ.

location / {
    proxy_pass http://127.0.0.1:8000;
    proxy_read_timeout 180s;        # разбор с агентом занимает до минуты
    client_max_body_size 45m;       # два файла по 20 МБ
}

Проверка после развёртывания: откройте /app и нажмите «Контрольный комплект» — через минуту появится разбор документов из кейса. Полная проверка в браузере: python scripts/e2e_demo.py с переменной ORGTRACE_URL=http://<адрес-сервера>:8000 (нужен Playwright).

Сторонние материалы и open-source

КомпонентЛицензияЧто используется
FastAPIMITHTTP-слой
UvicornBSD-3ASGI-сервер
openai (python)Apache-2.0Эмбеддинги, агент-верификатор, заключение
python-docxMITВыгрузка заключения в Word
Иллюстрация на стартовой странице (static/cta.jpg)создана командойСгенерирована с помощью ИИ по собственному описанию команды
Визуальные решения интерфейса—Композиция страниц (навигация, герой, сайдбар, сетка возможностей) вдохновлена компонентами каталога 21st.dev на базе shadcn/ui (MIT). Код интерфейса написан заново на HTML и CSS; техника клетчатого SVG-узора в сетке возможностей повторяет подход компонента grid-feature-cards
pytestMITТесты

Тестовые документы предоставлены организатором в составе кейса. Заранее подготовленный технический шаблон (каркас проекта, движок правил src/rules_engine.py с тестами) создан до начала соревновательной части; вся функциональность анализа организационных документов разработана 23.09.2026 в период с 13:00 до 18:00.

Ограничения

  • Выводы носят рекомендательный характер и требуют проверки ответственным сотрудником.
  • Агент не утверждает ничего, что не подтверждено текстом документов: при слабом соответствии он сообщает о низкой уверенности, а не о факте.
  • Разбор рассчитан на документы с иерархической нумерацией пунктов. Форматы PDF и Excel подключаются к той же схеме Clause, в прототипе реализован .docx.
  • Правило конфликта интересов в прототипе опирается на совмещение исполнения проверок и контроля их качества; список признаков расширяется таблицей в compare.CONFLICT_ROLES.

Что дальше

Подключение PDF и Excel к существующей схеме пунктов; сверка функций с внешними требованиями и стандартами (опциональный пункт ТЗ) — корпус нормативных документов подключается тем же парсером; бенчмаркинг структуры против других операторов; рекомендации по перераспределению функций. Решение применимо к любой организации, где реорганизация оформляется положениями и приложениями к распорядительным документам, — от оператора связи до государственного органа.

Надёжность и безопасность

Проверка входных файлов. Принимается только Word (.docx); пустой, повреждённый или не-Word файл отклоняется с понятным объяснением. Лимит 20 МБ на файл и 200 МБ после распаковки — .docx является zip-архивом, и без второго лимита небольшой файл мог бы распаковаться в гигабайты. Временные файлы удаляются сразу после разбора.

Изоляция результатов. Каждый разбор получает собственный идентификатор; выгрузка заключения возможна только по нему.

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

Защита агента от подмены источника. Текст документов передаётся модели как данные, отделённые от инструкций, с прямым указанием игнорировать команды внутри них. Кроме того, это проверяется кодом, а не доверием к модели: вердикт «функция найдена» принимается, только если агент сам получил указанный пункт через инструменты в этой же проверке, а решение без единого обращения к документу отклоняется. Поэтому документ не может заставить агента сослаться на пункт, которого тот не видел.

Отказоустойчивость. Анализ выполняется в пуле потоков и не блокирует сервер для других запросов. У обращений к OpenAI таймаут 40 секунд и два повтора; при недоступности сети сервис переходит в резервный режим сопоставления без модели. Векторы пунктов кешируются, поэтому один и тот же текст не отправляется в OpenAI повторно.

Настройка порогов. Пороги сходства подобраны на контрольном комплекте — единственном размеченном наборе, и на других документах их может понадобиться подстроить. Каждый порог переопределяется переменной окружения без правки кода, например ORGTRACE_EMBEDDINGS_MATCH=0.6. Ошибки порога на стороне потерь дополнительно гасит агент-верификатор.

Тесты. 34 теста проходят без сети за секунду (ORGTRACE_OFFLINE=1 выставляется автоматически): разбор и сопоставление на документах кейса, приём файлов, лимиты, zip-бомба, удаление временных файлов, изоляция выгрузки, очистка имени файла, защиты агента — проверяются поддельным клиентом модели.

Сквозная проверка в браузере. scripts/e2e_demo.py проходит весь путь пользователя в настоящем браузере (Playwright): стартовая страница, контрольный комплект, все разделы и их счётчики, поиск, работа агента, выгрузка заключения с проверкой, что файл открывается в Word, загрузка своих и повреждённых файлов, мобильная вёрстка, отсутствие ошибок JavaScript. Отдельно проверяется, что документ со спрятанными <script> и <img onerror> не выполняет их в браузере. Результат последнего прогона — 56 из 56 проверок.

Проверено воспроизведение с нуля: клонирование репозитория, установка зависимостей из requirements.txt в чистое окружение, запуск тестов и сервера без файла .env.

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

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

RendersC 26

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

  • 2026-09-23 17:58Revert "Документы на английском: разбор подразделений и функций"RendersC
  • 2026-09-23 17:57Документы на английском: разбор подразделений и функцийRendersC
  • 2026-09-23 17:55Документы на казахском и смешанныеRendersC
  • 2026-09-23 17:50README: инструкция по развёртыванию на сервереRendersC
  • 2026-09-23 17:45README: логотип под тёмную тему GitHubRendersC
  • 2026-09-23 17:42Сквозная проверка: 56 сценариев; раскрытие источников оформленияRendersC
  • 2026-09-23 17:37README: обновлены скриншоты, добавлены сетка возможностей и блок с иллюстрациейRendersC
  • 2026-09-23 17:31Лендинг: иллюстрация в блоке «Проверьте на своём комплекте»RendersC
Все коммиты (26)
  • 2026-09-23 17:22Лендинг: финальный блок с изображением и футер с колонкамиRendersC
  • 2026-09-23 17:13Лендинг: сетка возможностей в разделе о доверии к выводамRendersC
  • 2026-09-23 17:06Сквозная проверка демо в браузере, исправлена мобильная шапкаRendersC
  • 2026-09-23 16:51Логотип OrgTraceRendersC
  • 2026-09-23 16:44README: скриншоты интерфейса; агент всегда выносит вердиктRendersC
  • 2026-09-23 16:22Лендинг: убрано затухание снизу снимка рабочего экранаRendersC
  • 2026-09-23 16:18Доведение ревью: защита агента, кеш, настраиваемые порогиRendersC
  • 2026-09-23 16:05Час 10: ревью надёжности и безопасности, светлая тема, название OrgTraceRendersC
  • 2026-09-23 15:43Час 9: разделы отвечают до анализа и место под настоящий скриншотRendersC
  • 2026-09-23 15:32Час 8: оформление по эталонам заказчикаRendersC
  • 2026-09-23 15:23Час 7: выгрузка заключения, конфликт интересов, рекомендации, поискRendersC
  • 2026-09-23 15:04Час 6: палитра интерфейса и устойчивость к нештатным файламRendersC
  • 2026-09-23 14:55Час 5: новый интерфейс — лендинг и рабочий экран с сайдбаромRendersC
  • 2026-09-23 14:39Час 4: стартовая страница сервисаRendersC
  • 2026-09-23 14:36Час 3: точность поиска, новый тип вывода и метрикаRendersC
  • 2026-09-23 14:15Час 2: агент-верификатор с вызовом инструментовRendersC
  • 2026-09-23 14:09Объединение с базовой веткой репозиторияRendersC
  • 2026-09-23 14:09Час 1: прототип анализа оргструктурыRendersC
Структура репозитория (45 файлов)
.env.example
.gitignore
README.md
data/samples/polozhenie_red8.docx
data/samples/polozhenie_red9.docx
docs/logo-dark.png
docs/screenshots/agent.png
docs/screenshots/app-summary.png
docs/screenshots/conflict.png
docs/screenshots/landing-cta.png
docs/screenshots/landing-features.png
docs/screenshots/landing.png
docs/screenshots/recommendation.png
docs/screenshots/units.png
docs/tz_case.docx
requirements.txt
scripts/e2e_demo.py
scripts/screenshots.py
src/__init__.py
src/agent.py
src/align.py
src/app.py
src/app_page.py
src/compare.py
src/config.py
src/docparse.py
src/evaluate.py
src/export.py
src/orgmap.py
src/pages.py
src/recommend.py
src/report.py
src/rules_engine.py
static/README.md
static/app-preview.jpg
static/cta.jpg
static/favicon.png
static/logo-mark.png
static/logo.png
tests/__init__.py
tests/conftest.py
tests/test_agent_guards.py
tests/test_api.py
tests/test_pipeline.py
tests/test_rules_engine.py

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

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

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