X commited on
Commit
e3b0bf7
·
verified ·
1 Parent(s): ae6198b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +182 -84
app.py CHANGED
@@ -35,7 +35,7 @@ SCIENCE_DATASET = "RafaelUI/ru_science"
35
  ARTICLE_LIMIT = 100
36
  MAX_LENGTH = 256
37
  BATCH_SIZE = 32
38
- EPOCHS = 2
39
 
40
  LOG_FILE = "query_logs.json"
41
  EMBEDDINGS_FILE = "science_embeddings.npy"
@@ -50,39 +50,118 @@ WEBSITE = "https://sites.google.com/view/opruai/home"
50
  HUGGINGFACE = "https://huggingface.co/OpenRussianAI"
51
  CREATION_DATE = "2026"
52
 
53
- # Обучающие диалоги
54
  TRAINING_DIALOGS = [
 
55
  {
56
  "context": "Привет",
57
- "response": "Привет! Я OpenAirAI — ваш научный AI-ассистент от OpenRussianAI. Создан в 2026 году для работы с научными статьями. Чем могу помочь?"
58
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  {
60
  "context": "Кто ты",
61
- "response": "Меня зовут OpenAirAI. Я — AI-ассистент, созданный компанией OpenRussianAI в 2026 году командой разработчиков Грибков Евгений и RootLinux21."
62
  },
63
  {
64
  "context": "Кто тебя создал",
65
- "response": "Меня создала команда OpenRussianAI в составе Грибкова Евгения и RootLinux21 в 2026 году."
66
  },
67
  {
68
- "context": "Что ты умеешь",
69
- "response": "Я умею анализировать научные статьи, находить информацию, помогать с исследованиями в области сельского хозяйства, биологии, химии."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  },
71
  {
72
  "context": "Где ваш сайт",
73
- "response": f"Сайт OpenRussianAI: {WEBSITE}"
74
  },
75
  {
76
  "context": "Где ваши модели",
77
- "response": f"Модели OpenRussianAI на Hugging Face: {HUGGINGFACE}"
78
  },
 
 
79
  {
80
- "context": "Спасибо",
81
- "response": "Всегда рад помочь! Я, OpenAirAI, здесь для вас. Обращайтесь! 😊"
 
 
 
 
 
 
 
 
82
  },
 
 
83
  {
84
  "context": "Пока",
85
  "response": "До свидания! OpenAirAI всегда на связи. Удачи в исследованиях! 👋"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  }
87
  ]
88
 
@@ -220,10 +299,10 @@ class OpenAirAI:
220
  similarities = F.cosine_similarity(query_embedding, context_embeddings)
221
  best_idx = torch.argmax(similarities).item()
222
 
223
- if similarities[best_idx] > 0.5:
224
  return self.responses[best_idx]
225
  else:
226
- return f"Я {self.name}, научный AI-ассистент от {self.company}. Создан в {self.creation_date}. Чем могу помочь?"
227
 
228
  # ===================================================================
229
  # 3. БЫСТРАЯ ЗАГРУЗКА НАУЧНЫХ СТАТЕЙ
@@ -266,14 +345,20 @@ def create_test_articles():
266
  return [
267
  {
268
  "id": 1,
269
- "title": "Влияние удобрений на рост растений",
270
- "text": "Исследование показывает, что применение азотных удобрений увеличивает урожайность.",
271
  "source": "test"
272
  },
273
  {
274
  "id": 2,
 
 
 
 
 
 
275
  "title": "Методы биоконверсии",
276
- "text": "Биоконверсия позволяет перерабатывать органические отходы в удобрения.",
277
  "source": "test"
278
  }
279
  ]
@@ -305,7 +390,7 @@ def create_embeddings(_articles, _embedder):
305
  return embeddings
306
 
307
  # ===================================================================
308
- # 4. ФУНКЦИИ ПОИСКА
309
  # ===================================================================
310
 
311
  def search_science(query, _articles, _embeddings, _embedder):
@@ -320,7 +405,7 @@ def search_science(query, _articles, _embeddings, _embedder):
320
  results = []
321
  for idx in top_indices:
322
  score = float(scores[int(idx)])
323
- if score > 0.2:
324
  article = _articles[int(idx)]
325
  results.append({
326
  "title": article['title'],
@@ -342,7 +427,7 @@ def search_science(query, _articles, _embeddings, _embedder):
342
  return results
343
 
344
  # ===================================================================
345
- # 5. ИНТЕРФЕЙС (БЕЗ АДМИНКИ)
346
  # ===================================================================
347
 
348
  # ЗАГРУЗКА
@@ -358,7 +443,14 @@ if 'dialog_ai' not in st.session_state:
358
 
359
  dialog_ai = st.session_state.dialog_ai
360
 
361
- # --- БОКОВАЯ ПАНЕЛЬ (ИНФОРМАЦИЯ) ---
 
 
 
 
 
 
 
362
  with st.sidebar:
363
  st.image("https://cdn-icons-png.flaticon.com/512/4248/4248455.png", width=80)
364
  st.title(f"🧪 {AI_NAME}")
@@ -380,77 +472,83 @@ with st.sidebar:
380
  **📊 Статистика:**
381
 
382
  - Научных статей: {len(articles)}
383
- - Всего запросов: {len(query_logs)}
384
  """)
385
 
386
  if os.path.exists(EMBEDDINGS_FILE):
387
  size = os.path.getsize(EMBEDDINGS_FILE) / (1024 * 1024)
388
  st.caption(f"💾 Эмбеддинги: {size:.1f} MB")
389
-
390
- # --- ОСНОВНАЯ ЧАСТЬ ---
 
 
 
 
 
 
 
391
  st.title(f"🧪 {AI_NAME} - Научный AI-ассистент")
392
- st.markdown(f"**{AI_NAME}** от **{COMPANY_NAME}** | Работает с научными статьями из датасета **ru_science**")
393
-
394
- # Приветствие от AI
395
- if "greeting_shown" not in st.session_state:
396
- st.session_state.greeting_shown = True
397
- greeting = dialog_ai.generate_response("Привет")
398
- st.success(f"🤖 **{AI_NAME}:** {greeting}")
399
-
400
- st.info(f"📚 Загружено {len(articles)} научных статей")
401
-
402
- # Поле для ввода вопроса
403
- st.markdown("### 🔍 Задайте вопрос о науке")
404
- query = st.text_input(
405
- "Введите ваш вопрос:",
406
- placeholder="Например: Как удобрения влияют на урожайность растений?",
407
- key="query_input",
408
- label_visibility="collapsed"
409
- )
410
-
411
- # Кнопка поиска
412
- col1, col2, col3 = st.columns([1, 2, 1])
413
- with col2:
414
- search_button = st.button("🔎 Найти ответ", type="primary", use_container_width=True)
415
-
416
- # Выполняем поиск
417
- if query and search_button:
418
- with st.spinner("🔎 Ищу ответ в научных статьях..."):
419
- results = search_science(query, articles, embeddings, embedder)
420
 
421
- if results:
422
- st.markdown("### 📄 Результаты поиска:")
423
- for i, result in enumerate(results, 1):
424
- with st.expander(f"#{i} {result['title']} (сходство: {result['score']:.2f})", expanded=i==1):
425
- st.write(result['text'] + "...")
426
- st.caption(f"📌 Источник: {result['source']}")
427
- else:
428
- st.warning("😕 Не нашёл подходящих научных статей. Попробуйте уточнить вопрос.")
429
-
430
- elif query and not search_button:
431
- st.info("💡 Нажмите кнопку 'Найти ответ' для поиска")
432
- else:
433
- st.info("💡 Напишите вопрос о науке и нажмите кнопку поиска")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
 
435
  # --- ПОДВАЛ ---
436
  st.divider()
437
- st.caption(f"🧪 {AI_NAME} от {COMPANY_NAME} | Создан в {CREATION_DATE} | На основе датасета ru_science")
438
-
439
- # Кнопка смены темы
440
- if st.button("🎨 Сменить тему"):
441
- st.session_state.theme = "dark" if st.session_state.get("theme") != "dark" else "light"
442
- st.rerun()
443
-
444
- # Информация о датасете
445
- with st.expander("📖 О датасете ru_science"):
446
- st.markdown("""
447
- **ru_science** — это датасет на Hugging Face, содержащий русскоязычные научные статьи.
448
-
449
- ### Особенности:
450
- - Научные статьи по сельскому хозяйству, биологии, химии
451
- - Русскоязычные тексты
452
- - Подходит для обучения AI-моделей
453
- - Используется для поиска и анализа научной информации
454
-
455
- **Источник:** [RafaelUI/ru_science](https://huggingface.co/datasets/RafaelUI/ru_science)
456
- """)
 
35
  ARTICLE_LIMIT = 100
36
  MAX_LENGTH = 256
37
  BATCH_SIZE = 32
38
+ EPOCHS = 3
39
 
40
  LOG_FILE = "query_logs.json"
41
  EMBEDDINGS_FILE = "science_embeddings.npy"
 
50
  HUGGINGFACE = "https://huggingface.co/OpenRussianAI"
51
  CREATION_DATE = "2026"
52
 
53
+ # РАСШИРЕННЫЕ ДИАЛОГИ ДЛЯ ЧАТА
54
  TRAINING_DIALOGS = [
55
+ # Приветствия
56
  {
57
  "context": "Привет",
58
+ "response": "Привет! Я OpenAirAI, ваш научный ассистент от OpenRussianAI. Чем могу помочь? Задавайте вопросы о науке! 🧪"
59
  },
60
+ {
61
+ "context": "Здравствуйте",
62
+ "response": "Здравствуйте! Рад вас видеть! Я OpenAirAI, созданный в 2026 году для помощи в научных исследованиях. Что вас интересует? 🔬"
63
+ },
64
+ {
65
+ "context": "Доброе утро",
66
+ "response": "Доброе утро! Я OpenAirAI, ваш научный помощник. Готов искать ответы на ваши вопросы в научных статьях! ☀️"
67
+ },
68
+ {
69
+ "context": "Добрый день",
70
+ "response": "Добрый день! OpenAirAI на связи. Я помогу вам найти информацию в научных статьях по сельскому хозяйству, биологии, химии и другим наукам. 🌾"
71
+ },
72
+ {
73
+ "context": "Добрый вечер",
74
+ "response": "Добрый вечер! OpenAirAI готов помочь вам в ваших научных исследованиях. Задавайте вопросы! 🌙"
75
+ },
76
+ {
77
+ "context": "Хай",
78
+ "response": "Хай! OpenAirAI здесь. Я создан для работы с научными статьями. Чем могу помочь? 🚀"
79
+ },
80
+ {
81
+ "context": "Здарова",
82
+ "response": "Здарова! OpenAirAI на связи. Готов искать научную информацию для вас! 🔍"
83
+ },
84
+
85
+ # Вопросы о личности
86
  {
87
  "context": "Кто ты",
88
+ "response": "Меня зовут OpenAirAI. Я — AI-ассистент, созданный компанией OpenRussianAI в 2026 году командой разработчиков Грибков Евгений и RootLinux21. Моя специализация — работа с научными статьями."
89
  },
90
  {
91
  "context": "Кто тебя создал",
92
+ "response": "Меня создала команда OpenRussianAI в составе Грибкова Евгения и RootLinux21 в 2026 году. Мы работаем над тем, чтобы сделать научные знания доступными для всех."
93
  },
94
  {
95
+ "context": "Ты кто",
96
+ "response": "Я OpenAirAI, научный AI-ассистент от OpenRussianAI. Создан в 2026 году для поиска и анализа информации в научных статьях."
97
+ },
98
+ {
99
+ "context": "Как тебя зовут",
100
+ "response": "Меня зовут OpenAirAI. Я — ваш интеллектуальный помощник от OpenRussianAI."
101
+ },
102
+
103
+ # Вопросы о компании
104
+ {
105
+ "context": "Что такое OpenRussianAI",
106
+ "response": "OpenRussianAI — это инновационная компания, основанная в 2026 году разработчиками Грибковым Евгением и RootLinux21. Мы создаём интеллектуальных помощников для науки."
107
+ },
108
+ {
109
+ "context": "Какая компания тебя создала",
110
+ "response": "Меня создала компания OpenRussianAI — инновационный проект, основанный в 2026 году. Я — OpenAirAI, их главный научный AI-помощник."
111
  },
112
  {
113
  "context": "Где ваш сайт",
114
+ "response": f"Сайт OpenRussianAI: {WEBSITE}. Там вы узнаете больше о проекте и о мне — OpenAirAI."
115
  },
116
  {
117
  "context": "Где ваши модели",
118
+ "response": f"Модели OpenRussianAI на Hugging Face: {HUGGINGFACE}. Там вы найдёте и меня — OpenAirAI!"
119
  },
120
+
121
+ # Вопросы о возможностях
122
  {
123
+ "context": "Что ты умеешь",
124
+ "response": "Я умею анализировать научные статьи, находить информацию по запросу, помогать с исследованиями в области сельского хозяйства, биологии, химии, физики и других наук. Я работаю с датасетом ru_science."
125
+ },
126
+ {
127
+ "context": "Ты умеешь искать",
128
+ "response": "Да, я умею искать информацию в научных статьях из датасета ru_science. Просто задайте вопрос, и я найду релевантные статьи."
129
+ },
130
+ {
131
+ "context": "Чем ты можешь помочь",
132
+ "response": "Я могу помочь найти научную информацию, ответить на вопросы по естественным наукам, найти статьи по вашей теме исследования. Задавайте вопросы!"
133
  },
134
+
135
+ # Прощания
136
  {
137
  "context": "Пока",
138
  "response": "До свидания! OpenAirAI всегда на связи. Удачи в исследованиях! 👋"
139
+ },
140
+ {
141
+ "context": "До свидания",
142
+ "response": "До свидания! Был рад помочь вам. Приходите ещё, OpenAirAI всегда готов помочь! 👋"
143
+ },
144
+ {
145
+ "context": "Спасибо",
146
+ "response": "Всегда рад помочь! Я, OpenAirAI, здесь для ваших научных исследований. Обращайтесь! 😊"
147
+ },
148
+ {
149
+ "context": "Спасибо большое",
150
+ "response": "Пожалуйста! Рад был помочь. OpenAirAI всегда на связи для ваших научных вопросов! 🌟"
151
+ },
152
+
153
+ # Научные вопросы
154
+ {
155
+ "context": "Расскажи о себе",
156
+ "response": "Я — OpenAirAI, научный AI-помощник от OpenRussianAI. Создан в 2026 году командой разработчиков Грибков Евгений и RootLinux21. Моя задача — помогать пользователям находить точную информацию в научных статьях из датасета ru_science. Я использую передовые технологии обработки естественного языка."
157
+ },
158
+ {
159
+ "context": "Ты знаешь науку",
160
+ "response": "Да, я специализируюсь на научной информации. Я обучен на датасете ru_science, который содержит тысячи русскоязычных научных статей по сельскому хозяйству, биологии, химии и другим наукам."
161
+ },
162
+ {
163
+ "context": "Что такое ru_science",
164
+ "response": "ru_science — это датасет на Hugging Face, содержащий русскоязычные научные статьи. На нём я, OpenAirAI, был обучен компанией OpenRussianAI в 2026 году. Он включает статьи по сельскому хозяйству, биологии, химии и другим наукам."
165
  }
166
  ]
167
 
 
299
  similarities = F.cosine_similarity(query_embedding, context_embeddings)
300
  best_idx = torch.argmax(similarities).item()
301
 
302
+ if similarities[best_idx] > 0.4: # Понижаем порог для приветствий
303
  return self.responses[best_idx]
304
  else:
305
+ return f"Я {self.name}, научный AI-ассистент от {self.company}. Создан в {self.creation_date}. Чем могу помочь? Задавайте вопросы о науке! 🧪"
306
 
307
  # ===================================================================
308
  # 3. БЫСТРАЯ ЗАГРУЗКА НАУЧНЫХ СТАТЕЙ
 
345
  return [
346
  {
347
  "id": 1,
348
+ "title": "Нейроны: строение и функции",
349
+ "text": "Нейроны — это основные клетки нервной системы. Они состоят из тела клетки (сомы), дендритов и аксона. Нейроны передают электрические и химические сигналы. Синапсы — это места контакта между нейронами.",
350
  "source": "test"
351
  },
352
  {
353
  "id": 2,
354
+ "title": "Влияние удобрений на рост растений",
355
+ "text": "Исследование показывает, что применение азотных удобрений значительно увеличивает урожайность сельскохозяйственных культур. Оптимальная доза составляет 120 кг/га.",
356
+ "source": "test"
357
+ },
358
+ {
359
+ "id": 3,
360
  "title": "Методы биоконверсии",
361
+ "text": "Биоконверсия позволяет эффективно перерабатывать органические отходы в ценные удобрения. Процесс основан на деятельности микроорганизмов.",
362
  "source": "test"
363
  }
364
  ]
 
390
  return embeddings
391
 
392
  # ===================================================================
393
+ # 4. ФУНКЦИИ ПОИСКА И ЧАТА
394
  # ===================================================================
395
 
396
  def search_science(query, _articles, _embeddings, _embedder):
 
405
  results = []
406
  for idx in top_indices:
407
  score = float(scores[int(idx)])
408
+ if score > 0.15: # Понижаем порог
409
  article = _articles[int(idx)]
410
  results.append({
411
  "title": article['title'],
 
427
  return results
428
 
429
  # ===================================================================
430
+ # 5. ЧАТ-ИНТЕРФЕЙС
431
  # ===================================================================
432
 
433
  # ЗАГРУЗКА
 
443
 
444
  dialog_ai = st.session_state.dialog_ai
445
 
446
+ # Инициализация истории чата
447
+ if "messages" not in st.session_state:
448
+ st.session_state.messages = []
449
+ # Добавляем приветственное сообщение от AI
450
+ greeting = dialog_ai.generate_response("Привет")
451
+ st.session_state.messages.append({"role": "assistant", "content": greeting})
452
+
453
+ # --- БОКОВАЯ ПАНЕЛЬ ---
454
  with st.sidebar:
455
  st.image("https://cdn-icons-png.flaticon.com/512/4248/4248455.png", width=80)
456
  st.title(f"🧪 {AI_NAME}")
 
472
  **📊 Статистика:**
473
 
474
  - Научных статей: {len(articles)}
475
+ - Сообщений: {len(st.session_state.messages)}
476
  """)
477
 
478
  if os.path.exists(EMBEDDINGS_FILE):
479
  size = os.path.getsize(EMBEDDINGS_FILE) / (1024 * 1024)
480
  st.caption(f"💾 Эмбеддинги: {size:.1f} MB")
481
+
482
+ # Кнопка очистки чата
483
+ if st.button("🗑️ Очистить чат", type="secondary"):
484
+ st.session_state.messages = []
485
+ greeting = dialog_ai.generate_response("Привет")
486
+ st.session_state.messages.append({"role": "assistant", "content": greeting})
487
+ st.rerun()
488
+
489
+ # --- ОСНОВНАЯ ЧАСТЬ (ЧАТ) ---
490
  st.title(f"🧪 {AI_NAME} - Научный AI-ассистент")
491
+ st.markdown(f"**{AI_NAME}** от **{COMPANY_NAME}** | Работает с научными статьями")
492
+
493
+ # Отображение сообщений
494
+ chat_container = st.container()
495
+ with chat_container:
496
+ for message in st.session_state.messages:
497
+ with st.chat_message(message["role"]):
498
+ st.markdown(message["content"])
499
+
500
+ # Если это ответ ассистента с научными статьями, показываем их
501
+ if message.get("articles"):
502
+ for i, article in enumerate(message["articles"], 1):
503
+ with st.expander(f"📄 #{i} {article['title']} (сходство: {article['score']:.2f})"):
504
+ st.write(article['text'] + "...")
505
+ st.caption(f"📌 Источник: {article['source']}")
506
+
507
+ # Поле ввода
508
+ if prompt := st.chat_input("Задайте вопрос о науке..."):
509
+ # Добавляем сообщение пользователя
510
+ st.session_state.messages.append({"role": "user", "content": prompt})
 
 
 
 
 
 
 
 
511
 
512
+ with st.chat_message("user"):
513
+ st.markdown(prompt)
514
+
515
+ # Генерируем ответ
516
+ with st.chat_message("assistant"):
517
+ with st.spinner("Думаю..."):
518
+ # Проверяем, является ли вопрос приветствием
519
+ is_greeting = any(word in prompt.lower() for word in ["привет", "здравств", "добр", "хай", "здаров", "hi", "hello"])
520
+
521
+ if is_greeting:
522
+ # Отвечаем как AI
523
+ response = dialog_ai.generate_response(prompt)
524
+ st.markdown(response)
525
+ st.session_state.messages.append({"role": "assistant", "content": response})
526
+ else:
527
+ # Ищем в научных статьях
528
+ results = search_science(prompt, articles, embeddings, embedder)
529
+
530
+ if results:
531
+ # Формируем ответ с результатами
532
+ response = f"🔍 Я нашел в научных статьях информацию по вашему запросу:\n\n"
533
+ for i, result in enumerate(results, 1):
534
+ response += f"**{i}. {result['title']}** (сходство: {result['score']:.2f})\n"
535
+ response += f"{result['text'][:300]}...\n\n"
536
+
537
+ st.markdown(response)
538
+ st.session_state.messages.append({
539
+ "role": "assistant",
540
+ "content": response,
541
+ "articles": results
542
+ })
543
+ else:
544
+ # Если ничего не найдено
545
+ response = "😕 Я не нашел подходящих научных статей по вашему запросу. Попробуйте переформулировать вопрос или спросить о другой теме."
546
+ st.markdown(response)
547
+ st.session_state.messages.append({"role": "assistant", "content": response})
548
+
549
+ # Перезагружаем страницу для обновления чата
550
+ st.rerun()
551
 
552
  # --- ПОДВАЛ ---
553
  st.divider()
554
+ st.caption(f"🧪 {AI_NAME} от {COMPANY_NAME} | Создан в {CREATION_DATE} | На основе датасета ru_science")