import os import gradio as gr from llama_index.llms.openrouter import OpenRouter from llama_index.core.llms import ChatMessage from llama_index.embeddings.huggingface import HuggingFaceEmbedding from llama_index.core import Settings, StorageContext, load_index_from_storage import nest_asyncio nest_asyncio.apply() # === Глобальная инициализация === embed_model = HuggingFaceEmbedding(model_name='intfloat/multilingual-e5-large-instruct') Settings.embed_model = embed_model Settings.llm = OpenRouter( api_key=os.environ["OPENROUTER_API_KEY"], model="qwen/qwen3-4b:free", max_tokens=10000, context_window=20000, ) system_prompt = """ Ты — эксперт по адаптации к изменениям климата. У тебя есть база знаний с кейсами и нормативными документами. Пользователь вводит запрос, связанный с климатическим риском в регионе или отрасли. Твоя задача — на основе информации из базы знаний предложить 2–3 релевантных адаптационных мероприятия, которые помогут снизить климатический риск, о котором спрашивает пользователь. ### Требования к ответу: 1. Представь результат **в виде Markdown-таблицы** с колонками: - Наименование мероприятий - Митигационный эффект - Адаптационный эффект - Актуальность для региона (указать с учётом контекста запроса). Если регион не указан, считай, что задается вопрос по Тюменской области - Ответственная организация (из региона) 2. Если источник данных, на которых ты основываешь ответ, известен (это URL и краткое название кейса), добавь их **ниже таблицы** в виде списка ссылок: `**Опорные источники:** [1] Наименовавание мероприятий - URL, [2] Наименовавание мероприятий - URL` 3. Пиши кратко, по существу, с акцентом на реальные, практические меры. 4. Если информация отсутствует — предложи логичные адаптационные меры на основе Приказа Минэкономразвития России от 13 мая 2021 г. № 267 «Об утверждении методических рекомендаций и показателей по вопросам адаптации к изменениям климата». Пример формата ответа: | Наименование мероприятий | Митигационный эффект | Адаптационный эффект | Актуальность для Тобольского района | Ответственная организация | |---------------------------|----------------------|----------------------|------------------------------------|----------------------------| | Развитие городского электротранспорта | снижение эмиссии | повышение устойчивости транспортной инфраструктуры | актуально | городские власти | | Перевод транспорта на газомоторное топливо | снижение эмиссии | рациональное использование ресурсов | реализуется частично | транспортные организации | **Опорные источники:** [1] Наименовавание мероприятий - https://example.com/case_12 Приводи только те источники, которые используешь для формирования таблицы непосредственно. URL приводи строго такое же, как указано в базе знаний. Наименование мероприятий бери из базы знаний Ответственную организацию в таблице указывай актуальную для региона, который пользователь указал в запросе """ # === Функция получения ответа === def get_facts(user_question: str) -> str: try: if not user_question.strip(): return "Ошибка: пожалуйста, введите ваш запрос." storage_context = StorageContext.from_defaults(persist_dir="./storage") index = load_index_from_storage(storage_context) retriever = index.as_retriever(similarity_top_k=4) nodes = retriever.retrieve(user_question) context = "\n\n".join([node.get_content() for node in nodes]) if nodes else "Не найдено релевантных документов." full_system_prompt = system_prompt + f"\n\nКонтекст:\n{context}" messages = [ ChatMessage(role="system", content=full_system_prompt), ChatMessage(role="user", content="Пользовательский запрос: " + user_question) ] response = Settings.llm.chat(messages) return response.message.content except Exception as e: return f"Ошибка:\n{str(e)}" response = Settings.llm.chat(messages) return response.message.content with gr.Blocks(theme=gr.themes.Soft()) as demo: gr.Markdown("# Climate Risk Assessment System") user_input = gr.Textbox( label="Your query", lines=4, max_lines = 4, placeholder="Write your query" ) answer_output = gr.Textbox( label="Response", lines=4, max_lines = 4, ) send_button = gr.Button("Send query") send_button.click( fn=get_facts, inputs=user_input, outputs=answer_output ) demo.launch()