RAG по своим PDF без облака: свой сервер вместо загрузки в чат
Папка с полусотней PDF — договоры, выписки, медкарты, протоколы — и задача простая: найти нужный пункт за секунды, а не листать всё руками. Первый порыв — закинуть файлы в ChatGPT и спросить. Второй, более трезвый — вспомнить, что в этих PDF лежат персональные данные или коммерческая тайна, которую по 152-ФЗ нельзя выгружать за периметр. Дальше документы возвращаются в папку, а вопрос остаётся без ответа. Решение — RAG на собственном сервере: те же вопросы к тем же файлам, но индекс, векторная база и модель — ваши, и ни один байт документа не уходит наружу.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое RAG простыми словами
RAG — retrieval-augmented generation, поиск с дополнением генерацией. Обычная языковая модель отвечает только тем, что запомнила при обучении: спросите про пункт 4.3 вашего договора аренды — она честно скажет, что такого договора не видела, или, хуже, придумает правдоподобный ответ. RAG решает это иначе: перед тем как модель начнёт отвечать, система ищет в ваших документах релевантные фрагменты и подкладывает их в промпт вместе с вопросом. Модель отвечает не по памяти, а по тексту, который ей только что показали.
Механика внутри — три шага. Документы заранее разбиваются на куски по несколько сотен-тысяч символов и превращаются в векторы через отдельную модель-эмбеддер: числовое представление смысла текста, а не набор ключевых слов. Векторы оседают в векторной базе. Когда приходит вопрос, он тоже превращается в вектор, и база отдаёт несколько ближайших по смыслу фрагментов — это и есть retrieval. Языковая модель получает вопрос плюс эти фрагменты и формулирует ответ — это generation. Устройство такого пайплайна на уровне компонентов разобрано в статье как поднять RAG по своим документам на сервере, про саму векторную базу — в материале как поднять векторную базу для RAG.
Важное следствие: качество ответа определяется не только моделью, но и тем, что нашлось на шаге retrieval. Плохая нарезка на куски или неудачный эмбеддер — и модель получит нерелевантные фрагменты, а ответ будет уверенным и неправильным. Это не недостаток RAG как идеи, а зона, где придётся настраивать вручную — об этом ниже.
Почему свой сервер безопаснее, чем ChatGPT
Когда вы вставляете текст PDF в облачный чат или прикрепляете файл, документ уходит на серверы провайдера. Даже при обещании не использовать данные для обучения модели остаются проблемы. Файл физически лежит на чужой инфраструктуре, под чужой юрисдикцией — для персональных данных это прямое нарушение 152-ФЗ, если данные о гражданах РФ обязаны оставаться в России. Компания теряет контроль над сроком хранения и доступом: политика провайдера может измениться, аккаунт — быть скомпрометирован. И это происходит на каждый чат заново: вставили документ, обсудили, начали новую сессию — файл снова пересекает периметр.
На собственном сервере схема другая. Документ загружается один раз, индексируется в вашей же векторной базе на арендованном VPS и остаётся там до тех пор, пока вы его не удалите. Запрос к языковой модели — если вы используете локальную модель через Ollama — вообще не покидает сервер. Если предпочитаете отвечать через API OpenAI или Anthropic, наружу уходит только текст конкретного запроса с уже найденными фрагментами, а не весь корпус документов и не сами файлы. Разница принципиальная: контролируемая утечка одного запроса против постоянного присутствия всей базы знаний на чужой инфраструктуре.
Отдельный плюс — предсказуемость доступа: на своём сервере вы сами решаете, кто заходит в интерфейс — пароль, отдельные учётные записи, сетевые ограничения. В облачном сервисе это решает провайдер, а вы узнаёте об инцидентах постфактум.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть AnythingLLMAnythingLLM: готовый RAG без велосипеда
Собрать пайплайн из отдельных кусков — эмбеддер, векторная база, оркестрация запросов, веб-интерфейс — можно и руками, но это неделя работы ради того, что уже существует готовым продуктом. AnythingLLM от Mintplex Labs закрывает весь путь одним приложением: загрузка документов через браузер, встроенная поддержка нескольких векторных баз, выбор эмбеддера и модели через выпадающие списки, разделение на рабочие пространства (workspace) — свой индекс и своя история чата под каждую задачу или клиента.
Ключевое решение — LLM и эмбеддер выбираются независимо друг от друга. Можно взять полностью локальный контур: эмбеддер и языковую модель через Ollama на том же сервере, тогда ни один запрос вообще не покидает VPS. Можно оставить эмбеддинг локальным, а за качественными ответами ходить в API — GPT, Claude, Gemini или любой OpenAI-совместимый эндпоинт. Третий вариант — оба звена через API, если сервер держит только векторную базу и интерфейс, а тяжёлые вычисления не нужны локально.
Встроенная векторная база у AnythingLLM есть по умолчанию (LanceDB, работает без отдельной настройки), но для рабочей нагрузки — десятки тысяч фрагментов, несколько параллельных workspace — практичнее подключить внешний Qdrant: он быстрее на больших коллекциях и переживает перезапуск контейнера AnythingLLM без риска повредить индекс.
Установка AnythingLLM на VPS
Разворачивается AnythingLLM одним контейнером. Минимальный рабочий вызов:
docker run -d \
--name anythingllm \
-p 127.0.0.1:3001:3001 \
-v /data/anythingllm:/app/server/storage \
-e STORAGE_DIR=/app/server/storage \
--restart unless-stopped \
mintplexlabs/anythingllm:1.16.1
Три момента здесь не для галочки. Порт публикуется на 127.0.0.1, а не на 0.0.0.0: свежая установка пускает в интерфейс без пароля, пока вы не включите многопользовательский режим, и открытый наружу порт — это открытая дверь к вашим документам и ключам API до первого захода в настройки. Наружу пускайте только через Nginx с TLS на отдельном поддомене.
Volume /data/anythingllm:/app/server/storage — это персистентность: внутри вся база — индекс документов, история чатов, встроенная LanceDB, файл .env с настройками провайдеров. Без volume контейнер стартует чистым при каждом пересоздании, и вся работа по загрузке и настройке пропадает вместе с docker rm. Тег версии стоит фиксировать явно (1.16.1, а не latest) — образ обновляется часто, а миграции внутренней базы выполняются автоматически при старте и назад не откатываются.
После запуска — docker ps должен показать Up ... (healthy) через одну-две минуты, интерфейс открывается на http://127.0.0.1:3001 (через SSH-туннель или уже настроенный Nginx). Первым делом — включить многопользовательский режим и задать пароль администратора, до этого шага любой, кто дотянулся до порта, работает с системой без ограничений.
Загрузка PDF, workspace и выбор моделей
Документы в AnythingLLM живут внутри workspace — изолированного пространства со своим индексом и своей историей чата. Разумная практика — не сваливать все PDF в одно пространство, а завести отдельный workspace под задачу или клиента: «Договоры 2025», «Медкарты отдела», «Финансовая отчётность». Так границы поиска не размываются, и модель не подтягивает фрагмент чужого договора в ответ на вопрос про другой.
Загрузка — через кнопку «Upload» внутри workspace: перетащить PDF, AnythingLLM сам разберёт текст, разобьёт на фрагменты и отправит на эмбеддинг. Размер куска (chunk size) и перекрытие между кусками (chunk overlap) настраиваются в параметрах workspace — значения по умолчанию подходят для обычного текста, но для документов с таблицами и нумерованными пунктами (типично для договоров) увеличенный overlap снижает риск разрезать смысловой блок пополам.
Модель-эмбеддер выбирается в настройках workspace или глобально в System Settings → LLM Preference. Если приоритет — чтобы текст документов вообще не покидал сервер, ставьте эмбеддер через Ollama (nomic-embed-text или аналог) — вычисление векторов идёт локально на CPU и не требует видеокарты, разбор такого запуска — в статье как поднять локальный запуск LLM через Ollama. Альтернатива — эмбеддер через API (например, OpenAI), быстрее и точнее на смешанных языках, но каждый фрагмент документа на секунду уходит наружу для вычисления вектора — компромисс, который стоит взвесить для по-настоящему чувствительных данных.
Языковая модель для ответов — отдельная настройка, независимая от эмбеддера. Тот же принцип: локальная модель через Ollama (Qwen, Llama, Mistral — по объёму видеопамяти) держит весь диалог на сервере, модель через API даёт более сильные ответы ценой того, что вопрос и найденные фрагменты уходят к провайдеру. Рабочий компромисс для конфиденциальных документов — локальный эмбеддер плюс локальная LLM: полностью закрытый контур, где облако не участвует вообще.
Типичные проблемы: сканы, OCR и большие PDF
Два типа PDF ломают RAG-пайплайн предсказуемо, и оба стоит проверить до того, как загружать сотню файлов подряд.
Первая проблема — сканы без текстового слоя. Если PDF — это набор картинок (типично для старых договоров и медицинских документов, пропущенных через сканер), встроенный парсер AnythingLLM извлекает пустоту или мусор. Решение — прогнать документы через OCR до загрузки. Практический вариант — ocrmypdf, который добавляет в PDF невидимый текстовый слой поверх картинки, не трогая исходный вид документа:
ocrmypdf --language rus+eng input.pdf output.pdf
После этого файл индексируется как обычный текстовый PDF. Если в коллекции много сканов, разумнее один раз прогнать их пакетом скриптом, чем выяснять постфактум, почему workspace «не видит» половину документов.
Вторая проблема — слишком большие PDF: годовой отчёт на триста страниц, документация одним файлом. Беда не в объёме диска, а в качестве поиска: чем крупнее документ, тем выше шанс, что нужный кусок потеряется среди тысяч похожих по структуре абзацев, и retrieval вытащит что-то формально близкое, но не то. Выход — делить такие документы на логические части до загрузки (по главам, по разделам), тогда фрагменты остаются тематически однородными, и модель точнее находит релевантный кусок.
Третья, менее очевидная проблема — таблицы. PDF-парсеры часто превращают табличные данные в бессвязный текст, теряя структуру строк и столбцов. Для финансовой отчётности стоит проверить пару ответов вручную: если модель путает цифры из соседних колонок, помогает либо предварительная конвертация таблиц в текст, либо более щедрый chunk size, чтобы вся таблица попадала в один фрагмент целиком.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть AnythingLLMОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Нужна ли видеокарта для RAG по PDF на AnythingLLM?
Нет, если используете эмбеддер и модель через API — достаточно обычного VPS с несколькими ядрами CPU. Видеокарта нужна только для комфортной работы локальной LLM через Ollama: без неё модель на 7-8 миллиардов параметров отвечает медленнее, но всё равно работает на CPU.
Сколько документов выдержит один сервер?
Зависит от объёма RAM и выбранной векторной базы. Встроенная LanceDB спокойно тянет несколько тысяч документов на обычном VPS с 8-16 ГБ RAM; для десятков тысяч и активной параллельной работы нескольких workspace практичнее подключить отдельный Qdrant.
Можно ли полностью отключить облако и работать офлайн?
Да: эмбеддер через Ollama, языковая модель через Ollama, векторная база локальная или в том же Docker-стеке — с таким набором ни один запрос не покидает сервер, интернет нужен только для первоначальной загрузки образов и моделей.
Что делать, если модель отвечает неточно, хотя документ загружен?
Проверить, действительно ли нужный фрагмент попал в число найденных: в интерфейсе AnythingLLM есть режим просмотра источников ответа. Если фрагмент не найден — чаще всего дело в нарезке (chunk size) или в выборе эмбеддера, а не в языковой модели: она честно отвечает по тому, что ей подложили.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.