Учебник

Поиск по договорам и финансовым отчётам через RAG

Ваши менеджеры тратят часы на поиск цифр в PDF: выручка за прошлый год, сумма договора, сроки поставки. Стандартные парсеры превращают таблицы в кашу, а сканы в пустоту. Разбираем три инструмента - Docling, LlamaParse, Unstructured - которые вы или ваш менеджер настроите за 2-8 часов без единой строчки кода (кроме готовых скриптов). Получите точные ответы от ИИ по любым документам.

Макс Космов··7 мин чтения

У вас на сервере или в облаке лежат сотни 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 в своём бизнесе без программиста. Разбираем инструменты и схемы - без курсов и теории.