У вас на сервере или в облаке лежат сотни PDF: договоры, отчёты, регламенты, сметы. Когда нужно быстро найти цифру - например, выручку за 2024 год из годового отчёта - вы открываете файл, листаете страницы, тратите 10-15 минут. Если попросить об этом ИИ-помощника, он выдаст ответ с вероятностью 40-50%. Потому что стандартные парсеры читают PDF как кашу: колонки перемешаны, таблицы разорваны. В этой статье разберём три инструмента, которые решают проблему. Вы сможете внедрить любой из них за вечер - без программиста в штате.
Почему простые парсеры ломают ваш RAG
Прежде чем платить за ИИ-помощника, поймите одну вещь: PDF хранит текст не как книгу, а как набор объектов на странице. Левый столбец, правый столбец, заголовок, подпись - всё вперемешку. PyPDF2 (популярная бесплатная библиотека) читает эти объекты в порядке хранения в файле. Результат: таблица из 5 строк и 4 столбцов превращается в 20 фрагментов без структуры. Спросите про выручку - получите случайные числа.
Разберём на примере стройфирмы. У вас есть смета на ремонт: таблица с материалами, ценами и количеством. PyPDF2 выдаст: "Бетон М300 Цемент 5000 руб 10 мешков 200 руб" - ищите сами, где что. ИИ не поймёт.
Вот как это выглядит в коде (вам не нужно это писать, просто посмотрите на проблему):
# Пример проблемы: два столбца PDF читаются в кашу
# Левый столбец: "Метод А показал результат 87%"
# Правый столбец: "Метод Б показал результат 91%"
# PyPDF2 выдаёт:
# "Метод А показал Метод Б показал результат 87% результат 91%"
# Что НЕ нужно делать в рабочей системе:
import PyPDF2
with open('report.pdf', 'rb') as f:
reader = PyPDF2.PdfReader(f)
# Смешанные колонки, потерянные таблицы - RAG даст неверные ответы
text = '\n'.join(page.extract_text() for page in reader.pages)
Сканированный PDF - отдельная история. PyPDF2 вернёт пустую строку, потому что не умеет распознавать текст с картинок (это называется OCR - оптическое распознавание символов).
Docling от IBM: точность 97,9% на таблицах - бесплатно и на вашем сервере
Если вы хотите обрабатывать документы самостоятельно, не отправляя данные в облако, Docling - ваш выбор. Это библиотека с открытым кодом от IBM Research, выпущенная в 2024 году под бесплатной лицензией MIT. Она использует две нейронные сети: одна определяет, где на странице заголовок, таблица или рисунок, вторая распознаёт структуру таблиц. Точность на таблицах - 97,9%, что на 8-12% лучше стандартных методов.
Разберём на примере проектного бюро. У вас есть альбом чертежей с таблицами спецификаций. Docling превратит их в читаемые Markdown-таблицы, которые ИИ поймёт правильно.
Вот как его настроить (скопируйте менеджеру или сделайте сами за 10 минут):
from docling.document_converter import DocumentConverter
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions
# Настройка: включаем распознавание структуры таблиц
pipeline_options = PdfPipelineOptions()
pipeline_options.do_ocr = False # включить для сканированных PDF
pipeline_options.do_table_structure = True
pipeline_options.table_structure_options.do_cell_matching = True
converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(
pipeline_options=pipeline_options
)
}
)
# Конвертация: получаем структурированный Markdown
result = converter.convert('annual_report.pdf')
markdown = result.document.export_to_markdown()
print(markdown[:2000])
Результат: таблицы сохраняются в читаемом формате:
| Показатель | 2023 | 2024 | Изменение |
|---|---|---|---|
| Выручка | 45.2 млрд | 52.7 млрд | +16.6% |
| EBITDA | 8.1 млрд | 9.3 млрд | +14.8% |
Теперь вопрос "Какая выручка в 2024 году?" получит точный ответ: "52.7 млрд".
Требования к ресурсам: около 2 ГБ памяти. Скорость: 2-5 секунд на страницу на обычном процессоре, 0.3-0.8 секунды на видеокарте.
LlamaParse: облачный инструмент для сложных документов (формулы, диаграммы)
Для документов с формулами, диаграммами и нестандартной вёрсткой Docling иногда даёт артефакты. LlamaParse от LlamaIndex работает иначе: каждая страница PDF превращается в снимок экрана и отправляется в мультимодальную языковую модель (например, GPT-4o Vision), которая видит страницу как человек. Это дороже, но лучше справляется с нестандартными форматами.
Разберём на примере контент-производства. У вас есть PDF-брошюра с инфографикой и диаграммами продаж. LlamaParse опишет диаграмму текстом: "Столбчатая диаграмма показывает рост продаж с 10 млн в январе до 15 млн в июне".
Вот как подключить LlamaParse (понадобится API-ключ с cloud.llamaindex.ai):
from llama_parse import LlamaParse
from llama_index.core import SimpleDirectoryReader
# API-ключ получается на cloud.llamaindex.ai
parser = LlamaParse(
api_key='llx-...',
result_type='markdown',
language='ru',
parsing_instruction='"""Документ содержит финансовую отчётность. Таблицы конвертировать в Markdown. Числа сохранять точно."""'
)
file_extractor = {'.pdf': parser}
documents = SimpleDirectoryReader(
'./reports/',
file_extractor=file_extractor
).load_data()
print(f'Загружено {len(documents)} документов')
Стоимость: 3 доллара за 1000 страниц в стандартном режиме, 10 долларов за 1000 в расширенном. 100-страничный отчёт обойдётся в 30-100 центов. При корпусе из 10 тысяч документов по 20 страниц - единовременные затраты 600-2000 долларов.
Важное ограничение: LlamaParse работает только как облачный сервис. Документы отправляются на внешние серверы. Для юридических или медицинских данных это может быть неприемлемо.
Unstructured: единый инструмент для смешанных форматов (PDF, Word, HTML, письма)
Когда в вашей базе перемешаны PDF, Word, HTML, письма и презентации - нужен единый инструмент. Unstructured.io обрабатывает все эти форматы и присваивает каждому элементу семантический тип: заголовок, основной текст, пункт списка, таблица, колонтитул.
Разберём на примере турагентства. У вас есть PDF-договоры с клиентами, Word-описания туров, HTML-страницы с отелями. Unstructured приведёт всё к единому формату, отфильтрует колонтитулы и нарежет по заголовкам.
Вот как это сделать (можно запустить через Docker - данные не покидают ваш сервер):
from unstructured.partition.pdf import partition_pdf
from unstructured.chunking.title import chunk_by_title
# Разбор с высокой точностью
elements = partition_pdf(
filename='contract.pdf',
strategy='hi_res',
infer_table_structure=True,
include_page_breaks=True
)
# Оставляем только содержательные элементы, убираем колонтитулы
content_elements = [
el for el in elements
if el.category in ['NarrativeText', 'Table', 'Title', 'ListItem']
]
# Нарезаем по заголовкам: каждый раздел договора - отдельный фрагмент
chunks = chunk_by_title(
elements,
max_characters=1000,
overlap=200
)
print(f'{len(chunks)} смысловых фрагментов')
Развернуть Unstructured можно самостоятельно через Docker:
docker run -p 8000:8000 \
-e UNSTRUCTURED_API_KEY='' \
downloads.unstructured.io/unstructured-io/unstructured-api:latest
OCR для сканированных PDF: Tesseract, Azure и AWS
Сканированные документы встречаются в каждой компании: старые договоры, регламенты, акты. Ни один из трёх инструментов выше не поможет без предварительного OCR (оптического распознавания символов). Выбор зависит от бюджета и требований к точности.
Tesseract 5.x - бесплатный инструмент с открытым кодом, поддерживает русский язык. Точность: 85-92% для хорошего скана, 60-75% для плохого. Данные не покидают сервер.
Разберём на примере ремонтной фирмы. У вас есть сканы старых актов выполненных работ. Tesseract распознает текст, а Docling затем восстановит структуру.
Вот как обработать сканированный PDF через Tesseract:
import pytesseract
from pdf2image import convert_from_path
# Конвертируем страницы PDF в изображения с высоким разрешением
pages = convert_from_path('scan.pdf', dpi=300)
texts = []
for i, page in enumerate(pages):
text = pytesseract.image_to_string(
page,
lang='rus+eng',
config='--psm 6'
)
texts.append(text)
print(f'Страница {i+1}: {len(text)} символов')
Azure Document Intelligence - облачный сервис с распознаванием рукописного текста, печатей и сложных таблиц. Точность 94-98%. Стоимость: 1,5 доллара за 1000 страниц. Для кириллицы предпочтительнее AWS Textract.
Вот как подключить Azure для извлечения структурированных таблиц из скана:
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential
client = DocumentAnalysisClient(
конечная точка API='https://your-resource.cognitiveservices.azure.com/',
credential=AzureKeyCredential('your-key')
)
with open('scan.pdf', 'rb') as f:
poller = client.begin_analyze_document('prebuilt-document', f)
result = poller.result()
for table in result.tables:
print(f'Таблица {table.row_count}x{table.column_count}')
for cell in table.cells:
print(f' [{cell.row_index},{cell.column_index}]: {cell.content}')
Какой инструмент для каких документов
Нет универсального решения. Вот практическая матрица выбора:
| Тип документа | Инструмент | Причина |
|---|---|---|
| Финансовые отчёты, регламенты | Docling | Отличные таблицы, бесплатно, данные у вас |
| Научные статьи с формулами | LlamaParse расширенный | Понимает формулы, выдаёт LaTeX |
| PDF + Word + HTML вместе | Unstructured | Единый интерфейс для всех форматов |
| Сканированный PDF, русский | Tesseract + Docling | Распознавание + структура |
| Юридические формы | Azure Document Intelligence | Высокая точность, структурированный ответ |
| Презентации с диаграммами | LlamaParse | Описывает диаграммы текстом |
Вот простой маршрутизатор, который автоматически выбирает инструмент по типу файла (скопируйте менеджеру):
from pathlib import Path
import pymupdf
def choose_parser(file_path: str) -> str:
path = Path(file_path)
ext = path.suffix.lower()
if ext == '.pdf':
doc = pymupdf.open(file_path)
text_blocks = doc[0].get_text('blocks')
if not text_blocks:
return 'azure_ocr' # сканированный PDF
raw_text = doc[0].get_text()
has_formulas = any(s in raw_text for s in ['\\frac', '\\int', '\u222b', '\u2211'])
if has_formulas:
return 'llamaparse_premium'
return 'docling'
elif ext in ['.docx', '.pptx', '.html', '.eml']:
return 'unstructured'
return 'plain_text'
Как хранить таблицы после парсинга
Выбор формата хранения таблиц влияет на качество ответов ИИ-помощника. Три подхода:
Markdown-таблица - лучший вариант для большинства случаев. Структура сохранена, ИИ читает её корректно, легко индексируется. Один фрагмент = одна таблица.
JSON - подходит для программного доступа, но хуже для смыслового поиска: структура снижает качество векторного представления текста.
Текстовое описание - генерируется через LLM при индексации: 'Таблица показывает финансовые результаты за 2023-2024 годы. Выручка выросла на 16.6% до 52.7 млрд рублей...'. Лучше находится при общих вопросах, но теряет точные числа.
Оптимально: двойная индексация. Markdown - для точных вопросов, текстовое описание - для общих ('как изменились финансовые результаты').
Типичные ошибки
Использовать PyPDF2 для корпоративных отчётов. Потери структуры таблиц критичны для финансовых данных.
Игнорировать сканированные PDF в базе. Документы без текстового слоя вернут пустые фрагменты и загрязнят результаты поиска.
Отправлять чувствительные данные в облачные парсеры без проверки политики конфиденциальности.
Не проверять качество распознавания перед индексацией. Текст с точностью 70% даёт бесполезные фрагменты.
Частые вопросы
Docling или LlamaParse для русскоязычных PDF с таблицами?
Начните с Docling: бесплатно, данные на вашем сервере, хорошая точность для структурированных корпоративных отчётов. Переключайтесь на LlamaParse для документов, где Docling даёт артефакты.
Как обрабатывать PDF-презентации с картинками?
Если исходный PPTX доступен - парсите его напрямую, это точнее конвертации в PDF. Для слайдов с диаграммами LlamaParse с мультимодальной моделью существенно лучше: даёт текстовое описание диаграммы.
Когда выгоднее развернуть Unstructured самостоятельно?
API стоит 10 долларов за 1000 страниц. Собственный сервер с видеокартой A10G - около 75 центов в час. При обработке более 5000 страниц в месяц собственный сервер выгоднее.
Как сохранить структуру таблицы при индексировании?
Два подхода: таблица целиком как один фрагмент с Markdown-форматированием, или каждая строка как отдельный фрагмент с заголовками столбцов. Второй вариант лучше для точных вопросов по конкретным ячейкам.
Что делать с PDF, где текст не выделяется?
Конвертировать страницы в изображения с разрешением 300 DPI через pdf2image, затем Tesseract для русского или Azure Document Intelligence для критически важных документов. Проверить качество распознавания перед индексацией.
Что дальше и выводы
Правильный парсинг - фундамент всего RAG. Из хорошо распознанных документов система извлечёт правильные фрагменты. Из каши - нет, сколько бы умной ни была языковая модель.
Ваш следующий шаг: выберите один инструмент из таблицы выше под ваш тип документов. Если у вас финансовые отчёты - поставьте Docling. Если смешанные форматы - Unstructured. Скачайте готовый скрипт из статьи, скопируйте менеджеру, пусть запустит на ноутбуке или сервере. На всю настройку уйдёт 2-4 часа.
AI Компас (t.me/kosmoslab_ai) - канал для предпринимателей в РФ и СНГ, которые применяют AI в своём бизнесе без программиста. Разбираем инструменты и схемы - без курсов и теории.