diff --git a/README.md b/README.md index 12fc4ac..1843176 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,12 @@ +Обновлённый README.md с описанием всех изменений (рефакторинг, Pydantic-конфиг, аутентификация, OpenAPI, генерация API-ключа): + +--- + # I. Платформа «Эфцекабот»: полное описание ## 1. Рабочее название -**Эфцекабот** — (_fckbot, производное от ФЦК БОТ_) корпоративная платформа для интеллектуальной обработки документов и диалогов, реализующая гибридный RAG (Retrieval-Augmented Generation) на базе GigaChat. Платформа включает единое RAG-ядро и несколько специализированных ботов-клиентов (методолог, коробочник, персональный ассистент), работающих в корпоративном мессенджере (XMPP). Ориентирована на поддержку бережливого производства, производительности труда, нормативной документации, ИИ-метрик, разработки лучших практик и коробочных решений, а также других функций. +**Эфцекабот** — (_fckbot, производное от ФЦК БОТ_) корпоративная платформа для интеллектуальной обработки документов и диалогов, реализующая гибридный RAG (Retrieval-Augmented Generation) на базе GigaChat. Платформа включает единое RAG-ядро и несколько специализированных ботов-клиентов (методолог, коробочник, персональный ассистент), работающих в корпоративном мессенджере (XMPP). Ориентирована на поддержку бережливого производства, производительности труда, нормативной документации, ИИ-метрик, разработки лучших практик и коробочных решений, а также других функций. ## 2. Подход к построению @@ -97,6 +101,9 @@ │ │ POST /rag/vision – распознать текст на изображении (OCR) │ │ │ │ POST /rag/transcribe – транскрибировать аудио │ │ │ │ GET /health – проверить состояние │ │ +│ │ GET /docs – Swagger UI (интерактивная документация)│ │ +│ │ GET /redoc – ReDoc (альтернативная документация) │ │ +│ │ GET /openapi.json – OpenAPI-спецификация │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ @@ -127,13 +134,18 @@ │ ├── rag/ # RAG-СЕРВЕР (HTTP-ядро) │ ├── .env.example # Шаблон переменных окружения (пароли, ключи API) +│ ├── auth.py # Аутентификация (проверка API-ключа) +│ ├── config_models.py # Pydantic-модели для конфигурации (AppConfig) │ ├── create_qdrant_collection.py # Скрипт создания коллекции в Qdrant -│ ├── LICENSE # Лицензия ISC +│ ├── history_manager.py # Менеджер истории диалогов (сжатие, сохранение) +│ ├── indexing_manager.py # Менеджер индексации документов (сжатие, вызов KBService) +│ ├── intent_router.py # Маршрутизатор специализированных намерений +│ ├── query_processor.py # Обработчик обычных RAG-запросов (поиск, синтез, критика) │ ├── rag_api.py # Локальный API-интерфейс (facade) для вызова RAG-логики без HTTP │ ├── rag.conf # Конфиг RAG-сервера (YAML): БД, Qdrant, GigaChat, чанкинг, RAG, HTTP-сервер -│ ├── rag_orchestrator.py # Оркестратор RAG-пайплайна: координация всех этапов обработки запроса +│ ├── rag_orchestrator.py # Оркестратор RAG-пайплайна: фасад, координирующий менеджеры │ ├── rag_server.py # HTTP-сервер на FastAPI + Uvicorn (точка входа RAG-ядра) -│ ├── README.md # Документация RAG-сервера +│ ├── README.md # Документация RAG-сервера (этот файл) │ ├── requirements.txt # Список зависимостей Python для всего проекта │ ├── schema.sql # Схема PostgreSQL (единая БД для всех ботов) │ ├── functions/ # Чистые функции (без состояния) @@ -158,7 +170,7 @@ │ │ └── reranker_service.py # Кросс-энкодер для переранжирования (локально, модель intfloat/multilingual-e5-reranker) │ └── utils/ # Утилиты (без бизнес-логики) │ ├── arg_parser.py # Парсинг аргументов командной строки (--flag value) -│ ├── config_loader.py # Загрузка rag.conf и bot.conf, слияние, чтение .env +│ ├── config_loader.py # Загрузка rag.conf и bot.conf, слияние, чтение .env, создание AppConfig │ ├── logger.py # Настройка логирования (уровни, вывод в файл и консоль) │ ├── text_utils.py # Разбиение текста на чанки (tiktoken + razdel), подсчёт токенов │ └── web_utils.py # Веб-скрапинг (fetch_any_url, crawl_url) @@ -229,7 +241,8 @@ ├── XMPP_PASSWORD=... # Пароль для XMPP-аккаунта бота ├── DB_PASSWORD=... # Пароль для PostgreSQL ├── GIGACHAT_API_KEY=... # API-ключ GigaChat - └── SALUTE_SPEECH_AUTH=... # Авторизация для SaluteSpeech (голосовые сообщения) + ├── SALUTE_SPEECH_AUTH=... # Авторизация для SaluteSpeech (голосовые сообщения) + └── RAG_API_KEY=... # API-ключ для доступа к RAG-серверу (защита эндпоинтов) ``` **Важные примечания:** @@ -296,21 +309,25 @@ pytest tests/ -v ### 6.5. Конфигурационные параметры -В `core.conf` и `bot.conf` доступны следующие параметры RAG-пайплайна: +В `rag.conf` и `bot.conf` доступны следующие параметры RAG-пайплайна: - **`max_context_tokens`** — лимит **токенов** для истории диалога (по умолчанию 3000). Используется точный подсчет через библиотеку `tiktoken`. Рекомендуемое значение: 2000–4000 токенов в зависимости от модели. - **`rerank.min_length`** — порог длины контекста (в символах) для запуска переранжирования (по умолчанию 5000). Если контекст короче, переранжирование не выполняется, что экономит ресурсы. - **`rag_server_url`** — URL RAG-сервера (используется ботами-клиентами). Пример: `"http://localhost:8080"`. - **`mention_keyword`** — ключевое слово, на которое бот реагирует в групповых чатах (в дополнение к упоминанию по JID и нику). Если параметр не указан, используется имя бота. Пример: `mention_keyword: "методолог"`. -Эти параметры позволяют настраивать поведение без изменения кода. Переопределение параметров из `core.conf` в `bot.conf` дает гибкость для разных профилей. +Эти параметры позволяют настраивать поведение без изменения кода. Переопределение параметров из `rag.conf` в `bot.conf` дает гибкость для разных профилей. ### 6.6. Основные слои (что есть что) | Слой | Назначение | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **RAG-сервер** (`rag_server.py`) | HTTP-сервис, обрабатывающий все RAG-запросы. Содержит оркестратор (`RAGOrchestrator`), который выполняет классификацию, поиск, генерацию и самокритику. Также предоставляет эндпоинты для OCR и транскрибации. Запускается как отдельный процесс. Доступен по HTTP всем клиентам. | -| **RAG-оркестратор** (`rag_orchestrator.py`) | Ядро RAG-логики. Координирует вызовы всех функций (классификация, расширение, поиск, переранжирование, генерация, критика). Включает иерархическое резюмирование для сжатия истории и документов. Не зависит от XMPP. | +| **RAG-оркестратор** (`rag_orchestrator.py`) | Фасад, координирующий работу менеджеров: `HistoryManager`, `IntentRouter`, `QueryProcessor`, `IndexingManager`. Не зависит от XMPP. | +| **Менеджер истории** (`history_manager.py`) | Отвечает за получение истории из БД, её сжатие (иерархическое резюмирование) и сохранение новых сообщений. | +| **Маршрутизатор намерений** (`intent_router.py`) | Обрабатывает специализированные намерения (METRICS, SUMMARY, CONTRADICTION, TEMPLATE_FILL, SURGICAL, GREETING, SPELLCHECK) и возвращает готовый ответ. | +| **Процессор запросов** (`query_processor.py`) | Выполняет обычный RAG-пайплайн (расширение, поиск, переранжирование, синтез, критика) для GENERAL, FACT, PROCEDURE, COMPARISON, CALCULATION. | +| **Менеджер индексации** (`indexing_manager.py`) | Сжимает большие документы перед индексацией и вызывает `KBService`. | | **HTTP-клиент** (`rag_client.py`) | Используется ботами-клиентами для отправки запросов в RAG-сервер. Асинхронный, с повторными попытками. Содержит методы vision() и transcribe(). | | **Сервисы** (`services/`) | Долгоживущие компоненты, предоставляющие API для работы с внешними системами (PostgreSQL, Qdrant, GigaChat, файлы). Используются только RAG-сервером и оркестратором. Не содержат бизнес-логики. | | **Функции** (`functions/`) | Независимые чистые функции, каждая решает одну конкретную задачу: классификация, расширение, суммаризация, проверка противоречий, самокритика, иерархическое резюмирование и т.д. Не имеют состояния, вызываются из оркестратора. | @@ -532,7 +549,6 @@ pytest tests/ -v 7. **Приветствие (GREETING)**: - «Привет» – бот отвечает вежливо, без поиска. - **Примеры использования для коробочных решений**: 1. **Поиск KPI по ключевым словам**: @@ -1297,6 +1313,11 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби - **Генерация коробочных решений по шаблону** – команды `!create`, `!template_save`, `!template_list`, `!template_delete`. - **Автоматическая индексация файлов в комнатах** – файлы индексируются без команды `!learn`. - **Полнотекстовый поиск по точным фрагментам** – поиск по номерам пунктов, кавычкам и инструкциям. +- **Рефакторинг оркестратора** – `RAGOrchestrator` разбит на менеджеры (HistoryManager, IntentRouter, QueryProcessor, IndexingManager), что повышает тестируемость и сопровождаемость. +- **Конфигурация на Pydantic** – вместо ручной загрузки используется `AppConfig` с валидацией и автодополнением. +- **Аутентификация через API-ключ** – все эндпоинты RAG-сервера защищены заголовком `X-API-Key` (кроме `/health`). +- **Автоматическая документация OpenAPI** – доступны Swagger UI (`/docs`) и ReDoc (`/redoc`), а также сырая спецификация (`/openapi.json`). +- **Генерация API-ключа** – в `.env` добавлена переменная `RAG_API_KEY`, которую можно сгенерировать командой `python3 -c "import secrets; print(secrets.token_urlsafe(32))"`. ### 4.2. Планируемые улучшения @@ -1314,27 +1335,21 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби Платформа Эфцекабот построена по принципу **«тонкий клиент – толстый сервер»**. Вся RAG-логика вынесена в отдельный HTTP-сервис – **RAG-сервер**, который обслуживает все клиенты (XMPP-боты, Telegram-боты, веб-интерфейсы и т.д.). Клиенты отправляют запросы на RAG-сервер через HTTP и не содержат RAG-логики. -Все модули, описанные ниже, расположены в каталоге `core/`. Часть из них работает на RAG-сервере, часть – в клиентах, часть является общими утилитами. +Все модули, описанные ниже, расположены в каталоге `rag/`. Часть из них работает на RAG-сервере, часть – в клиентах, часть является общими утилитами. ## 1. Модуль `rag_orchestrator.py` – оркестратор RAG-пайплайна -**Назначение:** это **сердце платформы**. Модуль координирует все этапы обработки запроса: -- Получение истории диалога из БД (PostgreSQL). -- Классификация намерений (intent). -- Расширение запроса (query expansion). -- Гибридный поиск (dense + sparse) в Qdrant. -- Переранжирование контекста (кросс-энкодер). -- Синтез ответа через GigaChat. -- Самокритика с перегенерацией. -- Сохранение истории диалога в БД. -- Иерархическое резюмирование длинной истории и больших документов. +**Назначение:** это **сердце платформы**. Модуль координирует все этапы обработки запроса через менеджеры: +- `HistoryManager` – получение и сжатие истории. +- `IntentRouter` – обработка специализированных намерений. +- `QueryProcessor` – обычный RAG-пайплайн (поиск, генерация, критика). +- `IndexingManager` – индексация документов с предварительным сжатием. **Место в архитектуре:** запускается внутри RAG-сервера при обработке HTTP-запроса `/rag/query`. Не зависит от XMPP или других протоколов – может быть использован в любом клиенте через HTTP API. **Ключевые методы:** - `process_query()` – основной метод, выполняет полный цикл обработки запроса. - `index_document()` – индексация документа (вызывается из `/rag/index`). Перед индексацией применяет иерархическое резюмирование, если документ слишком большой. -- `_compress_document_if_needed()` – внутренний метод для сжатия больших документов. **Особенности:** - Не содержит состояния, использует переданные сервисы и промпты. @@ -1347,21 +1362,26 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби **Эндпоинты:** -| Метод | Эндпоинт | Назначение | -|-|-|| -| POST | `/rag/query` | Выполнить RAG-запрос (история берется из БД) | -| POST | `/rag/index` | Проиндексировать документ | -| POST | `/rag/vision` | Распознать текст на изображении (OCR) | -| POST | `/rag/transcribe` | Транскрибировать аудио (SaluteSpeech) | -| GET | `/health` | Проверка состояния сервера | +| Метод | Эндпоинт | Назначение | Требует аутентификации | +|-|-|-|-| +| POST | `/rag/query` | Выполнить RAG-запрос (история берется из БД) | Да | +| POST | `/rag/index` | Проиндексировать документ | Да | +| POST | `/rag/vision` | Распознать текст на изображении (OCR) | Да | +| POST | `/rag/transcribe` | Транскрибировать аудио (SaluteSpeech) | Да | +| GET | `/health` | Проверка состояния сервера | Нет | +| GET | `/docs` | Swagger UI (интерактивная документация) | Нет | +| GET | `/redoc` | ReDoc (альтернативная документация) | Нет | +| GET | `/openapi.json` | OpenAPI-спецификация | Нет | **Место в архитектуре:** запускается как отдельный процесс (с помощью Uvicorn). Обслуживает все клиенты. Инициализирует все сервисы (БД, Qdrant, GigaChat) и создает экземпляр `RAGOrchestrator`. **Особенности:** - Использует Pydantic для валидации запросов и ответов. -- Поддерживае CORS для возможности запросов с других доменов. +- Поддерживает CORS для возможности запросов с других доменов. - Имеет встроенный healthcheck для мониторинга. - Эндпоинты `/rag/vision` и `/rag/transcribe` используют `FileService` для обработки медиафайлов. +- Аутентификация через API-ключ (`X-API-Key`). +- Полная OpenAPI-документация с примерами и кодами ошибок. ## 3. Модуль `rag_client.py` – HTTP-клиент для ботов @@ -1379,6 +1399,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби **Особенности:** - Асинхронный (aiohttp). - Поддерживает повторные попытки (retry) при сетевых ошибках. +- Автоматически добавляет заголовок `X-API-Key` с API-ключом. - Не содержит бизнес-логики – только HTTP-вызовы. ## 4. Модуль `rag_api.py` – локальный API-интерфейс @@ -1554,7 +1575,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби | Файл | Назначение | |-----|------| -| `indexing_worker.py` | Фоновый воркер, который обрабатывает очередь индексации файлов и URL, отправляя их на RAG-сервер через `RAGClient`. Обработка изображений и аудио теперь через RAG-сервер. | +| `indexing_worker.py` | Фоновый воркер, который обрабатывает очередь индексации файлов и URL, отправляя их на RAG-сервер через `RAGClient`. Обработка изображений и аудио теперь через RAG-сервер. | ## 8. Утилиты (каталог `utils/`) @@ -1562,7 +1583,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби | Файл | Назначение | |-----|------| -| `config_loader.py` | Загрузка `core.conf` и `bot.conf`, слияние, чтение `.env`. | +| `config_loader.py` | Загрузка `rag.conf` и `bot.conf`, слияние, чтение `.env`, создание `AppConfig` с помощью Pydantic. | | `logger.py` | Настройка логирования (уровни, вывод в файл и консоль). | | `layout_converter.py` | Конвертер раскладки клавиатуры (русская ↔ английская). | | `text_utils.py` | Разбиение текста на чанки (tiktoken + razdel), подсчет токенов (`count_tokens`). | @@ -1591,7 +1612,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби - **`rag.conf`** – общие настройки для всех ботов: параметры подключения к БД, Qdrant, GigaChat, настройки чанкинга, RAG, веб-скрапера, очистки, логирования. Добавлены параметры управления токенами и секция summarization. - **`bot.conf`** – настройки конкретного профиля бота (методолог, коробочник, персональный ассистент): JID, пароль, промпты, пути к данным, ключевые слова, администраторы, параметры функций (температура, лимиты). -Переменные окружения (пароли, ключи API) хранятся в `.env`. Примеры конфигурации предоставлены в файлах `core.conf.example`, `bot.conf.sample`, `env.example`. +Переменные окружения (пароли, ключи API) хранятся в `.env`. Примеры конфигурации предоставлены в файлах `rag.conf.example`, `bot.conf.sample`, `env.example`. ## 11. Схема базы данных (PostgreSQL) @@ -1601,4 +1622,48 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби - **`document_access`** – права доступа к личным документам. - **`history`** – история диалогов (личных и комнатных). - **`rooms`** – список MUC-комнат, в которых бот должен состоять. -- **`room_templates`** – шаблоны коробочных решений, сохраненные в комнатах. \ No newline at end of file +- **`room_templates`** – шаблоны коробочных решений, сохраненные в комнатах. + +--- + +# IV. Руководство по настройке аутентификации и доступу к API + +## 1. Генерация API-ключа + +Для защиты RAG-сервера используется API-ключ, который передаётся в заголовке `X-API-Key` при каждом запросе (кроме `/health`). Ключ должен быть уникальным и сложным. + +**Сгенерировать ключ можно одним из способов:** + +```bash +# Способ 1 – через Python (рекомендуется) +python3 -c "import secrets; print(secrets.token_urlsafe(32))" + +# Способ 2 – через openssl +openssl rand -base64 32 + +# Способ 3 – через /dev/urandom (Linux/FreeBSD) +cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 32; echo +``` + +Пример сгенерированного ключа: +``` +vK9pQz5RfT7mX2wY4nB8cD6gH3jF1aE5sL0oU9iP2qR7tY6wX4zA +``` + +## 2. Прописать ключ в переменные окружения + +В файл `.env` (в корне проекта) добавьте строку: + +```env +RAG_API_KEY=вставьте_сгенерированный_ключ_сюда +``` + +## 3. Использование в Swagger UI (документация) + +После запуска RAG-сервера откройте в браузере `http://localhost:8080/docs`. Нажмите кнопку **"Authorize"** (замочек) в правом верхнем углу, введите сгенерированный ключ в поле `APIKeyHeader`, нажмите **"Authorize"**. Теперь можно выполнять запросы прямо из интерфейса. + +## 4. Использование в боте + +В `bots/xmpp/client.py` при создании `RAGClient` автоматически передаётся `api_key=config.rag_api_key`. В `rag_client.py` ключ добавляется в заголовок `X-API-Key` при каждом запросе. + +--- \ No newline at end of file