Як підготувати PDF документи для AI за допомогою Vision LLM: читання графіків і діаграм для RAG систем

Як витягувати дані з графіків і діаграм у PDF за допомогою Vision LLM для RAG систем

Більшість RAG систем чудово справляються з текстом, але повністю ігнорують графіки, діаграми та таблиці у PDF — а саме там часто захована найціннішя аналітична інформація. Цей туторіал покаже, як використати Vision LLM (GPT-4o або Gemini 1.5 Pro) щоб автоматично перетворити візуальний контент PDF на структурований текст, придатний для векторної бази даних. Весь процес займе близько 2 годин і не потребує глибоких знань з програмування — достатньо базового Python.

🛠️ Що знадобиться

  • Python 3.11+ — основне середовище виконання; встанови через python.org або використовуй Google Colab безкоштовно
  • OpenAI API або Google Gemini API — для Vision LLM аналізу зображень; GPT-4o коштує ~$0.005 за сторінку, Gemini 1.5 Flash дешевший і має безкоштовний ліміт
  • PyMuPDF (fitz) — бібліотека для розбивки PDF на зображення сторінок; безкоштовна, встановлюється через pip
  • LangChain або LlamaIndex — для фінальної інтеграції оброблених чанків у RAG пайплайн; обидві безкоштовні open-source
  • ChromaDB або Qdrant — векторна база даних для зберігання embeddings; обидві мають безкоштовний локальний режим

📋 Покрокова інструкція

Крок 1: Встановлення залежностей і підготовка середовища

Відкрий термінал і виконай команду: pip install pymupdf openai google-generativeai langchain chromadb pillow tqdm. Після встановлення створи файл .env у кореневій папці проєкту і додай туди свої ключі: OPENAI_API_KEY=sk-... та GOOGLE_API_KEY=AIza.... Якщо використовуєш Google Colab — замість .env файлу скористайся розділом Secrets (іконка ключа зліва) і додай ті самі змінні там. Перевір установку командою python -c "import fitz; print(fitz.__version__)" — маєш побачити версію 1.24 або новішу.

Крок 2: Конвертація PDF сторінок у зображення з високою роздільністю

Це критичний крок — якість зображення прямо впливає на точність розпізнавання. Створи файл pdf_to_images.py і встав такий код:

import fitz
from pathlib import Path

def pdf_to_images(pdf_path: str, output_dir: str, dpi: int = 200):
    doc = fitz.open(pdf_path)
    Path(output_dir).mkdir(exist_ok=True)
    images = []
    for page_num in range(len(doc)):
        page = doc[page_num]
        mat = fitz.Matrix(dpi/72, dpi/72)
        pix = page.get_pixmap(matrix=mat)
        img_path = f"{output_dir}/page_{page_num+1:04d}.png"
        pix.save(img_path)
        images.append(img_path)
    return images

Важливо: встанови DPI рівно 200 — при 150 DPI дрібні підписи на графіках розмиваються і Vision LLM їх не зчитує, а при 300 DPI файли стають завеликими і API повертає помилку про розмір. Запусти функцію: images = pdf_to_images("report.pdf", "pages/").

Крок 3: Автоматичне визначення типу контенту на сторінці

Не кожна сторінка потребує дорогого Vision аналізу — текстові сторінки краще обробляти звичайним PDF парсером. Додай функцію класифікації сторінок: використай PyMuPDF щоб порахувати кількість текстових блоків на сторінці командою page.get_text("blocks"). Якщо текстових блоків менше 5 або сторінка містить об’єкти типу “image” через page.get_images() — познач її як “visual” і відправляй у Vision LLM. Якщо блоків більше 5 і немає зображень — познач як “text” і парси звичайним page.get_text(). Такий підхід економить до 60% витрат на API, бо більшість корпоративних звітів — це переважно текст із вкрапленнями графіків.

Крок 4: Аналіз графіків і діаграм через Vision LLM

Для сторінок типу “visual” відправляй зображення в GPT-4o з чітким промптом. Відкрий файл vision_analyzer.py і використай такий промпт:

VISION_PROMPT = """
Ти аналізуєш сторінку з бізнес-документа для RAG системи.
Твоє завдання — витягти ВСЮ інформацію у структурованому текстовому форматі.

1. ЗАГОЛОВОК: Вкажи назву графіка/діаграми якщо є
2. ТИП ВІЗУАЛІЗАЦІЇ: (лінійний графік / стовпчикова діаграма / кругова діаграма / таблиця / схема)
3. ЧИСЛОВІ ДАНІ: Перерахуй всі значення, підписи осей, легенду
4. ТРЕНДИ ТА ВИСНОВКИ: Опиши що показує візуалізація
5. КОНТЕКСТ: Одиниці вимірювання, часовий період, джерело даних

Відповідай структурованим текстом, не використовуй markdown.
"""

Викликай API так: response = client.chat.completions.create(model="gpt-4o", messages=[{"role":"user","content":[{"type":"image_url","image_url":{"url":f"data:image/png;base64,{base64_image}"}},{"type":"text","text":VISION_PROMPT}]}]). Для Gemini замість цього використай model.generate_content([image, prompt]) — він дешевший для великих батчів.

Крок 5: Формування чанків і завантаження у векторну базу

Тепер об’єднай текст із звичайних сторінок і Vision-опис із візуальних сторінок у єдиний список чанків. Кожен чанк має містити метадані: {"source": "report.pdf", "page": 5, "type": "visual", "content_type": "bar_chart"} — це дозволить фільтрувати результати пошуку пізніше. Завантаж у ChromaDB командами: collection = chroma_client.create_collection("documents"), потім collection.add(documents=chunks, metadatas=metadatas, ids=ids). Фінальний результат: векторна база із повноцінним описом ВСІХ сторінок PDF, включно з графіками, яку можна запитувати через LangChain retriever звичайним способом.

⚠️ Типові помилки та як їх уникнути

  • Занадто низький DPI при конвертації — при 72 DPI (стандарт) числа на осях графіків стають нечитабельними; завжди використовуй мінімум 150 DPI, оптимально 200 DPI
  • Відправка повного PDF як зображення одним запитом — Vision LLM втрачає деталі при аналізі цілого документа; завжди розбивай на окремі сторінки і аналізуй кожну окремо
  • Ігнорування rate limits API — при обробці 100+ сторінок ти миттєво отримаєш помилку 429; додай time.sleep(1) між запитами або використовуй бібліотеку tenacity для автоматичного retry з exponential backoff
  • Зберігання Vision-тексту без контексту сторінки — якщо не додаєш метадані про номер сторінки і тип контенту, RAG система не зможе давати точні посилання на джерело; завжди зберігай повні метадані
  • Використання одного великого чанка на сторінку — сторінки з кількома графіками краще розбивати на окремі чанки для кожного графіка, щоб векторний пошук знаходив саме релевантну діаграму

💡 Поради для кращого результату

По-перше, для фінансових звітів із щільними таблицями використовуй Gemini 1.5 Pro замість GPT-4o — він краще справляється з багатоколонковими таблицями і коштує вдвічі дешевше. По-друге, якщо PDF містить схеми бізнес-процесів або архітектурні діаграми, додай у промпт фразу “опиши зв’язки між елементами у форматі: Елемент А → Елемент Б (тип зв’язку)” — це дає набагато кориснішй текст для RAG ніж просте перерахування блоків. По-третє, кешуй результати Vision аналізу у JSON файл після першого запуску — це рятує від повторних витрат на API при налагодженні коду. По-четверте, перед завантаженням у векторну базу додавай до тексту сторінки префікс з назвою документа і датою, наприклад “Квартальний звіт Q1 2025, стор. 7:” — це різко покращує якість відповідей RAG системи при запитах про конкретні документи.

❓ Часті запитання (FAQ)

1. Чи можна використовувати локальну Vision модель замість платного API?
Так, LLaVA 1.6 або Qwen2-VL через Ollama працюють локально і безкоштовно. Але якість розпізнавання дрібних підписів на графіках у них на 30-40% гірша порівняно з GPT-4o. Для продакшн систем із важливими фінансовими даними рекомендуємо платні API, для прототипів — локальні моделі цілком підійдуть.

2. Скільки коштує обробити 500-сторінковий PDF?
При використанні GPT-4o і 200 DPI зображень приблизна вартість — $2-3 за весь документ, якщо близько 40% сторінок візуальні. З Gemini 1.5 Flash це обійдеться в $0.30-0.50. Точну вартість можна розрахувати заздалегідь через калькулятори на сайтах OpenAI і Google.

3. Що робити якщо PDF захищений паролем?
PyMuPDF підтримує відкриття захищених PDF через fitz.open(pdf_path, password="your_password"). Якщо пароль невідомий — інструменти типу qpdf або PDF24 можуть зняти захист для документів, на які у тебе є права доступу.

4. Як обробляти PDF із двоколонковим макетом (наукові статті)?
Стандартний PDF парсер зчитує двоколонковий текст у неправильному порядку. Рекомендуємо для таких документів одразу відправляти ВСІ сторінки через Vision LLM — він правильно визначає колонки і читає текст у логічному порядку. Альтернатива — бібліотека pdfplumber із налаштуванням bbox для кожної колонки.

5. Чи підходить цей підхід для сканованих PDF (без текстового шару)?
Так, і це одна з головних переваг Vision підходу. Скановані документи конвертуються у зображення так само, як звичайні PDF, і Vision LLM читає їх без проблем. Єдине обмеження — дуже низька якість сканування (менше 100 DPI) або сильно нахилені сторінки знижують точність розпізнавання.

🏁 Підсумок

Після виконання цього туторіалу у тебе є повноцінний пайплайн, який перетворює PDF документи — включно з графіками, діаграмами і таблицями — на структурований текст, готовий для векторної бази даних. Твоя RAG система тепер відповідає на запити про візуальний контент так само добре, як і про звичайний текст.

Почни прямо зараз: завантаж один невеликий PDF (5-10 сторінок), запусти конвертацію через PyMuPDF і надішли одну сторінку з графіком у GPT-4o з наведеним промптом — вже через 10 хвилин побачиш результат і зрозумієш наскільки це потужно для твоїх конкретних документів.

РОЗСИЛКА

📬 Щотижневий AI-дайджест

Найкращі статті про ШІ та автоматизацію — без спаму, лише суть

Без спаму · Відписатись будь-коли

Telegram