File size: 6,565 Bytes
d36fbf5
 
 
 
 
6e346f9
8428681
d36fbf5
 
 
8428681
6e346f9
 
 
30bead8
5d9338c
6e346f9
 
 
7fe1e6f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90769c8
7fe1e6f
 
 
 
 
 
 
 
 
 
 
90769c8
 
7da0fa8
7fe1e6f
6e346f9
8428681
55ae362
e2c8e01
 
8428681
e2c8e01
 
 
 
 
 
 
8428681
e2c8e01
b79dbf3
8428681
 
b79dbf3
8428681
23bf6ca
8428681
23bf6ca
 
d920f58
8428681
 
 
69237ed
8428681
e2c8e01
7fe1e6f
6e346f9
 
e2c8e01
8428681
 
 
 
55ae362
 
8428681
 
 
 
7fe1e6f
8428681
3d61541
d06a2a1
8428681
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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="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",
    model="deepseek/deepseek-r1-0528-qwen3-8b: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("# Информационная система для помощи в адаптации к климатическим рискам")

    user_input = gr.Textbox(
        label="Ваш запрос",
        lines=4,
        max_lines = 4,
        placeholder="Введите свой запрос"
    )
        
    gr.Markdown("# Ответ")
    answer_output = gr.Markdown(height=300)
    send_button = gr.Button("Получить ответ")
        
    send_button.click(
        fn=get_facts,
        inputs=user_input,
        outputs=answer_output
    )

demo.launch()