AAYMA
RU
Войти

ОргАналитик AI

Streamlit-сервис, который сравнивает документы оргструктуры ДО и ПОСЛЕ реорганизации (PDF/DOCX/XLSX).

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

О проекте

Команда: Nomad
Кейс HackAlem.ai: Спецтрек — Казахтелеком
Стадия: Рабочий MVP

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

Суть

Streamlit-сервис, который сравнивает документы оргструктуры ДО и ПОСЛЕ реорганизации (PDF/DOCX/XLSX). Он показывает созданные, удалённые и преобразованные подразделения, перераспределение функций и гипотезы о рисках, и к каждому выводу прикладывает проверяемую ссылку на исходный фрагмент.

Как устроено

Парсеры PyMuPDF, python-docx и openpyxl режут документы на SourceChunk с метаданными: страница, пункт, лист/строка, детерминированный chunk_id. Затем идёт поэтапная работа с OpenAI Responses API и Structured Outputs: сначала извлекается структура подразделений, потом функции с привязкой к подтверждённым подразделениям, потом семантическое сравнение, потеря и дублирование функций, конфликты интересов. После каждого этапа код проверяет схемы Pydantic и существование ссылок, а неподтверждённые объекты отбрасывает. Результаты кэшируются в session_state по хешам файлов, модели и версиям кода. Итоговое заключение собирается без дополнительного вызова AI.

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

  • OpenAI Responses API
  • Structured Outputs
  • Pydantic schemas
  • source-chunk traceability
  • citation validation
  • staged extraction (structure → functions → comparison)
  • hash-based session cache

Особенности

Принцип «AI интерпретирует — система проверяет источники»: каждый chunk_id, который вернул LLM, валидируется, а цитата в UI берётся из текста парсера, а не из ответа модели. Кандидаты на потерю функции дополнительно проверяются на перенос в другие подразделения ПОСЛЕ. Кэш учитывает отпечатки файлов реализации.

Стек

Python · Streamlit · PyMuPDF · python-docx · openpyxl · OpenAI SDK · Pydantic · unittest

Модели

gpt-4.1-mini


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

README

README.md

ОргАналитик AI

AI-сервис для анализа организационной структуры и функций до и после реорганизации. HackAlem MVP: два документа, сравнение изменений и проверяемые ссылки на исходный текст.

Проблема

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

Решение

Документы ДО/ПОСЛЕ → парсинг → извлечение организационной структуры → анализ функций и ответственности → сравнение → проверка источников → потенциальные риски и рекомендации.

«AI интерпретирует — система проверяет источники.»

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

Возможности

  • Загрузка документов ДО/ПОСЛЕ в PDF, DOCX и XLSX, до 20 МБ каждый.
  • Извлечение структурных подразделений, поддержанных источником наименований и алиасов.
  • Извлечение функций с привязкой к подтверждённым подразделениям.
  • Сравнение структуры: сохранение, создание, удаление и преобразование подразделений.
  • Анализ изменений и перераспределения ответственности по исходному тексту.
  • Гипотезы о возможной потере функций, дублировании и конфликтах интересов; рекомендации по проверке.
  • Просмотр оригинальных фрагментов, имени документа, страницы, пункта или другого указателя.
  • Русский интерфейс, единый запуск анализа и сравнения с этапами прогресса.
  • Раздельный кэш успешного извлечения и завершённого сравнения в текущей сессии.
  • Итоговое аналитическое заключение из уже проверенных результатов: структура, функции, риски, существующие рекомендации и ограничения; без дополнительного AI-запроса.

Архитектура

flowchart TD
    User["Пользователь"] --> UI["Streamlit UI"]
    subgraph Code["Детерминированный Python-код"]
        UI --> Parser["Парсеры PDF / DOCX / XLSX"]
        Parser --> Chunks["SourceChunk: текст и метаданные"]
        Chunks --> Structure["Извлечение структуры"]
        Structure --> Functions["Извлечение функций"]
        Functions --> Compare["Сравнение структуры и ответственности"]
        Chunks --> Compare
        Compare --> Validator["Валидация ссылок на источники"]
        Validator --> Findings["Выводы и рекомендации с источниками"]
        Findings --> UI
        UI <--> Cache["Кэш и результаты в session_state"]
    end
    subgraph AI["AI inference — внешний сервис"]
        API["OpenAI Responses API / Structured Outputs"]
    end
    Structure <--> API
    Functions <--> API
    Compare <--> API

Узлы извлечения и сравнения — Python-оркестраторы: смысловые ответы формирует OpenAI, а код задаёт схему, проверяет владельцев и ссылки. Валидация также выполняется после каждого этапа извлечения, до передачи данных дальше. Подробности: архитектура.

Как работает AI

Детерминированный кодAI
Читает файлы и выделяет текстИнтерпретирует организационную структуру
Сохраняет метаданные и распознаёт номера пунктовВыделяет обязанности и их владельцев
Формирует порции контекста и проверяет схемы ответовСемантически сравнивает ответственность
Проверяет существование ссылок и допустимые подразделенияФормулирует гипотезы о рисках и рекомендации
Обслуживает кэш, состояние и интерфейсВозвращает ссылки на предоставленные источники

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

Сравнение использует подразделения и исходные фрагменты напрямую, поэтому не ограничено списком извлечённых функций. Кандидаты на потерю проходят дополнительную проверку переноса на другие подразделения ПОСЛЕ. Анализ дублирования и конфликтов использует документ ПОСЛЕ.

Traceability / Explainability

SourceChunk хранит chunk_id, document_id, filename, page, section, locator, text. Например, before_p006_003 — детерминированный идентификатор позиции фрагмента, который разрешается в контексте конкретного документа. Идентификатор документа учитывает сторону, имя файла и содержимое; один chunk_id не является глобальным ID всех загрузок.

Подразделения, функции и результаты сравнения ссылаются на эти фрагменты. Неизвестные ссылки отклоняются; объекты без достаточных допустимых подтверждений не показываются как проверенные результаты. Цитата в «Показать подтверждение» берётся из сохранённого текста парсера, а не генерируется AI. Для DOCX/XLSX вместо номера страницы используется абзац либо лист и строка. Номер пункта может отсутствовать.

Tech Stack

  • Python 3.10+; локальные проверки выполнены в Python 3.12.
  • Streamlit — интерфейс и состояние сессии.
  • PyMuPDF — PDF; python-docx — DOCX; openpyxl — XLSX.
  • OpenAI Python SDK — Responses API и Structured Outputs.
  • Pydantic — схемы ответов; dataclasses — внутренние модели.
  • python-dotenv — чтение .env.
  • unittest, unittest.mock и Streamlit AppTest — автоматические проверки.

Базы данных, векторного хранилища, embeddings, OCR и аутентификации нет.

Структура проекта

app.py                         # единый пользовательский сценарий
requirements.txt               # зависимости с диапазонами версий
.env.example                   # шаблон без ключа
.gitignore
.streamlit/config.toml         # тема и лимит загрузки
src/
  config.py                    # настройки из окружения и .env
  models.py                    # документы, фрагменты, результаты
  ui_common.py                 # общие элементы UI и источники
  comparison_ui.py             # вкладки результатов
  parsers/
    parser_factory.py          # проверка загрузки и выбор парсера
    pdf_parser.py
    docx_parser.py
    xlsx_parser.py
  services/
    chunking.py                # фрагменты и номера пунктов
    extraction.py              # структура, затем функции
    comparison.py              # сравнение, риски, проверка потерь
    pipeline.py                # последовательность и кэш
tests/                        # unittest и AppTest
docs/
   architecture.md
   demo.md

Быстрый запуск

Нужны Python 3.10+, доступ к сети для установки пакетов и OpenAI API, а также действующий API-ключ с доступом к выбранной модели. Команды выполняются из корня репозитория. Реальный анализ отправляет текст в OpenAI и может быть платным.

Windows PowerShell:

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
# Только если .env ещё не существует:
Copy-Item .env.example .env

В локальном .env укажите собственный ключ (не коммитьте его):

OPENAI_API_KEY=your-key-here
OPENAI_MODEL=gpt-4.1-mini
.\.venv\Scripts\python.exe -m streamlit run app.py

macOS/Linux:

python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
# Только если .env ещё не существует:
cp .env.example .env
# Заполните .env своим ключом перед анализом.
.venv/bin/python -m streamlit run app.py

Откройте адрес, выведенный Streamlit, обычно http://localhost:8501. Активация виртуального окружения не требуется: команды используют его Python напрямую.

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

ПеременнаяНазначениеЗначение по умолчанию
OPENAI_API_KEYКлюч доступа к OpenAI; необходим для запуска анализаНет
OPENAI_MODELМодель с поддержкой используемых структурированных ответовgpt-4.1-mini

Переменные процесса имеют приоритет над .env в корне репозитория. Настройки читаются при явном запуске анализа. При отсутствии ключа интерфейс сообщает об ошибке настройки.

Поддерживаемые форматы

ФорматЧто извлекаетсяОграничения
PDFТекст страниц с разделением по распознанным номерам пунктовНет OCR; PDF с паролем не поддерживается; порядок текста зависит от вёрстки
DOCXНепустые абзацы тела документа с физическими индексамиТаблицы, колонтитулы, текстовые поля и автоматические номера списков не извлекаются
XLSXНепустые строки, лист, номер строки и буквы столбцовФормулы сохраняются как текст, не вычисляются

Пустые, повреждённые, неподдерживаемые файлы и файлы свыше 20 МБ отклоняются. В смешанном PDF страницы без доступного текстового слоя не анализируются.

Сценарий проверки

  1. Запустите приложение.
  2. Загрузите исходный документ в «До реорганизации».
  3. Загрузите новую редакцию в «После реорганизации».
  4. Нажмите «Провести анализ».
  5. Дождитесь этапов чтения, определения структуры и функций, сравнения, формирования рисков и рекомендаций.
  6. В «Результаты сравнения» изучите вкладку «ОБЗОР ИЗМЕНЕНИЙ».
  7. Откройте «ИЗМЕНЕНИЯ ФУНКЦИЙ» и проверьте перераспределение ответственности.
  8. На вкладке «РИСКИ И РЕКОМЕНДАЦИИ» изучите карточки найденных гипотез, если они есть.
  9. Раскройте «Показать подтверждение».
  10. Сверьте документ, страницу/локатор, пункт и исходный фрагмент с выводом.

Повторите запуск с той же парой в той же сессии: завершённые этапы берутся из кэша без повторных запросов. Ключ включает хеши обоих файлов, исходные имена, модель, версии обработки и отпечатки файлов реализации. Хранятся до трёх пар на каждый кэш; переименование файла тоже вызывает новый анализ, чтобы не перепутать источники. Обычные rerun интерфейса не повторяют запросы. Для завершённого сравнения каждое извлечённое подразделение ДО/ПОСЛЕ должно быть покрыто принятым сопоставлением. Неполное сопоставление явно отмечается предупреждением и счётчиками покрытия; при пустом результате вместо нулей структуры показывается «—». Полезные частичные результаты сохраняются, но не кэшируются как успешно завершённое сравнение. Код не назначает отсутствующие статусы автоматически. Ошибки не кэшируются; после сбоя сравнения успешное извлечение сохраняется и используется при повторной попытке.

Сценарий демонстрации на 3 минуты.

Тестирование

Windows:

.\.venv\Scripts\python.exe -m unittest discover -s tests -v

macOS/Linux:

.venv/bin/python -m unittest discover -s tests -v

Финальный локальный прогон 23.09.2026: 92 теста, все прошли, Python 3.12, существующее изолированное окружение .venv-h2. Проверены парсеры на генерируемых PDF/DOCX/XLSX, проверки источников, роли и алиасы, принадлежность функций, сравнение, обработка ошибок, русский UI, кэш и сохранение результатов при rerun, полнота покрытия структуры и детерминированное итоговое заключение. OpenAI в тестах замокан: API-кредиты не расходуются. Эти тесты не доказывают качество реального анализа редакций 8/9 и не измеряют его скорость.

Дополнительно проверены импорт app.py, запуск Streamlit и ответ ok на health endpoint, соответствие установленных версий requirements.txt и pip check без конфликтов. Локальная среда: Python 3.12.14, Streamlit 1.64.0, PyMuPDF 1.28.2, python-docx 1.2.0, openpyxl 3.1.5, openai 2.54.0, python-dotenv 1.2.3, Pydantic 2.13.5. Чистая установка в новое окружение и запуск на macOS/Linux в этой проверке не выполнялись. Команды сверены с путями и точкой входа проекта; Mermaid проверен по структуре текста, без отдельного рендерера диаграмм. Реальные запросы OpenAI в финальной QA не выполнялись.

Ограничения

Решение — прототип поддержки принятия решений. Выводы AI являются гипотезами и рекомендациями, а не установленными фактами или юридическими заключениями. Итоговые организационные выводы должен проверить ответственный сотрудник по оригинальным документам.

  • Время первого анализа. На реальных организационных документах первый AI-анализ может занимать несколько минут; по результатам реального тестирования в одном запуске он превысил 7 минут. Время зависит от размера и структуры документов, количества выделенных разделов, числа этапов AI-анализа, задержек OpenAI API и сети. Конкретная максимальная длительность не гарантируется.
  • Кэш сессии. Успешные результаты кэшируются только в текущей Streamlit-сессии, поэтому повторный анализ тех же документов в той же сессии может быть быстрее. Кэш теряется при новой сессии или перезапуске сервера; постоянного кэша нет.
  • Вариативность AI. Извлечение структуры и функций выполняет LLM. При новых запусках AI одни и те же документы могут дать разное количество кандидатов в подразделения и функции. Проверка источников и явная маркировка неполного сравнения не гарантируют смысловой полноты или детерминированного ответа AI. Результаты требуют проверки человеком.
  • Неполное сравнение. Если подразделения не удалось уверенно сопоставить, приложение показывает предупреждение о частичном анализе и доступные подтверждённые результаты. Отсутствующие сопоставления не трактуются как «ноль изменений». При неполном контексте ПОСЛЕ гипотезы о потенциальной потере функций могут быть скрыты.
  • Точность зависит от структуры, качества текста и однозначности описания ответственности.
  • Извлечение выполняется порциями контекста; дальние связи и семантические дубликаты могут быть пропущены.
  • Для больших документов сравнение использует выбранные исходные фрагменты — до 65 000 UTF-8 байт на сторону. При неполном покрытии ПОСЛЕ выводы о потере скрываются. Чрезмерный контекст может привести к отказу обработки.
  • Нет экспорта отчётов, БД и управления пользователями. MVP рассчитан на доверенные локальные документы.
  • Зависимости заданы диапазонами, без lock-файла; побитовая воспроизводимость окружения не гарантируется.

Дальнейшее развитие

Возможные будущие улучшения; перечисленное ниже не реализовано:

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

Безопасность

Ключ хранится в переменных окружения или локальном .env, который игнорируется Git. .env.example содержит пустой OPENAI_API_KEY; реальный ключ в репозиторий добавлять нельзя. Проверка текущих отслеживаемых файлов на распространённые признаки ключей и секретов не выявила совпадений; это не полный аудит истории Git или безопасности приложения.

Для inference исходный текст и организационные данные передаются в OpenAI; используйте документы, которые разрешено обрабатывать таким способом. Вызовы используют store=False; это не заявление о полной политике хранения внешнего сервиса. Кэш и результаты находятся в памяти сессии. Ссылки доказательств проверяются по распарсенным источникам, а показываемый текст берётся из них напрямую. Аутентификация не реализована: не публикуйте локальный MVP как открытый многопользовательский сервис без отдельной доработки безопасности.

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

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

TuDi01 9

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

  • 2026-09-23 17:53docs: document runtime limitations and development roadmapTuDi01
  • 2026-09-23 17:40fix: validate comparison completeness and add analytical conclusionTuDi01
  • 2026-09-23 17:06docs: finalize README architecture and demo guideTuDi01
  • 2026-09-23 16:57feat: finalize Russian UI and optimize demo flowTuDi01
  • 2026-09-23 16:21feat: add evidence-backed organizational comparison and findingsTuDi01
  • 2026-09-23 15:59feat: add AI structure extraction with evidence traceabilityTuDi01
  • 2026-09-23 14:33feat: add document upload parsing and source traceabilityTuDi01
  • 2026-09-23 14:05Build H1 Streamlit document extraction and source previewsTuDi01
Все коммиты (9)
  • 2026-09-23 12:34chore: initialize hackathon projectTuDi01
Структура репозитория (34 файлов)
.env.example
.gitignore
.streamlit/config.toml
README.md
app.py
docs/architecture.md
docs/demo.md
requirements.txt
src/__init__.py
src/comparison_ui.py
src/config.py
src/models.py
src/parsers/__init__.py
src/parsers/docx_parser.py
src/parsers/parser_factory.py
src/parsers/pdf_parser.py
src/parsers/xlsx_parser.py
src/services/__init__.py
src/services/chunking.py
src/services/comparison.py
src/services/conclusion.py
src/services/extraction.py
src/services/pipeline.py
src/ui_common.py
tests/stage_mocks.py
tests/test_h1.py
tests/test_h2.py
tests/test_h21.py
tests/test_h22.py
tests/test_h23.py
tests/test_h3.py
tests/test_h41.py
tests/test_h4_ui.py
tests/test_p0.py
Ветки (2)

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

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

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