Когда 10 000 PDF - это не шутка, а понедельник
Вы открываете папку с 10 000 PDF. Начинается паника. Google Drive плачет. Облачные сервисы требуют вашу почку. А локальный компьютер с 32 ГБ ОЗУ смотрит на вас как на сумасшедшего.
Но что если я скажу, что это реально? Что можно создать автономного агента, который сам разберет эту гору документов, проиндексирует, и будет отвечать на вопросы? Без облаков. Без подписок. Без отправки данных куда-либо.
Спойлер: это не магия. Это правильная архитектура и понимание того, как работают современные локальные LLM. И да, на 32 ГБ ОЗУ это реально, если не пытаться загрузить все в память одновременно.
Почему классический RAG ломается на 10 000 PDF
Обычный RAG (Retrieval-Augmented Generation) работает так: загружаем документы, разбиваем на чанки, создаем эмбеддинги, ищем похожие куски. Просто? Да. Работает на 100 документах? Отлично. На 10 000? Катастрофа.
Проблемы начинаются с самого начала:
- Память: 10 000 PDF = 50-100 ГБ текста после извлечения. Векторная база сожрет всю оперативку
- Время индексации: дни, а не часы
- Качество поиска: простой семантический поиск теряет контекст в больших документах
- Обработка ошибок: один битый PDF - и вся индексация падает
Именно поэтому нужен не просто RAG, а Agentic RAG - агент, который умеет планировать, разбивать задачу, обрабатывать ошибки и работать рекурсивно.
Архитектура: как агент думает о 10 000 PDF
Представьте библиотекаря в огромной библиотеке. Он не читает все книги сразу. Он знает систему каталогов, умеет быстро находить нужный раздел, а потом уже углубляется в конкретные книги.
Наш агент работает так же:
| Уровень | Что делает | Потребление памяти |
|---|---|---|
| Мета-индекс | Анализирует названия, авторов, даты, размеры PDF | ~500 МБ |
| Тематические кластеры | Группирует PDF по темам (используя легкую модель) | ~1 ГБ |
| Детальные эмбеддинги | Только для активных документов (последние 100-200) | ~4-8 ГБ |
| LLM для ответов | Llama 3.2 13B (квантованная версия) | ~8-10 ГБ |
Итого: 14-20 ГБ из 32. Остается запас для системы и кэша. Главный трюк - никогда не загружать все эмбеддинги одновременно.
Шаг 1: Подготовка - что нужно установить
1 Установка AnythingLLM с поддержкой агентов
AnythingLLM к 2026 году сильно вырос. Теперь это не просто интерфейс для Ollama, а полноценная платформа с агентами, планировщиками и встроенной обработкой документов.
# Клонируем репозиторий (актуально на февраль 2026)
git clone https://github.com/mintplex-labs/anything-llm.git
cd anything-llm
# Устанавливаем зависимости
npm install
# Запускаем в режиме разработчика
npm run dev
Важный момент: нужна версия с поддержкой Agent Framework. В стандартной сборке его может не быть. Проверяйте ветку `agent-framework` или смотрите последние релизы.
2 Настройка Ollama с Llama 3.2
Ollama к 2026 году научилась работать с квантованными моделями намного эффективнее. Но нужно правильно настроить контекстное окно.
# Скачиваем Llama 3.2 13B в 4-битном квантовании
ollama pull llama3.2:13b-q4_K_M
# Создаем кастомную модель с увеличенным контекстом
ollama create my-researcher -f ./Modelfile
Содержимое Modelfile:
FROM llama3.2:13b-q4_K_M
# Увеличиваем контекст для работы с большими документами
PARAMETER num_ctx 16384
# Настраиваем температуру для исследовательских задач
PARAMETER temperature 0.1
# Системный промпт для исследовательского агента
SYSTEM """
Ты - автономный исследовательский агент. Твоя задача анализировать тысячи PDF документов.
Ты умеешь:
1. Разбивать большие задачи на подзадачи
2. Определять релевантность документов к запросу
3. Синтезировать информацию из множества источников
4. Предоставлять ответы с цитатами и ссылками
Всегда указывай источник информации (номер документа, страница).
"""
Шаг 2: Создание автономного агента
В AnythingLLM заходим в раздел Agents → Create New Agent. Здесь начинается магия.
Ошибка новичков: пытаться создать одного агента на все задачи. Не делайте так. Создайте несколько специализированных агентов, которые работают вместе.
Архитектура multi-agent системы:
- Менеджер задач - разбивает запрос пользователя на подзадачи
- Индексатор - отвечает за обработку новых PDF и обновление индекса
- Поисковик - ищет релевантные документы в базе
- Аналитик - анализирует найденные документы и синтезирует ответ
- Валидатор - проверяет качество ответа и наличие цитат
В AnythingLLM это настраивается через YAML конфигурацию агента:
name: "PDF Research Agent System"
description: "Автономная система для анализа 10000 PDF документов"
agents:
- name: "task_manager"
model: "my-researcher"
role: "Разбивает сложные запросы на подзадачи"
capabilities:
- "task_decomposition"
- "priority_assignment"
- name: "indexer"
model: "my-researcher"
role: "Управляет индексацией и обработкой PDF"
capabilities:
- "pdf_processing"
- "incremental_indexing"
- "error_handling"
- name: "researcher"
model: "my-researcher"
role: "Анализирует документы и синтезирует ответы"
capabilities:
- "deep_analysis"
- "cross_document_synthesis"
- "citation_extraction"
workflow:
- step: "task_manager receives user query"
- step: "task_manager decomposes query into subtasks"
- step: "indexer checks if needed documents are indexed"
- step: "researcher analyzes relevant documents"
- step: "final answer synthesis and validation"
Шаг 3: Оптимизация обработки PDF
10 000 PDF - это не шутка. Если обрабатывать их наивно, индексация займет недели. Нужны оптимизации.
Пакетная обработка с приоритизацией
Не загружайте все PDF сразу. Разбейте на пачки по 100-200 файлов. Начните с самых новых документов или тех, что чаще всего запрашиваются.
# Пример скрипта для пакетной обработки
import os
from pathlib import Path
pdf_folder = "/path/to/10000pdfs"
batches = []
# Сортируем по дате изменения (сначала самые новые)
pdf_files = sorted(
Path(pdf_folder).glob("*.pdf"),
key=lambda x: x.stat().st_mtime,
reverse=True
)
# Разбиваем на батчи по 100 файлов
for i in range(0, len(pdf_files), 100):
batch = pdf_files[i:i+100]
batches.append(batch)
print(f"Создано {len(batches)} батчей для обработки")
Извлечение текста с кэшированием
Самая тяжелая операция - извлечение текста из PDF. Делайте это один раз и кэшируйте результат.
Шаг 4: Рекурсивный поиск вместо простого RAG
Простой семантический поиск на 10 000 документов дает много шума. Нужен рекурсивный поиск:
- Сначала ищем по метаданным (название, автор, дата)
- Потом сужаем поиск до тематических кластеров
- Запускаем семантический поиск только в релевантных кластерах
- Для найденных документов делаем углубленный анализ
В AnythingLLM это реализуется через кастомные обработчики поиска:
// Пример кастомного поискового обработчика
class RecursiveSearchHandler {
async search(query, options = {}) {
// Шаг 1: Поиск по метаданным
const metaResults = await this.searchMetadata(query);
// Шаг 2: Если мало результатов, ищем по тематическим кластерам
if (metaResults.length < 5) {
const clusters = await this.findRelevantClusters(query);
const clusterResults = await this.searchInClusters(query, clusters);
metaResults.push(...clusterResults);
}
// Шаг 3: Семантический поиск в найденных документах
const semanticResults = await this.semanticSearch(query, metaResults);
// Шаг 4: Ранжирование и возврат результатов
return this.rankAndDeduplicate([...metaResults, ...semanticResults]);
}
}
Шаг 5: Управление памятью - ключ к успеху
32 ГБ ОЗУ - это много, но и мало одновременно. Нужно жесткое управление памятью:
| Что мониторить | Критический уровень | Действие при превышении |
|---|---|---|
| Использование ОЗУ | 28 ГБ | Очистка кэша эмбеддингов |
| Память Ollama | 10 ГБ | Перезагрузка модели |
| Дисковый кэш | 50 ГБ | Удаление старых временных файлов |
Настройте мониторинг и автоматические действия. В Linux это можно сделать через cron и простые скрипты:
#!/bin/bash
# Скрипт мониторинга памяти для агента
MEM_THRESHOLD=28000 # 28 ГБ в МБ
OLLAMA_THRESHOLD=10000 # 10 ГБ
# Проверяем общее использование памяти
total_mem=$(free -m | awk '/^Mem:/{print $3}')
if [ $total_mem -gt $MEM_THRESHOLD ]; then
echo "[$(date)] Превышен порог памяти: ${total_mem}MB"
# Очищаем кэш AnythingLLM
curl -X POST http://localhost:3001/api/v1/system/clear-cache
# Перезапускаем Ollama с очисткой памяти
ollama stop
sleep 5
ollama start
fi
Реальные цифры: что ожидать
После настройки всей системы:
- Индексация 10 000 PDF: 3-7 дней (в зависимости от сложности документов)
- Среднее время ответа на запрос: 15-45 секунд
- Точность поиска: 70-85% (зависит от качества документов)
- Потребление ОЗУ в пике: 26-30 ГБ
- Дисковое пространство: 60-120 ГБ для индекса и кэша
Это не мгновенные ответы как в ChatGPT. Но это ваши документы. Ваши данные. Никуда не уходящие.
Чего не хватает в AnythingLLM в 2026 году
При всей мощи системы, есть проблемы:
- Слабая документация по multi-agent системам
- Нет встроенной поддержки инкрементальной индексации
- Ограниченные возможности кастомизации поиска
- Сложная отладка агентов
Но эти проблемы решаются кастомными скриптами и патчами. Сообщество активно развивает проект.
Альтернативы: когда AnythingLLM не подходит
Если ваш кейс сложнее или нужна более стабильная система:
- Для 100 000+ PDF - смотрите решения на Pathway или более тяжелые фреймворки
- Для слабого железа - нужны другие подходы и более легкие модели
- Для сканов и изображений - требуется серьезная OCR подготовка
Совет, который сэкономит неделю отладки
Не начинайте с 10 000 PDF. Начните с 100. Отладьте pipeline. Проверьте качество извлечения текста. Убедитесь, что поиск работает.
Потом масштабируйте до 1 000. И только когда все стабильно - до 10 000.
И самое главное - настройте мониторинг с самого начала. Логируйте все: время обработки каждого PDF, ошибки, использование памяти. Через неделю работы у вас будут данные для оптимизации.
Будущее за гибридными системами. В 2026 году появляются решения, где легкая модель на устройстве решает, какие запросы обрабатывать локально, а какие отправлять в более мощную облачную модель. Но для 10 000 PDF локальная обработка - это вопрос не только приватности, но и экономики. Облачная обработка такого объема стоит тысяч долларов.
Автономный исследовательский агент на AnythingLLM - это не будущее. Это настоящее, которое работает сегодня. На 32 ГБ ОЗУ. На вашем компьютере. С вашими документами.
Начните с малого. Масштабируйте постепенно. И помните: каждая большая система когда-то была маленьким скриптом.