Add new file

This commit is contained in:
Markov Andrey
2026-06-30 20:51:26 +00:00
parent 65301aff0a
commit cdf2e65c4c

145
rag/agents/roles.py Normal file
View File

@@ -0,0 +1,145 @@
# rag/agents/roles.py
"""
Определение базового класса агента и конкретных ролей.
"""
import logging
from abc import ABC, abstractmethod
from typing import Optional, List, Dict, Any
from rag.services.giga_client import GigaClient
from rag.config_models import AppConfig
logger = logging.getLogger(__name__)
class BaseAgent(ABC):
"""
Базовый абстрактный класс для агента.
Каждый агент имеет системный промпт, может использовать GigaChat.
"""
def __init__(
self,
name: str,
system_prompt: str,
giga: GigaClient,
config: AppConfig,
temperature: Optional[float] = None,
):
self.name = name
self.system_prompt = system_prompt
self.giga = giga
self.config = config
self.temperature = temperature or getattr(config, 'agent_temperature', 0.3)
@abstractmethod
async def process(
self,
query: str,
context: str,
history: List[Dict[str, str]],
tools: Optional[List[Dict[str, Any]]] = None,
) -> Dict[str, Any]:
"""
Обрабатывает запрос и возвращает ответ или запрос на действие.
Возвращает словарь с ключами:
'type': 'answer' или 'action'
'content': если 'answer' -> текст ответа; если 'action' -> {'tool': ..., 'params': ...}
"""
pass
class MethodologistAgent(BaseAgent):
"""Агент-методолог, специализируется на стандартах, ГОСТах, методиках."""
async def process(
self,
query: str,
context: str,
history: List[Dict[str, str]],
tools: Optional[List[Dict[str, Any]]] = None,
) -> Dict[str, Any]:
# Формируем промпт с учётом системного промпта и контекста
# Здесь можно использовать prompt_builder, но для простоты составим вручную
messages = []
if self.system_prompt:
messages.append({"role": "system", "content": self.system_prompt})
messages.extend(history)
messages.append({"role": "user", "content": f"Контекст:\n{context}\n\nВопрос: {query}"})
try:
response = await self.giga.chat(
history=messages,
query="", # уже включено в history
system_prompt=None,
file_id=None,
temperature=self.temperature,
)
# В простейшем случае возвращаем ответ как финальный
return {"type": "answer", "content": response}
except Exception as e:
logger.error(f"Ошибка в MethodologistAgent: {e}")
return {"type": "answer", "content": f"Извините, произошла ошибка: {str(e)}"}
class BoxSolutionAgent(BaseAgent):
"""Агент для генерации коробочных решений."""
async def process(
self,
query: str,
context: str,
history: List[Dict[str, str]],
tools: Optional[List[Dict[str, Any]]] = None,
) -> Dict[str, Any]:
messages = []
if self.system_prompt:
messages.append({"role": "system", "content": self.system_prompt})
messages.extend(history)
messages.append({"role": "user", "content": f"Контекст:\n{context}\n\nЗапрос на коробочное решение: {query}"})
try:
response = await self.giga.chat(
history=messages,
query="",
system_prompt=None,
file_id=None,
temperature=self.temperature,
)
return {"type": "answer", "content": response}
except Exception as e:
logger.error(f"Ошибка в BoxSolutionAgent: {e}")
return {"type": "answer", "content": f"Извините, произошла ошибка: {str(e)}"}
class PersonalAssistantAgent(BaseAgent):
"""Персональный ассистент (бронирование, календарь, командировки)."""
async def process(
self,
query: str,
context: str,
history: List[Dict[str, str]],
tools: Optional[List[Dict[str, Any]]] = None,
) -> Dict[str, Any]:
# Для персонального ассистента можно использовать ReAct или просто генерацию
messages = []
if self.system_prompt:
messages.append({"role": "system", "content": self.system_prompt})
messages.extend(history)
messages.append({"role": "user", "content": f"Контекст:\n{context}\n\nЗапрос: {query}"})
try:
response = await self.giga.chat(
history=messages,
query="",
system_prompt=None,
file_id=None,
temperature=self.temperature,
)
return {"type": "answer", "content": response}
except Exception as e:
logger.error(f"Ошибка в PersonalAssistantAgent: {e}")
return {"type": "answer", "content": f"Извините, произошла ошибка: {str(e)}"}