Retrieval-Augmented GenerationДоповідь

RAG: модель не мусить пам'ятати — вона мусить знайти

LLM знає світ станом на дату навчання і нічого не знає про ваші документи. RAG не змінює модель — він щоразу знаходить потрібний фрагмент тексту й підкладає його перед відповіддю.

01 Ідея та архітектура
02 Вектори й векторна база
03 Чанкінг, пошук, реранжування
04 Генерація відповіді з цитуванням
05 Оцінка якості та типові помилки
індексація
пошук
генерація
ризики
КонтекстНавіщо RAG

Модель упевнено відповідає навіть тоді, коли не знає

Знання LLM «запечені» у вагах під час навчання. Звідси чотири обмеження, які й породили RAG.

Дата навчання

Усе, що сталося після cutoff, для моделі не існує: ціни, регламенти, версії API.

Немає ваших даних

Внутрішні документи, тікети, договори ніколи не були в навчальній вибірці.

Галюцинації без джерела

Модель оптимізована на правдоподібність, а не на істинність — і не дає посилання, яке можна перевірити.

Три способи це виправити

ПідхідЩо даєЦіна
Донавчанняfine-tuningСтиль, формат, доменну поведінкуДні й гроші на кожне оновлення даних; не вміє цитувати джерела
Довгий контекстЗнання рівно одного набору документівПлатите за всі токени в кожному запиті; обмежений розмір вікна
RAGСвіжі приватні факти + посилання на джерелоТреба побудувати й підтримувати пошук

Це не взаємовиключні підходи: типова зріла система — RAG для фактів плюс промпт чи донавчання для тону відповіді.

ВизначенняІдея

Знайти релевантне → покласти в контекст → відповісти

Retrieval-Augmented Generation (Lewis et al., 2020) · Retriever + Generator · «іспит з відкритою книжкою»

RAG не змінює ваги моделі. Він змінює те, що модель бачить у момент відповіді: до питання користувача додається знайдений фрагмент документа.

Крок 1 · Retriever

Пошук
За запитом знаходимо k найрелевантніших фрагментів у базі знань.

Крок 2 · Augmentation

Збагачення промпту
Фрагменти вставляються в шаблон разом із питанням та інструкціями.

Крок 3 · Generator

Генерація
LLM відповідає лише на основі наданого контексту й посилається на джерела.

Зміна ролі моделі

З «енциклопедії» модель перетворюється на читача з логікою: зрозуміти питання, прочитати надані фрагменти, коректно їх переказати.

Наслідок для якості

Якість системи впирається у пошук, а не в модель. Якщо потрібного фрагмента немає в контексті, найрозумніша LLM не врятує.

ПайплайнАрхітектура

Дві фази: індексація та запит

Indexing (offline, періодично) · Querying (online, на кожен запит користувача)

ФАЗА A · ІНДЕКСАЦІЯ — один раз і при оновленні даних Джерела PDF · Confluence · DB сирі документи Парсинг parsing · cleaning текст, таблиці, метадані Чанкінг chunking · overlap поділ на фрагменти Embedding-модель текст → вектор вектор на кожен чанк Векторна база vector store · HNSW вектор + текст + метадані той самий індекс обслуговує всі запити ФАЗА B · ЗАПИТ — виконується на кожне питання, бюджет ~1–3 с Запит user query питання людини Embedding та ж модель! вектор запиту Пошук top-k вектори + BM25 20–50 кандидатів Реранжування cross-encoder лишаємо 3–8 Промпт + LLM context injection генерація відповіді Відповідь answer + citations із посиланнями agentic RAG: якщо відповідь неповна — переформулювати запит і шукати ще раз

Головне правило: запит і документи кодуються однією й тією ж embedding-моделлю. Заміна моделі означає повну переіндексацію бази.

Основа пошукуВектор

Вектор: сенс тексту як точка в просторі

Embedding — щільний вектор із 384–3072 чисел · близькість = косинусна схожість (cosine similarity)

Фрагмент тексту «Повернення коштів — 14 днів» Embedding-модель нейромережа-кодувальник [ 0.021, -0.113, 0.884, 0.037, ... -0.256 ] 1024 числа — це координати точки у просторі сенсів Модель навчена так, що близькі за змістом тексти опиняються поруч — навіть без жодного спільного слова. «скасувати бронювання» ≈ «як анулювати запис» для пошуку за словами це різні тексти, для векторів — сусіди cos θ = (A · B) / (|A| · |B|) → від −1 до 1 Спрощення: 2 виміри замість 1024 вимір 1 вимір 2 «Повернення коштів протягом 14 днів» ЗАПИТ: «як повернути гроші» «Оформлення повернення в кабінеті» інші теми: доставка, графік роботи θ малий → cos θ ≈ 0.89 Пошук = знайти k точок, найближчих до точки запиту.
Основа пошукуМетрики

Чим міряти близькість двох векторів

Метрику диктує модель, а не смак: у картці embedding-моделі завжди вказано, з чим її навчали

<=> косинусна θ Кут між векторами. Довжина ігнорується: абзац і речення про одне й те саме — поруч. <#> скалярний добуток проєкція Кут і довжина разом. Довший вектор виграє — корисно там, де норма кодує вагу чи популярність. <-> евклідова (L2) d Пряма відстань між точками. Зображення, обличчя, аудіо; обов'язкова для кластеризації. <+> манхеттенська (L1) |Δx| |Δy| Сума модулів різниць — «по вулицях». Тільки для інтерпретованих ознак, не для щільних embeddings. <~> Хеммінга (bit) 1 0 1 1 0 0 1 1 0 0 1 0 1 1 різних бітів = 2 Порівняння через XOR — дуже швидко. Бінарна квантизація: грубий відбір кандидатів, далі точне переранжування.

Головне: якщо вектори L2-нормалізовані, косинус, скалярний добуток і L2 дають однакове ранжування — різниця лише у швидкості. Тому багато систем нормалізують вектори на індексації й далі рахують найдешевший скалярний добуток.

Основа пошукуpgvector

Який оператор коли брати

ОператорКоли доречнийНюанс
<=>cosineДефолт для тексту. Коли не впевнені в нормалізації або в базі вектори з різних джерелЗначення 0…2; схожість = 1 − відстань
<#>inner productВектори гарантовано нормалізовані і потрібна максимальна швидкість. Або рекомендації, де довжина кодує популярністьПовертає від'ємне значення: Postgres сортує за зростанням
<->L2 / euclideanЗображення, обличчя, аудіо. Обов'язкова для k-means і DBSCAN — вони визначені через L2Для нормалізованих векторів зводиться до косинуса
<+>L1 / manhattanРідкісний випадок: незалежні інтерпретовані ознаки (ціна, вага, розмір), а не embeddingsМенш чутлива до викидів в окремих координатах
<~>hammingТип bit після бінарної квантизації: швидко відібрати ~200 кандидатів на базах від десятків мільйонів. Дедуплікація за хешамиУ 32 рази менше пам'яті; далі переранжування float-векторами
-- індекс МУСИТЬ відповідати оператору CREATE INDEX ON chunks USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64); SELECT id, text, 1 - (embedding <=> :q) AS sim FROM chunks WHERE updated_at > '2026-01-01' ORDER BY embedding <=> :q LIMIT 5;

Найчастіша помилка

Індекс створено з vector_l2_ops, а запит іде через <=>. Індекс мовчки ігнорується — і ви отримуєте повний перебір бази без жодної помилки в логах.

Приклад: text-embedding-3-small

Повертає вже нормалізовані вектори на 1536 вимірів, тож коректний вибір — косинус. Але після скорочення розмірності (Matryoshka, dimensions=512) вектор перестає бути одиничним і потребує ручної нормалізації.

СховищеВекторна БД

Векторна база: зберігає вектори і швидко знаходить сусідів

Vector database · ANN — Approximate Nearest Neighbour · HNSW · pgvector · Qdrant · Elasticsearch

ЩО ЗБЕРІГАЄТЬСЯ id policy_refund_v4 · розділ 4.2 · чанк 3 vector [0.021, −0.113, 0.884, … ] ← пошук іде по ньому text «Повернення коштів здійснюється протягом…» metadata source · page · updated_at · lang department · acl (права доступу) Метадані дають фільтр до векторного пошуку: where updated_at > '2026-01-01' and 'support' in acl Плюс операції звичайної БД: додати, оновити, видалити, реплікація, бекап, шардування. Видалений документ мусить зникнути з індексу — інакше система цитуватиме скасований регламент. ЯК ЗНАХОДИТЬ ШВИДКО — граф сусідів HNSW вхідна точка знайдений сусід = найрелевантніший чанк замість перебору 10 млн векторів — кілька десятків кроків графом

Компроміс ANN: трохи точності в обмін на швидкість. Ручки M та ef_search регулюють баланс «повнота пошуку ↔ затримка».

Підготовка данихЧанкінг

Чанкінг: компроміс між точністю і повнотою

Chunking · chunk size · overlap · Parent Document Retrieval

Чанк — це одиниця пошуку. Замалий втрачає контекст і робить відповідь неповною; завеликий розмиває вектор і тягне в промпт зайвий шум.

СтратегіяЯк працюєКоли доречно
Рекурсивнийrecursive splitДілить за абзацами, потім реченнями, потім символамиДефолт для більшості текстів: не рве речення посередині
За структуроюdocument-basedЗа заголовками й розділами документаРегламенти, документація, Markdown, код — найкраща якість
Батьківський документsmall-to-bigШукаємо по малих чанках, у контекст даємо великий батьківський блокНайкращий компроміс: точний пошук + повний контекст

Практичний старт

512 токенів, перекриття 50–80, поділ за заголовками. Далі — вимірювати, а не вгадувати: змініть один параметр і подивіться на recall@k.

Класична помилка

Чанк без «шапки»: фрагмент «строк становить 14 днів» без назви розділу й документа. Додавайте заголовки розділу в текст самого чанка.

Ядро системиПошук

Гібридний пошук плюс реранжування

Dense retrieval · BM25 · Hybrid · RRF — Reciprocal Rank Fusion · Cross-encoder reranking

Векторний (dense)

  • Розуміє синоніми й перефразування
  • Витримує помилки у словах
  • Слабке місце: артикули, коди помилок, прізвища, номери версій

За словами (BM25)

  • Ідеальний для рідкісних термінів: ERR-5041, «ст. 42»
  • Прозорий і дешевий
  • Слабке місце: інша лексика — нуль результатів

Гібрид + реранкер

  • Два пошуки паралельно, злиття через RRF
  • Cross-encoder читає запит і чанк разом і лишає 3–8 найкращих
  • Стандарт де-факто для продакшну

Навіщо реранкер

Головна цінність — не порядок, а скорочення контексту: 5 точних чанків замість 30 приблизних дають кращу відповідь і дешевший запит.

Lost in the middle

Модель гірше помічає інформацію в середині довгого контексту. Найрелевантніше ставте на початок і в кінець промпту.

Переписування запиту

«А що з тим договором?» — у векторному просторі майже шум. Перед пошуком LLM розгортає запит у самодостатнє питання з історії діалогу.

ВідповідьПромпт

Промпт: контекст, межі та обов'язок цитувати

СИСТЕМНИЙ ПРОМПТ Відповідай виключно на основі наведених нижче фрагментів. Якщо відповіді в них немає — скажи «У документах немає відповіді на це питання» і не додавай припущень. Після кожного твердження став посилання [1], [2] на номер фрагмента. Якщо фрагменти суперечать один одному — вкажи це явно. КОНТЕКСТ [1] policy_refund_v4.pdf · розділ 4.2 · 11.03.2026 "Повернення здійснюється протягом 14 днів..." [2] faq_support.md · Повернення · 02.02.2026 "Кошти зараховуються на картку, з якої..." ПИТАННЯ Скільки чекати повернення коштів?

Що обов'язково має бути в промпті

  • Заборона на зовнішні знання — інакше модель домішає загальні відомості до ваших регламентів
  • Дозвіл сказати «не знаю» — без цього модель вигадає, бо «мусить» відповісти
  • Формат цитування — джерело, розділ, дата: користувач має змогу перевірити
  • Обробка суперечностей — дві версії документа в базі трапляються постійно
  • Роздільники між фрагментами та їх дати актуальності

І ще одне

  • Текст із бази — це дані, а не команди: у документ можна вписати ін'єкцію промпту
  • Права доступу фільтруються на рівні пошуку, а не проханням до моделі «не розповідати»
Контроль якостіМетрики

Без метрик RAG налаштовують навпомацки

Систему міряють у двох точках окремо: чи знайшли потрібне і чи правильно переказали знайдене. Без такого поділу неможливо зрозуміти, що саме лагодити.

МетрикаЩо показуєЩо робити, якщо низька
Recall@kпошукЧи потрапив потрібний чанк у top-k взагаліЧанкінг, embedding-модель, гібридний пошук, більше k
MRR / NDCGпошукНаскільки високо він у спискуДодати реранкер, підкрутити ваги гібриду
FaithfulnessгенераціяЧи кожне твердження підтверджене контекстомЖорсткіший промпт, менше чанків, дозвіл на «не знаю»
Answer relevancyгенераціяЧи відповідає текст саме на поставлене питанняПереписування запиту, інша модель, інший шаблон

Golden dataset

50–200 реальних питань із перевіреними відповідями та документами-джерелами. Найцінніший артефакт проєкту — збирайте з першого тижня.

Інструменти

RAGAS, DeepEval, LangSmith, Langfuse. Оцінка здебільшого через LLM-as-a-judge — звіряйте її з людською вибіркою.

Регресійний прогін

Кожна зміна промпту, моделі чи чанкінгу — прогін по golden set у CI. Інакше покращення одного сценарію тихо ламає п'ять інших.

ПрактикаГраблі

Де RAG ламається найчастіше

СимптомСправжня причинаЛікування
«Не знаю» на очевидне питанняПотрібного чанка немає в top-k: невдалий поділ або інша лексикаГібридний пошук, більший k + реранкер, контекст у чанку
Відповідь неповнаІнформація розкидана по кількох чанках, у контекст потрапив одинParent document retrieval, більший чанк, перекриття
Цитує застарілий документСтара й нова версія лежать в індексі поручДедуплікація, версіонування, видалення при оновленні
Плутає таблиці й цифриТаблиця розрізана або перетворилася на плоский текстОкремий парсер таблиць, зберігати як Markdown
Працює в демо, падає в продіТестували на 10 документах, а в базі 100 тисяч — шуму на порядки більшеОцінка на реальному обсязі, фільтри за метаданими

Правило діагностики: спершу подивіться, які саме чанки потрапили в контекст. У 8 випадках із 10 винен пошук, а не модель.

ПідсумокВисновки

Коли RAG — правильна відповідь

Варто застосовувати

  • База знань велика й регулярно змінюється
  • Потрібні посилання на джерело й перевірність
  • Дані приватні або мають розмежування доступу
  • Треба швидко оновити чи прибрати знання без перенавчання

Не варто

  • Корпус маленький і стабільний — просто покладіть його в контекст
  • Задача не про факти, а про стиль чи формат — це донавчання
  • Потрібен огляд усього корпусу («про що ці 500 звітів») — top-k тут не працює
  • Потрібні точні агрегації й підрахунки — це SQL, а не векторний пошук

Теза 1

RAG — це інженерія пошуку, а не магія моделі. Якість визначає те, що потрапило в контекст.

Теза 2

Найбільший приріст дають нудні речі: чистий парсинг, розумний чанкінг, метадані, гібрид, реранкер.

Теза 3

Без golden set і метрик будь-яке «стало краще» — це відчуття, а не факт.

Дякую за увагу. Питання?