Update 5 files

- /rag/config_models.py
- /rag/utils/config_loader.py
- /rag/rag_orchestrator.py
- /rag/rag_server.py
- /rag/rag_api.py
This commit is contained in:
Markov Andrey
2026-06-30 14:11:06 +00:00
parent a3f52888db
commit 068504c988
5 changed files with 395 additions and 102 deletions

View File

@@ -3,16 +3,12 @@
"""
RAG-сервер отдельный HTTP-сервис для обработки RAG-запросов.
Предоставляет API для выполнения RAG-запросов и индексации документов.
Этот сервер запускается как отдельный процесс и может обслуживать
несколько ботов и других систем одновременно.
ИСПОЛЬЗУЕТ: FastAPI для создания REST API и Uvicorn для запуска.
ИСТОРИЯ ХРАНИТСЯ НА СЕРВЕРЕ (в PostgreSQL).
ДОБАВЛЕНО:
- Эндпоинт /rag/vision для распознавания текста на изображениях (OCR)
- Эндпоинт /rag/transcribe для транскрибации аудио (SaluteSpeech)
- Использование Pydantic-модели AppConfig для конфигурации.
"""
import logging
@@ -32,16 +28,16 @@ from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field
import uvicorn
# Импортируем наши модули (теперь из пакета rag)
from rag.utils.config_loader import load_config
from rag.utils.logger import setup_logging
from rag.services.postgres_service import PostgresService
from rag.services.qdrant_service import QdrantService
from rag.services.embedding_service import EmbeddingService
from rag.services.kb_service import KBService
from rag.services.giga_client import GigaClient
from rag.services.file_service import FileService
from rag.rag_orchestrator import RAGOrchestrator
# Импорты наших модулей
from .utils.config_loader import load_config
from .utils.logger import setup_logging
from .services.postgres_service import PostgresService
from .services.qdrant_service import QdrantService
from .services.embedding_service import EmbeddingService
from .services.kb_service import KBService
from .services.giga_client import GigaClient
from .services.file_service import FileService
from .rag_orchestrator import RAGOrchestrator
logger = logging.getLogger(__name__)
@@ -114,7 +110,7 @@ class TranscribeResponse(BaseModel):
# ============================================================
_orchestrator: Optional[RAGOrchestrator] = None
_config: Optional[AppConfig] = None
_config = None
def get_orchestrator() -> RAGOrchestrator:
@@ -125,7 +121,7 @@ def get_orchestrator() -> RAGOrchestrator:
return _orchestrator
def init_orchestrator(config: AppConfig) -> RAGOrchestrator:
def init_orchestrator(config):
"""Инициализирует все сервисы и создаёт RAGOrchestrator."""
global _orchestrator, _config
_config = config
@@ -134,31 +130,31 @@ def init_orchestrator(config: AppConfig) -> RAGOrchestrator:
# ---- 1. Инициализация сервисов ----
# PostgreSQL (история, документы)
db = PostgresService(
host=config.database.host,
port=config.database.port,
user=config.database.user,
host=config.db_host,
port=config.db_port,
user=config.db_user,
password=config.db_password,
db_name=config.database.database
db_name=config.db_name
)
# Qdrant (векторный поиск)
qdrant = QdrantService(
host=config.qdrant.host,
port=config.qdrant.port,
grpc_port=config.qdrant.grpc_port,
collection_name=config.qdrant.collection,
vector_size=config.qdrant.vector_size,
distance=config.qdrant.distance,
host=config.qdrant_host,
port=config.qdrant_port,
grpc_port=config.qdrant_grpc_port,
collection_name=config.qdrant_collection,
vector_size=config.qdrant_vector_size,
distance=config.qdrant_distance,
prefer_grpc=False
)
# Эмбеддинги (GigaChat)
embedding = EmbeddingService(
api_key=config.gigachat_api_key,
model=config.embedding.model,
timeout=config.embedding.timeout,
cache_size=config.embedding.cache_size,
verify_ssl=config.embedding.verify_ssl_certs
model=config.embedding_model,
timeout=config.embedding_timeout,
cache_size=config.embedding_cache_size,
verify_ssl=config.embedding_verify_ssl
)
# База знаний (индексация, поиск)
@@ -166,19 +162,19 @@ def init_orchestrator(config: AppConfig) -> RAGOrchestrator:
db=db,
qdrant=qdrant,
embedding=embedding,
collection_name=config.qdrant.collection,
chunk_size_tokens=config.chunking.chunk_size_tokens,
overlap_tokens=config.chunking.overlap_tokens,
approx_chunk_chars=config.chunking.approx_chunk_chars,
approx_overlap_chars=config.chunking.approx_overlap_chars
collection_name=config.qdrant_collection,
chunk_size_tokens=config.chunk_size_tokens,
overlap_tokens=config.overlap_tokens,
approx_chunk_chars=config.chunking_approx_chunk_chars,
approx_overlap_chars=config.chunking_approx_overlap_chars
)
# GigaChat клиент (генерация)
giga = GigaClient(
api_key=config.gigachat_api_key,
model=config.gigachat.model_generation,
temperature=config.gigachat.temperature,
timeout=config.gigachat.timeout,
model=config.ai_model,
temperature=config.ai_temperature,
timeout=config.ai_timeout,
verify_ssl=False
)
@@ -186,11 +182,15 @@ def init_orchestrator(config: AppConfig) -> RAGOrchestrator:
files = FileService(config)
# ---- 2. Создание оркестратора ----
# Загружаем дефолтные промпты (из config.prompts_content)
default_prompts = config.prompts_content or {}
system_prompt = default_prompts.get('system')
if system_prompt:
default_prompts['system'] = system_prompt
# Загружаем дефолтные промпты (опционально)
default_prompts = {}
system_prompt_path = getattr(config, 'system_prompt_file', None)
if system_prompt_path and system_prompt_path.exists():
try:
with open(system_prompt_path, 'r', encoding='utf-8') as f:
default_prompts['system'] = f.read()
except Exception as e:
logger.warning(f"Не удалось загрузить системный промпт: {e}")
orchestrator = RAGOrchestrator(
db=db,
@@ -215,7 +215,7 @@ def init_orchestrator(config: AppConfig) -> RAGOrchestrator:
app = FastAPI(
title="RAG-сервер",
description="Единый сервис для RAG-обработки запросов и индексации документов",
version="1.0.0"
version="3.0.0"
)
# Разрешаем CORS для возможности запросов с других доменов (для тестов)
@@ -436,7 +436,7 @@ def main():
)
args = parser.parse_args()
# Загружаем конфигурацию с помощью новой функции load_config
# Загружаем конфигурацию через Pydantic
try:
config = load_config(args.profile_dir)
except Exception as e:
@@ -445,9 +445,7 @@ def main():
# Настраиваем логирование
log_level = getattr(logging, args.log_level.upper(), logging.INFO)
# Передаём путь к логу из конфига
log_file_path = config.log_file_path or Path("/tmp/rag_server.log")
setup_logging(config.name, log_file_path, log_level=log_level)
setup_logging(config.name, config.log_file_path, log_level=log_level)
logger.info(f"Запуск RAG-сервера с профилем {args.profile_dir}")
logger.info(f"Хост: {args.host}, порт: {args.port}")
@@ -461,7 +459,7 @@ def main():
# Запускаем Uvicorn
uvicorn.run(
"rag.rag_server:app", # теперь модуль из пакета rag
"rag.rag_server:app",
host=args.host,
port=args.port,
log_level=args.log_level,