Пошук уроків, статей та іншого контенту
Як поєднати пошук по власних документах із генерацією тексту LLM, щоб отримати відповіді, обґрунтовані реальними даними, а не лише пам'яттю моделі.
Велика мовна модель (стаття «Що таке LLM») навчена на загальнодоступних текстах до певної дати й нічого не знає про внутрішню документацію вашої компанії, вчорашні дані з бази даних чи приватні файли користувача. Два наївні варіанти вирішення — дороге дообучення моделі (fine-tuning) під конкретні дані щоразу, коли вони змінюються, або спроба «влізти» з усім потрібним текстом прямо в запит, що обмежене контекстним вікном моделі й дорого коштує на кожен запит.
RAG вирішує це інакше: замість того щоб модель «знала» всі дані наперед, перед кожним запитом система спочатку знаходить (retrieval) кілька найбільш релевантних фрагментів тексту з власної бази знань, а потім підставляє їх у запит до LLM як контекст — модель генерує (generation) відповідь, спираючись саме на ці фрагменти, а не лише на власну «пам'ять» з навчання.
Підготовка (одноразово чи при оновленні даних): документи розбивають на невеликі фрагменти (chunks), кожен фрагмент перетворюють на embedding-вектор (стаття «Що таке embeddings») і зберігають у векторній базі даних разом із оригінальним текстом.
Запит користувача теж перетворюють на embedding-вектор тим самим способом.
У векторній базі знаходять кілька фрагментів, найближчих за косинусною подібністю до вектора запиту — це і є найрелевантніші фрагменти документів.
Знайдені фрагменти підставляють у промпт до LLM разом з оригінальним запитом користувача: «На основі цього контексту дай відповідь на питання».
LLM генерує відповідь, спираючись на наданий контекст, а не вигадуючи щось із загальних знань.
Промпт, що фактично йде в LLM:
"Контекст:
[фрагмент 1 з документації]
[фрагмент 2 з документації]
На основі наведеного вище контексту дай відповідь на питання:
Як скасувати підписку?"Коли LLM відповідає лише зі своєї внутрішньої «пам'яті» (параметрів, вивчених під час навчання), вона іноді впевнено генерує правдоподібний, але фактично неправильний текст — так звані галюцинації. RAG не усуває цю проблему повністю, але суттєво зменшує її: модель отримує реальний, конкретний текст у контексті запиту й переважно генерує відповідь, спираючись саме на нього, замість того щоб «вигадувати» з нуля.
RAG не гарантує стовідсоткову точність — модель може неправильно інтерпретувати навіть наданий контекст, проігнорувати його частину чи змішати кілька фрагментів некоректно. Це знижує ризик галюцинацій, а не усуває його повністю.
Розбивати документи на занадто великі чи занадто малі фрагменти — надто великі фрагменти «розмивають» релевантність (embedding усереднює сенс усього шматка), надто малі — втрачають контекст, необхідний для розуміння сенсу фрагмента окремо.
Не оновлювати векторну базу даних при зміні вихідних документів — RAG знаходитиме застарілі фрагменти, і LLM генеруватиме відповіді на основі неактуальної інформації, навіть маючи технічно правильний пайплайн пошуку.
Плутати RAG із fine-tuning — RAG додає зовнішні знання в момент запиту й не змінює саму модель; якщо потрібно змінити стиль/поведінку моделі загалом (а не додати конкретні факти), RAG для цього не призначений.
RAG поєднує пошук релевантних фрагментів через embeddings і векторну базу даних (retrieval) із генерацією відповіді через LLM (generation): замість того щоб модель «знала все наперед», потрібний контекст підставляється в промпт на льоту для кожного конкретного запиту. Це дозволяє відповідати на основі актуальних, приватних даних без дорогого перенавчання моделі й суттєво знижує ризик фактичних галюцинацій.