Как подготовить документы для ИИ с Unstructured: прогоните файл через partition, получите типизированные элементы с metadata, затем выполните chunking и сверьте атрибуцию каждого фрагмента с исходником. Ниже — учебный документ, порядок шагов и карта проверки результата.
Partition и типизированные элементы документа
Partition — первый шаг подготовки. Документация проекта описывает его так: в библиотеке есть функция partition, и при её вызове Unstructured использует libmagic, чтобы автоматически определить тип файла и вызвать подходящую функцию разбора. Функция пытается определить формат на входе; корректность выбранного способа разбора проверьте по результату.
Результат partition — набор элементов документа. Каждый элемент несёт тип, и именно тип определяет, как с ним обращаться дальше. Для учебного примера возьмём короткий документ «Правила мастерской»: заголовок, абзац «Сдача до 18:00» и таблицу с колонками «Тип» и «Срок». После partition ожидаются три целевых элемента: Title для заголовка, NarrativeText для абзаца, Table для таблицы.
Документация проекта отдельно упоминает альтернативный путь: MCP-сервер Unstructured Transform позволяет любому MCP-совместимому инструменту или агенту отправить документы в Unstructured на partition. Там же сказано, что достаточно подать файл и получить структурированный вывод, готовый для агента, без кода разбора. Этот путь удобен, когда разбор нужен разово из интерфейса агента.
Практический вывод для читателя: сначала определитесь, какие типы элементов вам нужны в итоге. Если downstream-задача ищет таблицы, проверьте, что таблица выделена отдельным элементом Table. Тип элемента — первый контрольный пункт, и он проверяется до всякой дальнейшей обработки.
Title, NarrativeText и Table на одном полном учебном вводе
Соберём полный учебный ввод и разберём, что должно получиться. Документ состоит из трёх частей: заголовок «Правила мастерской», абзац «Сдача до 18:00», таблица из двух строк. Ниже — текст, из которого удобно сделать PDF в текстовом редакторе и прогнать его через partition.
Правила мастерской
Сдача до 18:00
Тип | Срок
Осмотр | 1 день
Ремонт | После оценки
Ожидаемая карта элементов:
| Часть документа | Ожидаемый тип | Что проверяем |
|---|---|---|
| «Правила мастерской» | Title | Заголовок выделен как заголовок |
| «Сдача до 18:00» | NarrativeText | Абзац остался связным текстом |
| Таблица Тип/Срок | Table | Две строки и две колонки сохранены |
Смысл проверки в том, что таблица держит пары «тип — срок» вместе. Если разбор отдаёт плоскую строку вида «Осмотр1РемонтПослеоценки», пары теряются: непонятно, какой срок к какому типу относится. Table с двумя строками сохраняет их для сверки. Два условных выхода служат учебным сравнением; разбор документа не запускался.
Отдельно проверьте, что заголовок выделен отдельным элементом Title. Заголовок часто служит якорем для последующих фрагментов, и его потеря усложняет навигацию по документу. NarrativeText, в свою очередь, должен остаться цельным абзацем: дробление связного текста на куски без причины ухудшает читаемость результата для модели.
Metadata: источник, страница и связь с исходником
Metadata — то, что превращает набор элементов в проверяемый результат. В учебном примере у каждого целевого элемента заданы filename=rules.pdf и page_number=1. Эти два поля дают ответ на вопрос «откуда этот фрагмент», и без них сверка с исходником невозможна.
Порядок работы с metadata:
- Зафиксируйте имя файла-источника до запуска разбора.
- Проверьте, что каждый элемент несёт это имя в metadata.
- Сверьте номер страницы с реальным положением фрагмента в документе.
- Сохраните связку «элемент — файл — страница» рядом с текстом элемента.
Документация проекта по chunking уточняет важную деталь: исходные элементы, из которых собран chunk, доступны через поле .metadata.orig_elements на самом chunk. Это означает, что после объединения фрагментов происхождение проверяется по вложенным исходным элементам. В одностраничном учебном примере для проверки происхождения включите include_orig_elements и сверьте filename и page_number внутри orig_elements после chunking.
Практический смысл: не полагайтесь на то, что каждый исходный элемент останется отдельной записью с собственными metadata после объединения. Проверяйте происхождение там, где документация проекта указывает его искать. Для читателя это конкретное действие: открыть orig_elements у готового chunk и убедиться, что имя файла и страница совпадают с ожидаемыми.
Стратегии извлечения и дополнительные зависимости OCR
Способ извлечения текста влияет на результат сильнее, чем кажется. Документация проекта в разделе про open source библиотеку прямо говорит: вам придётся самостоятельно управлять многими зависимостями кода, например библиотеками Poppler и Tesseract. Это относится к локальной установке: часть разбора опирается на внешние инструменты, и их наличие — ваша зона ответственности.
Отсюда практический порядок:
- определите, есть ли в документе сканы или изображения с текстом;
- если да, заранее подготовьте OCR-зависимости, названные в документации проекта;
- проверьте, что извлечённый текст не превратился в мусор из-за отсутствия нужной библиотеки;
- сравните результат на странице со сканом и на странице с текстовым слоем.
Документация проекта также отмечает, что использование GPU для open source библиотеки не поддерживается. Это ограничение стоит учитывать при планировании: расчёт идёт на CPU, и для больших объёмов это влияет на время обработки.
Ещё одно ограничение из того же раздела: open source библиотека задумана как отправная точка для быстрого прототипирования и имеет пределы. Для читателя это означает, что качество извлечения следует проверить на своих документах. Стратегию извлечения выбирайте под тип документа: текстовый слой, скан, таблица — каждый случай требует своей проверки.
Chunking после partition и сохранение атрибуции
Chunking — отдельный шаг, который выполняется после partition и работает по элементам, созданным на этапе разбора. Документация проекта формулирует это прямо: разбиение выполняется над элементами документа и представляет собой отдельный шаг после partition.
Ключевое правило из документации проекта: элемент Table всегда изолируется и не объединяется с другим элементом. Для нашего учебного примера это значит, что таблица «Тип/Срок» останется отдельным chunk, и пары «Осмотр — 1 день», «Ремонт — После оценки» не разъедутся по разным фрагментам.
Порядок действий при chunking:
- Выполните partition и получите элементы.
- Запустите chunking по этим элементам.
- Для каждого chunk проверьте текст и атрибуцию.
- У таблиц убедитесь, что обе строки остались внутри одного chunk.
- При необходимости включите
include_orig_elementsи сверьте происхождение.
Атрибуция после chunking — самое хрупкое место. Метаданные могут консолидироваться при объединении, поэтому происхождение проверяется по orig_elements, как указывает документация проекта. Не обещайте себе автоматического сохранения каждой исходной страницы в любом режиме: проверяйте на своём документе, что именно попало в orig_elements и совпадают ли filename и page_number.
Проверка пары тип/срок в таблице и запрет выдуманного срока ремонта
На этом шаге проверяется смысл извлечённых пар. В учебном документе есть эталон: «один день» относится к осмотру, а для ремонта фиксированного срока нет — там указано «После оценки». Задача проверки — убедиться, что после разбора и chunking это соответствие сохранилось.
Карта контроля:
| Что проверяем | Эталон | Признак ошибки |
|---|---|---|
| Тип элемента | Title, NarrativeText, Table | Таблица стала NarrativeText |
| Страница | page_number=1 | Номер потерян или изменён |
| Целостность пары | Осмотр — 1 день | Срок оторван от типа |
| Новые числа | Их нет | Появился срок, которого не было |
Последний пункт — запрет выдуманного срока ремонта. Если в результате разбора у ремонта появилось конкретное число дней, которого в исходном документе не было, это ошибка извлечения, и такой фрагмент нельзя отдавать модели как факт. Проверка простая: сверьте каждое число в результате с исходным текстом.
Практический приём: держите рядом исходный документ и результат разбора, проходите по строкам таблицы и отмечайте совпадения. Для учебного примера достаточно двух строк, но принцип масштабируется на длинные таблицы: каждая пара «тип — срок» должна находиться в одном chunk и совпадать с источником.
Локальная библиотека, hosted API и пределы качества извлечения
Два пути запуска различаются по требованиям. Документация LangChain описывает локальную установку так: при локальной установке API-ключ не нужен. Там же указано, что загрузчик обработает документ через hosted serverless API Unstructured, если передать api_key и установить partition_via_api=True. Это два разных режима с разными условиями.
Сравнение по явным критериям:
| Критерий | Локальная библиотека | Hosted API |
|---|---|---|
| API-ключ | Не нужен | Нужен |
| Зависимости | Управляете сами (Poppler, Tesseract) | Берёт на себя сервис |
| GPU | Не поддерживается | Условия задаёт сервис |
| Назначение | Быстрое прототипирование | Обработка через сервис |
Документация LangChain также отмечает, что UnstructuredLoader не поддерживает параметр mode для группировки текста, который был у более старого загрузчика UnstructuredFileLoader. При переносе старого кода это стоит проверить отдельно.
Про пределы качества: open source библиотека задумана как отправная точка для прототипирования и имеет пределы, а использование GPU для неё не поддерживается. Практический вывод — тестируйте на своих документах, фиксируйте, где извлечение ошибается, и выбирайте режим под задачу. Если документы простые и текстовые, локального пути достаточно. Если нужен сервис без управления зависимостями, подойдёт hosted API с ключом.
Частые вопросы
Что такое partition в Unstructured?
Partition — первый шаг разбора документа. При вызове функции partition библиотека использует libmagic, чтобы определить тип файла и вызвать подходящую функцию разбора. Результат — набор типизированных элементов: заголовки, абзацы, таблицы. Дальнейшая обработка идёт уже по этим элементам.
Какие типы элементов даёт разбор учебного документа?
Для документа «Правила мастерской» ожидаются Title для заголовка, NarrativeText для абзаца «Сдача до 18:00» и Table для таблицы «Тип/Срок». Проверьте, что таблица выделена отдельным элементом Table. Тип элемента — первый контрольный пункт после разбора.
Зачем нужны metadata и orig_elements?
Metadata связывают элемент с исходником: в учебном примере это filename=rules.pdf и page_number=1. После chunking исходные элементы доступны через .metadata.orig_elements. Включите include_orig_elements и сверьте имя файла и страницу внутри orig_elements, чтобы подтвердить происхождение фрагмента.
Как проверить, что срок ремонта не выдуман?
Сверьте каждое число в результате разбора с исходным текстом. В учебном документе «один день» относится к осмотру, а у ремонта указано «После оценки» без фиксированного срока. Если в результате у ремонта появилось конкретное число дней, это ошибка извлечения, и такой фрагмент нельзя использовать как факт.
Чем локальная библиотека отличается от hosted API?
При локальной установке API-ключ не нужен, но зависимостями вроде Poppler и Tesseract управляете вы. Hosted serverless API включается передачей api_key и параметра partition_via_api=True. Локальный путь подходит для прототипирования, hosted — когда нужно обработать документы через сервис.
