Как вы проверяете качество parsing документов (PDF, DOCX) в production?

Краткий тезис

Качество parsing (извлечения текста и структуры из PDF/DOCX) — критический фактор для RAG-системы: ошибки на этом этапе необратимо портят все downstream‑процессы (chunking, retrieval, генерацию). Для объективной оценки необходим golden dataset (золотой стандарт) из документов с ручной разметкой, метрики accuracy (точность), structured loss metrics (метрики потерь структуры) и автоматизированный CI/CD пайплайн для регрессионного тестирования при каждом изменении парсера. В production также требуется мониторинг ошибок парсинга и fallback‑стратегии.


1. Термин: Parsing документов (PDF, DOCX)

Parsing — процесс извлечения машиночитаемого текста и структурных элементов (заголовков, списков, таблиц, изображений, метаданных) из бинарных форматов PDF и DOCX. От качества парсинга зависит, какой контент попадёт в базу знаний RAG.

Почему это важно:

  • PDF может содержать текст как текстовый слой (выбираемый) или как растровые изображения (сканы, требуют OCR). DOCX имеет внутреннюю XML-структуру, но может включать вложенные объекты (таблицы, формулы).
  • Ошибки парсинга: потеря символов, перепутанные колонки, разорванные таблицы, отсутствие заголовков → некорректный chunking → падение качества retrieval.
  • В production парсинг должен быть надёжным для тысяч документов разных типов.

2. Создание Golden Dataset (Gold Standard)

Golden dataset — набор документов, для которых вручную размечена «идеальная» версия текста и структуры. Это эталон для оценки парсера.

ШагОписание
1. Выбор репрезентативных документов200–1000 документов, отражающих реальное распределение: разные размеры, языки, типы PDF (текстовые/отсканированные), DOCX (с таблицами, списками, встроенными изображениями).
2. Ручная разметкаДля каждого документа аннотатор вручную фиксирует: точную последовательность слов, границы абзацев, уровни заголовков, ячейки таблиц, alt-текст для изображений.
3. Разбивка на чанки (опционально)Если парсинг далее влияет на chunking, можно размеченный текст разбить на логические блоки (по заголовкам, абзацам) — это даст метрику структурной точности.
4. ВерсионированиеGolden dataset хранится в системе контроля версий (Git LFS) вместе с тестовыми скриптами.

Важно: golden dataset должен регулярно пополняться новыми типами документов, встречающимися в production.

3. Метрики качества Parsing

3.1 Точность извлечения текста

Error Rate|Character Error Rate (CER) — доля неверных символов (вставок, удалений, замен) относительно эталонного текста.

Формула:

CER = (S + D + I) / N

где S — замены, D — удаления, I — вставки, N — длина эталонной строки (в символах).

Word Error Rate (WER) — аналогично на уровне слов. Чаще используется, так как для RAG важна целостность слов.

Значение WERИнтерпретация
< 1%Отлично
1–5%Приемлемо
> 5%Требует улучшений

Расчёт на Python с помощью jiwer:

from jiwer import wer

reference = "Парсинг документов — важный этап RAG."
hypothesis = "Парсинг документов важный этап RAG."  # потеря тире и пробелов
error = wer(reference, hypothesis)  # ≈ 0.133 (2 ошибки из 15 слов)

Ограничения: CER/WER не учитывают структуру и не штрафуют за перестановку строк.

3.2 Структурированные метрики (Structured Loss Metrics)

Для оценки заголовков, таблиц, списков вводят метрики на уровне аннотированных блоков.

  • F1 для заголовков: парсер должен найти все заголовки и правильно сопоставить уровень (H1, H2, …).
  • Intersection over Union (IoU) для bounding box (для PDF с координатами): насколько хорошо парсер определяет границы абзацев/таблиц.
  • Table recovery accuracy: доля ячеек таблицы, извлечённых с правильным содержимым и порядком.

Пример метрики для заголовков:

ПарсерPrecisionRecallF1
A0.850.900.87
B0.920.780.84

3.3 Сквозные метрики для RAG

Парсинг — не самоцель. Можно измерить его влияние на downstream: взять golden dataset, пропустить эталонный текст и распарсенный текст через одинаковый pipeline (chunking + embedding + retrieval + generation) и сравнить метрики RAG (hit rate, faithfulness). Это дорого, но даёт прямую бизнес-ценность.

4. CI/CD Pipeline для регрессионного тестирования

При каждом изменении парсера (новая версия библиотеки, кастомный алгоритм, OCR-модель) должен автоматически запускаться прогон на golden dataset.

Процесс:

  1. Триггер: commit в ветку парсера, pull request.
  2. Шаги пайплайна:
    • Извлечение текста и структуры парсером из документов golden dataset.
    • Расчёт метрик (CER, WER, F1 по заголовкам).
    • Сравнение с baseline (предыдущей версией).
  3. Пороговые значения:
    • WER не должен вырасти более чем на 0.5%.
    • F1 для заголовков не ниже 0.95 от baseline.
  4. Действия при превышении порога:
    • Отклонение PR с подробным отчётом (diff ошибок).
    • Если парсер улучшает одни метрики, но ухудшает другие — ручное ревью.

Инструменты: GitHub Actions / GitLab CI, pytest с параметризацией, отчёты в Allure или в wandb.

5. Инструменты и библиотеки для парсинга

ФорматПопулярные инструментыОсобенности
PDF (текстовый слой)PyMuPDF (fitz), pdfplumber, pdfminer.sixpdfplumber хорошо извлекает таблицы, PyMuPDF – быстрый, pdfminer – медленный, но детальный.
PDF (сканы/OCR)Tesseract OCR, EasyOCR, PaddleOCR, DocTRТребуют предобработки (deskew, binarization). Лучше использовать end-to-end решения вроде Docling.
DOCXpython-docx, python-pptx (для PPTX)python-docx даёт доступ к абзацам, таблицам, спискам. Для сложных макетов – mammoth (конвертация в HTML).
Структурный анализLayoutLM, Unstructured.io, DoclingПомогают распознавать заголовки, разделы даже в сканах.

Рекомендация: в production комбинировать несколько парсеров и выбирать результат с наибольшей уверенностью (ансамбль) или fallback-цепочку (сначала текстовый PDF, если ошибка > порога – OCR).

6. Проблемы парсинга в production

ПроблемаПричинаРешение
Защищённые PDF (пароль, шифрование)Пользовательский контентОтклонять документ с явной ошибкой, логировать.
Нестандартные шрифты/символыPDF с кодировками CJK, математические символыДополнительный постинжиниринг: map символов, fallback на OCR.
Таблицы без границНекорректная структура в исходном документеИспользовать табличные парсеры (Camelot, tabula-py).
DOCX с макросами / встроенными OLEВредоносный или устаревший контентСанирующий парсинг (извлекать только text/XML).
Большие объёмы (100+ страниц)Ограничение памяти, таймаутыПотоковый парсинг, чанкизация перед парсингом.

7. Мониторинг качества в production

Даже при хорошем offline-тестировании в production могут проявиться новые ошибки.

Метрики мониторинга:

  • Доля документов, успешно прошедших парсинг (без ошибок).
  • Средняя длина извлечённого текста (сравнение с ожидаемой).
  • Количество символов, не определённых Unicode ().
  • Время парсинга (latency) – если превышает порог, нужно проанализировать.

Инструменты: Prometheus + Grafana, ELK-стек (логгирование ошибок с полным текстом документа), Sentry для exception.

Action:

  • При повышении доли ошибок >5% – автоматически переключать пользователей на запасной парсер (например, OCR вместо текстового).
  • Периодически размечать небольшую выборку из production (50 документов) и считать delta по WER относительно golden dataset.

8. A/B тестирование парсеров

В production можно рандомно разбивать поступающие документы на группы и сравнивать парсеры.

ГруппаПарсерМетрика downstream (hit rate RAG)
A (50%)Старый (baseline)0.82
B (50%)Новый (с LayoutLM)0.87

Статистическая значимость проверяется t-тестом. Если новая версия стабильно лучше — делаем rollout.

9. Связь с downstream этапами (chunking, retrieval, generation)

Плохой парсинг может:

  • Пропустить заголовки → chunking не разобьёт документ логически → потеря контекста.
  • Исказить таблицы → retrieval не сможет найти нужную ячейку.
  • Добавить мусорные символы → эмбеддинги будут шумными → снижение accuracy.

Поэтому тестирование парсинга должно сопровождаться интеграционными тестами: взять 10 проблемных документов, прогнать через полный RAG‑пайплайн и убедиться, что ответы корректны.

Пет-проект для закрепления

Задача: создать систему автоматической оценки парсера PDF с golden dataset и CI-пайплайном.

Инструменты:

  • Python, PyMuPDF, pdfplumber, Tesseract OCR.
  • jiwer, rouge-score (для сравнения текста).
  • GitHub Actions.
  • Docker (изоляция окружения парсера).

Шаги:

  1. Собрать 20 PDF разных типов (с текстом, сканом, таблицами).
  2. Вручную разместить текст в JSON-файлах.
  3. Написать функцию, которая для каждого парсера (PyMuPDF, pdfplumber, Tesseract) считает WER и F1 для заголовков.
  4. Сравнить парсеры и выбрать лучший.
  5. Написать pytest-тест с порогами: если WER > 5% – падение.
  6. Поместить тест в GitHub Actions, добавить golden dataset в Git LFS.

Ожидаемый результат:

  • Готовый скрипт оценки.
  • Отчёт с метриками.
  • CI-пайплайн, который блокирует PR, если новый парсер ухудшает метрики.

Связь с другими вопросами

ВопросТема
[Вопрос [258(258_вопрос)Chunking стратегии (зависят от качества парсинга)
Вопрос 260. Как вы отслеживаете data drift для распределения запросов к RAG260(260_вопрос)
Вопрос 262. Как вы проектируете feature store для ML фичей, используемых LLM262(262_вопрос)
Вопрос 267. Что такое data version control (DVC) для RAG корпуса документов267(267_вопрос)
Вопрос 270. Как вы управляете cost хранения векторной БД при миллиарде векторов270(270_вопрос)

Навигация

  • Предыдущий: 271. Как вы делаете schema evolution для метаданных документов в RAG|271](/answers/258)
  • Следующий: 273
  • Индекс: 00. Индекс разборов