Більшість туторіалів з RAG закінчуються на блокноті. Вони завантажують кілька відшліфованих PDF-файлів, розбивають текст кожні тисячу символів, запихають фрагменти у векторну базу даних і називають це архітектурою. У п'ятницю вдень це демо працює ідеально. У продакшені той самий конвеєр тихо перетворюється на проблему.
Справжнім вузьким місцем у системі пошуку рідко є модель або промпт. Це інжестування. RAG-конвеєр може отримати лише те, що йому надали, і якщо вхідні дані шумні, застарілі або неповні, модель видасть впевнену нісенітницю. Коли користувачі скаржаться, що бот галюцинував, провина часто лежить набагато вище по течії — у конвеєрі даних, за яким ніхто пильно не стежить.
Пастка білої дошки
Діаграми архітектури змушують інжестування виглядати як одна стрілка з написом «Документи → Векторна БД». Реальність складніша. Вихідні системи змінюються без попередження. Макет HTML переробляється. URL-адреси перенаправляють на загальні цільові сторінки. JavaScript-фреймворки замінюють контент після початкової HTTP-відповіді. Вважати інжестування разовим завданням з налаштування — це перша помилка. Це постійна проблема інженерії даних, яка потребує такої ж суворості, як і будь-який ETL-конвеєр.
Чому збої RAG — це зазвичай збої подачі даних
Уявіть ситуацію: користувач запитує вашого внутрішнього помічника про поточну політику повернення коштів. Модель бере топовий чанк із векторного сховища і стверджує, що термін становить 30 днів. Насправді минулого кварталу політику змінили на 60 днів. LLM не вигадала неправильну відповідь. Вона довірилася поганим вхідним даним. Шар пошуку надав стару сторінку, і оскільки ембедінг виглядав достатньо семантично близьким, модель сприйняла його як істину.
Цей сценарій повторюється постійно. Команди витрачають години на підкручування temperature та top-k, коли їхній корпус текстів заповнений футерами навігації, дубльованими пресрелізами та чанками, які розрізають таблиці навпіл. Перш ніж оптимізувати генерацію, проведіть аудит того, що вашій системі дозволено знати.
Сім пасток, що руйнують інжестування
1. Перший запуск — це брехня
Зелена галочка під час першого сканування майже нічого не означає. Продакшен-дані — це живий організм. Сторінки документації рефакторяться, постійні посилання блогів ламаються, а карти сайтів тихо втрачають розділи. Якщо ви перевіряєте лише те, що конвеєр завершився без помилок, ви дієте наосліп. Вам потрібно перевіряти результат. Переконайтеся, що очікувані документи присутні, що їхня структура все ще коректно розпізнається і що загальний обсяг тексту не скоротився через те, що джерело вирішило змінити пагінацію результатів.
2. Сканування — це не інжестування
Отримати HTML — це найпростіше. Сире сканування захоплює все: банери з файлами cookie, бічні панелі «Схожі статті», рекламні блоки та повідомлення про авторські права у футері. Якщо ви наївно розіб'єте цей сирий HTML на чанки, кожен фрагмент тексту нестиме в собі частини меню навігації. Коли користувач запитає про ліміти API, ретривер може видати чанк, який на 40 відсотків складається з посилань бічної панелі. Чисте вилучення має значення. Вам потрібно визначити основну область контенту, видалити шаблонний текст і прибрати елементи, що повторюються на кожній сторінці. Інакше ви будуєте не базу знань, а пошукову систему для елементів інтерфейсу вебсайту.
3. Чанкінг руйнує зміст
Чанкінг фіксованого розміру є стандартом майже в кожному посібнику для швидкого старту, і це небезпечно. Розбийте документ суто за кількістю символів, і ви розріжете таблиці посередині, розділите кроки 4 і 5 у нумерованій процедурі та відірвете марковані списки від їхніх заголовків. Чанк, що містить лише другу половину таблиці з цінами, є семантично марним. Чанкінг із урахуванням структури поважає оригінальний формат. Аналізуйте ієрархію заголовків. По можливості зберігайте таблиці цілісними. Розбивайте на межах абзаців у межах одного H2 або H3. Зберігайте списки всередині одного чанка, якщо вони достатньо короткі. Мета — не рівномірні блоки. Мета — зв'язні одиниці змісту.
4. Проблема актуальності
Статичний знімок внутрішньої вікі — це простий режим. Безперервне збирання даних із «живого» вебу — це складно. Вам потрібно знати, коли сторінка була зібрана востаннє, чи змінилася вона з того часу та як довго ця інформація залишається актуальною. Застарілі дані — це не завжди помітна стара дата. Іноді сторінка оновлює текст, але зберігає той самий URL, тому ваша система нічого не помітить без хешування вмісту. Створюйте чіткі правила оновлення залежно від мінливості джерела. Фінансовій стрічці даних можуть знадобитися щогодинні перевірки. Сторінка «Про компанію» може потребувати квартальних перевірок. Фіксуйте часові мітки та встановлюйте межі часу життя (time-to-live), особливо якщо ваша сфера діяльності стосується регульованих галузей або критичних для безпеки інструкцій, де застарілі факти можуть завдати реальної шкоди.
5. Забруднення дублікатами
Вебсайти переповнені повторами. Один і той самий опис продукту з'являється на сторінці категорії, сторінці продукту та на промо-лендінгу. Один і той самий пресреліз може бути доступний за адресами /news/, /press/ та /blog/. Векторний пошук не видаляє дублікати автоматично. Якщо у вашій базі даних знаходяться десять майже ідентичних фрагментів (chunks), вони можуть витіснити різноманітні та релевантні результати під час вибірки top-k. Вам потрібне канонічне відстеження або дедуплікація вмісту перед ембедингом. Якщо два фрагменти говорять про одне й те саме, залиште авторитетне джерело, а копії видаліть. Ваш ретривер (retriever) має обмежену кількість слотів. Не дозволяйте їм витрачатися марно.
6. Відсутність метаданих
Векторна база даних без метаданих — це просто двигун щільного текстового пошуку без пам'яті про контекст. Розумна вибірка залежить від сигналів фільтрації та ранжування, які не можуть надати сирі ембединги. Зберігайте URL-адресу джерела, дату збору, категорію документа та номер версії. Якщо ви збираєте документацію API, версіонування є критично важливим. Без нього запит може змішати специфікації v1 та v2 в одну відповідь. Якщо ви збираєте кадровий політики (HR policies), тегування за регіоном або відділом дозволить вам фільтрувати результати ще до того, як вони потраплять до моделі. Метадані перетворюють масив тексту на кураторську систему знань.
7. Прогалини JavaScript
Сучасні сайти не передають свій контент у першому ж HTML-пакеті. Вони надсилають «скелет» і наповнюють його (hydrate) за допомогою викликів JavaScript. Звичайний HTTP-запит може побачити лише індикатор завантаження та каркас макета. Якщо ваш конвеєр (pipeline) не може виконувати JavaScript, ви будете збирати порожні сторінки або неповні фрагменти, навіть не усвідомлюючи, що щось не так. Використання headless-браузера вирішує проблему рендерингу, але створює нові: більше споживання пам'яті, нижча пропускна здатність і бар'єри для виявлення ботів. Вибирайте компроміси свідомо, але не вдавайте, ніби простого еквівалента curl достатньо для кожного джерела.
Практичний чек-лист для збору даних
Якщо ви створюєте або перевіряєте RAG-стрічку, почніть з цього:
- Перевірте охоплення джерел та пагінацію. Карта сайту (sitemap) може містити лише перші десять статей у категорії. Проводьте глибокий краулінг і перевіряйте, чи дійсно захоплюється контент із пагінацією або динамічним завантаженням.
- Видаляйте шаблонний контент (boilerplate) перед нарізанням на фрагменти. Видаляйте навігацію, рекламу, футери та повторювані юридичні відмови. Якщо фраза з'являється на кожній сторінці, це шум.
- Використовуйте нарізання з урахуванням структури. Дотримуйтесь заголовків, маркованих списків і таблиць. Розділяйте на основі семантичних меж, а не кількості символів.
- Додавайте розширені метадані. Включайте URL, дату збору, категорію контенту та версію. Зробіть ці поля доступними для фільтрації у ваших запитах на вибірку.
- Встановлюйте частоту оновлення залежно від мінливості даних. Джерела з високою частотою змін потребують частих повторних обходів. Статичні архіви — ні.
- Моніторте корпус, а не лише статус завдання. Конвеєр може завершитися з кодом zero, видаючи при цьому сміття. Регулярно перевіряйте зразки збережених фрагментів на предмет дрейфу та якості.
- Визначте правила для версіонування та видалення. Коли сторінку джерела видаляють, видаляйте і її фрагменти. Коли вона оновлюється, перезаписуйте їх або створюйте нові версії. «Сирітські» дані — це тихий убивця.
Гірка правда про ембединги
Жодна модель ембедингів, якою б просунутою вона не була, не зможе відновити відсутній документ. Вона не зможе вгадати, що сторінка була оновлена минулого тижня, якщо ваша стрічка все ще містить копію минулого року. Вона не зможе вивести контекст рядка таблиці, який був відокремлений від свого заголовка через невдалу межу фрагмента. Ембединги стискають значення, але вони не створюють значення там, де рівень збору даних не зміг його зберегти.
Якість вибірки починається на рівні збору даних. Саме цей рівень визначає, чи буде ваша RAG-система корисним інструментом, чи просто впевненим брехуном із векторною базою даних за спиною.
Головний висновок
Припиніть оцінювати якість завантаження даних лише за допомогою дашбордів пайплайнів. Успішні завдання та чисті логи не гарантують чистоти корпусу. Відкрийте базу даних і прочитайте ті самі чанки, які отримуватимуть ваші користувачі. Якщо текст переповнений повідомленнями про авторські права, розірваними таблицями та застарілими сторінками з правилами, ваша проблема не в LLM. Спочатку виправте джерело даних. Все інше — це лише налаштування поверх сміття.
