From 6353a9421e4859b682f852879b9f6a56116ef9d2 Mon Sep 17 00:00:00 2001 From: Markov Andrey Date: Tue, 30 Jun 2026 21:01:28 +0000 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B4=D0=B0=D0=BA=D1=82=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20react.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rag/functions/react.py | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/rag/functions/react.py b/rag/functions/react.py index f906752..d2444ac 100644 --- a/rag/functions/react.py +++ b/rag/functions/react.py @@ -47,12 +47,10 @@ async def react_loop( Исключения: RuntimeError: если превышен лимит итераций или возникла критическая ошибка. """ - # Формируем системный промпт с описанием инструментов system_prompt_template = prompts.get("react_system") if not system_prompt_template: raise ValueError("Промпт react_system не найден") - # Описание инструментов для модели tools_desc = [] for tool in tools: tools_desc.append(f"- {tool['name']}: {tool['description']} (параметры: {tool.get('parameters', {})})") @@ -60,10 +58,7 @@ async def react_loop( system_prompt = system_prompt_template.format(tools_description=tools_description) - # Создаём внутреннюю историю (копируем переданную, но не модифицируем) internal_history = history.copy() if history else [] - - # Добавляем текущий запрос как сообщение пользователя (если его нет в конце) if not internal_history or internal_history[-1].get("role") != "user" or internal_history[-1].get("content") != query: internal_history.append({"role": "user", "content": query}) @@ -72,52 +67,39 @@ async def react_loop( iteration += 1 logger.debug(f"ReAct итерация {iteration}") - # Формируем промпт (можно использовать стандартный билдер, но здесь упрощённо) messages = [{"role": "system", "content": system_prompt}] + internal_history - # Добавляем указание формата вывода messages.append({"role": "user", "content": "Выведи JSON с действием или финальным ответом."}) - # Вызываем GigaChat response = await giga.chat( - history=messages, # history передаётся как список сообщений - query="", # не нужно, так как мы уже включили в history + history=messages, + query="", system_prompt=None, file_id=None, temperature=getattr(config, 'react_temperature', 0.3), ) - # Парсим JSON try: data = json.loads(response.strip()) except json.JSONDecodeError: logger.error(f"Невалидный JSON от модели: {response[:200]}") - # В качестве fallback пробуем извлечь final_answer или action вручную - # Если не удаётся, считаем, что это финальный ответ if "final_answer" in response.lower(): - # грубое извлечение import re match = re.search(r'"final_answer"\s*:\s*"([^"]+)"', response) if match: return match.group(1) - # Если ничего не вышло, выбрасываем ошибку raise RuntimeError(f"Модель вернула невалидный JSON на итерации {iteration}: {response[:200]}") - # Проверяем наличие финального ответа if "final_answer" in data: return data["final_answer"] - # Проверяем наличие действия action = data.get("action") action_input = data.get("action_input", {}) if not action: - # Если нет ни final_answer, ни action, считаем, что модель ошиблась - # Добавляем сообщение об ошибке в историю и продолжаем internal_history.append({"role": "assistant", "content": response}) internal_history.append({"role": "user", "content": "Не удалось распознать действие или финальный ответ. Пожалуйста, выведи JSON с 'action' или 'final_answer'."}) continue - # Находим обработчик инструмента handler = None for tool in tools: if tool["name"] == action: @@ -131,16 +113,13 @@ async def react_loop( internal_history.append({"role": "user", "content": f"Ошибка: {error_msg}. Попробуй другой инструмент или дай финальный ответ."}) continue - # Вызываем обработчик try: result = await handler(action_input) except Exception as e: result = f"Ошибка при вызове инструмента '{action}': {str(e)}" logger.exception(result) - # Добавляем результат в историю internal_history.append({"role": "assistant", "content": response}) internal_history.append({"role": "tool", "content": result}) - # Если цикл завершился без ответа, генерируем исключение raise RuntimeError(f"Превышено максимальное число итераций ({max_iterations}) без получения финального ответа.") \ No newline at end of file