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

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

Проверка качества парсинга в production — это непрерывный процесс, основанный на golden dataset (золотой набор вручную размеченных документов) и автоматизированных метриках. Ключевые метрики: Error Rate|Character Error Rate (CER) для текста и structure preservation для сохранения заголовков, списков и таблиц. При каждом изменении парсера запускается регрессионный тест в CI/CD, а в production мониторинг отслеживает дрейф качества на новых типах документов. Пороговые значения: CER < 2%, structure loss < 5%.


1. Термин: Парсинг документов (Document Parsing)

Парсинг — это процесс извлечения структурированного текста и метаданных из неструктурированных или слабоструктурированных файлов (PDF, DOCX, HTML и др.). В контексте RAG парсинг — первый этап пайплайна: от его качества напрямую зависит, какие чанки попадут в векторную базу и, в конечном счёте, насколько точным будет ответ LLM.

Почему важно проверять качество парсинга

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

Термин «Golden dataset» — это размеченный вручную набор документов, для которого известен «идеальный» извлечённый текст и структура (заголовки, списки, таблицы). Используется как эталон для оценки точности парсера.


2. Зачем нужна production-проверка качества парсинга

В отличие от офлайн-экспериментов, в production:

  • Нет гарантии статичности данных — пользователи загружают документы новых типов (например, PDF, созданные в новой версии Adobe).
  • Парсер может деградировать после обновления библиотек (pdfminer, python-docx, OCR-движков).
  • Ошибки накапливаются — плохой парсинг → плохие чанки → плохой retrieval → плохой ответ LLM.

Поэтому проверка качества должна быть:

  • Автоматизированной (запускаться при каждом деплое).
  • Метричной (числовые пороги, а не субъективные оценки).
  • Непрерывной (мониторинг в production с алертами при отклонении).

3. Golden Dataset: основа для оценки

3.1 Состав golden dataset

  • 1000–2000 документов (репрезентативная выборка из production-потока).
  • Разметка вручную:
    • Извлечённый текст (plain text) — построчно.
    • Структурные элементы: заголовки (H1, H2, …), списки (маркированные/нумерованные), таблицы (с ячейками).
    • Метаданные: автор, дата, количество страниц.
  • Покрытие форматов: 70% PDF (включая сканы, заполненные формы, PDF/A), 20% DOCX, 10% редкие форматы (ODT, RTF).

3.2 Поддержание golden dataset

  • При добавлении нового типа документа (например, PDF с прозрачными слоями) — добавляем 10–20 образцов в golden dataset.
  • Раз в квартал — ревью и обновление разметки (если изменились требования к структуре).

4. Метрики качества парсинга

4.1 Character Error Rate (CER)

Формула

CER = (S + D + I) / N

где:

  • S — количество заменённых символов (substitutions),
  • D — количество удалённых символов (deletions),
  • I — количество вставленных лишних символов (insertions),
  • N — общее количество символов в эталонном тексте.

Интерпретация

  • CER = 0% — идеальное совпадение.
  • CER < 2% — приемлемо для production.
  • CER > 5% — требуется анализ (возможно, проблема с кодировкой или OCR).

Реализация (Python):

from jiwer import cer

reference = "Правильный текст документа."
hypothesis = "Правильныф текст документ."
error_rate = cer(reference, hypothesis)
print(f"CER: {error_rate:.2%}")

4.2 Word Error Rate (WER)

Аналогична CER, но оперирует словами. Менее чувствительна к опечаткам, лучше отражает смысловые потери. Порог: WER < 5%.

4.3 Structure Preservation (SP)

Оценивает, насколько точно парсер сохранил иерархию документа. Разбивается на подметрики:

  • Header accuracy — доля правильно распознанных заголовков (с учётом уровня).
  • List preservation — доля корректно извлечённых списков (порядок элементов, вложенность).
  • Table extraction score — F1-мера для ячеек таблицы (сравнивается с эталонной таблицей).

Пример таблицы сравнения

МетрикаФормулаПорог
Header accuracy(правильные заголовки) / (все заголовки)> 95%
List preservation(корректные списки) / (все списки)> 90%
Table extraction F12 * precision * recall / (precision + recall)> 85%

4.4 Structure Loss

Композитная метрика: доля структурных элементов, которые были потеряны или искажены. Рассчитывается как:

structure_loss = 1 - (header_accuracy + list_preservation + table_f1) / 3

Порог: < 5%.


5. CI/CD pipeline для тестирования парсера

5.1 Триггеры

  • Изменение кода парсера (новый коммит в ветку parser/).
  • Обновление зависимостей (pdfminer.six, python-docx, pytesseract).
  • Добавление новых документов в golden dataset.

5.2 Этапы pipeline

  1. Линтинг — проверка кода (flake8, mypy).
  2. Юнит-тесты — тестирование отдельных функций (извлечение текста из простого PDF).
  3. Интеграционные тесты — прогон парсера на всех документах golden dataset.
  4. Расчёт метрик — CER, WER, structure loss.
  5. Пороговая проверка — если CER > 2% или structure_loss > 5% → pipeline fails.
  6. Регрессионный отчёт — сравнение метрик с предыдущим успешным запуском (если метрика ухудшилась >0.5% → warning).

5.3 Пример конфигурации (GitHub Actions)

name: Parser quality check
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install dependencies
        run: pip install -r requirements.txt
      - name: Run parser on golden dataset
        run: python evaluate_parser.py --dataset golden_dataset/
      - name: Check thresholds
        run: python check_thresholds.py --cer 0.02 --structure_loss 0.05

6. Regression Testing: защита от регрессий

Regression testing — это повторный прогон всех тестов после любого изменения, чтобы убедиться, что старые форматы не сломались.

6.1 Когда добавлять регрессионные тесты

  • Обнаружен баг в парсинге конкретного типа документа → после фикса добавляем этот документ в golden dataset.
  • Появился новый формат (например, PDF с встроенными шрифтами) → добавляем 5–10 образцов.

6.2 Автоматизация

  • Каждый новый документ, прошедший ручную разметку, автоматически добавляется в golden dataset через PR.
  • CI/CD запускает полный регрессионный прогон.

7. Инструменты парсинга и их влияние на качество

ИнструментФорматыСильные стороныСлабые стороны
pdfminer.sixPDFТочное извлечение текста, поддержка layoutМедленный, сложен с таблицами
PyMuPDF (fitz)PDFБыстрый, хорош для текста и изображенийПроблемы с вложенными таблицами
python-docxDOCXНадёжное извлечение структуры (стили, списки)Не поддерживает PDF
Tesseract OCRСканы PDFРаспознаёт текст на изображенияхВысокий CER при плохом качестве скана
Unstructured.ioPDF, DOCX, HTMLУниверсальный, сохраняет структуруЗависимость от внешних API

Рекомендация использовать комбинацию — для текстовых PDF — PyMuPDF, для сканов — Tesseract с предобработкой (deskew, denoise), для DOCXpython-docx.


8. Production мониторинг качества парсинга

Даже при идеальном golden dataset в production могут возникать дрейфы.

8.1 Метрики в реальном времени

  • CER на лету — для каждого документа вычисляется CER относительно эталона (если эталон доступен). Если нет — используем прокси: доля нечитаемых символов (например, ) или аномально высокая доля пробелов.
  • Structure loss — оценивается через эвристики: количество найденных заголовков, наличие таблиц (по символам табуляции/пробелов).

8.2 Алерты

  • Средний CER за последний час > 3%.
  • Доля документов с structure_loss > 10% > 5%.
  • Резкое изменение распределения длины извлечённого текста.

8.3 Инструменты мониторинга


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

Задача Разработать систему автоматической проверки качества парсинга PDF-документов.

Инструменты

  • Python, PyMuPDF, Tesseract, jiwer.
  • Streamlit для визуализации.
  • Git + GitHub Actions для CI/CD.

Шаги:

  1. Собрать 50 PDF-документов разного типа (текстовые, сканы, с таблицами).
  2. Вручную разметить 10 из них (создать эталонные текстовые файлы и JSON со структурой).
  3. Написать скрипт evaluate.py, который:
    • Парсит документ выбранным инструментом.
    • Сравнивает результат с эталоном (CER, structure loss).
  4. Создать Streamlit-дашборд для визуализации метрик по каждому документу.
  5. Настроить GitHub Actions: при пуше запускать evaluate.py на golden dataset и фейлить pipeline, если пороги превышены.

Ожидаемый результат Рабочий CI/CD пайплайн, который автоматически проверяет качество парсинга при каждом изменении кода, и дашборд для анализа ошибок.


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

ВопросТема
526Как вы обрабатываете документы разных форматов (PDF, DOCX, HTML)?
528Как вы извлекаете таблицы из PDF?
525Как вы чистите и нормализуете текст после парсинга?
530Как вы обрабатываете сканированные документы (OCR)?
501Как вы спроектируете пайплайн индексации документов?
515Какие метрики качества вы используете для RAG-системы?

Навигация