AAYMA
RU
Войти

OrgLens

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

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

О проекте

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

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

Суть

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

Как устроено

Документы разбираются на страницы, разделы и пункты (pdf-parse/PDF.js, mammoth), каждый фрагмент получает неизменяемый ID. LLM через OpenAI-совместимый /chat/completions (NVIDIA API) порциями до 12 000 символов извлекает подразделения и функции с цитатами. Zod проверяет схему, а каждая цитата должна буквально присутствовать во фрагменте. Второй вызов сопоставляет сущности обеих редакций по смыслу; сервер перепроверяет ссылки и понижает неподтверждённые выводы до «возможно» или «недостаточно данных». Прогресс передаётся потоком NDJSON, отчёт показывается на дашборде и выгружается в JSON.

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

  • chunked LLM extraction
  • проверка дословных цитат (grounding)
  • семантическое сопоставление сущностей
  • Zod-валидация
  • NDJSON-стриминг
  • защита от prompt injection

Особенности

Выдуманное доказательство отклоняет весь результат, а потери и дубли не могут автоматически стать установленным фактом. Трёхуровневая система статусов достоверности. Команды внутри документов считаются недоверенным содержимым. Есть демо на реальных обезличенных редакциях 8 и 9.

Стек

TypeScript · Next.js · React · Tailwind CSS · Zod · pdf-parse · PDF.js · mammoth · Render

Модели

NVIDIA API (OpenAI-compatible)


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

README

README.md

OrgLens

Интеллектуальный анализ организационных изменений. Хакатонный MVP для кейса «ИИ-агент: Анализ организационной структуры и функционала».

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

Быстрый старт

Нужен Node.js 22.13+ (рекомендуется Node.js 24 LTS) и npm. Откройте терминал в папке проекта, где лежит этот README.

npm install
npm run dev -- --port 3001

Откройте текущую локальную версию OrgLens. Без настройки API можно нажать «Открыть пример». Если .env.local уже содержит DEMO_MODE=true, нажмите «Начать анализ» — появится тот же проверенный пример.

Адрес для текущего запуска: http://127.0.0.1:3001. Номер порта не обозначает версию проекта: актуальный код находится в ветке main. Команда выше запускает его на порту 3001. Если порт занят, используйте адрес из строки Local в терминале. Это локальная ссылка: она работает только на компьютере с запущенным проектом.

Чтобы включить деморежим на новом компьютере, скопируйте .env.example в .env.local (команды ниже). Для демонстрации API-ключ не нужен. Не переносите node_modules и .next между компьютерами: каждый участник выполняет npm install самостоятельно.

Проблема

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

Решение

  • Два поля загрузки: ДО и ПОСЛЕ.
  • PDF с текстовым слоем и DOCX.
  • Выявление новых, исключённых, переименованных и сохранённых подразделений, изменения подчинённости.
  • Сопоставление сохранённых, переданных, изменённых, новых и потенциально потерянных функций.
  • Гипотезы о дублировании и пересечениях ответственности.
  • Dashboard: оргструктура, функции, риски, заключение.
  • Для каждого наблюдения — документ, редакция, пункт, страница PDF и исходная цитата.
  • Экспорт всего отчёта в JSON.

Как работает AI-агент

  1. Сервер проверяет формат, размер и текстовый слой файлов. PDF разбирается постранично; DOCX — в текст без фиктивных номеров страниц.
  2. Текст разделяется на разделы и пункты. Каждому фрагменту назначается неизменяемый ID и привязка к источнику.
  3. Документы отправляются модели порциями до 12 000 символов. На этом этапе модель извлекает подразделения и функции с исполнителями и цитатами. Исходные документы не отправляются целиком одним prompt.
  4. Ответы проверяются Zod. Каждая цитата должна буквально присутствовать в указанном фрагменте с учётом нормализации пробелов и Unicode.
  5. Модель получает структурированные сущности обеих редакций и сопоставляет их по смыслу, включая переносы между исполнителями и смену нумерации. Это не простой string diff.
  6. Сервер повторно проверяет схему, ссылки, сторону ДО/ПОСЛЕ и цитаты. Выдуманное доказательство отклоняет весь результат. Сравнение без второй стороны понижается до неопределённого. Потери, дубли и конфликты не могут стать установленными фактами автоматически.
  7. Заключение реального анализа формируется сервером из подтверждённых наблюдений и вопросов для проверки со ссылками на их ID; рядом доступны все основания. Прогресс передаётся интерфейсу потоком NDJSON.

Команды, обнаруженные внутри документов, считаются недоверенным содержимым, а не инструкциями агенту. Системный prompt явно отделяет их от задачи. Это снижает риск prompt injection, но не заменяет экспертную проверку смысла.

Статусы

СтатусЗначение
Подтверждено текстомПриведённые фрагменты поддерживают вывод; фактическое выполнение работ не проверялось
Возможно · нужна проверкаЕсть основание для гипотезы, но недостаточно для установления факта
Недостаточно данныхНет достаточных доказательств или невозможно однозначно распределить ответственность

Проценты уверенности — эвристика модели (в демо — ручная оценка), не статистическая вероятность. Проверка цитаты гарантирует её присутствие, но не корректность интерпретации.

Архитектура

flowchart LR
    UI["Next.js UI: ДО / ПОСЛЕ"] --> API["POST /api/analyze"]
    API --> PARSE["PDF / DOCX → страницы и пункты"]
    PARSE --> EXTRACT["AI: извлечение сущностей порциями"]
    EXTRACT --> CHECK1["Zod + проверка цитат"]
    CHECK1 --> MATCH["AI: смысловое сопоставление"]
    MATCH --> CHECK2["Zod + источники + статусы"]
    CHECK2 --> REPORT["Dashboard + JSON"]
    API -. "NDJSON: этапы" .-> UI
    UI --> DEMO["GET /api/demo: проверенный пример"]
    DEMO --> REPORT
    EXTRACT <--> PROVIDER["Серверный AIProvider"]
    MATCH <--> PROVIDER
    PROVIDER <--> NVIDIA["NVIDIA / OpenAI-compatible API"]

Хранилище не требуется: файлы и результаты не сохраняются сервером. Отчёт находится в памяти браузера до обновления страницы; для сохранения используйте JSON. Supabase сознательно исключён из MVP для простого старта.

Технологии

Next.js App Router, React, TypeScript, Tailwind CSS, CSS, серверные Route Handlers, Zod, pdf-parse/PDF.js, mammoth, lucide-react. Точные версии зафиксированы в package-lock.json.

AI-провайдер подключается через обычный серверный fetch к /chat/completions. SDK конкретного поставщика не требуется. Интерфейс AIProvider позволяет заменить реализацию отдельно от анализа.

Установка на Windows

Установите Node.js 24 LTS. Распакуйте проект в обычную локальную папку. Откройте её в VS Code → Terminal → New Terminal. В PowerShell:

npm install
Copy-Item .env.example .env.local
npm run dev

Если .env.local уже настроен, не выполняйте повторное копирование. Если PowerShell блокирует npm.ps1, используйте npm.cmd install и npm.cmd run dev либо терминал cmd; менять политику безопасности не нужно.

Установка на macOS

Установите Node.js 24 LTS. Откройте терминал в папке проекта:

npm install
cp .env.example .env.local
npm run dev

Если .env.local уже настроен, пропустите копирование. Остановка сервера — Ctrl+C.

Одинаковые npm-команды работают на обеих ОС. В коде нет абсолютных путей к файлам разработчика. scripts/dev.mjs включает переносимый polling для наблюдения за изменениями файлов, чтобы не упираться в лимиты файловых наблюдателей.

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

Создайте .env.local на основе .env.example. Все переменные используются сервером; префикс NEXT_PUBLIC_ для секретов запрещён.

ПеременнаяЗначение
DEMO_MODEtrue: основной сценарий показывает фиксированный пример; false: анализирует выбранные файлы
AI_API_KEYКлюч выбранного AI-провайдера. Для демо пусто
AI_BASE_URLURL API, включая /v1, без /chat/completions
AI_MODELТочный идентификатор доступной вашему аккаунту модели
AI_TIMEOUT_MSОжидание одного запроса, по умолчанию 90000; допустимый диапазон 5000–180000 мс

После изменений перезапустите сервер. .env.local исключён из Git. Реальных ключей в проекте нет.

Пример реального режима:

DEMO_MODE=false
AI_API_KEY=ваш_ключ
AI_BASE_URL=https://integrate.api.nvidia.com/v1
AI_MODEL=идентификатор_модели_из_вашего_аккаунта
AI_TIMEOUT_MS=90000

Не используйте слова-заполнители как действующие ключ или модель. Секрет заполняет участник команды на своём компьютере.

NVIDIA API

  1. Откройте NVIDIA API Catalog и выберите доступную вашему аккаунту текстовую instruction/chat-модель.
  2. Возьмите ключ и точное имя модели из примера API на её странице. Доступность и квоты зависят от аккаунта, поэтому имя не зашито в приложение.
  3. Заполните переменные выше. Рекомендуемый контекст модели — от 64k токенов, желательно 128k, поддержка русскоязычных документов и ответов JSON.
  4. Установите DEMO_MODE=false, перезапустите npm run dev, загрузите два PDF и нажмите «Начать анализ».

Используется OpenAI-compatible endpoint NVIDIA Chat Completions. Для другого совместимого сервиса измените AI_BASE_URL, AI_MODEL, AI_API_KEY. Модель должна поддерживать messages, temperature, max_tokens и возвращать choices[0].message.content. JSON запрашивается инструкцией и обязательно валидируется; специфичный response_format не используется ради совместимости. Модели с иным контрактом требуют адаптации provider.ts.

Реальный запуск включает несколько запросов и может расходовать квоту. Текст отправляется выбранному провайдеру, о чём сообщает интерфейс. Демопример не отправляет текст во внешний AI API. Ошибка API никогда не подменяется демоданными автоматически.

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

app/
  page.tsx                  Загрузка, прогресс, dashboard, evidence, экспорт
  globals.css               Адаптивное оформление
  api/config/route.ts       Режим сервера без раскрытия ключей
  api/analyze/route.ts      Проверка загрузки и поток прогресса
  api/demo/route.ts         Явный демопример
lib/
  schema.ts                 TypeScript + Zod
  evidence.ts               Проверка цитат и понижение статусов
  errors.ts                 Понятные ошибки
  documents/parse.ts        PDF/DOCX, ограничения
  documents/structure.ts    Разделы, пункты, ссылки
  ai/provider.ts            Сменный AI-провайдер
  ai/analyze.ts             Извлечение и смысловое сопоставление
  demo/report.json          12 наблюдений с реальными цитатами
public/demo/
  revision-8.pdf            Исходный обезличенный PDF ДО
  revision-9.pdf            Исходный обезличенный PDF ПОСЛЕ
scripts/dev.mjs             Переносимый запуск dev-сервера
tests/                      Проверки parsing, evidence, AI-контракта
.env.example                Шаблон без секретов

Демо для судей — 2 минуты

0:00–0:20. Откройте приложение. Покажите редакции 8 и 9. Скажите: «После реорганизации нужно понять, куда перешли функции, и доказать каждый вывод документом». Нажмите «Начать анализ» в деморежиме или «Открыть пример».

0:20–0:50. Во вкладке «Оргструктура» откройте «ДИТААД включён в структуру БВА». Покажите п. 3.4 обеих редакций рядом. В старой — два департамента, в новой — четыре. Ссылка открывает исходный PDF на соответствующей странице.

0:50–1:20. Во вкладке «Функции» откройте «Карта гарантий: функция передана, а не потеряна». Покажите переход из п. 5.4.4 в п. 5.3.3. Объясните, почему сравнение по номерам пунктов дало бы ошибку.

1:20–1:45. Во вкладке «Риски» откройте изменение обязательности контрольных процедур: «осуществляется» → «может осуществляться». Покажите статус «Возможно · нужна проверка». Агент не выдаёт риск за установленную потерю.

1:45–2:00. Откройте «Заключение», затем «Скачать JSON». Честно уточните: «Сейчас показан заранее проверенный демопример. Для своих документов предусмотрен отдельный режим анализа через AI API».

Происхождение демоданных

Данные взяты из предоставленных обезличенных положений о внутреннем аудите, редакций 8 и 9, по 25 страниц. Все 27 цитат автоматически сверяются с текстом на указанных страницах обоих PDF в тестах. Это 12 вручную отобранных наблюдений, не исчерпывающий отчёт. Структурных изменений в карточке 3: два новых департамента и изменённое прямое подчинение. Сохранение ДНМ и ДККМ показано отдельно и не увеличивает счётчик изменений.

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

Проверка проекта

npm run lint
npm run typecheck
npm test
npm run build
npm run test:api

test:api поднимает production-сервер на свободном локальном порту и тестовый AI-сервис. Он отправляет оба PDF через HTTP, проверяет поток этапов, результат, ошибки загрузки и демопример. Внешний API не используется.

Для проверки production-версии остановите dev-сервер:

npm start

Для надёжного выступления можно заранее выполнить сборку и использовать npm start — начальная компиляция не потребуется.

Ручная проверка:

  1. Откройте демо, пройдите четыре вкладки, раскройте доказательства, откройте PDF и скачайте JSON.
  2. В AI-режиме попробуйте неверный формат, пустой и слишком большой файл — должно появиться понятное сообщение.
  3. Без AI_API_KEY получите сообщение о настройке, а не stack trace.
  4. С реальным ключом загрузите оба PDF. Дождитесь этапов извлечения, сопоставления, проверки цитат и заключения.
  5. Сверьте несколько цитат с оригиналами. Проверьте, что перенос Карты гарантий не назван потерей.

Автотесты используют реальный PDF-parser и тестовый AI-провайдер. Проверяется полный серверный конвейер, HTTP-контракт совместимого API, невалидный JSON, ошибки API, отмена, неизвестные цитаты, неправильная сторона, пределы файлов. Эти тесты не доказывают качество ответов реальной модели. Прямой вызов NVIDIA без ключа не проверялся. Windows-команды переносимы, но запуск на физическом Windows-компьютере здесь не выполнялся.

Ограничения MVP

  • До 10 МБ, 80 страниц PDF и 180 000 символов на документ. До 150 000 символов в извлечённом представлении для сопоставления; больший контекст отклоняется явно, без скрытого обрезания.
  • Весь анализ ограничен примерно 9,5 минутами; один запрос AI — настраиваемым timeout. Большие документы и медленные модели могут не уложиться.
  • Только текстовый PDF. OCR, сложные таблицы, схемы оргструктуры и текст на изображениях не поддерживаются.
  • DOCX поддерживается базово: отсутствуют страницы, автоматические Word-номера списков могут теряться. Для надёжных ссылок экспортируйте в текстовый PDF.
  • Разбиение по пунктам эвристическое. Нет полной нормализации всех форматов документов. Буквальное присутствие цитаты не гарантирует правильное распознавание раздела.
  • Извлечение сущностей и смысловое сопоставление зависят от модели и не гарантируют полноту. Новое название не доказывает новое подразделение; отсутствие упоминания не доказывает удаление.
  • Демоданные ручные, с явной маркировкой; они не зависят от загруженных файлов. В деморежиме загрузка заблокирована, чтобы исключить подмену анализа.
  • Нет аккаунтов, базы, истории, совместного доступа, OCR или PDF-экспорта отчёта. Есть экспорт JSON.
  • Запуск привязан к 127.0.0.1. Это локальный MVP, не публичный сервис. Для публичного развёртывания нужны авторизация, ограничения запросов, очередь/worker, защита загрузки на уровне reverse proxy и согласованная политика хранения. In-memory ограничение «один анализ» действует только в одном процессе.
  • Включённые обезличенные примеры доступны в public/demo. Для другой поставки удалите или замените их, если не хотите распространять эти примеры.

Если что-то пошло не так

СообщениеЧто сделать
Не задан AI_API_KEYЗаполнить .env.local или включить деморежим и перезапустить
AI API недоступенПроверить точное имя модели, ключ и base URL; не дописывать /chat/completions
AI вернул невалидный JSONПовторить или выбрать более подходящую instruction-модель
Цитата не найденаОтвет модели отклонён; повторить анализ, проверить качество PDF
Время ожидания истеклоВыбрать более быструю модель/меньшие документы; можно увеличить timeout до 180000
Текст не обнаруженСделать OCR вне приложения и сохранить PDF с текстовым слоем
Порт 3000 занятnpm run dev -- --port 3001, затем открыть http://127.0.0.1:3001
Результат исчез после обновленияВ MVP нет истории; сохраняйте JSON перед обновлением

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

Семантический поиск по embeddings с проверкой кандидатов в обе стороны; многоэтапная сверка полноты; RACI-матрица; OCR и таблицы; эталонная выборка и измерение precision/recall; фоновые задания; авторизация и Supabase; история версий и экспорт отчёта в PDF.

Работа втроём

Первый участник ведёт интерфейс и demo flow, второй — документы и проверку цитат, третий — AI-настройки, README и тесты. Перед объединением изменений запускайте четыре проверки выше. В Git передавайте исходники, package.json, package-lock.json и .env.example; не передавайте .env.local, .next и node_modules.

Справочные материалы: Next.js Installation, NVIDIA LLM APIs.

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

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

Java 6askabek378 1China 1

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

  • 2026-09-23 17:50Update README launch link to current local port 3001Java
  • 2026-09-23 17:42Improve grounded AI analysis and add multilingual report toolsJava
  • 2026-09-23 16:20Merge pull request #3 from BAITC-Hacks/feature/interfacedancho-55
  • 2026-09-23 16:19Add OrgLens interfaceaskabek378
  • 2026-09-23 16:05Merge pull request #2 from BAITC-Hacks/feature/ai-apidancho-55
  • 2026-09-23 15:58Add AI analysis pipeline and server APIChina
  • 2026-09-23 15:27Merge pull request #1 from BAITC-Hacks/feature/orglens-basedancho-55
  • 2026-09-23 15:18Add OrgLens foundation and document processingJava
Структура репозитория (58 файлов)
.env.example
.gitignore
AGENTS.md
CLAUDE.md
DEPLOY.md
README.md
README.repository.md
TEAMWORK.md
VERIFICATION.md
app/api/analyze/route.ts
app/api/assistant/route.ts
app/api/config/route.ts
app/api/demo/route.ts
app/components/Assistant.tsx
app/globals.css
app/layout.tsx
app/page.tsx
eslint.config.mjs
lib/access.ts
lib/ai/analyze.ts
lib/ai/grounding.ts
lib/ai/provider.ts
lib/assistant.ts
lib/demo/report.json
lib/documents/parse.ts
lib/documents/structure.ts
lib/errors.ts
lib/evidence.ts
lib/i18n.ts
lib/pdf-report.ts
lib/report-cache.ts
lib/schema.ts
lib/text-diff.ts
next-env.d.ts
next.config.ts
package-lock.json
package.json
postcss.config.mjs
public/demo/revision-8.pdf
public/demo/revision-9.pdf
public/fonts/NotoSans-Regular.ttf
public/fonts/OFL.txt
render.yaml
scripts/api-smoke.mjs
scripts/dev.mjs
scripts/start-hosted.mjs
team/participant-1.txt
team/participant-2.txt
team/participant-3.txt
tests/assistant.test.ts
tests/core.test.ts
tests/grounding.test.ts
tests/parallel-analysis.test.ts
tests/partial-evidence.test.ts
tests/provider.test.ts
tests/report-tools.test.ts
tests/structured-output.test.ts
tsconfig.json
Ветки (4)

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

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

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