vydrking commited on
Commit
490fb9e
·
verified ·
1 Parent(s): 53fe915

Upload 22 files

Browse files
__pycache__/knowledge_base.cpython-310.pyc ADDED
Binary file (9.91 kB). View file
 
app.py CHANGED
@@ -26,6 +26,18 @@ def chat_with_bot(message, history):
26
  if not response or response.startswith('[') or len(response.strip()) < 5:
27
  response = 'К сожалению, не смог сгенерировать ответ. Попробуйте переформулировать вопрос.'
28
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  return history + [[message, response]], ''
30
  except Exception as e:
31
  print(f'Ошибка в чате: {e}')
 
26
  if not response or response.startswith('[') or len(response.strip()) < 5:
27
  response = 'К сожалению, не смог сгенерировать ответ. Попробуйте переформулировать вопрос.'
28
 
29
+ # Убираем лишние скобки и форматирование
30
+ if response.startswith('[[') and response.endswith(']]'):
31
+ # Извлекаем только текст ответа из формата [['user', 'bot_response']]
32
+ try:
33
+ import ast
34
+ parsed = ast.literal_eval(response)
35
+ if isinstance(parsed, list) and len(parsed) > 0 and isinstance(parsed[0], list) and len(parsed[0]) > 1:
36
+ response = parsed[0][1]
37
+ except:
38
+ # Если не удалось распарсить, берем как есть
39
+ pass
40
+
41
  return history + [[message, response]], ''
42
  except Exception as e:
43
  print(f'Ошибка в чате: {e}')
app_simple_fixed.py ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from knowledge_base import KnowledgeBase
3
+
4
+ # Инициализация базы знаний
5
+ kb = KnowledgeBase()
6
+
7
+ def is_itmo_query(message):
8
+ itmo_keywords = [
9
+ 'итмо', 'магистратура', 'учебный план', 'дисциплина', 'курс',
10
+ 'ии', 'ai', 'ai product', 'институт ии', 'программа',
11
+ 'машинное обучение', 'глубокое обучение', 'nlp', 'компьютерное зрение'
12
+ ]
13
+ message_lower = message.lower()
14
+ return any(keyword in message_lower for keyword in itmo_keywords)
15
+
16
+ def simple_search(query, courses):
17
+ query_lower = query.lower()
18
+ results = []
19
+
20
+ for course in courses:
21
+ course_text = f"{course['name']} {course.get('short_desc', '')}".lower()
22
+ if any(word in course_text for word in query_lower.split()):
23
+ results.append(course)
24
+
25
+ return results[:3] # Возвращаем топ-3 результата
26
+
27
+ def chat_with_bot(message, history):
28
+ if not message.strip():
29
+ return history, ''
30
+
31
+ if not is_itmo_query(message):
32
+ return history + [[message, '''Похоже, вопрос не относится к магистратурам ITMO и их учебным планам.
33
+
34
+ Попробуйте спросить, например:
35
+ • "Какие дисциплины по NLP в 1 семестре программы ИИ?"
36
+ • "Расскажи о программе AI Product"
37
+ • "Какие курсы по машинному обучению есть в программе ИИ?"
38
+ • "Сколько кредитов за дисциплину 'Глубокое обучение'?"''']], ''
39
+
40
+ results = simple_search(message, kb.courses)
41
+
42
+ if not results:
43
+ response = 'К сожалению, не нашел релевантной информации в учебных планах ITMO. Попробуйте переформулировать вопрос.'
44
+ else:
45
+ response = 'Найденные курсы:\n\n'
46
+ for i, course in enumerate(results, 1):
47
+ response += f'{i}. {course["name"]} ({course["semester"]} семестр, {course["credits"]} кредитов)\n'
48
+ if course.get('short_desc'):
49
+ response += f' {course["short_desc"]}\n'
50
+ response += '\n'
51
+
52
+ return history + [[message, response]], ''
53
+
54
+ def get_recommendations(programming_exp, math_level, interests, semester, skills):
55
+ if not semester:
56
+ return 'Пожалуйста, укажите семестр для получения рекомендаций.'
57
+
58
+ try:
59
+ semester = int(semester)
60
+ except ValueError:
61
+ return 'Пожалуйста, выберите корректный семестр.'
62
+
63
+ filtered_courses = kb.get_courses_by_semester(semester)
64
+
65
+ if not filtered_courses:
66
+ return f'К сожалению, не найдено курсов для {semester} семестра.'
67
+
68
+ # Простая логика рекомендаций
69
+ recommendations = []
70
+ for course in filtered_courses[:5]: # Топ-5 курсов
71
+ score = 0
72
+ why_reasons = []
73
+
74
+ # Оценка по интересам
75
+ all_interests = interests + skills
76
+ matching_tags = [tag for tag in all_interests if tag in course.get('tags', [])]
77
+ if matching_tags:
78
+ score += 2
79
+ why_reasons.append(f'соответствует вашим интересам: {", ".join(matching_tags)}')
80
+
81
+ # Оценка по опыту программирования
82
+ if programming_exp >= 3 and any(tag in course.get('tags', []) for tag in ['ml', 'dl', 'systems']):
83
+ score += 1
84
+ why_reasons.append('подходит для вашего уровня программирования')
85
+
86
+ # Оценка по математике
87
+ if math_level >= 3 and any(tag in course.get('tags', []) for tag in ['math', 'stats', 'dl']):
88
+ score += 1
89
+ why_reasons.append('соответствует вашему уровню математики')
90
+
91
+ if score > 0:
92
+ recommendations.append({
93
+ 'name': course['name'],
94
+ 'credits': course['credits'],
95
+ 'why': '; '.join(why_reasons) if why_reasons else 'курс из учебного плана программы'
96
+ })
97
+
98
+ if not recommendations:
99
+ # Если нет подходящих, показываем все курсы
100
+ for course in filtered_courses[:3]:
101
+ recommendations.append({
102
+ 'name': course['name'],
103
+ 'credits': course['credits'],
104
+ 'why': 'курс из учебного плана программы'
105
+ })
106
+
107
+ result = f'🎯 Рекомендуемые курсы для {semester} семестра:\n\n'
108
+ for i, rec in enumerate(recommendations, 1):
109
+ result += f'{i}. {rec["name"]} ({rec["credits"]} кредитов)\n'
110
+ result += f' {rec["why"]}\n\n'
111
+
112
+ return result
113
+
114
+ def update_data_ui():
115
+ return 'Данные успешно обновлены! (Используются данные из базы знаний)'
116
+
117
+ def update_data_thread():
118
+ return gr.update(value='Обновление данных...', interactive=False)
119
+
120
+ with gr.Blocks(title='ITMO Магистратура - Чат-бот', theme=gr.themes.Soft()) as demo:
121
+ gr.Markdown('# 🤖 Чат-бот для абитуриентов магистратур ITMO')
122
+ gr.Markdown('Задавайте вопросы о программах ИИ и AI Product, получайте персональные рекомендации по курсам.')
123
+
124
+ with gr.Row():
125
+ with gr.Column(scale=2):
126
+ chatbot_interface = gr.ChatInterface(
127
+ chat_with_bot,
128
+ title='💬 Чат с ботом',
129
+ description='Спрашивайте о дисциплинах, программах, учебных планах',
130
+ examples=[
131
+ 'Какие дисциплины по NLP в 1 семестре программы ИИ?',
132
+ 'Расскажи о программе AI Product',
133
+ 'Какие курсы по машинному обучению есть в программе ИИ?',
134
+ 'Сколько кредитов за дисциплину "Глубокое обучение"?'
135
+ ]
136
+ )
137
+
138
+ with gr.Column(scale=1):
139
+ gr.Markdown('### 👤 Профиль для рекомендаций')
140
+
141
+ with gr.Row():
142
+ programming_exp = gr.Slider(
143
+ minimum=0, maximum=5, value=2, step=1,
144
+ label='Опыт программирования (0-5)',
145
+ info='0 - нет опыта, 5 - эксперт'
146
+ )
147
+
148
+ math_level = gr.Slider(
149
+ minimum=0, maximum=4, value=2, step=1,
150
+ label='Уровень математики (0-4)',
151
+ info='0 - базовый, 4 - продвинутый'
152
+ )
153
+
154
+ gr.Markdown('**Интересы:**')
155
+ interests = gr.CheckboxGroup(
156
+ choices=['ml', 'dl', 'nlp', 'cv', 'product', 'business', 'research', 'data', 'systems'],
157
+ value=['ml'],
158
+ label='Области интересов',
159
+ info='Выберите интересующие направления'
160
+ )
161
+
162
+ gr.Markdown('**Навыки:**')
163
+ skills = gr.CheckboxGroup(
164
+ choices=['python', 'java', 'sql', 'git', 'docker', 'aws', 'tensorflow', 'pytorch', 'scikit-learn'],
165
+ value=['python'],
166
+ label='Технические навыки',
167
+ info='Выберите имеющиеся навыки'
168
+ )
169
+
170
+ semester = gr.Dropdown(
171
+ choices=['1', '2', '3', '4'],
172
+ label='Целевой семестр',
173
+ info='Для получения рекомендаций'
174
+ )
175
+
176
+ recommend_btn = gr.Button('🎯 Получить рекомендации', variant='primary')
177
+ recommendations_output = gr.Textbox(
178
+ label='Рекомендации',
179
+ lines=12,
180
+ interactive=False
181
+ )
182
+
183
+ recommend_btn.click(
184
+ get_recommendations,
185
+ inputs=[programming_exp, math_level, interests, semester, skills],
186
+ outputs=recommendations_output
187
+ )
188
+
189
+ with gr.Row():
190
+ update_btn = gr.Button('🔄 Обновить данные', variant='secondary')
191
+ update_status = gr.Textbox(
192
+ label='Статус обновления',
193
+ interactive=False,
194
+ visible=False
195
+ )
196
+
197
+ update_btn.click(
198
+ update_data_thread,
199
+ outputs=update_status
200
+ ).then(
201
+ update_data_ui,
202
+ outputs=update_status
203
+ )
204
+
205
+ if __name__ == '__main__':
206
+ demo.launch(server_name='0.0.0.0', server_port=7860)
chatbot.py CHANGED
@@ -107,12 +107,22 @@ class ITMOChatbot:
107
 
108
  answer = response[0]['generated_text'].strip()
109
 
110
- # Очистка ответа
111
  if answer.startswith('Ответ:'):
112
  answer = answer[6:].strip()
113
  elif answer.startswith('Бот:'):
114
  answer = answer[4:].strip()
115
 
 
 
 
 
 
 
 
 
 
 
116
  # Проверяем, что ответ не пустой и не содержит технических деталей
117
  if answer and len(answer) > 10 and not answer.startswith('['):
118
  return answer
@@ -158,7 +168,7 @@ class ITMOChatbot:
158
 
159
  def _build_prompt(self, message: str, context: List[Dict], history: List[List[str]]) -> str:
160
  # Системные инструкции
161
- system_prompt = '''Ты - помощник для абитуриентов магистратур ITMO. Отвечай на вопросы о программах и курсах на основе предоставленного контекста. Отвечай кратко, дружелюбно и по делу. Если информации недостаточно, скажи об этом прямо.'''
162
 
163
  # История диалога (последние 3 хода)
164
  history_text = ''
 
107
 
108
  answer = response[0]['generated_text'].strip()
109
 
110
+ # Очистка ответа от лишних элементов
111
  if answer.startswith('Ответ:'):
112
  answer = answer[6:].strip()
113
  elif answer.startswith('Бот:'):
114
  answer = answer[4:].strip()
115
 
116
+ # Убираем лишние скобки и форматирование
117
+ if answer.startswith('[[') and answer.endswith(']]'):
118
+ try:
119
+ import ast
120
+ parsed = ast.literal_eval(answer)
121
+ if isinstance(parsed, list) and len(parsed) > 0 and isinstance(parsed[0], list) and len(parsed[0]) > 1:
122
+ answer = parsed[0][1]
123
+ except:
124
+ answer = self._fallback_answer(context)
125
+
126
  # Проверяем, что ответ не пустой и не содержит технических деталей
127
  if answer and len(answer) > 10 and not answer.startswith('['):
128
  return answer
 
168
 
169
  def _build_prompt(self, message: str, context: List[Dict], history: List[List[str]]) -> str:
170
  # Системные инструкции
171
+ system_prompt = '''Ты - помощник для абитуриентов магистратур ITMO. Отвечай на вопросы о программах и курсах на основе предоставленного контекста. Отвечай кратко, дружелюбно и по делу. Если информации недостаточно, скажи об этом прямо. НЕ используй скобки или специальное форматирование в ответе.'''
172
 
173
  # История диалога (последние 3 хода)
174
  history_text = ''
test_data.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from knowledge_base import KnowledgeBase
2
+
3
+ def test_data():
4
+ print("Тестирование базы знаний...")
5
+
6
+ kb = KnowledgeBase()
7
+ print(f"Курсов в базе: {len(kb.courses)}")
8
+
9
+ if kb.courses:
10
+ print("Первые 3 курса:")
11
+ for i, course in enumerate(kb.courses[:3], 1):
12
+ print(f"{i}. {course['name']} (семестр {course.get('semester', 'N/A')})")
13
+ else:
14
+ print("Курсы не найдены!")
15
+
16
+ print(f"Программ в базе: {len(kb.programs)}")
17
+
18
+ # Тест поиска по семестрам
19
+ for semester in [1, 2, 3, 4]:
20
+ courses = kb.get_courses_by_semester(semester)
21
+ print(f"Семестр {semester}: {len(courses)} курсов")
22
+
23
+ if __name__ == '__main__':
24
+ test_data()