RAG та LLM у 2026: Retrieval-Augmented Generation для співбесід з data science
Retrieval-Augmented Generation (RAG) пояснений для співбесід з data science у 2026 році. Векторні бази, стратегії chunking, моделі векторизації, agentic RAG, Graph RAG та архітектура конвеєра, готового до продакшну.

Retrieval-Augmented Generation (RAG) став стандартною архітектурою для прив'язки відповідей LLM до фактичних та актуальних даних. На співбесідах з data science та інженерії штучного інтелекту у 2026 році питання про RAG тепер з'являються поряд із класичними темами ML, перевіряючи як системне мислення, так і практичні навички реалізації.
Retrieval-Augmented Generation поєднує систему пошуку (векторний пошук по базі знань) із генератором LLM, тож модель відповідає на основі реальних документів, а не покладається на запам'ятовані тренувальні дані.
Як працює конвеєр RAG від початку до кінця
Система RAG працює у дві фази: офлайн-фаза інжесту, що будує базу знань, та онлайн-фаза запитів, що отримує релевантний контекст і генерує відповідь.
Під час інжесту сирі документи проходять очищення, розбиття на фрагменти (chunking) та векторизацію (embedding), перш ніж потрапити до векторної бази. Під час інференсу запит користувача йде тим самим шляхом векторизації, а пошук найближчих сусідів отримує найрелевантніші фрагменти. Ці фрагменти стають частиною промпта LLM, прив'язуючи згенеровану відповідь до вихідного матеріалу.
# rag_pipeline.py
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
# Offline: ingest documents into the vector store
def build_index(documents: list[str]) -> Chroma:
splitter = RecursiveCharacterTextSplitter(
chunk_size=512, # tokens per chunk
chunk_overlap=64, # overlap preserves context at boundaries
separators=["\n\n", "\n", ". ", " "]
)
chunks = splitter.create_documents(documents)
embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
return Chroma.from_documents(chunks, embeddings)
# Online: retrieve + generate
def query(vectorstore: Chroma, question: str) -> str:
retriever = vectorstore.as_retriever(
search_type="mmr", # Maximal Marginal Relevance for diversity
search_kwargs={"k": 5, "fetch_k": 20}
)
prompt = ChatPromptTemplate.from_template(
"Answer based on this context only:\n{context}\n\nQuestion: {question}"
)
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| ChatOpenAI(model="gpt-4o", temperature=0)
)
return chain.invoke(question).contentЦей конвеєр охоплює основний цикл RAG: розбий, векторизуй, збережи, отримай, згенеруй. Параметр search_type="mmr" гарантує, що отримані фрагменти є водночас релевантними та різноманітними, зменшуючи надлишковість у вікні контексту.
Стратегії chunking, які справді мають значення
Chunking визначає якість пошуку більше за будь-який інший компонент. Поганий chunking означає, що пошуковик повертає фрагменти, яким або бракує контексту, або вони розбавляють сигнал нерелевантним вмістом.
У продакшн-системах 2026 року домінують три підходи до chunking:
Chunking фіксованого розміру розбиває текст за встановленою кількістю токенів (зазвичай 256-512 токенів) із перекриттям (overlap). Простий у реалізації, але розриває речення та думки посередині.
Семантичний chunking виявляє межі тем, вимірюючи схожість векторів між сусідніми реченнями. Коли схожість падає нижче порогу, починається новий фрагмент. Кожен фрагмент несе цілісну думку, а не довільний зріз тексту.
Пізній chunking (late chunking) спершу застосовує модель-трансформер до всього документа, створюючи контекстні вектори токенів, і лише потім розбиває на фрагменти. Це зберігає далекосяжні залежності, які традиційний chunking руйнує.
# semantic_chunking.py
import numpy as np
from sentence_transformers import SentenceTransformer
def semantic_chunk(text: str, threshold: float = 0.3) -> list[str]:
"""Split text where semantic similarity drops below threshold."""
model = SentenceTransformer("all-MiniLM-L6-v2")
sentences = text.split(". ")
embeddings = model.encode(sentences)
chunks, current_chunk = [], [sentences[0]]
for i in range(1, len(sentences)):
# Cosine similarity between consecutive sentences
sim = np.dot(embeddings[i-1], embeddings[i]) / (
np.linalg.norm(embeddings[i-1]) * np.linalg.norm(embeddings[i])
)
if sim < threshold: # topic shift detected
chunks.append(". ".join(current_chunk))
current_chunk = [sentences[i]]
else:
current_chunk.append(sentences[i])
chunks.append(". ".join(current_chunk)) # final chunk
return chunksКлючове усвідомлення для співбесіди: розмір фрагмента — це компроміс між точністю та повнотою (precision-recall). Малі фрагменти (100 токенів) підвищують точність пошуку, але фрагментують контекст. Великі фрагменти (1000 токенів) зберігають контекст, але розбавляють специфічність векторів. Більшість продакшн-систем зупиняється на 256-512 токенах із 10-20% перекриттям.
Векторні бази та моделі векторизації у продакшні
Векторна база зберігає вектори та підтримує швидкий приблизний пошук найближчих сусідів (ANN). Вибір правильної комбінації моделі векторизації та векторної бази безпосередньо впливає на затримку та точність пошуку.
Моделі векторизації у 2026 році зосередилися навколо кількох високопродуктивних варіантів. text-embedding-3-large від OpenAI (3072 виміри) та опенсорсні альтернативи, як-от bge-m3 від BAAI чи embed-v4 від Cohere, пропонують потужний багатомовний пошук. Лідерборд MTEB залишається стандартним бенчмарком для порівняння якості векторизації.
Векторні бази, як-от Pinecone, Weaviate, Milvus, Qdrant і pgvector, роблять різні компроміси:
| База | Індексація | Керована | Сильна сторона | |----------|----------|---------|----------| | Pinecone | Власна | Так | Простота, безсерверне масштабування | | Weaviate | HNSW | Так/Самостійно | Гібридний пошук (вектори + BM25) | | Milvus | IVF, HNSW | Так/Самостійно | Набори даних мільярдного масштабу | | Qdrant | HNSW | Так/Самостійно | Фільтрація + зберігання payload | | pgvector | IVF, HNSW | Самостійно | Інтеграція з PostgreSQL |
Для обговорень на співбесіді ключовим є розуміння алгоритму HNSW (Hierarchical Navigable Small World): він будує багатошаровий граф, де кожен вузол з'єднується з найближчими сусідами, забезпечуючи пошук O(log n) ціною вищого споживання пам'яті.
Готовий до співбесід з Data Science & ML?
Практикуйся з нашими інтерактивними симуляторами, flashcards та технічними тестами.
Гібридний пошук: поєднання щільного та розрідженого пошуку
Чистий векторний пошук зазнає невдачі при точних збігах ключових слів та рідкісних термінах. Чистий лексичний пошук (BM25) пропускає семантичну схожість. Гібридний пошук поєднує обидва підходи, і у 2026 році це стандарт за замовчуванням для продакшн-систем RAG.
Стандартний патерн використовує Reciprocal Rank Fusion (RRF) для злиття ранжованих результатів обох пошуковиків:
# hybrid_retrieval.py
from rank_bm25 import BM25Okapi
import numpy as np
def reciprocal_rank_fusion(
dense_results: list[str],
sparse_results: list[str],
k: int = 60
) -> list[str]:
"""Merge dense (vector) and sparse (BM25) results using RRF."""
scores: dict[str, float] = {}
for rank, doc_id in enumerate(dense_results):
scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)
for rank, doc_id in enumerate(sparse_results):
scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)
# Sort by combined RRF score, highest first
return sorted(scores.keys(), key=lambda d: scores[d], reverse=True)Гібридний пошук вирішує проблему «розбіжності словника», коли користувач запитує про «скасування підписки», а релевантний документ використовує формулювання «політика припинення облікового запису». BM25 ловить точний збіг термінів, тоді як векторний пошук вловлює семантичний зв'язок.
Реранкінг: фільтр другого етапу
Пошук повертає кандидатів. Реранкінг сортує їх за справжньою релевантністю. Реранкери типу cross-encoder, як-от Cohere Rerank чи bge-reranker-v2.5-gemma2-lightweight, оцінюють кожну пару запит-документ спільно, даючи значно точніші оцінки релевантності, ніж схожість bi-encoder.
Двоетапний конвеєр пошуку — широкий перший етап (топ 50-100 кандидатів через вектори + BM25), а потім точний реранкінг (топ 5-10 для промпта) — є стандартом у продакшні. Це утримує затримку керованою: перший етап використовує швидкий пошук ANN, а дорогий cross-encoder обробляє лише невеликий набір кандидатів.
Cross-encoder точніші за bi-encoder, бо обробляють запит і документ разом крізь усі шари трансформера. Bi-encoder векторизують їх незалежно, втрачаючи тонкі сигнали взаємодії. Компромісом є швидкість: cross-encoder неможливо проіндексувати заздалегідь.
Agentic RAG: за межами одноразового пошуку
Наївний RAG отримує один раз і генерує. Agentic RAG розглядає LLM як агента-міркувальника, який вирішує, коли шукати, що шукати і чи достатнім є отриманий контекст.
У 2026 році agentic RAG є домінантним патерном для складних запитів, що потребують багатоетапного міркування. Агент може:
- Самооцінка: Оцінити, чи отримані документи відповідають на питання
- Повторний запит: Переформулювати пошуковий запит, якщо початкові результати недостатні
- Маршрутизація (routing): Обрати між різними джерелами знань (векторна БД, SQL-база, API)
- Перевірка: Перехресно звірити факти у кількох отриманих уривках
# agentic_rag.py
from langgraph.graph import StateGraph, END
from typing import TypedDict
class RAGState(TypedDict):
question: str
documents: list[str]
generation: str
retries: int
def retrieve(state: RAGState) -> RAGState:
"""Retrieve documents from vector store."""
docs = vectorstore.similarity_search(state["question"], k=5)
return {"documents": [d.page_content for d in docs]}
def grade_documents(state: RAGState) -> str:
"""Decide if documents are relevant enough to answer."""
prompt = f"Are these documents relevant to: {state['question']}?\n"
prompt += "\n".join(state["documents"])
relevance = llm.invoke(prompt) # returns 'relevant' or 'not_relevant'
return "generate" if "relevant" in relevance.content else "rewrite"
def rewrite_query(state: RAGState) -> RAGState:
"""Reformulate the query for better retrieval."""
new_query = llm.invoke(
f"Rewrite this query for better search results: {state['question']}"
)
return {"question": new_query.content, "retries": state["retries"] + 1}
# Build the agent graph
workflow = StateGraph(RAGState)
workflow.add_node("retrieve", retrieve)
workflow.add_node("grade", grade_documents) # conditional routing
workflow.add_node("rewrite", rewrite_query)
workflow.add_node("generate", generate_answer)
workflow.set_entry_point("retrieve")
workflow.add_edge("retrieve", "grade")
workflow.add_conditional_edges("grade", grade_documents,
{"generate": "generate", "rewrite": "rewrite"})
workflow.add_edge("rewrite", "retrieve") # retry loop
workflow.add_edge("generate", END)Цей патерн — отримай, оціни, за потреби переформулюй і повтори — відомий як Corrective RAG (CRAG). Фреймворк LangGraph моделює робочий процес як спрямований циклічний граф з умовним розгалуженням, що спрощує додавання кроків перевірки, контрольних точок за участю людини (human-in-the-loop) чи маршрутизації між кількома джерелами.
Graph RAG: пошук структурованих знань
Graph RAG витягує сутності та зв'язки з документів у граф знань, а потім запитує і граф, і векторне сховище. Ця архітектура зменшує галюцинації при фактологічних запитах, прив'язуючи відповіді до явних зв'язків між сутностями замість неструктурованої схожості тексту.
Конвеєр інжесту витягує трійки (суб'єкт, предикат, об'єкт) з кожного фрагмента документа. Під час запиту система визначає релевантні сутності у питанні, обходить граф знань у пошуку пов'язаних фактів і поєднує контекст із графа з уривками, отриманими векторно.
Graph RAG чудово справляється з питаннями, що потребують багатокрокового (multi-hop) міркування, як-от «Яка команда веде проєкт, що використовує фреймворк, згаданий у документі X?» — запитами, що вимагають поєднання фактів із кількох документів. Чистий векторний пошук тут має труднощі, бо жоден окремий фрагмент не містить повної відповіді.
Graph RAG значно підвищує фактологічну точність (до 40% менше галюцинацій при запитах, насичених сутностями), але потребує зрілого конвеєра витягання сутностей. Зашумлене витягання дає зашумлений граф, що може погіршити результати нижче рівня наївного RAG.
Оцінювання систем RAG: метрики, що мають значення
Оцінювання RAG поділяється на метрики пошуку та метрики генерації. Обидва набори потрібно вимірювати незалежно, щоб діагностувати збої.
Метрики пошуку:
- Recall@k: Чи з'явилися релевантні документи у топ k результатів?
- MRR (Mean Reciprocal Rank): Наскільки високо ранжовано перший релевантний результат?
- NDCG: Чи відповідає ранжування ідеальному порядку релевантності?
Метрики генерації:
- Вірність (faithfulness): Чи використовує відповідь лише інформацію з отриманого контексту? (Вимірює галюцинації)
- Релевантність відповіді: Чи відповідь стосується початкового питання?
- Точність контексту: Чи дійсно отримані фрагменти використані у відповіді?
Фреймворки на кшталт Ragas та DeepEval автоматизують ці оцінки, використовуючи патерни LLM-як-суддя (LLM-as-judge). Найпопулярніші питання співбесід з data science дедалі частіше включають проєктування оцінювання RAG — варто очікувати питання про те, як виміряти, чи правильно працює система RAG.
Режими збоїв у продакшні та налагодження
Системи RAG зазнають невдач передбачувано. Знання цих патернів є необхідним як для співбесід, так і для реального розгортання.
Забруднення вікна контексту трапляється, коли забагато отриманих фрагментів розбавляють релевантний сигнал. LLM отримує 10 фрагментів, але лише 2 містять корисну інформацію. Виправлення: використовуйте реранкер для фільтрації та зменшіть top-k у пошуковику.
Артефакти chunking виникають, коли розбиття фіксованого розміру розриває речення, таблиці чи блоки коду посередині елемента. Отриманий фрагмент є синтаксично неповним і семантично марним. Це вирішує семантичний chunking або розбиття з урахуванням документа (з повагою до заголовків, абзаців, блоків коду).
Дрейф векторів (embedding drift) виникає, коли модель векторизації оновлюється, але векторне сховище досі містить вектори зі старої моделі. Запити, закодовані новою моделлю, шукають у векторному просторі, побудованому старою, погіршуючи якість пошуку. Рішення: повторно векторизуйте весь корпус після будь-якої зміни моделі.
Застарілі індекси видають неактуальну інформацію, бо конвеєр інжесту відстав від оновлень документів. У системах машинного навчання це аналогічно розбіжності тренування-обслуговування (training-serving skew) — система пошуку бачить інший розподіл даних, ніж той, що існує у продакшні.
Починай практикувати!
Перевір свої знання з нашими симуляторами співбесід та технічними тестами.
Висновок
- RAG поєднує пошук (векторний пошук по базі знань) із генерацією LLM, щоб давати прив'язані до фактів відповіді без перенавчання моделі
- Стратегія chunking має найбільший вплив на якість пошуку — семантичний та пізній chunking перевершують розбиття фіксованого розміру у більшості сценаріїв
- Гібридний пошук (щільні вектори + розріджений BM25) з Reciprocal Rank Fusion є продакшн-стандартом, що вирішує проблему розбіжності словника, з якою не справляється чистий векторний пошук
- Реранкери cross-encoder додають шар точності після широкого пошуку, обробляючи лише невеликий набір кандидатів, щоб тримати затримку прийнятною
- Agentic RAG (отримай, оціни, переформулюй, повтори) та Graph RAG (витягання зв'язків між сутностями) — два головні архітектурні досягнення 2026 року, що опрацьовують складні багатокрокові запити, на яких наївний RAG зазнає невдачі
- Оцінювання має відокремлювати метрики пошуку (Recall@k, MRR) від метрик генерації (вірність, релевантність відповіді), щоб діагностувати, де ламається конвеєр
- Найпоширеніші продакшн-збої — забруднення контексту, артефакти chunking, дрейф векторів, застарілі індекси — мають прості виправлення, щойно їх виявлено
Починай практикувати!
Перевір свої знання з нашими симуляторами співбесід та технічними тестами.
Теги
Поділитися
Пов'язані статті

Feature Engineering для Machine Learning: техніки та питання на співбесідах 2026
Повний огляд технік feature engineering для машинного навчання: кодування категорій, масштабування ознак, відбір фіч, побудова pipeline та питання для співбесід у 2026 році.

LangChain для Data Scientists у 2026: LLM, Агенти та Питання на Співбесідах
Повний туторіал LangChain для аналітиків даних. Вивчіть LCEL, патерни RAG, агентів ReAct та найпоширеніші питання на технічних співбесідах з практичними прикладами коду Python.

MLOps у 2026: MLflow, Model Registry та технічні питання співбесіди
Питання співбесіди з MLOps: життєвий цикл ML, відстеження експериментів у MLflow, просування моделей у Model Registry, патерни розгортання, моніторинг дрейфу та системний дизайн для 2026 року, з кодом на Python і відповідями.