From 2c86f9cbbbf34ace6c24de8981f24a30bb7fcfff Mon Sep 17 00:00:00 2001 From: Markov Andrey Date: Tue, 30 Jun 2026 20:49:54 +0000 Subject: [PATCH] Add new file --- rag/functions/plan_generation.py | 79 ++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 rag/functions/plan_generation.py diff --git a/rag/functions/plan_generation.py b/rag/functions/plan_generation.py new file mode 100644 index 0000000..fa7e080 --- /dev/null +++ b/rag/functions/plan_generation.py @@ -0,0 +1,79 @@ +""" +Генерация плана действий для сложных запросов. +Модель составляет пошаговый план, который затем может быть выполнен. +""" + +import json +import logging +from typing import List, Dict, Any + +from rag.services.giga_client import GigaClient +from rag.config_models import AppConfig + +logger = logging.getLogger(__name__) + + +async def generate_plan( + query: str, + history: List[Dict[str, str]], + config: AppConfig, + giga: GigaClient, + prompts: Dict[str, str], +) -> List[Dict[str, Any]]: + """ + Генерирует план действий для сложного запроса. + + Аргументы: + query: запрос пользователя. + history: история диалога (может использоваться для контекста). + config: конфигурация. + giga: клиент GigaChat. + prompts: словарь с промптами (ключ 'planning'). + + Возвращает: + List[Dict]: список шагов, каждый с полями: + step_description: str, + required_data: str (опционально), + expected_output: str (опционально). + В случае ошибки возвращает пустой список или базовый план. + """ + prompt_template = prompts.get("planning") + if not prompt_template: + logger.error("Промпт для генерации плана не найден") + return [] + + # Формируем полный промпт + # Можно использовать историю для контекста, но для простоты берём только последнее сообщение + context = "" + if history: + # Берём последние 3 сообщения для контекста + context = "\n".join([f"{msg['role']}: {msg['content']}" for msg in history[-3:]]) + full_prompt = prompt_template.format(query=query, context=context) + + try: + response = await giga.chat( + history=[], + query=full_prompt, + system_prompt=None, + file_id=None, + temperature=getattr(config, 'planning_temperature', 0.2), + ) + # Ожидаем JSON-список + data = json.loads(response.strip()) + if isinstance(data, list): + # Проверяем, что каждый элемент содержит step_description + for item in data: + if "step_description" not in item: + logger.warning("План содержит шаг без step_description, игнорируем") + # Можно добавить базовые поля + item["step_description"] = item.get("description", "Неизвестный шаг") + return data + else: + logger.error("План не является списком JSON") + return [] + except json.JSONDecodeError as e: + logger.error(f"Ошибка парсинга JSON плана: {e}, ответ: {response[:200]}") + return [] + except Exception as e: + logger.exception(f"Ошибка при генерации плана: {e}") + return [] \ No newline at end of file