final
This commit is contained in:
164
input-to-route/ouput_chat.py
Normal file
164
input-to-route/ouput_chat.py
Normal file
@@ -0,0 +1,164 @@
|
||||
from typing import List, Dict, Optional
|
||||
from gemini_model import GeminiModel
|
||||
|
||||
|
||||
class RouteDescriber:
|
||||
"""
|
||||
Класс для работы с описанием маршрутов и ответами на вопросы пользователей через GeminiModel.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.model = GeminiModel()
|
||||
self.conversation_history = []
|
||||
self.route_points = []
|
||||
self.route_description = ""
|
||||
self.parser_chat_context = ""
|
||||
|
||||
def _call_model(self, prompt: str, system_instruction: Optional[str] = None) -> str:
|
||||
"""
|
||||
Вызывает GeminiModel с составленным промптом и системной инструкцией.
|
||||
"""
|
||||
full_prompt = prompt
|
||||
if system_instruction:
|
||||
full_prompt = f"Системная инструкция:\n{system_instruction}\n\n{prompt}"
|
||||
|
||||
return self.model.call(full_prompt)
|
||||
|
||||
def generate_route_description(self, route_points: List[Dict],
|
||||
parser_chat_history: Optional[List[Dict]] = None) -> str:
|
||||
"""
|
||||
Генерирует описание маршрута на основе точек.
|
||||
"""
|
||||
self.route_points = route_points
|
||||
self.conversation_history = []
|
||||
|
||||
# Формируем контекст парсера
|
||||
if parser_chat_history:
|
||||
print(parser_chat_history)
|
||||
parser_messages = [f"{msg['role'].upper()}: {msg['content']}" for msg in parser_chat_history]
|
||||
self.parser_chat_context = "\n".join(parser_messages)
|
||||
else:
|
||||
self.parser_chat_context = ""
|
||||
|
||||
# Формируем промпт с точками маршрута
|
||||
points_info = []
|
||||
for i, point in enumerate(route_points, 1):
|
||||
name = point.get('title', f'Точка {i}')
|
||||
description = point.get('description', '')
|
||||
points_info.append(f"{i}. {name}\nОписание: {description}")
|
||||
|
||||
prompt = f"""Создай краткое описание маршрута из {len(route_points)} точек.
|
||||
Для каждой точки напиши 1-2 предложения, которые заинтересуют посетителя.
|
||||
Используй только информацию из описаний точек.
|
||||
|
||||
Точки маршрута:
|
||||
{chr(10).join(points_info)}
|
||||
"""
|
||||
|
||||
if self.parser_chat_context:
|
||||
prompt = f"История запроса пользователя:\n{self.parser_chat_context}\n\n{prompt}"
|
||||
|
||||
system_instruction = """Ты — помощник для описания туристических маршрутов.
|
||||
Твоя задача — создавать краткие, привлекательные описания точек маршрута (1-2 предложения на точку).
|
||||
Используй только информацию, представленную в описаниях точек.
|
||||
|
||||
Пиши на русском языке."""
|
||||
|
||||
description = self._call_model(prompt, system_instruction)
|
||||
self.route_description = description
|
||||
return description
|
||||
|
||||
def answer_question(self, question: str) -> str:
|
||||
"""
|
||||
Отвечает на вопрос пользователя о точках маршрута.
|
||||
"""
|
||||
# Формируем контекст с информацией о точках
|
||||
points_context = [f"{i+1}. {p['name']}: {p.get('description', 'Нет описания')}"
|
||||
for i, p in enumerate(self.route_points)]
|
||||
context = "\n\n".join(points_context)
|
||||
|
||||
# Дополнительный контекст парсера и описания маршрута
|
||||
parser_info = f"\n\nИстория запроса пользователя:\n{self.parser_chat_context}" if self.parser_chat_context else ""
|
||||
route_desc_info = f"\n\nОписание маршрута:\n{self.route_description}" if self.route_description else ""
|
||||
|
||||
system_instruction = f"""Ты — помощник по туристическому маршруту.
|
||||
{parser_info}{route_desc_info}
|
||||
|
||||
Доступная информация о точках маршрута:
|
||||
{context}
|
||||
|
||||
СТРОГИЕ ПРАВИЛА:
|
||||
1. Отвечай ТОЛЬКО на вопросы о точках маршрута
|
||||
2. Используй ТОЛЬКО информацию из описаний точек выше
|
||||
3. Если в описаниях нет информации для ответа на вопрос, вежливо уходи от ответа фразами вида "Вы узнаете ответ, когда посетите это место", адаптируй под контекст.
|
||||
4. НЕ давай рекомендаций и советов
|
||||
5. НЕ отвечай на вопросы, не связанные с маршрутом. В таких случаях отвечай: "Я могу ответить только на вопросы о точках вашего маршрута"
|
||||
6. НЕ придумывай информацию, которой нет в описаниях
|
||||
7. Отвечай кратко и по существу на русском языке
|
||||
8. Ты видишь всю историю разговора, поэтому можешь отвечать на уточняющие вопросы"""
|
||||
|
||||
answer = self._call_model(question, system_instruction)
|
||||
return answer
|
||||
|
||||
def reset_conversation(self):
|
||||
"""Очищает историю разговора и маршрута."""
|
||||
self.conversation_history = []
|
||||
self.route_points = []
|
||||
self.route_description = ""
|
||||
self.parser_chat_context = ""
|
||||
|
||||
|
||||
|
||||
# Пример использования
|
||||
if __name__ == "__main__":
|
||||
# Инициализация (замените на ваш API ключ)
|
||||
API_KEY = "YOUR_GEMINI_API_KEY"
|
||||
describer = RouteDescriber()
|
||||
|
||||
# Пример истории чата с парсером
|
||||
parser_chat = [
|
||||
{"role": "user", "text": "Хочу погулять по центру Москвы, интересует история и искусство"},
|
||||
{"role": "model", "text": "Понял, вы хотите прогулку по историческому центру с посещением музеев. Сколько времени у вас есть?"},
|
||||
{"role": "user", "text": "Часа 3-4"},
|
||||
{"role": "model", "text": "Отлично, я составил маршрут из 3 точек по центру Москвы с историческими местами и музеем искусства."}
|
||||
]
|
||||
|
||||
# Пример данных маршрута
|
||||
route_points = [
|
||||
{
|
||||
"name": "Красная площадь",
|
||||
"description": "Главная площадь Москвы, окружённая историческими зданиями. Здесь находятся Кремль, собор Василия Блаженного и Мавзолей Ленина. Площадь была основана в конце XV века."
|
||||
},
|
||||
{
|
||||
"name": "Парк Горького",
|
||||
"description": "Один из самых известных парков Москвы, расположенный на берегу Москвы-реки. Здесь есть зоны для отдыха, спортивные площадки, прокат велосипедов. Парк был открыт в 1928 году."
|
||||
},
|
||||
{
|
||||
"name": "Третьяковская галерея",
|
||||
"description": "Художественный музей с крупнейшей коллекцией русского искусства. В экспозиции представлены работы от древнерусских икон до картин XX века. Основана купцом Павлом Третьяковым."
|
||||
}
|
||||
]
|
||||
|
||||
# Генерация описания маршрута с историей парсера
|
||||
print("=== ОПИСАНИЕ МАРШРУТА ===")
|
||||
description = describer.generate_route_description(route_points, parser_chat)
|
||||
print(description)
|
||||
print()
|
||||
|
||||
# Примеры вопросов (теперь с контекстом истории)
|
||||
print("=== ДИАЛОГ С ПОЛЬЗОВАТЕЛЕМ ===")
|
||||
|
||||
questions = [
|
||||
"Когда был основан Парк Горького?",
|
||||
"А что там можно делать?", # Уточняющий вопрос о предыдущей теме
|
||||
"Какие картины есть в Третьяковской галерее?",
|
||||
"Сколько стоит билет?", # Без контекста, но система поймет что это про музей
|
||||
"Расскажи про Кремль",
|
||||
"Что посоветуешь взять с собой?", # Попытка получить рекомендацию
|
||||
"Как погода сегодня?" # Нерелевантный вопрос
|
||||
]
|
||||
|
||||
for q in questions:
|
||||
print(f"\n👤 Пользователь: {q}")
|
||||
answer = describer.answer_question(q)
|
||||
print(f"🤖 Бот: {answer}")
|
||||
Reference in New Issue
Block a user