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
This commit is contained in:
@@ -1,16 +1,12 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Пакет core – общий код для всех компонентов платформы Эфцекабот.
|
Пакет rag – RAG-ядро платформы Эфцекабот.
|
||||||
Содержит:
|
Содержит:
|
||||||
- RAG-сервер и оркестратор,
|
- RAG-сервер и оркестратор,
|
||||||
- HTTP-клиент для ботов,
|
|
||||||
- сервисы (PostgreSQL, Qdrant, GigaChat),
|
- сервисы (PostgreSQL, Qdrant, GigaChat),
|
||||||
- функции (классификация, суммаризация, проверка орфографии и др.),
|
- функции (классификация, суммаризация, проверка орфографии и др.),
|
||||||
- обработчики XMPP-событий,
|
|
||||||
- команды ботов,
|
|
||||||
- фоновые воркеры,
|
|
||||||
- утилиты.
|
- утилиты.
|
||||||
Используется как RAG-ядром, так и тонкими XMPP-клиентами-профилями.
|
Используется как HTTP-сервис.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = "3.0.0"
|
__version__ = "3.0.0"
|
||||||
|
|||||||
@@ -13,10 +13,11 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import List, Dict, Optional, Any
|
from typing import List, Dict, Optional, Any
|
||||||
|
|
||||||
from core.services.postgres_service import PostgresService
|
from rag.services.postgres_service import PostgresService
|
||||||
from core.services.giga_client import GigaClient
|
from rag.services.giga_client import GigaClient
|
||||||
from core.utils.text_utils import count_tokens
|
from rag.utils.text_utils import count_tokens
|
||||||
from core.functions.hierarchical_summarize import hierarchical_summarize
|
from rag.functions.hierarchical_summarize import hierarchical_summarize
|
||||||
|
from rag.config_models import AppConfig
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ class HistoryManager:
|
|||||||
self,
|
self,
|
||||||
db: PostgresService,
|
db: PostgresService,
|
||||||
giga: GigaClient,
|
giga: GigaClient,
|
||||||
config,
|
config: AppConfig,
|
||||||
default_prompts: Optional[Dict[str, str]] = None
|
default_prompts: Optional[Dict[str, str]] = None
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
@@ -39,7 +40,7 @@ class HistoryManager:
|
|||||||
Аргументы:
|
Аргументы:
|
||||||
db: сервис PostgreSQL (для получения и сохранения истории)
|
db: сервис PostgreSQL (для получения и сохранения истории)
|
||||||
giga: клиент GigaChat (для сжатия истории)
|
giga: клиент GigaChat (для сжатия истории)
|
||||||
config: объект конфигурации (BotConfig)
|
config: объект конфигурации (AppConfig)
|
||||||
default_prompts: словарь промптов по умолчанию (нужен для hierarchical_summary)
|
default_prompts: словарь промптов по умолчанию (нужен для hierarchical_summary)
|
||||||
"""
|
"""
|
||||||
self.db = db
|
self.db = db
|
||||||
@@ -47,10 +48,6 @@ class HistoryManager:
|
|||||||
self.config = config
|
self.config = config
|
||||||
self.default_prompts = default_prompts or {}
|
self.default_prompts = default_prompts or {}
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
|
||||||
# Получение и форматирование истории
|
|
||||||
# ------------------------------------------------------------------
|
|
||||||
|
|
||||||
async def get_history(
|
async def get_history(
|
||||||
self,
|
self,
|
||||||
user_jid: str,
|
user_jid: str,
|
||||||
@@ -116,7 +113,7 @@ class HistoryManager:
|
|||||||
if not prompt_template:
|
if not prompt_template:
|
||||||
# Пытаемся загрузить из файла, если он есть
|
# Пытаемся загрузить из файла, если он есть
|
||||||
try:
|
try:
|
||||||
prompt_path = self.config.prompts_dir / 'hierarchical_summary.txt'
|
prompt_path = self.config.prompts_dir_path / 'hierarchical_summary.txt'
|
||||||
with open(prompt_path, 'r', encoding='utf-8') as f:
|
with open(prompt_path, 'r', encoding='utf-8') as f:
|
||||||
prompt_template = f.read()
|
prompt_template = f.read()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -130,11 +127,11 @@ class HistoryManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Параметры сжатия из конфига
|
# Параметры сжатия из конфига
|
||||||
summarization_config = getattr(self.config, 'summarization', {})
|
summarization_config = self.config.summarization
|
||||||
target_tokens = summarization_config.get('target_tokens_after_summary', max_tokens)
|
target_tokens = summarization_config.target_tokens_after_summary
|
||||||
chunk_size = summarization_config.get('chunk_size_tokens', 500)
|
chunk_size = summarization_config.chunk_size_tokens
|
||||||
max_depth = summarization_config.get('max_depth', 2)
|
max_depth = summarization_config.max_depth
|
||||||
temperature = getattr(self.config, 'ai_temperature', 0.1)
|
temperature = self.config.ai.temperature
|
||||||
|
|
||||||
try:
|
try:
|
||||||
compressed_text = await hierarchical_summarize(
|
compressed_text = await hierarchical_summarize(
|
||||||
|
|||||||
@@ -9,12 +9,13 @@ import logging
|
|||||||
import re
|
import re
|
||||||
from typing import Optional, Dict, List, Any
|
from typing import Optional, Dict, List, Any
|
||||||
|
|
||||||
from core.services.giga_client import GigaClient
|
from rag.services.giga_client import GigaClient
|
||||||
from core.services.kb_service import KBService
|
from rag.services.kb_service import KBService
|
||||||
from core.functions.expand_query import expand_query
|
from rag.functions.expand_query import expand_query
|
||||||
from core.functions.rerank_context import rerank_context
|
from rag.functions.rerank_context import rerank_context
|
||||||
from core.functions.critique_answer import critique_answer
|
from rag.functions.critique_answer import critique_answer
|
||||||
from core.utils.text_utils import count_tokens
|
from rag.utils.text_utils import count_tokens
|
||||||
|
from rag.config_models import AppConfig
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ class QueryProcessor:
|
|||||||
self,
|
self,
|
||||||
giga: GigaClient,
|
giga: GigaClient,
|
||||||
kb: KBService,
|
kb: KBService,
|
||||||
config,
|
config: AppConfig,
|
||||||
default_prompts: Optional[Dict[str, str]] = None
|
default_prompts: Optional[Dict[str, str]] = None
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
@@ -37,7 +38,7 @@ class QueryProcessor:
|
|||||||
Аргументы:
|
Аргументы:
|
||||||
giga: клиент GigaChat
|
giga: клиент GigaChat
|
||||||
kb: сервис базы знаний
|
kb: сервис базы знаний
|
||||||
config: объект конфигурации
|
config: объект конфигурации (AppConfig)
|
||||||
default_prompts: словарь промптов по умолчанию
|
default_prompts: словарь промптов по умолчанию
|
||||||
"""
|
"""
|
||||||
self.giga = giga
|
self.giga = giga
|
||||||
@@ -73,18 +74,20 @@ class QueryProcessor:
|
|||||||
Словарь с ключами 'answer', 'context', 'sources', 'confidence'
|
Словарь с ключами 'answer', 'context', 'sources', 'confidence'
|
||||||
"""
|
"""
|
||||||
# 1. Расширение запроса
|
# 1. Расширение запроса
|
||||||
|
expand_prompt = prompts.get('expand', '')
|
||||||
expanded = await expand_query(
|
expanded = await expand_query(
|
||||||
giga=self.giga,
|
giga=self.giga,
|
||||||
query=query,
|
query=query,
|
||||||
prompt_text=prompts.get('expand', ''),
|
prompt_text=expand_prompt,
|
||||||
bot_config=self.config
|
bot_config=self.config
|
||||||
)
|
)
|
||||||
search_query = expanded if expanded and expanded != query else query
|
search_query = expanded if expanded and expanded != query else query
|
||||||
|
|
||||||
# 2. Поиск релевантного контекста в базе знаний
|
# 2. Поиск релевантного контекста в базе знаний
|
||||||
|
top_k = self.config.rag.default_top_k
|
||||||
context = await self.kb.find_relevant_info(
|
context = await self.kb.find_relevant_info(
|
||||||
search_query, user_jid, room_jid,
|
search_query, user_jid, room_jid,
|
||||||
top_k=getattr(self.config, 'rag_default_top_k', 30)
|
top_k=top_k
|
||||||
)
|
)
|
||||||
logger.info(f"Найден контекст длиной {len(context)} символов (room={room_jid})")
|
logger.info(f"Найден контекст длиной {len(context)} символов (room={room_jid})")
|
||||||
|
|
||||||
@@ -103,7 +106,7 @@ class QueryProcessor:
|
|||||||
context = ""
|
context = ""
|
||||||
|
|
||||||
# 4. Переранжирование контекста (если включено и контекст достаточно длинный)
|
# 4. Переранжирование контекста (если включено и контекст достаточно длинный)
|
||||||
rerank_min_length = getattr(self.config, 'rerank_min_length', 5000)
|
rerank_min_length = self.config.rag.rerank_min_length
|
||||||
if intent != "FACT" and len(context) > rerank_min_length:
|
if intent != "FACT" and len(context) > rerank_min_length:
|
||||||
context = await rerank_context(
|
context = await rerank_context(
|
||||||
bot=None,
|
bot=None,
|
||||||
@@ -130,16 +133,17 @@ class QueryProcessor:
|
|||||||
logger.debug(f"Полный запрос к GigaChat (первые 500 символов): {full_query[:500]}")
|
logger.debug(f"Полный запрос к GigaChat (первые 500 символов): {full_query[:500]}")
|
||||||
|
|
||||||
# 6. Генерация ответа
|
# 6. Генерация ответа
|
||||||
|
temperature = self.config.ai.temperature
|
||||||
answer = await self.giga.chat(
|
answer = await self.giga.chat(
|
||||||
history=history,
|
history=history,
|
||||||
query=full_query,
|
query=full_query,
|
||||||
system_prompt=system_prompt,
|
system_prompt=system_prompt,
|
||||||
file_id=None,
|
file_id=None,
|
||||||
temperature=getattr(self.config, 'ai_temperature', 0.1)
|
temperature=temperature
|
||||||
)
|
)
|
||||||
|
|
||||||
# 7. Самокритика (если включена)
|
# 7. Самокритика (если включена)
|
||||||
if getattr(self.config, 'enable_self_critique', False) and context:
|
if self.config.features.enable_self_critique and context:
|
||||||
critique_prompt = prompts.get('critique', '')
|
critique_prompt = prompts.get('critique', '')
|
||||||
if critique_prompt:
|
if critique_prompt:
|
||||||
logger.debug("Запуск самокритики")
|
logger.debug("Запуск самокритики")
|
||||||
@@ -159,7 +163,7 @@ class QueryProcessor:
|
|||||||
query=full_query_retry,
|
query=full_query_retry,
|
||||||
system_prompt=system_prompt,
|
system_prompt=system_prompt,
|
||||||
file_id=None,
|
file_id=None,
|
||||||
temperature=getattr(self.config, 'ai_temperature', 0.1)
|
temperature=temperature
|
||||||
)
|
)
|
||||||
# Повторная проверка после перегенерации
|
# Повторная проверка после перегенерации
|
||||||
if not await critique_answer(
|
if not await critique_answer(
|
||||||
|
|||||||
@@ -16,11 +16,12 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Optional, Dict, List, Any
|
from typing import Optional, Dict, List, Any
|
||||||
|
|
||||||
from core.rag_orchestrator import RAGOrchestrator
|
from rag.rag_orchestrator import RAGOrchestrator
|
||||||
from core.services.kb_service import KBService
|
from rag.services.kb_service import KBService
|
||||||
from core.services.giga_client import GigaClient
|
from rag.services.giga_client import GigaClient
|
||||||
from core.services.file_service import FileService
|
from rag.services.file_service import FileService
|
||||||
from core.services.postgres_service import PostgresService
|
from rag.services.postgres_service import PostgresService
|
||||||
|
from rag.config_models import AppConfig
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ class RAGAPI:
|
|||||||
kb: KBService,
|
kb: KBService,
|
||||||
giga: GigaClient,
|
giga: GigaClient,
|
||||||
files: FileService,
|
files: FileService,
|
||||||
config,
|
config: AppConfig,
|
||||||
default_prompts: Optional[Dict[str, str]] = None
|
default_prompts: Optional[Dict[str, str]] = None
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
@@ -53,7 +54,7 @@ class RAGAPI:
|
|||||||
kb: сервис базы знаний (KBService)
|
kb: сервис базы знаний (KBService)
|
||||||
giga: клиент GigaChat (GigaClient)
|
giga: клиент GigaChat (GigaClient)
|
||||||
files: сервис файлов (FileService)
|
files: сервис файлов (FileService)
|
||||||
config: объект конфигурации (BotConfig)
|
config: объект конфигурации (AppConfig)
|
||||||
default_prompts: словарь промптов по умолчанию.
|
default_prompts: словарь промптов по умолчанию.
|
||||||
Используется, если в запросе не переданы свои промпты.
|
Используется, если в запросе не переданы свои промпты.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -8,18 +8,19 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Optional, Dict, List, Any
|
from typing import Optional, Dict, List, Any
|
||||||
|
|
||||||
from core.services.postgres_service import PostgresService
|
from rag.services.postgres_service import PostgresService
|
||||||
from core.services.qdrant_service import QdrantService
|
from rag.services.qdrant_service import QdrantService
|
||||||
from core.services.embedding_service import EmbeddingService
|
from rag.services.embedding_service import EmbeddingService
|
||||||
from core.services.kb_service import KBService
|
from rag.services.kb_service import KBService
|
||||||
from core.services.giga_client import GigaClient
|
from rag.services.giga_client import GigaClient
|
||||||
from core.services.file_service import FileService
|
from rag.services.file_service import FileService
|
||||||
from core.history_manager import HistoryManager
|
from rag.history_manager import HistoryManager
|
||||||
from core.intent_router import IntentRouter
|
from rag.intent_router import IntentRouter
|
||||||
from core.query_processor import QueryProcessor
|
from rag.query_processor import QueryProcessor
|
||||||
from core.indexing_manager import IndexingManager
|
from rag.indexing_manager import IndexingManager
|
||||||
from core.functions.intent_classify import classify_intent
|
from rag.functions.intent_classify import classify_intent
|
||||||
from core.utils.text_utils import count_tokens
|
from rag.utils.text_utils import count_tokens
|
||||||
|
from rag.config_models import AppConfig
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ class RAGOrchestrator:
|
|||||||
kb: KBService,
|
kb: KBService,
|
||||||
giga: GigaClient,
|
giga: GigaClient,
|
||||||
files: FileService,
|
files: FileService,
|
||||||
config,
|
config: AppConfig,
|
||||||
default_prompts: Optional[Dict[str, str]] = None
|
default_prompts: Optional[Dict[str, str]] = None
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
@@ -52,7 +53,7 @@ class RAGOrchestrator:
|
|||||||
kb: сервис базы знаний
|
kb: сервис базы знаний
|
||||||
giga: клиент GigaChat
|
giga: клиент GigaChat
|
||||||
files: сервис файлов
|
files: сервис файлов
|
||||||
config: объект конфигурации (BotConfig)
|
config: объект конфигурации (AppConfig)
|
||||||
default_prompts: словарь промптов по умолчанию
|
default_prompts: словарь промптов по умолчанию
|
||||||
"""
|
"""
|
||||||
self.db = db
|
self.db = db
|
||||||
@@ -182,9 +183,9 @@ class RAGOrchestrator:
|
|||||||
system_prompt = prompts.get('system', None)
|
system_prompt = prompts.get('system', None)
|
||||||
|
|
||||||
# 2. Расчёт лимитов токенов
|
# 2. Расчёт лимитов токенов
|
||||||
max_model_tokens = getattr(self.config, 'max_model_tokens', 8192)
|
max_model_tokens = self.config.rag.max_model_tokens
|
||||||
reserved_for_answer = getattr(self.config, 'reserved_for_answer_tokens', 1000)
|
reserved_for_answer = self.config.rag.reserved_for_answer_tokens
|
||||||
reserved_for_overhead = getattr(self.config, 'reserved_for_overhead_tokens', 200)
|
reserved_for_overhead = self.config.rag.reserved_for_overhead_tokens
|
||||||
|
|
||||||
token_info = self._prepare_prompt_parts(
|
token_info = self._prepare_prompt_parts(
|
||||||
synthesis_template=synthesis_template,
|
synthesis_template=synthesis_template,
|
||||||
@@ -210,7 +211,7 @@ class RAGOrchestrator:
|
|||||||
|
|
||||||
# 5. Классификация намерений
|
# 5. Классификация намерений
|
||||||
intent = intent_override
|
intent = intent_override
|
||||||
if intent is None and getattr(self.config, 'enable_intent_classification', True):
|
if intent is None and self.config.features.enable_intent_classification:
|
||||||
intent_prompt = prompts.get('intent', '')
|
intent_prompt = prompts.get('intent', '')
|
||||||
if intent_prompt:
|
if intent_prompt:
|
||||||
intent = await classify_intent(
|
intent = await classify_intent(
|
||||||
@@ -225,7 +226,7 @@ class RAGOrchestrator:
|
|||||||
intent = intent or "GENERAL"
|
intent = intent or "GENERAL"
|
||||||
|
|
||||||
# 6. Принудительная установка SURGICAL по ключевым словам
|
# 6. Принудительная установка SURGICAL по ключевым словам
|
||||||
keywords = getattr(self.config, 'surgical_keywords', [])
|
keywords = self.config.features.surgical_keywords
|
||||||
if any(kw in query.lower() for kw in keywords) and last_file_path:
|
if any(kw in query.lower() for kw in keywords) and last_file_path:
|
||||||
intent = "SURGICAL"
|
intent = "SURGICAL"
|
||||||
logger.info(f"Принудительный Intent: SURGICAL (есть файл и ключевые слова)")
|
logger.info(f"Принудительный Intent: SURGICAL (есть файл и ключевые слова)")
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import asyncio
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional, Dict, List, Any
|
from typing import Optional, Dict, List, Any
|
||||||
|
|
||||||
# Добавляем путь к core, если запускаем из корня проекта
|
# Добавляем путь к rag, если запускаем из корня проекта
|
||||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException, Depends, UploadFile, File as FastAPIFile
|
from fastapi import FastAPI, HTTPException, Depends, UploadFile, File as FastAPIFile
|
||||||
@@ -32,16 +32,16 @@ from fastapi.middleware.cors import CORSMiddleware
|
|||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
# Импортируем наши модули
|
# Импортируем наши модули (теперь из пакета rag)
|
||||||
from core.utils.config_loader import BotConfig
|
from rag.utils.config_loader import load_config
|
||||||
from core.utils.logger import setup_logging
|
from rag.utils.logger import setup_logging
|
||||||
from core.services.postgres_service import PostgresService
|
from rag.services.postgres_service import PostgresService
|
||||||
from core.services.qdrant_service import QdrantService
|
from rag.services.qdrant_service import QdrantService
|
||||||
from core.services.embedding_service import EmbeddingService
|
from rag.services.embedding_service import EmbeddingService
|
||||||
from core.services.kb_service import KBService
|
from rag.services.kb_service import KBService
|
||||||
from core.services.giga_client import GigaClient
|
from rag.services.giga_client import GigaClient
|
||||||
from core.services.file_service import FileService
|
from rag.services.file_service import FileService
|
||||||
from core.rag_orchestrator import RAGOrchestrator
|
from rag.rag_orchestrator import RAGOrchestrator
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -58,14 +58,10 @@ class QueryRequest(BaseModel):
|
|||||||
query: str = Field(..., description="Текст запроса пользователя")
|
query: str = Field(..., description="Текст запроса пользователя")
|
||||||
user_jid: str = Field(..., description="JID пользователя (без ресурса)")
|
user_jid: str = Field(..., description="JID пользователя (без ресурса)")
|
||||||
room_jid: Optional[str] = Field(None, description="JID комнаты (None для личного чата)")
|
room_jid: Optional[str] = Field(None, description="JID комнаты (None для личного чата)")
|
||||||
|
|
||||||
# history: List[Dict[str, str]] = Field(...) # УБРАНО!
|
|
||||||
|
|
||||||
prompts: Dict[str, str] = Field(
|
prompts: Dict[str, str] = Field(
|
||||||
default_factory=dict,
|
default_factory=dict,
|
||||||
description="Словарь промптов (system, synthesis, intent, expand, critique и т.д.)"
|
description="Словарь промптов (system, synthesis, intent, expand, critique и т.д.)"
|
||||||
)
|
)
|
||||||
|
|
||||||
intent_override: Optional[str] = Field(None, description="Принудительное переопределение намерения")
|
intent_override: Optional[str] = Field(None, description="Принудительное переопределение намерения")
|
||||||
last_file_path: Optional[str] = Field(None, description="Путь к последнему загруженному файлу")
|
last_file_path: Optional[str] = Field(None, description="Путь к последнему загруженному файлу")
|
||||||
last_file_text: Optional[str] = Field(None, description="Текст последнего загруженного файла")
|
last_file_text: Optional[str] = Field(None, description="Текст последнего загруженного файла")
|
||||||
@@ -118,7 +114,7 @@ class TranscribeResponse(BaseModel):
|
|||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
_orchestrator: Optional[RAGOrchestrator] = None
|
_orchestrator: Optional[RAGOrchestrator] = None
|
||||||
_config: Optional[BotConfig] = None
|
_config: Optional[AppConfig] = None
|
||||||
|
|
||||||
|
|
||||||
def get_orchestrator() -> RAGOrchestrator:
|
def get_orchestrator() -> RAGOrchestrator:
|
||||||
@@ -129,7 +125,7 @@ def get_orchestrator() -> RAGOrchestrator:
|
|||||||
return _orchestrator
|
return _orchestrator
|
||||||
|
|
||||||
|
|
||||||
def init_orchestrator(config: BotConfig) -> RAGOrchestrator:
|
def init_orchestrator(config: AppConfig) -> RAGOrchestrator:
|
||||||
"""Инициализирует все сервисы и создаёт RAGOrchestrator."""
|
"""Инициализирует все сервисы и создаёт RAGOrchestrator."""
|
||||||
global _orchestrator, _config
|
global _orchestrator, _config
|
||||||
_config = config
|
_config = config
|
||||||
@@ -138,31 +134,31 @@ def init_orchestrator(config: BotConfig) -> RAGOrchestrator:
|
|||||||
# ---- 1. Инициализация сервисов ----
|
# ---- 1. Инициализация сервисов ----
|
||||||
# PostgreSQL (история, документы)
|
# PostgreSQL (история, документы)
|
||||||
db = PostgresService(
|
db = PostgresService(
|
||||||
host=config.db_host,
|
host=config.database.host,
|
||||||
port=config.db_port,
|
port=config.database.port,
|
||||||
user=config.db_user,
|
user=config.database.user,
|
||||||
password=config.db_password,
|
password=config.db_password,
|
||||||
db_name=config.db_name
|
db_name=config.database.database
|
||||||
)
|
)
|
||||||
|
|
||||||
# Qdrant (векторный поиск)
|
# Qdrant (векторный поиск)
|
||||||
qdrant = QdrantService(
|
qdrant = QdrantService(
|
||||||
host=config.qdrant_host,
|
host=config.qdrant.host,
|
||||||
port=config.qdrant_port,
|
port=config.qdrant.port,
|
||||||
grpc_port=config.qdrant_grpc_port,
|
grpc_port=config.qdrant.grpc_port,
|
||||||
collection_name=config.qdrant_collection,
|
collection_name=config.qdrant.collection,
|
||||||
vector_size=config.qdrant_vector_size,
|
vector_size=config.qdrant.vector_size,
|
||||||
distance=config.qdrant_distance,
|
distance=config.qdrant.distance,
|
||||||
prefer_grpc=False
|
prefer_grpc=False
|
||||||
)
|
)
|
||||||
|
|
||||||
# Эмбеддинги (GigaChat)
|
# Эмбеддинги (GigaChat)
|
||||||
embedding = EmbeddingService(
|
embedding = EmbeddingService(
|
||||||
api_key=config.gigachat_api_key,
|
api_key=config.gigachat_api_key,
|
||||||
model=config.embedding_model,
|
model=config.embedding.model,
|
||||||
timeout=config.embedding_timeout,
|
timeout=config.embedding.timeout,
|
||||||
cache_size=config.embedding_cache_size,
|
cache_size=config.embedding.cache_size,
|
||||||
verify_ssl=config.embedding_verify_ssl
|
verify_ssl=config.embedding.verify_ssl_certs
|
||||||
)
|
)
|
||||||
|
|
||||||
# База знаний (индексация, поиск)
|
# База знаний (индексация, поиск)
|
||||||
@@ -170,19 +166,19 @@ def init_orchestrator(config: BotConfig) -> RAGOrchestrator:
|
|||||||
db=db,
|
db=db,
|
||||||
qdrant=qdrant,
|
qdrant=qdrant,
|
||||||
embedding=embedding,
|
embedding=embedding,
|
||||||
collection_name=config.qdrant_collection,
|
collection_name=config.qdrant.collection,
|
||||||
chunk_size_tokens=config.chunk_size_tokens,
|
chunk_size_tokens=config.chunking.chunk_size_tokens,
|
||||||
overlap_tokens=config.overlap_tokens,
|
overlap_tokens=config.chunking.overlap_tokens,
|
||||||
approx_chunk_chars=config.chunking_approx_chunk_chars,
|
approx_chunk_chars=config.chunking.approx_chunk_chars,
|
||||||
approx_overlap_chars=config.chunking_approx_overlap_chars
|
approx_overlap_chars=config.chunking.approx_overlap_chars
|
||||||
)
|
)
|
||||||
|
|
||||||
# GigaChat клиент (генерация)
|
# GigaChat клиент (генерация)
|
||||||
giga = GigaClient(
|
giga = GigaClient(
|
||||||
api_key=config.gigachat_api_key,
|
api_key=config.gigachat_api_key,
|
||||||
model=config.ai_model,
|
model=config.gigachat.model_generation,
|
||||||
temperature=config.ai_temperature,
|
temperature=config.gigachat.temperature,
|
||||||
timeout=config.ai_timeout,
|
timeout=config.gigachat.timeout,
|
||||||
verify_ssl=False
|
verify_ssl=False
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -190,15 +186,11 @@ def init_orchestrator(config: BotConfig) -> RAGOrchestrator:
|
|||||||
files = FileService(config)
|
files = FileService(config)
|
||||||
|
|
||||||
# ---- 2. Создание оркестратора ----
|
# ---- 2. Создание оркестратора ----
|
||||||
# Загружаем дефолтные промпты (опционально)
|
# Загружаем дефолтные промпты (из config.prompts_content)
|
||||||
default_prompts = {}
|
default_prompts = config.prompts_content or {}
|
||||||
system_prompt_path = getattr(config, 'system_prompt_file', None)
|
system_prompt = default_prompts.get('system')
|
||||||
if system_prompt_path and system_prompt_path.exists():
|
if system_prompt:
|
||||||
try:
|
default_prompts['system'] = system_prompt
|
||||||
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(
|
orchestrator = RAGOrchestrator(
|
||||||
db=db,
|
db=db,
|
||||||
@@ -444,16 +436,18 @@ def main():
|
|||||||
)
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Загружаем конфигурацию
|
# Загружаем конфигурацию с помощью новой функции load_config
|
||||||
try:
|
try:
|
||||||
config = BotConfig(args.profile_dir)
|
config = load_config(args.profile_dir)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Ошибка загрузки конфигурации: {e}")
|
print(f"Ошибка загрузки конфигурации: {e}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Настраиваем логирование
|
# Настраиваем логирование
|
||||||
log_level = getattr(logging, args.log_level.upper(), logging.INFO)
|
log_level = getattr(logging, args.log_level.upper(), logging.INFO)
|
||||||
setup_logging(config.name, config.log_file, log_level=log_level)
|
# Передаём путь к логу из конфига
|
||||||
|
log_file_path = config.log_file_path or Path("/tmp/rag_server.log")
|
||||||
|
setup_logging(config.name, log_file_path, log_level=log_level)
|
||||||
|
|
||||||
logger.info(f"Запуск RAG-сервера с профилем {args.profile_dir}")
|
logger.info(f"Запуск RAG-сервера с профилем {args.profile_dir}")
|
||||||
logger.info(f"Хост: {args.host}, порт: {args.port}")
|
logger.info(f"Хост: {args.host}, порт: {args.port}")
|
||||||
@@ -467,7 +461,7 @@ def main():
|
|||||||
|
|
||||||
# Запускаем Uvicorn
|
# Запускаем Uvicorn
|
||||||
uvicorn.run(
|
uvicorn.run(
|
||||||
"core.rag_server:app",
|
"rag.rag_server:app", # теперь модуль из пакета rag
|
||||||
host=args.host,
|
host=args.host,
|
||||||
port=args.port,
|
port=args.port,
|
||||||
log_level=args.log_level,
|
log_level=args.log_level,
|
||||||
|
|||||||
Reference in New Issue
Block a user