<|channel|>final solution.py<|message|>import sys from typing import Optional # Библиотеки, которые должны быть установлены в окружении задачи. # Мы используем langchain для взаимодействия с LLM и rich для красивого вывода. try: from langchain.chat_models import ChatOpenAI except ImportError as exc: # pragma: no cover raise RuntimeError( "Не удалось импортировать langchain. Убедитесь, что пакет установлен." ) from exc try: from rich.console import Console from rich.prompt import Prompt from rich.text import Text except ImportError as exc: # pragma: no cover raise RuntimeError( "Не удалось импортировать rich. Убедитесь, что пакет установлен." ) from exc class TextAdventureGame: """ Простая текстовая игра на основе LLM. Игрок вводит команды, которые отправляются в модель, а ответ модели выводится пользователю. """ def __init__(self, model_name: str = "gpt-3.5-turbo", temperature: float = 0.7): """ Инициализация игрового процесса. :param model_name: имя LLM из OpenAI :param temperature: степень случайности генерации текста """ self.console = Console() # Создаём объект модели. Для работы требуется переменная окружения OPENAI_API_KEY. try: self.llm = ChatOpenAI(model=model_name, temperature=temperature) except Exception as exc: # pragma: no cover raise RuntimeError( "Не удалось создать экземпляр LLM. Проверьте ключ OpenAI." ) from exc def _display_welcome(self) -> None: """Показываем приветственное сообщение.""" welcome = Text("Добро пожаловать в текстовую игру!", style="bold green") self.console.print(welcome) def _get_player_input(self, prompt: str = "Что вы делаете?") -> Optional[str]: """ Получаем ввод от игрока. Если пользователь введёт 'quit', возвращаем None для завершения игры. """ try: user_input = Prompt.ask(prompt) except KeyboardInterrupt: # pragma: no cover self.console.print("\n[red]Игра прервана пользователем.[/red]") return None if user_input.strip().lower() in {"quit", "exit"}: return None return user_input def _generate_response(self, player_action: str) -> str: """ Отправляем действие игрока в LLM и получаем ответ. :param player_action: строка с командой игрока :return: текст ответа модели """ # Формируем сообщение для чат‑модели. messages = [ {"role": "system", "content": "Вы — мудрый рассказчик, описывающий события в мире приключений."}, {"role": "user", "content": player_action}, ] try: response = self.llm.invoke(messages) except Exception as exc: # pragma: no cover raise RuntimeError("Ошибка при вызове LLM.") from exc return response.content.strip() def run(self) -> None: """Основной цикл игры.""" self._display_welcome() while True: action = self._get_player_input() if action is None: # пользователь ввёл quit или прервал self.console.print("[bold magenta]Спасибо за игру![/bold magenta]") break self.console.print(f"[cyan]Вы сказали:[/cyan] {action}") try: result = self._generate_response(action) except Exception as exc: # pragma: no cover self.console.print(f"[red]Ошибка генерации ответа: {exc}[/red]") continue self.console.print("\n[green]Ответ модели:[/green]\n") self.console.print(result, style="italic") self.console.print("-" * 40) if __name__ == "__main__": # Запускаем игру. Если переменная окружения OPENAI_API_KEY не задана, # langchain выбросит исключение при создании модели. game = TextAdventureGame() try: game.run() except Exception as exc: # pragma: no cover sys.stderr.write(f"Произошла ошибка: {exc}\n") sys.exit(1)