Більшість 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-дайджест
Найкращі статті про ШІ та автоматизацію — без спаму, лише суть
Без спаму · Відписатись будь-коли

