AI Basics

RAG за 7 минут

Этот урок открыт без регистрации. Если зашло — зарегистрируйся и продолжай Track A.

LLM знает много, но не знает вашего: ваших документов, актуальных цен, внутренней документации компании, истории клиентов в CRM. Она также не знает того, что появилось после её даты отсечки обучающих данных (training cutoff, обычно несколько месяцев назад).

RAG (Retrieval-Augmented Generation, «генерация с дополнительным извлечением») — стандартный приём, чтобы дать модели доступ к данным во время ответа, не переобучая модель.

Архитектура из четырёх блоков

фрагменты ──> векторизация ──> поиск ──> генерация
   офлайн         офлайн         онлайн       онлайн

1. Разбиение на фрагменты (chunk)

Разбиваем ваши документы (PDF, веб-страницы, Notion, что угодно) на куски по 200–1000 токенов. Куски не должны разрывать смысловые единицы (предложения, абзацы). Часто используется перекрытие 10–20% между соседними фрагментами — чтобы не потерять контекст на границе.

2. Векторизация (embed)

Каждый фрагмент прогоняется через модель векторных представлений (embedding model) — например, text-embedding-3-small от OpenAI или открытая bge-m3 — и превращается в вектор длиной 256–3072 чисел.

Вектор — это смысловой отпечаток фрагмента. Фрагменты про похожие вещи имеют близкие векторы. Фрагменты про разное — далёкие.

Векторы сохраняются в векторную базу данных (vector database: Postgres + pgvector, Pinecone, Qdrant, Weaviate, Chroma). Это офлайн-этап, делается один раз на весь корпус.

3. Поиск (retrieve)

Когда пользователь задаёт вопрос — мы:

  1. превращаем вопрос в вектор той же моделью векторных представлений;
  2. ищем в БД топ-N ближайших фрагментов (по косинусной близости, cosine similarity);
  3. получаем 3–10 самых релевантных фрагментов.

Это онлайн-этап, выполняется на каждый запрос. Современные векторные БД делают это за миллисекунды на миллиардах векторов.

4. Генерация (generate)

Собираем промпт:

[Релевантные фрагменты документации]
Фрагмент 1: ...
Фрагмент 2: ...
Фрагмент 3: ...

[Вопрос пользователя]
{user_query}

[Инструкция]
Ответь, используя только информацию из фрагментов выше.
Если в фрагментах нет ответа — скажи «не знаю».

И отправляем в LLM. Получаем ответ, обоснованный вашими данными, а не выдуманный моделью.

Где RAG проигрывает

RAG — не серебряная пуля. Случаи, когда он не работает:

Многошаговое рассуждение (multi-hop reasoning)

Какие сотрудники, начавшие работать после 2020 года и работающие в Москве, имеют зарплату выше средней?

Это требует нескольких отдельных запросов к базе данных + арифметики + сравнения. RAG найдёт релевантные документы, но не построит логическую цепочку. Нужно либо:

  • агентный подход (модель формирует под-запросы и выполняет их по очереди);
  • генерация SQL по тексту (Text-to-SQL: вместо извлечения — генерация SQL и его выполнение).

Математика и точные расчёты

LLM плохо считает в уме. RAG не помогает — нужна интеграция с инструментом-калькулятором или запуск Python-кода.

Свежие новости и точные даты

Если в ваших фрагментах нет данных за последний час — RAG бессилен. Нужны инструменты поиска (Brave Search API, SerpAPI) или парсеры реального времени.

Структурированные данные

Для CRM, ERP, баз заказов RAG неэффективен. Лучше SQL-агент или прямые вызовы API. RAG работает на неструктурированном тексте.

Минимальный RAG за 30 строк (псевдо-Python)

import openai

# Офлайн (один раз):
docs = read_all_documents()  # list of strings
chunks = [c for d in docs for c in split_into_chunks(d, size=500, overlap=50)]
embeddings = openai.embeddings.create(model="text-embedding-3-small", input=chunks)
vector_db.upsert(chunks, embeddings)

# Онлайн (на каждый запрос):
def answer(query):
    q_emb = openai.embeddings.create(model="text-embedding-3-small", input=[query])
    top_chunks = vector_db.search(q_emb, top_k=5)

    context = "\n\n".join(top_chunks)
    response = openai.chat.completions.create(
        model="gpt-4",
        messages=[
            {"role": "system", "content": "Отвечай только на основе предоставленного контекста."},
            {"role": "user", "content": f"Контекст:\n{context}\n\nВопрос: {query}"}
        ]
    )
    return response.choices[0].message.content

В проде добавляется: переранжирование (re-ranking), гибридный поиск (векторный + BM25), отслеживание ссылок на источники, обнаружение галлюцинаций. Но базовая механика — именно эти 30 строк.

Что важно запомнить

  1. RAG = подмешать релевантные фрагменты → задать вопрос LLM с этим контекстом.
  2. 4 этапа: разбиение → векторизация → поиск → генерация.
  3. Векторная БД — это просто база, где найти топ-N похожих векторов быстро.
  4. RAG не решает многошаговое рассуждение, математику, свежие данные, структурированные запросы.
  5. Современный прод — это гибрид: RAG + инструменты + агенты + традиционные базы данных.

Что дальше

Если эта тема зашла — зарегистрируйся и продолжай Track A. В следующих уроках:

  • Промпт-инжиниринг — детально (вы уже видели обзор в уроке 2);
  • Агенты — когда RAG недостаточен;
  • Векторные представления (embeddings) — глубже про смысловые векторы;
  • Этика и ограничения — что LLM не может и почему.

И параллельно — Track B (Classic ML/DL): от регрессии до трансформера на чистом NumPy.