Files
fckbot/rag/rag_api.py
Markov Andrey a3f52888db Update 6 files
- /rag/history_manager.py
- /rag/query_processor.py
- /rag/rag_orchestrator.py
- /rag/rag_api.py
- /rag/rag_server.py
- /rag/__init__.py
2026-06-30 14:04:31 +00:00

150 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
Единый API-интерфейс для работы с RAG-оркестратором.
Используется ботами для вызова RAG-логики без необходимости
знать внутреннее устройство оркестратора.
Этот класс является прослойкой (facade) между ботами и RAGOrchestrator.
В будущем он может быть легко заменён на HTTP-клиент,
если оркестратор будет вынесен в отдельный сервис.
Сейчас этот файл может использоваться для локальной работы,
но в новой архитектуре мы используем RAGClient (HTTP),
поэтому данный класс является опциональным.
"""
import logging
from typing import Optional, Dict, List, Any
from rag.rag_orchestrator import RAGOrchestrator
from rag.services.kb_service import KBService
from rag.services.giga_client import GigaClient
from rag.services.file_service import FileService
from rag.services.postgres_service import PostgresService
from rag.config_models import AppConfig
logger = logging.getLogger(__name__)
class RAGAPI:
"""
Единый API-интерфейс для RAG-функциональности.
Создаёт и содержит экземпляр RAGOrchestrator.
Предоставляет методы для выполнения запросов и индексации документов.
"""
def __init__(
self,
db: PostgresService,
qdrant,
embedding,
kb: KBService,
giga: GigaClient,
files: FileService,
config: AppConfig,
default_prompts: Optional[Dict[str, str]] = None
):
"""
Инициализация API.
Аргументы:
db: сервис PostgreSQL (PostgresService)
qdrant: сервис Qdrant (QdrantService)
embedding: сервис эмбеддингов (EmbeddingService)
kb: сервис базы знаний (KBService)
giga: клиент GigaChat (GigaClient)
files: сервис файлов (FileService)
config: объект конфигурации (AppConfig)
default_prompts: словарь промптов по умолчанию.
Используется, если в запросе не переданы свои промпты.
"""
self.config = config
self.default_prompts = default_prompts or {}
# Создаём оркестратор с переданными сервисами
self.orchestrator = RAGOrchestrator(
db=db,
qdrant=qdrant,
embedding=embedding,
kb=kb,
giga=giga,
files=files,
config=config,
default_prompts=self.default_prompts
)
logger.info("RAGAPI инициализирован")
async def query(
self,
query: str,
user_jid: str,
room_jid: Optional[str],
prompts: Optional[Dict[str, str]] = None,
intent_override: Optional[str] = None,
last_file_path: Optional[str] = None,
last_file_text: Optional[str] = None,
) -> Dict[str, Any]:
"""
Выполняет RAG-запрос через оркестратор.
ИСТОРИЯ НЕ ПЕРЕДАЁТСЯ оркестратор получает её из БД.
"""
try:
if prompts is None:
prompts = self.default_prompts.copy()
result = await self.orchestrator.process_query(
query=query,
user_jid=user_jid,
room_jid=room_jid,
prompts=prompts,
intent_override=intent_override,
last_file_path=last_file_path,
last_file_text=last_file_text
)
logger.debug(f"RAGAPI.query успешно выполнен для {user_jid}, intent={result.get('intent')}")
return result
except Exception as e:
logger.error(f"Ошибка в RAGAPI.query: {e}", exc_info=True)
return {
"answer": f"⚠️ Произошла ошибка при обработке запроса: {str(e)}",
"intent": "ERROR",
"context": "",
"sources": [],
"confidence": None,
"error": str(e)
}
async def index_document(
self,
file_name: str,
file_text: str,
user_jid: str,
room_jid: Optional[str],
is_global: bool = False,
title: Optional[str] = None,
metadata: Optional[Dict] = None,
file_hash: Optional[str] = None,
update_if_exists: bool = True
) -> Dict[str, Any]:
"""Индексирует документ через оркестратор."""
try:
result = await self.orchestrator.index_document(
file_name=file_name,
file_text=file_text,
user_jid=user_jid,
room_jid=room_jid,
is_global=is_global,
title=title,
metadata=metadata,
file_hash=file_hash,
update_if_exists=update_if_exists
)
logger.info(f"Документ {file_name} проиндексирован, doc_id={result.get('doc_id')}")
return result
except Exception as e:
logger.error(f"Ошибка в RAGAPI.index_document: {e}", exc_info=True)
return {"doc_id": None, "chunk_count": 0, "error": str(e)}
def close(self):
"""Закрывает ресурсы (если необходимо)."""
logger.debug("RAGAPI закрывается")