RAG: добавление своих данных в LLM-приложения
Вы создали чат-бота на базе мощной LLM, такой как GPT-4 или Claude, но он даёт общие ответы и ничего не знает о внутренних документах вашей компании. Как заставить его отвечать на вопросы по вашим данным? Дообучение (fine-tuning) дорого и статично. Решение — Retrieval-Augmented Generation (RAG).
В этой статье мы объясним RAG на практических примерах, покажем, как реализовать его шаг за шагом, и поделимся лучшими практиками для создания надёжных LLM-приложений, использующих ваши приватные данные.
Что такое RAG?
RAG объединяет две мощные техники: поиск (извлечение релевантной информации из базы знаний) и генерацию (использование LLM для получения ответа). Вместо того чтобы полагаться только на предобученные знания LLM, RAG динамически извлекает релевантные документы и включает их в промпт, привязывая ответ модели к вашим данным.
Представьте, что это экзамен с открытой книгой для ИИ: перед ответом он может найти ответ в ваших документах.
Зачем использовать RAG?
- Актуальная информация: обновляйте базу знаний без переобучения модели.
- Экономичность: не нужно дорогое дообучение или большие контекстные окна.
- Точность: снижает галлюцинации, привязывая ответы к извлечённым фактам.
- Конфиденциальность: ваши данные остаются в векторной базе; в LLM отправляются только релевантные фрагменты.
- Гибкость: работает с любой LLM (OpenAI, Anthropic, локальные модели) и любым типом документов.
Как работает RAG: основные компоненты
Типичная RAG-система состоит из четырёх основных частей:
- Загрузка документов: загрузка и предобработка документов (PDF, веб-страницы, базы данных).
- Модель эмбеддингов: преобразование текстовых фрагментов в числовые векторы, отражающие семантический смысл.
- Векторная база данных: хранение и индексация этих векторов для быстрого поиска по сходству.
- LLM: генерация ответов с использованием извлечённого контекста.
Пошаговое руководство: построение RAG-конвейера
1. Подготовьте документы
Соберите источники данных: PDF, Markdown-файлы, страницы Confluence или таблицы SQL. Очистите текст (удалите колонтитулы, шаблонные элементы) и разбейте его на фрагменты по 200–500 слов с небольшим перекрытием (например, 50 слов) для сохранения контекста.
Пример на Python:
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
chunks = text_splitter.split_text(your_document)
2. Сгенерируйте эмбеддинги
Используйте модель эмбеддингов, например OpenAI text-embedding-3-small или открытые модели вроде all-MiniLM-L6-v2, чтобы преобразовать каждый фрагмент в вектор.
from openai import OpenAI
client = OpenAI()
def get_embedding(text):
response = client.embeddings.create(
model="text-embedding-3-small",
input=text
)
return response.data[0].embedding
3. Сохраните в векторной базе данных
Выберите векторную базу данных: Pinecone, Weaviate, Qdrant или даже PostgreSQL с pgvector. Сохраните эмбеддинг каждого фрагмента вместе с метаданными (источник, номер страницы).
import pinecone
pinecone.init(api_key="YOUR_KEY", environment="us-west1-gcp")
index = pinecone.Index("rag-demo")
vectors = [(f"chunk-{i}", get_embedding(chunk), {"text": chunk}) for i, chunk in enumerate(chunks)]
index.upsert(vectors=vectors)
4. Извлеките релевантные фрагменты
Когда пользователь задаёт вопрос, преобразуйте запрос в эмбеддинг и найдите top-k наиболее похожих фрагментов.
query_embedding = get_embedding(user_question)
results = index.query(vector=query_embedding, top_k=3, include_metadata=True)
context = "\n\n".join([match.metadata["text"] for match in results.matches])
5. Сгенерируйте ответ
Составьте промпт, включающий извлечённый контекст, и попросите LLM ответить на его основе.
prompt = f"""Answer the question based only on the following context:
{context}
Question: {user_question}
Answer:"""
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
print(response.choices[0].message.content)
RAG против дообучения
| Аспект | RAG | Дообучение |
|---|---|---|
| Актуальность данных | Обновления в реальном времени | Статично до переобучения |
| Стоимость | Низкая (эмбеддинги + хранение) | Высокая (вычислительные ресурсы для обучения) |
| Реализация | Модульная, проще | Сложная, требует экспертизы в ML |
| Сценарий использования | Вопросы и ответы по документам | Адаптация стиля, доменный жаргон |
Лучшие практики для RAG
- Продуманное разбиение: перекрывайте фрагменты, чтобы не разрезать предложения; рассмотрите семантическое разбиение.
- Гибридный поиск: комбинируйте векторный поиск с поиском по ключевым словам (BM25) для лучшего召回.
- Переранжирование результатов: используйте кросс-энкодер для переупорядочивания извлечённых фрагментов по релевантности.
- Тщательный промпт: инструктируйте LLM ссылаться на источники и говорить «Я не знаю», если контекста недостаточно.
- Мониторинг и оценка: логируйте запросы и ответы; используйте метрики вроде hit rate и релевантности ответа.
Распространённые ошибки и как их избежать
- Плохой поиск: если эмбеддинги не улавливают доменный смысл, попробуйте дообучить модель эмбеддингов или использовать доменно-специфичную.
- Ограничения длины контекста: не вставляйте слишком много фрагментов; приоритезируйте лучшие результаты и делайте промпты лаконичными.
- Галлюцинации: даже с контекстом LLM может выдумывать факты. Используйте строгие промпты и рассмотрите этап верификации.
- Устаревший индекс: настройте конвейер для повторного создания эмбеддингов при изменении документов.
Часто задаваемые вопросы
В чём разница между RAG и дообучением?
RAG извлекает релевантную информацию во время вывода и включает её в промпт, тогда как дообучение корректирует веса модели для изучения новых паттернов. RAG лучше для динамичных, фактических знаний; дообучение — для адаптации стиля или домена.
Нужна ли векторная база данных для RAG?
Не обязательно — можно использовать любой поисковый индекс (например, Elasticsearch) или даже косинусное сходство в памяти для небольших наборов данных. Но векторные базы данных, такие как Pinecone или Qdrant, оптимизированы для быстрого и масштабируемого поиска по сходству.
Как оценить RAG-систему?
Измеряйте качество поиска (precision@k, recall) и качество генерации (релевантность ответа, достоверность). Инструменты вроде Ragas или TruLens помогают автоматизировать оценку.
Заключение
RAG — практичный и экономичный способ добавить свои данные в LLM-приложения. Следуя шагам выше и придерживаясь лучших практик, вы сможете создать ИИ-ассистентов, которые точно отвечают на вопросы, используя вашу приватную базу знаний. Начните с малого, итерируйте и всегда оценивайте.
При подготовке документов для RAG-конвейера часто требуется объединить несколько PDF в один файл для упрощения загрузки. Используйте наш бесплатный PDF Merger, чтобы быстро и безопасно объединить PDF.