|
|
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() |