Update file README.md

This commit is contained in:
Markov Andrey
2026-06-30 13:22:28 +00:00
parent 1078298671
commit 96de21687a

View File

@@ -8,9 +8,9 @@
**Архитектура**: платформа состоит из трех основных слоев: **Архитектура**: платформа состоит из трех основных слоев:
1. **RAG-ядро (HTTP-сервис)** — центральный компонент, выполняющий все этапы обработки запросов: классификацию намерений, расширение запроса, гибридный поиск (dense + sparse) в Qdrant, переранжирование через локальный кросс-энкодер, синтез ответа через GigaChat, самокритику и перегенерацию. Ядро также управляет индексацией документов и хранением истории диалогов в PostgreSQL. RAG-ядро реализовано как отдельный HTTP-сервер (FastAPI + Uvicorn), что позволяет использовать его для любых клиентов (XMPP, Telegram, Mastodon, веб-интерфейс, системы аналитики). 1. **RAG-ядро (HTTP-сервис)** — центральный компонент, выполняющий все этапы обработки запросов: классификацию намерений, расширение запроса, гибридный поиск (dense + sparse) в Qdrant, переранжирование через локальный кросс-энкодер, синтез ответа через GigaChat, самокритику и перегенерацию. Ядро также управляет индексацией документов и хранением истории диалогов в PostgreSQL. RAG-ядро реализовано как отдельный HTTP-сервер (FastAPI + Uvicorn), что позволяет использовать его для любых клиентов (XMPP, Telegram, Mastodon, веб-интерфейс, системы аналитики). RAG-сервер также предоставляет эндпоинты `/rag/vision` для распознавания текста на изображениях (OCR) и `/rag/transcribe` для транскрибации аудио, что централизует обработку медиафайлов.
2. **Тонкие XMPP-боты-клиенты** — каждый профиль (методолог, коробочник, персональный ассистент) представляет собой отдельный XMPP-клиент, который подключается к ejabberd, обрабатывает команды, принимает файлы и пересылает запросы пользователей в RAG-ядро по HTTP. Боты не содержат RAG-логики, не имеют локальной БД или Qdrant, а только загружают свои промпты и передают их в запросах. Это делает их легковесными и независимыми. 2. **Тонкие XMPP-боты-клиенты** — каждый профиль (методолог, коробочник, персональный ассистент) представляет собой отдельный XMPP-клиент, который подключается к ejabberd, обрабатывает команды, принимает файлы и пересылает запросы пользователей в RAG-ядро по HTTP. Боты не содержат RAG-логики, не имеют локальной БД или Qdrant, а только загружают свои промпты и передают их в запросах. Это делает их легковесными и независимыми. Вся обработка изображений и аудио выполняется на RAG-сервере, что дополнительно упрощает клиентов.
3. **Внешние системы хранения и API**: 3. **Внешние системы хранения и API**:
@@ -68,9 +68,9 @@
| Аспект | Влияние | | Аспект | Влияние |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Скорость** | GigaChat облачный API, задержка ~12 секунды на вызов. В текущей архитектуре все вызовы GigaChat происходят только из RAG-ядра (не из ботов). Пайплайн может делать 24 вызова на запрос (классификация, расширение, генерация, критика). Благодаря общему кэшированию (TTL 5 минут) для классификации и расширения, а также локальному кросс-энкодеру для переранжирования, количество вызовов GigaChat сокращено до минимума, что снижает итоговую задержку до 37 секунд. | | **Скорость** | GigaChat облачный API, задержка ~12 секунды на вызов. В текущей архитектуре все вызовы GigaChat происходят только из RAG-ядра (не из ботов). Пайплайн может делать 24 вызова на запрос (классификация, расширение, генерация, критика). Благодаря общему кэшированию (TTL 5 минут) для классификации и расширения, а также локальному кросс-энкодеру для переранжирования, количество вызовов GigaChat сокращено до минимума, что снижает итоговую задержку до 37 секунд. |
| **Экономия токенов** | Переранжирование и гибридный поиск (sparse + dense) уменьшают объём контекста. История диалога обрезается точно по токенам (через tiktoken) на стороне RAG-ядра, что позволяет эффективнее использовать контекстное окно. Централизация также позволяет агрегировать кэши и общие эмбеддинги, снижая общие затраты на токены. | | **Экономия токенов** | Переранжирование и гибридный поиск (sparse + dense) уменьшают объём контекста. История диалога обрезается точно по токенам (через tiktoken) на стороне RAG-ядра, что позволяет эффективнее использовать контекстное окно. Дополнительно внедрено иерархическое резюмирование для сжатия длинных диалогов и документов, что ещё больше экономит токены. Централизация также позволяет агрегировать кэши и общие эмбеддинги, снижая общие затраты на токены. |
| **Качество ответа** | GigaChat хорошо понимает русский язык, отлично справляется с деловой и технической терминологией. Но без точного промпта и контекста возможны галлюцинации самокритика и перегенерация, выполняемые в RAG-ядре, частично нивелируют это. Единые промпты для всех клиентов упрощают тонкую настройку качества. | | **Качество ответа** | GigaChat хорошо понимает русский язык, отлично справляется с деловой и технической терминологией. Но без точного промпта и контекста возможны галлюцинации самокритика и перегенерация, выполняемые в RAG-ядре, частично нивелируют это. Единые промпты для всех клиентов упрощают тонкую настройку качества. Иерархическое резюмирование помогает сохранить ключевую информацию в длинных документах. |
| **Надежность** | GigaChat имеет лимиты и может выдавать ошибки. RAG-ядро делает несколько попыток при эмбеддингах и генерации, а при отказе API возвращает сообщение о недоступности. Централизация позволяет реализовать единые политики повторных попыток и fallback. | | **Надежность** | GigaChat имеет лимиты и может выдавать ошибки. RAG-ядро делает несколько попыток при эмбеддингах и генерации, а при отказе API возвращает сообщение о недоступности. Централизация позволяет реализовать единые политики повторных попыток и fallback. RAGClient устойчив к сетевым ошибкам (ClientConnectorError и др.) |
| **Гибридные векторы** | GigaChat генерирует только dense-эмбеддинги, sparse-векторы вычисляются через FastEmbed (`Qdrant/bm25`) локально на сервере RAG-ядра. Это разгружает GigaChat и не требует дополнительных API, а также позволяет использовать общий кэш эмбеддингов для всех клиентов. | | **Гибридные векторы** | GigaChat генерирует только dense-эмбеддинги, sparse-векторы вычисляются через FastEmbed (`Qdrant/bm25`) локально на сервере RAG-ядра. Это разгружает GigaChat и не требует дополнительных API, а также позволяет использовать общий кэш эмбеддингов для всех клиентов. |
## 6. Архитектура проекта ## 6. Архитектура проекта
@@ -92,9 +92,11 @@
│ ▼ ▼ │ │ ▼ ▼ │
│ ┌────────────────────────────────────────────────────────────────┐ │ │ ┌────────────────────────────────────────────────────────────────┐ │
│ │ RAG-СЕРВЕР (HTTP API) │ │ │ │ RAG-СЕРВЕР (HTTP API) │ │
│ │ POST /rag/query выполнить RAG-запрос │ │ │ │ POST /rag/query выполнить RAG-запрос │ │
│ │ POST /rag/index проиндексировать документ │ │ │ │ POST /rag/index проиндексировать документ │ │
│ │ GET /health проверить состояния │ │ │ │ POST /rag/vision распознать текст на изображении (OCR) │ │
│ │ POST /rag/transcribe транскрибировать аудио │ │
│ │ GET /health проверить состояние │ │
│ └────────────────────────────────────────────────────────────────┘ │ │ └────────────────────────────────────────────────────────────────┘ │
│ │ │ │ │ │
│ ▼ │ │ ▼ │
@@ -108,6 +110,7 @@
│ │ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │ │ │ │ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │ │ └────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────┘ └──────────────────────────────────────────────────────────────────────┘
``` ```
**Ключевые компоненты:** **Ключевые компоненты:**
@@ -141,6 +144,7 @@
│ │ ├── extract_metrics.py # Извлечение числовых показателей (KPI) в JSON │ │ ├── extract_metrics.py # Извлечение числовых показателей (KPI) в JSON
│ │ ├── file_processor.py # Отправка файлов через HTTP Upload и обработка тегов [SURGICAL_REPLACE], [REWRITE], [FILE] │ │ ├── file_processor.py # Отправка файлов через HTTP Upload и обработка тегов [SURGICAL_REPLACE], [REWRITE], [FILE]
│ │ ├── generate_document.py # Генерация документа по шаблону (заполнение плейсхолдеров {{...}}) │ │ ├── generate_document.py # Генерация документа по шаблону (заполнение плейсхолдеров {{...}})
│ │ ├── hierarchical_summarize.py # Иерархическое резюмирование
│ │ ├── intent_classify.py # Классификация намерений пользователя (FACT, PROCEDURE, METRICS и др.) │ │ ├── intent_classify.py # Классификация намерений пользователя (FACT, PROCEDURE, METRICS и др.)
│ │ ├── rerank_context.py # Переранжирование контекста через локальный кросс-энкодер │ │ ├── rerank_context.py # Переранжирование контекста через локальный кросс-энкодер
│ │ └── summarize_document.py # Суммаризация документа (краткий пересказ ≤30%) │ │ └── summarize_document.py # Суммаризация документа (краткий пересказ ≤30%)
@@ -194,6 +198,7 @@
│ │ ├── consistency_check.txt # Проверка противоречий между фрагментами │ │ ├── consistency_check.txt # Проверка противоречий между фрагментами
│ │ ├── expand.txt # Расширение запроса (синонимы, аббревиатуры) │ │ ├── expand.txt # Расширение запроса (синонимы, аббревиатуры)
│ │ ├── generate_document.txt # Генерация документа по шаблону │ │ ├── generate_document.txt # Генерация документа по шаблону
│ │ ├── hierarchical_summary.txt # Иерархическое резюмирование
│ │ ├── intent_classify.txt # Классификация намерений │ │ ├── intent_classify.txt # Классификация намерений
│ │ ├── metrics_extract.txt # Извлечение KPI в JSON │ │ ├── metrics_extract.txt # Извлечение KPI в JSON
│ │ ├── quality_criteria.txt # Дополнительные критерии качества ответа │ │ ├── quality_criteria.txt # Дополнительные критерии качества ответа
@@ -211,6 +216,7 @@
│ ├── test_critique.py # Тесты самокритики │ ├── test_critique.py # Тесты самокритики
│ ├── test_expand_query.py # Тесты расширения запроса │ ├── test_expand_query.py # Тесты расширения запроса
│ ├── test_extract_metrics.py # Тесты извлечения метрик │ ├── test_extract_metrics.py # Тесты извлечения метрик
│ ├── test_hierarchical_summary.txt # Тесты иерархического резюмирования
│ ├── test_intent_classify.py # Тесты классификации намерений │ ├── test_intent_classify.py # Тесты классификации намерений
│ └── test_summarize.py # Тесты суммаризации │ └── test_summarize.py # Тесты суммаризации
@@ -263,6 +269,7 @@
2. RAG-сервер получает историю из PostgreSQL, ищет в Qdrant, генерирует ответ через GigaChat, выполняет самокритику. 2. RAG-сервер получает историю из PostgreSQL, ищет в Qdrant, генерирует ответ через GigaChat, выполняет самокритику.
3. **Ответ** → HTTP → XMPP-бот → ejabberd → пользователь. 3. **Ответ** → HTTP → XMPP-бот → ejabberd → пользователь.
4. **Индексация файла** → XMPP-бот → файл → HTTP → RAG-сервер → Qdrant + PostgreSQL. 4. **Индексация файла** → XMPP-бот → файл → HTTP → RAG-сервер → Qdrant + PostgreSQL.
5. **OCR/транскрибация** → XMPP-бот → медиафайл → HTTP → RAG-сервер (эндпоинты /rag/vision и /rag/transcribe) → распознанный текст → пользователь.
### 6.4. Тестирование ### 6.4. Тестирование
@@ -274,7 +281,8 @@
- суммаризацию (`test_summarize.py`), - суммаризацию (`test_summarize.py`),
- проверку противоречий (`test_consistency.py`), - проверку противоречий (`test_consistency.py`),
- самокритику (`test_critique.py`), - самокритику (`test_critique.py`),
- проверку орфографии (`test_check_spelling.py`). - проверку орфографии (`test_check_spelling.py`),
- иерархическое резюмирование (`test_hierarchical_summarize.py`).
**Запуск всех тестов:** **Запуск всех тестов:**
@@ -301,11 +309,11 @@ pytest tests/ -v
| Слой | Назначение | | Слой | Назначение |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **RAG-сервер** (`rag_server.py`) | HTTP-сервис, обрабатывающий все RAG-запросы. Содержит оркестратор (`RAGOrchestrator`), который выполняет классификацию, поиск, генерацию и самокритику. Запускается как отдельный процесс. Доступен по HTTP всем клиентам. | | **RAG-сервер** (`rag_server.py`) | HTTP-сервис, обрабатывающий все RAG-запросы. Содержит оркестратор (`RAGOrchestrator`), который выполняет классификацию, поиск, генерацию и самокритику. Также предоставляет эндпоинты для OCR и транскрибации. Запускается как отдельный процесс. Доступен по HTTP всем клиентам. |
| **RAG-оркестратор** (`rag_orchestrator.py`) | Ядро RAG-логики. Координирует вызовы всех функций (классификация, расширение, поиск, переранжирование, генерация, критика). Не зависит от XMPP. | | **RAG-оркестратор** (`rag_orchestrator.py`) | Ядро RAG-логики. Координирует вызовы всех функций (классификация, расширение, поиск, переранжирование, генерация, критика). Включает иерархическое резюмирование для сжатия истории и документов. Не зависит от XMPP. |
| **HTTP-клиент** (`rag_client.py`) | Используется ботами-клиентами для отправки запросов в RAG-сервер. Асинхронный, с повторными попытками. | | **HTTP-клиент** (`rag_client.py`) | Используется ботами-клиентами для отправки запросов в RAG-сервер. Асинхронный, с повторными попытками. Содержит методы vision() и transcribe(). |
| **Сервисы** (`services/`) | Долгоживущие компоненты, предоставляющие API для работы с внешними системами (PostgreSQL, Qdrant, GigaChat, файлы). Используются только RAG-сервером и оркестратором. Не содержат бизнес-логики. | | **Сервисы** (`services/`) | Долгоживущие компоненты, предоставляющие API для работы с внешними системами (PostgreSQL, Qdrant, GigaChat, файлы). Используются только RAG-сервером и оркестратором. Не содержат бизнес-логики. |
| **Функции** (`functions/`) | Независимые чистые функции, каждая решает одну конкретную задачу: классификация, расширение, суммаризация, проверка противоречий, самокритика и т.д. Не имеют состояния, вызываются из оркестратора. | | **Функции** (`functions/`) | Независимые чистые функции, каждая решает одну конкретную задачу: классификация, расширение, суммаризация, проверка противоречий, самокритика, иерархическое резюмирование и т.д. Не имеют состояния, вызываются из оркестратора. |
| **XMPP-боты-клиенты** (`xmpp/client.py`) | Тонкие клиенты, подключающиеся к ejabberd. Содержат только XMPP-логику, команды и загрузку промптов. Все RAG-запросы отправляют в RAG-сервер через `rag_client.py`. | | **XMPP-боты-клиенты** (`xmpp/client.py`) | Тонкие клиенты, подключающиеся к ejabberd. Содержат только XMPP-логику, команды и загрузку промптов. Все RAG-запросы отправляют в RAG-сервер через `rag_client.py`. |
| **Обработчики XMPP** (`handlers/`) | Реагируют на события XMPP (сообщения, приглашения, подписки). Маршрутизируют запросы: команды, файлы, AI-запросы (через RAG-клиент). | | **Обработчики XMPP** (`handlers/`) | Реагируют на события XMPP (сообщения, приглашения, подписки). Маршрутизируют запросы: команды, файлы, AI-запросы (через RAG-клиент). |
| **Воркеры** (`workers/`) | Фоновые асинхронные задачи: индексация файлов и URL (через HTTP-запросы в RAG-сервер). | | **Воркеры** (`workers/`) | Фоновые асинхронные задачи: индексация файлов и URL (через HTTP-запросы в RAG-сервер). |
@@ -1073,7 +1081,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
### **Работа с историей диалога** ### **Работа с историей диалога**
Бот автоматически сохраняет историю диалогов (личную и комнатную) в PostgreSQL. История используется для контекста при ответах. Команда `!reset` сбрасывает историю (личную или комнатную). Бот автоматически сохраняет историю диалогов (личную и комнатную) в PostgreSQL. История используется для контекста при ответах. Команда `!reset` сбрасывает историю (личную или комнатную). Для длинных диалогов применяется иерархическое резюмирование, чтобы сжать историю и не превысить лимит токенов.
### **Поддержка вложенных файлов и архивов** ### **Поддержка вложенных файлов и архивов**
@@ -1085,7 +1093,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
### **Работа с изображениями (Vision)** ### **Работа с изображениями (Vision)**
Если загружено изображение (JPEG, PNG, BMP, TIFF) и в конфиге включена опция `vision: true`, бот отправляет изображение в GigaChat Vision API для анализа (распознавание текста, описание содержимого). Результат отправляется в чат. Если загружено изображение (JPEG, PNG, BMP, TIFF) и в конфиге включена опция `vision: true`, бот отправляет изображение на RAG-сервер (эндпоинт `/rag/vision`) для распознавания текста (OCR). Распознанный текст отправляется в чат.
### **Работа с таблицами в DOCX** ### **Работа с таблицами в DOCX**
@@ -1319,12 +1327,14 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
- Синтез ответа через GigaChat. - Синтез ответа через GigaChat.
- Самокритика с перегенерацией. - Самокритика с перегенерацией.
- Сохранение истории диалога в БД. - Сохранение истории диалога в БД.
- Иерархическое резюмирование длинной истории и больших документов.
**Место в архитектуре:** запускается внутри RAG-сервера при обработке HTTP-запроса `/rag/query`. Не зависит от XMPP или других протоколов может быть использован в любом клиенте через HTTP API. **Место в архитектуре:** запускается внутри RAG-сервера при обработке HTTP-запроса `/rag/query`. Не зависит от XMPP или других протоколов может быть использован в любом клиенте через HTTP API.
**Ключевые методы:** **Ключевые методы:**
- `process_query()` основной метод, выполняет полный цикл обработки запроса. - `process_query()` основной метод, выполняет полный цикл обработки запроса.
- `index_document()` индексация документа (вызывается из `/rag/index`). - `index_document()` индексация документа (вызывается из `/rag/index`). Перед индексацией применяет иерархическое резюмирование, если документ слишком большой.
- `_compress_document_if_needed()` внутренний метод для сжатия больших документов.
**Особенности:** **Особенности:**
- Не содержит состояния, использует переданные сервисы и промпты. - Не содержит состояния, использует переданные сервисы и промпты.
@@ -1339,9 +1349,11 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
| Метод | Эндпоинт | Назначение | | Метод | Эндпоинт | Назначение |
|-|-|| |-|-||
| POST | `/rag/query` | Выполнить RAG-запрос (история берется из БД) | | POST | `/rag/query` | Выполнить RAG-запрос (история берется из БД) |
| POST | `/rag/index` | Проиндексировать документ | | POST | `/rag/index` | Проиндексировать документ |
| GET | `/health` | Проверка состояния сервера | | POST | `/rag/vision` | Распознать текст на изображении (OCR) |
| POST | `/rag/transcribe` | Транскрибировать аудио (SaluteSpeech) |
| GET | `/health` | Проверка состояния сервера |
**Место в архитектуре:** запускается как отдельный процесс (с помощью Uvicorn). Обслуживает все клиенты. Инициализирует все сервисы (БД, Qdrant, GigaChat) и создает экземпляр `RAGOrchestrator`. **Место в архитектуре:** запускается как отдельный процесс (с помощью Uvicorn). Обслуживает все клиенты. Инициализирует все сервисы (БД, Qdrant, GigaChat) и создает экземпляр `RAGOrchestrator`.
@@ -1349,6 +1361,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
- Использует Pydantic для валидации запросов и ответов. - Использует Pydantic для валидации запросов и ответов.
- Поддерживае CORS для возможности запросов с других доменов. - Поддерживае CORS для возможности запросов с других доменов.
- Имеет встроенный healthcheck для мониторинга. - Имеет встроенный healthcheck для мониторинга.
- Эндпоинты `/rag/vision` и `/rag/transcribe` используют `FileService` для обработки медиафайлов.
## 3. Модуль `rag_client.py` HTTP-клиент для ботов ## 3. Модуль `rag_client.py` HTTP-клиент для ботов
@@ -1357,6 +1370,9 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
**Методы:** **Методы:**
- `query()` отправляет запрос на `/rag/query`. - `query()` отправляет запрос на `/rag/query`.
- `index_document()` отправляет запрос на `/rag/index`. - `index_document()` отправляет запрос на `/rag/index`.
- `vision(file_path)` отправляет изображение на `/rag/vision`.
- `transcribe(file_path)` отправляет аудио на `/rag/transcribe`.
- `health_check()` проверяет доступность сервера.
**Место в архитектуре:** встраивается в клиентские приложения вместо локального вызова RAG-логики. **Место в архитектуре:** встраивается в клиентские приложения вместо локального вызова RAG-логики.
@@ -1377,7 +1393,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
### 5.1. `intent_classify.py` классификация намерений ### 5.1. `intent_classify.py` классификация намерений
**Назначение:** определяет тип запроса пользователя (FACT, PROCEDURE, METRICS, SUMMARY, CONTRADICTION, SURGICAL, GREETING, GENERAL, SPELLCHECK, TEMPLATE_FILL) по тексту запроса. **Назначение:** определяет тип запроса пользователя (FACT, PROCEDURE, METRICS, SUMMARY, CONTRADICTION, SURGICAL, GREETING, GENERAL, SPELLCHECK, TEMPLATE_FILL) по тексту запроса. **Примеры в промпте перемешаны для уменьшения эффекта якорения.**
**Место в архитектуре:** вызывается из `RAGOrchestrator` перед поиском. **Место в архитектуре:** вызывается из `RAGOrchestrator` перед поиском.
@@ -1419,7 +1435,21 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
**Вход:** текст, название, промпт, конфиг. **Вход:** текст, название, промпт, конфиг.
**Выход:** строка с кратким изложением. **Выход:** строка с кратким изложением.
### 5.5. `check_consistency.py` проверка противоречий ### 5.5. hierarchical_summarize.py иерархическое резюмирование (новое)
**Назначение:** сжимает очень большие тексты (документы, историю диалога) с помощью рекурсивного резюмирования блоков. Разбивает текст на блоки по предложениям, резюмирует каждый блок через GigaChat, объединяет результаты, и при необходимости повторяет процесс рекурсивно до достижения целевой длины.
**Место в архитектуре:** вызывается из RAGOrchestrator:
- В `process_query` для сжатия длинной истории диалога.
- В `index_document` для сжатия больших документов перед индексацией (через метод `_compress_document_if_needed`).
**Как работает:** использует промпт (hierarchical_summary.txt) для каждого блока.
**Вход:** текст, целевой размер в токенах, размер блока, глубина.
**Выход:** сжатый текст.
### 5.6. `check_consistency.py` проверка противоречий
**Назначение:** находит логические, числовые или терминологические расхождения в разных фрагментах текста. **Назначение:** находит логические, числовые или терминологические расхождения в разных фрагментах текста.
@@ -1430,7 +1460,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
**Вход:** список фрагментов, запрос, промпт, конфиг. **Вход:** список фрагментов, запрос, промпт, конфиг.
**Выход:** строка с результатом проверки. **Выход:** строка с результатом проверки.
### 5.6. `critique_answer.py` самокритика ответа ### 5.7. `critique_answer.py` самокритика ответа
**Назначение:** оценивает качество сгенерированного ответа по пяти критериям (соответствие источнику, отсутствие галлюцинаций, стиль, логика, запрет внешних знаний). **Назначение:** оценивает качество сгенерированного ответа по пяти критериям (соответствие источнику, отсутствие галлюцинаций, стиль, логика, запрет внешних знаний).
@@ -1441,7 +1471,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
**Вход:** запрос, контекст, ответ, промпт, конфиг. **Вход:** запрос, контекст, ответ, промпт, конфиг.
**Выход:** `True` (ответ хороший) или `False` (есть замечания). **Выход:** `True` (ответ хороший) или `False` (есть замечания).
### 5.7. `rerank_context.py` переранжирование контекста ### 5.8. `rerank_context.py` переранжирование контекста
**Назначение:** отбирает только релевантные фрагменты из результатов поиска, отбрасывая шум. Использует локальный кросс-энкодер вместо LLM. **Назначение:** отбирает только релевантные фрагменты из результатов поиска, отбрасывая шум. Использует локальный кросс-энкодер вместо LLM.
@@ -1452,7 +1482,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
**Вход:** запрос, контекст, конфиг. **Вход:** запрос, контекст, конфиг.
**Выход:** отфильтрованный контекст (строка). **Выход:** отфильтрованный контекст (строка).
### 5.8. `file_processor.py` обработка файлов ### 5.9. `file_processor.py` обработка файлов
**Назначение:** отправка файлов пользователю через HTTP Upload (XEP-0363) и обработка тегов `[SURGICAL_REPLACE]`, `[REWRITE]`, `[FILE]` из ответа AI. **Назначение:** отправка файлов пользователю через HTTP Upload (XEP-0363) и обработка тегов `[SURGICAL_REPLACE]`, `[REWRITE]`, `[FILE]` из ответа AI.
@@ -1463,7 +1493,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
**Вход:** ответ AI, JID пользователя, путь к файлу. **Вход:** ответ AI, JID пользователя, путь к файлу.
**Выход:** отправленный файл или сообщение об ошибке. **Выход:** отправленный файл или сообщение об ошибке.
### 5.9. `generate_document.py` генерация по шаблону ### 5.10. `generate_document.py` генерация по шаблону
**Назначение:** заполняет плейсхолдеры `{{название}}` в шаблоне документа на основе данных из базы знаний. **Назначение:** заполняет плейсхолдеры `{{название}}` в шаблоне документа на основе данных из базы знаний.
@@ -1483,8 +1513,8 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
| `postgres_service.py` | Пул соединений с PostgreSQL. CRUD для документов, истории диалогов, комнат, шаблонов, прав доступа. | | `postgres_service.py` | Пул соединений с PostgreSQL. CRUD для документов, истории диалогов, комнат, шаблонов, прав доступа. |
| `qdrant_service.py` | Векторная БД. Создание коллекции, гибридный поиск (dense + sparse), полнотекстовый поиск, удаление по doc_id. | | `qdrant_service.py` | Векторная БД. Создание коллекции, гибридный поиск (dense + sparse), полнотекстовый поиск, удаление по doc_id. |
| `embedding_service.py` | Эмбеддинги GigaChat. Одиночные/пакетные запросы, кэширование (`lru_cache`), обрезка текста до 800 символов. | | `embedding_service.py` | Эмбеддинги GigaChat. Одиночные/пакетные запросы, кэширование (`lru_cache`), обрезка текста до 800 символов. |
| `kb_service.py` | База знаний. Индексация документов (разбиение на чанки, получение эмбеддингов, сохранение в Qdrant и PostgreSQL), поиск, управление доступом. | | `kb_service.py` | База знаний. Индексация документов (разбиение на чанки, получение эмбеддингов, сохранение в Qdrant и PostgreSQL), поиск, управление доступом. Транзакционная индексация с флагом `indexed`. |
| `file_service.py` | Извлечение текста из файлов (DOCX, PDF, XLSX, PPTX, изображения, аудио, архивы). Хирургическая замена, создание DOCX. | | `file_service.py` | Извлечение текста из файлов (DOCX, PDF, XLSX, PPTX, изображения, аудио, архивы). Хирургическая замена, создание DOCX. Используется на RAG-сервере для OCR и транскрибации. |
| `giga_client.py` | Клиент GigaChat. Методы `chat()` и `upload_file()` без бизнес-логики. | | `giga_client.py` | Клиент GigaChat. Методы `chat()` и `upload_file()` без бизнес-логики. |
| `reranker_service.py` | Кросс-энкодер для переранжирования (локально). Ленивая загрузка модели. | | `reranker_service.py` | Кросс-энкодер для переранжирования (локально). Ленивая загрузка модели. |
@@ -1498,7 +1528,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
|-----|------| |-----|------|
| `metrics_handler.py` | Счетчики (сообщения, файлы, AI-запросы, ошибки). | | `metrics_handler.py` | Счетчики (сообщения, файлы, AI-запросы, ошибки). |
| `message_handler.py` | Маршрутизация входящих сообщений (использует `RAGClient`). | | `message_handler.py` | Маршрутизация входящих сообщений (использует `RAGClient`). |
| `file_handler.py` | Скачивание файлов и постановка в очередь индексации. | | `file_handler.py` | Скачивание файлов и постановка в очередь индексации. Убраны прямые вызовы GigaChat теперь всё через RAGClient. |
| `room_handler.py` | MUC комнаты (приглашения, вход, переподключение). | | `room_handler.py` | MUC комнаты (приглашения, вход, переподключение). |
| `subscription_handler.py` | Подписки (roster subscription). | | `subscription_handler.py` | Подписки (roster subscription). |
| `health_handler.py` | Очистка файлов, healthcheck БД/Qdrant (для клиентов). | | `health_handler.py` | Очистка файлов, healthcheck БД/Qdrant (для клиентов). |
@@ -1524,7 +1554,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
| Файл | Назначение | | Файл | Назначение |
|-----|------| |-----|------|
| `indexing_worker.py` | Фоновый воркер, который обрабатывает очередь индексации файлов и URL, отправляя их на RAG-сервер через `RAGClient`. | | `indexing_worker.py` | Фоновый воркер, который обрабатывает очередь индексации файлов и URL, отправляя их на RAG-сервер через `RAGClient`. Обработка изображений и аудио теперь через RAG-сервер. |
## 8. Утилиты (каталог `utils/`) ## 8. Утилиты (каталог `utils/`)
@@ -1550,6 +1580,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
- `test_consistency.py` проверка противоречий. - `test_consistency.py` проверка противоречий.
- `test_critique.py` самокритика. - `test_critique.py` самокритика.
- `test_check_spelling.py` проверка орфографии. - `test_check_spelling.py` проверка орфографии.
- `test_hierarchical_summarize.py` иерархическое резюмирование.
Тесты используют `pytest` и `pytest-asyncio`, не требуют реального подключения к внешним сервисам (используются моки). Запуск: `pytest tests/ -v`. Тесты используют `pytest` и `pytest-asyncio`, не требуют реального подключения к внешним сервисам (используются моки). Запуск: `pytest tests/ -v`.
@@ -1557,7 +1588,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
Платформа использует два основных конфигурационных файла: Платформа использует два основных конфигурационных файла:
- **`core.conf`** общие настройки для всех ботов: параметры подключения к БД, Qdrant, GigaChat, настройки чанкинга, RAG, веб-скрапера, очистки, логирования. - **`rag.conf`** общие настройки для всех ботов: параметры подключения к БД, Qdrant, GigaChat, настройки чанкинга, RAG, веб-скрапера, очистки, логирования. Добавлены параметры управления токенами и секция summarization.
- **`bot.conf`** настройки конкретного профиля бота (методолог, коробочник, персональный ассистент): JID, пароль, промпты, пути к данным, ключевые слова, администраторы, параметры функций (температура, лимиты). - **`bot.conf`** настройки конкретного профиля бота (методолог, коробочник, персональный ассистент): JID, пароль, промпты, пути к данным, ключевые слова, администраторы, параметры функций (температура, лимиты).
Переменные окружения (пароли, ключи API) хранятся в `.env`. Примеры конфигурации предоставлены в файлах `core.conf.example`, `bot.conf.sample`, `env.example`. Переменные окружения (пароли, ключи API) хранятся в `.env`. Примеры конфигурации предоставлены в файлах `core.conf.example`, `bot.conf.sample`, `env.example`.
@@ -1566,7 +1597,7 @@ Qdrant вернул 30 фрагментов. Кросс-энкодер отби
Схема создается автоматически через `schema.sql` и включает таблицы: Схема создается автоматически через `schema.sql` и включает таблицы:
- **`documents`** метаданные документов (источник, владелец, глобальный/комнатный флаг, хеш, коллекция Qdrant). - **`documents`** метаданные документов (источник, владелец, глобальный/комнатный флаг, хеш, коллекция Qdrant). Добавлена колонка indexed `BOOLEAN DEFAULT FALSE` для транзакционности индексации.
- **`document_access`** права доступа к личным документам. - **`document_access`** права доступа к личным документам.
- **`history`** история диалогов (личных и комнатных). - **`history`** история диалогов (личных и комнатных).
- **`rooms`** список MUC-комнат, в которых бот должен состоять. - **`rooms`** список MUC-комнат, в которых бот должен состоять.