Seppukku commited on
Commit
6863690
1 Parent(s): b89db29

titule image

Browse files
Files changed (3) hide show
  1. app.py +16 -11
  2. images/dog.png +0 -0
  3. pages/Summary.py +112 -31
app.py CHANGED
@@ -2,31 +2,36 @@ import streamlit as st
2
  from PIL import Image
3
 
4
  # Заголовок страницы
5
- st.set_page_config(page_title="AI Knowledge Assistant", page_icon="🤖", layout="wide")
6
 
7
  # Создание колонок для размещения текста и изображения
8
  col1, col2 = st.columns([2, 1])
9
 
10
  # Контент первой колонки (основной текст)
11
  with col1:
12
- st.title("AI Knowledge Assistant 🤖")
13
  st.markdown("""
14
- ## Добро пожаловать в вашу персональную AI-систему для вопросов по машинному обучению!
 
 
 
 
 
 
15
 
16
  Этот проект состоит из двух мощных инструментов:
17
- - **Первая страница:** Система Retrieval-Augmented Generation (RAG), которая отвечает на вопросы, используя базу знаний, собранную из транскриптов YouTube-видео по машинному обучению.
18
- - **Вторая страница:** Инструмент для создания текстовых саммари по видео. Просто введите ссылку на YouTube и выберите тип саммари, чтобы получить краткое содержание.
19
-
20
- ### Начните с первой страницы и получите ответы на вопросы по машинному обучению, или перейдите на вторую страницу для саммари видео!
21
- """)
22
 
23
  # Кнопка для перехода к первому инструменту
24
  #st.button("Перейти к системе RAG")
25
 
26
  # Контент второй колонки (изображение)
27
  with col2:
28
- image = Image.open('images/ai_assistant.png') # Загрузите изображение для более привлекательного вида
29
- st.image(image, caption="AI Knowledge Assistant", use_column_width=True)
30
 
31
  # Линия для разделения контента
32
  st.markdown("---")
@@ -34,6 +39,6 @@ st.markdown("---")
34
  # Добавим небольшой футер с информацией о проекте
35
  st.markdown("""
36
  <div style='text-align: center; color: gray;'>
37
- <small>Этот проект создан для помощи в изучении машинного обучения, предоставляя ответы на основе видео и облегчая получение информации с YouTube. Разработано с любовью к AI и Data Science.</small>
38
  </div>
39
  """, unsafe_allow_html=True)
 
2
  from PIL import Image
3
 
4
  # Заголовок страницы
5
+ st.set_page_config(page_title="Golden RetrAIever", page_icon="🤖", layout="wide")
6
 
7
  # Создание колонок для размещения текста и изображения
8
  col1, col2 = st.columns([2, 1])
9
 
10
  # Контент первой колонки (основной текст)
11
  with col1:
12
+ st.title("Golden RetrAIever - AI Knowledge Assistant 🤖")
13
  st.markdown("""
14
+ #### Сервис для подготовки к интервью и проф роста в DS/ML/DL
15
+
16
+ ## Как использовать продукт, чтобы подготовиться к интервью?
17
+ - Задать прямые вопросы про ML / NN / Math
18
+ - Делайте самопроверку
19
+ - Переслушивайте теорию за 15 минут, а не 2 часа!
20
+ - Кайфуйте. Если заскучали, то найдите очередной ролик на Ютуб про ML - и найдите пункт "заскучал" на этом сайте. Мы предложим решение :)
21
 
22
  Этот проект состоит из двух мощных инструментов:
23
+ - **Первая страница:** Система Retrieval-Augmented Generation (RAG), которая отвечает на вопросы, используя базу знаний, собранную из YouTube-видео - топ 5 каналов в мире!
24
+ - **Вторая страница:** Инструмент для создания текстовых саммари по видео. Просто введите ссылку на YouTube и выберите тип саммари. Основано на современной педагогике. Сделано с Anthropic API с любовью к искусству промпт инжиниринга.
25
+
26
+ ### Начните с первой страницы и получите ответы на вопросы по ML, Neural Networks, математике и всему, что нужно! """)
 
27
 
28
  # Кнопка для перехода к первому инструменту
29
  #st.button("Перейти к системе RAG")
30
 
31
  # Контент второй колонки (изображение)
32
  with col2:
33
+ image = Image.open('images/dog.png') # Загрузите изображение для более привлекательного вида
34
+ st.image(image, caption="", use_column_width=True)
35
 
36
  # Линия для разделения контента
37
  st.markdown("---")
 
39
  # Добавим небольшой футер с информацией о проекте
40
  st.markdown("""
41
  <div style='text-align: center; color: gray;'>
42
+ <small>Сервис для подготовки к интервью и проф роста в DS/ML/DL Мы на связи: Настя @anastasiap20, Саша @seppokku, Наташа @npatashkevich</small>
43
  </div>
44
  """, unsafe_allow_html=True)
images/dog.png ADDED
pages/Summary.py CHANGED
@@ -4,10 +4,15 @@ from youtube_transcript_api import YouTubeTranscriptApi
4
  import anthropic
5
  import os
6
  from dotenv import load_dotenv
 
7
 
8
  # Загрузка переменных окружения из .env файла
9
  load_dotenv()
10
 
 
 
 
 
11
  # Получаем ключи API из переменных окружения
12
  youtube_api_key = os.getenv("YOUTUBE_API_KEY")
13
  claude_api_key = os.getenv("CLAUDE_API_KEY")
@@ -15,6 +20,7 @@ claude_api_key = os.getenv("CLAUDE_API_KEY")
15
  # Инициализация клиента Claude
16
  client = anthropic.Client(api_key=claude_api_key)
17
 
 
18
  def get_video_id(url):
19
  if "v=" in url:
20
  return url.split("v=")[1].split("&")[0]
@@ -23,20 +29,20 @@ def get_video_id(url):
23
  return None
24
 
25
  def get_transcript(video_id):
26
- # try:
27
- transcript = YouTubeTranscriptApi.get_transcript(video_id, languages=['ru', 'en'])
28
- return ' '.join([x['text'] for x in transcript])
29
- # except Exception as e:
30
- # st.error(f"Ошибка получения транскрипта: {e}")
31
- # return None
32
 
33
  def generate_summary_with_claude(transcript, prompt_text):
34
  try:
35
  message = client.messages.create(
36
  model="claude-3-5-sonnet-20240620",
37
  extra_headers={"anthropic-beta": "prompt-caching-2024-07-31"},
38
- max_tokens=1500,
39
- temperature=0.05,
40
  messages=[
41
  {
42
  "role": "user",
@@ -58,34 +64,109 @@ def generate_summary_with_claude(transcript, prompt_text):
58
  except Exception as e:
59
  st.error(f"Ошибка при обращении к Claude: {e}")
60
  return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
- st.title("YouTube Video Analysis with Claude")
63
-
64
-
65
- url = st.text_input("Введите ссылку на YouTube видео:")
66
- if url:
67
- video_id = get_video_id(url)
68
- if video_id:
69
- transcript = get_transcript(video_id)
70
- if transcript:
71
- summary_options = {
72
- "Хочу переслушать лекцию. Пока��и таймстемпы": "List all themes and subthemes. Split into short blocks. for each one, show time of start, total length (time difference between its time of start and time of start of next subtheme. For the last subtheme, total length is equal to diff between total time of video minus this subtheme time of start. WRite in Russian. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted.",
73
- "Ценю свое время. Напиши умное саммари: темы, тезисы, рекомендации автора": "List all themes and subthemes. Split into short blocks. Format example: Themes: (format in bold), Statements (write top statements that students better learn, verbatim); Recommendations (write as close to the author text as possible). Write in Russian. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted.",
74
- "Заскучал. Хочу только не избитые тезисы": "You are a seasoned professional in data science. Start with the following, without preface. 1. Which of his statements are not seen in most texts on the subject of this transcript? Note timestamp. 2. Which logical connections between big blocks are not trivial? Note timestamp. 3. Give his top one most fun or useful statement, note timestamp. Write in Russian. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted.",
75
- "Не хочу писать конспект детальный - напиши вместо меня": "Assume the role of the PhD student who is best in the world at writing extremely detailed summaries. Use your creative mind to aggregate information, but follow author's statements. Avoid stating themes - write his statements instead. Structure with paragraphs. Remove intro and outro. If there are action items, write them; if there are none, do not write them. Write in Russian. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted",
76
- "Подсвети “фигню” в этом видео. Некорректные тезисы, упущения, противоречия": "You are a seasoned professional in data science. Start with the following, without preface. Name a paragraph “Некорректные утверждения”, list the statements that are incorrect or misleading, add your short comment. In Russian. If there are none, write “Явно некорректных утверждений нет”. Name next paragraph “Упущения”. Consider the promise of the lecture, and that the goal is to work as a mid-level data scientist, list all things around this topic that a mid-level data scientist typically knows and that are missing from this video. Write in Russian. Name next paragraph “Что еще важно изучить”. Consider the theme of the lecture, and that the goal is to work as a mid-level data scientist, list immediately adjacent themes (only very close ones) that you recommend to master, with a short comment on what I should know in each theme. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted.",
77
- "Нужно отработать материал. Задай мне простые и сложные вопросы по видео": "Here is an interview, list all the questions. Write his words fully, but edit for spelling and punctuation. In numbered list. Write in Russian. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted.",
78
- "Готовлюсь к интервью на работу. Это мок интервью, выпиши все вопросы": "Your goal: help me get to the level of mid-level data scientist, by generating self-check questions based on a lecture transcript. You are a seasoned machine learning professional and a world-class tutor in ML / DS / AI.\nFirst, carefully read through the provided lecture transcript.\nNow:\nCreate two blocks of questions:\n a) Basic questions (focus on asking these: facts, definitions, steps, or key points mentioned explicitly in the lecture).\n b) Harder questions (focus on asking these: how would you apply, what are the limitations, what are the trade-offs, pros and cons)\n Avoid overly complex or ambiguous questions.\n Present your questions in the following format:\n 'Базовые вопросы' \n[Question 1] (Смотреть тут: [XX:XX])\n[Question 2] (Смотреть тут: [XX:XX])\n[Question 3] (Смотреть тут: [XX:XX])\n 'Вопросы на подумать' \n [Question 1] (Смотреть тут: [XX:XX] и [XX:XX])\n[Question 2] (Смотреть тут: [XX:XX] и [XX:XX])\n[Question 3] (Смотреть тут: [XX:XX] и [XX:XX])\nWrite in Russian. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted."
79
  }
80
 
81
- selected_summary = st.radio("Выберите тип саммари:", list(summary_options.keys()))
82
-
83
- if st.button("Запустить анализ"):
 
 
 
 
 
 
 
 
 
 
84
  prompt_text = summary_options[selected_summary]
85
- with st.spinner("Подождите, идет загрузка саммари..."):
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  result = generate_summary_with_claude(transcript, prompt_text)
87
 
88
- st.text_area("Результат анализ��:", result, height=1500)
 
 
 
 
 
89
  else:
90
- st.error("Не удалось извлечь видео ID из ссылки.")
91
 
 
4
  import anthropic
5
  import os
6
  from dotenv import load_dotenv
7
+ import re
8
 
9
  # Загрузка переменных окружения из .env файла
10
  load_dotenv()
11
 
12
+
13
+ proxies = {
14
+ "http": "http://104.207.53.76:3128"
15
+ }
16
  # Получаем ключи API из переменных окружения
17
  youtube_api_key = os.getenv("YOUTUBE_API_KEY")
18
  claude_api_key = os.getenv("CLAUDE_API_KEY")
 
20
  # Инициализация клиента Claude
21
  client = anthropic.Client(api_key=claude_api_key)
22
 
23
+ # Функции для работы с видео
24
  def get_video_id(url):
25
  if "v=" in url:
26
  return url.split("v=")[1].split("&")[0]
 
29
  return None
30
 
31
  def get_transcript(video_id):
32
+ try:
33
+ transcript = YouTubeTranscriptApi.get_transcript(video_id, languages=['ru', 'en'], proxies=proxies)
34
+ return ' '.join([x['text'] for x in transcript])
35
+ except Exception as e:
36
+ st.error(f"Ошибка получения транскрипта: {e}")
37
+ return None
38
 
39
  def generate_summary_with_claude(transcript, prompt_text):
40
  try:
41
  message = client.messages.create(
42
  model="claude-3-5-sonnet-20240620",
43
  extra_headers={"anthropic-beta": "prompt-caching-2024-07-31"},
44
+ max_tokens=2000,
45
+ temperature=0.1,
46
  messages=[
47
  {
48
  "role": "user",
 
64
  except Exception as e:
65
  st.error(f"Ошибка при обращении к Claude: {e}")
66
  return None
67
+
68
+ def format_answer(answer):
69
+ """
70
+ Форматирует ответ с учетом следующих условий:
71
+ 1. Нумерованные списки
72
+ 2. Выделение фрагментов кода
73
+ 3. Корректное отображение абзацев и маркированных списков
74
+ """
75
+ # Разделим ответ на текстовые и кодовые блоки с помощью регулярных выражений
76
+ parts = re.split(r'(```.*?```)', answer, flags=re.DOTALL)
77
+
78
+ for part in parts:
79
+ if part.startswith('```') and part.endswith('```'):
80
+ # Убираем тройные кавычки и выводим содержимое как код
81
+ language_and_code = part[3:-3].strip().split("\n", 1)
82
+ if len(language_and_code) == 2:
83
+ language, code = language_and_code
84
+ st.code(code, language=language)
85
+ else:
86
+ st.code(language_and_code[0])
87
+ else:
88
+ # Обычный текст
89
+ # Форматируем как нумерованный список, если необходимо
90
+ if re.search(r'(\d+\.\s+)', part):
91
+ part = format_as_numbered_list(part)
92
+ # Обрабатываем абзацы и маркированные списки
93
+ paragraphs = part.split('\n\n')
94
+ for paragraph in paragraphs:
95
+ if re.match(r'^\d+\.\s', paragraph): # Нумерованный список
96
+ st.markdown(paragraph)
97
+ elif re.match(r'^\*\s', paragraph): # Маркированный список
98
+ st.markdown(paragraph)
99
+ else: # Обычные абзацы
100
+ st.markdown(paragraph)
101
+
102
+ # Функция для нумерованных списков
103
+ def format_as_numbered_list(text):
104
+ # Удаляем лишние номера перед предложениями
105
+ cleaned_text = re.sub(r'\d+\n', '', text) # Удаляем цифры с новой строки
106
+ cleaned_text = re.sub(r'\d+\s+', '', cleaned_text) # Удаляем цифры перед предложениями
107
+ sentences = cleaned_text.splitlines()
108
+
109
+ # Формируем нумерованный список
110
+ numbered_list = ""
111
+ for i, sentence in enumerate(sentences, start=1):
112
+ if sentence.strip(): # Пропускаем пустые строки
113
+ numbered_list += f"{i}. {sentence.strip()}\n"
114
 
115
+ return numbered_list
116
+
117
+ # STREAMLIT
118
+
119
+ # Заголовки с эмодзи и более дружелюбным тоном
120
+ st.title("Смотрим лекции YouTube как Суперчеловек 💪")
121
+ st.subheader("Можно сделать самые разные виды анализа. Зацените! И выберите, что важно нужно прямо сейчас?")
122
+
123
+ # Описания типов саммари
124
+ summary_options = {
125
+ "🕒 Хочу переслушать лекцию. Покажи таймстемпы": "List all themes and subthemes. Split into short blocks. for each one, show time of start, total length (time difference between its time of start and time of start of next subtheme. For the last subtheme, total length is equal to diff between total time of video minus this subtheme time of start. WRite in Russian. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted. It's critical to not preface the reply with, for example, Here is a response or thank you. Start with the reply itself.",
126
+ "📝 Ценю свое время. Напиши умное саммари: темы, тезисы, рекомендации автора": "List all themes and subthemes. Split into short blocks. Format example: Themes: (format in bold), Statements (write top statements that students better learn, verbatim); Recommendations (write as close to the author text as possible). Write in Russian. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted. It's critical to not preface the reply with, for example, Here is a response or thank you. Start with the reply itself.",
127
+ "💡 Заскучал. Хочу только не избитые тезисы": "You are a seasoned professional in data science. Start with the following, without preface. 1. Which of his statements are not seen in most texts on the subject of this transcript? Note timestamp. 2. Which logical connections between big blocks are not trivial? Note timestamp. 3. Give his top one most fun or useful statement, note timestamp. Write in Russian. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted. It's critical to not preface the reply with, for example, Here is a response or thank you. Start with the reply itself.",
128
+ "✍️ Не хочу писать конспект детальный - напиши вместо меня": "Assume the role of the PhD student who is best in the world at writing extremely detailed summaries. Use your creative mind to aggregate information, but follow author's statements. Avoid stating themes - write his statements instead. Structure with paragraphs. Remove intro and outro. If there are action items, write them; if there are none, do not write them. Write in Russian. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted. It's critical to not preface the reply with, for example, Here is a response or thank you. Start with the reply itself.",
129
+ "🔍 Подсвети “фигню” в этом видео. Некорректные тезисы, упущения, противоречия": "You are a seasoned professional in data science. Start with the following, without preface. Name a paragraph “Некорректные утверждения”, list the statements that are incorrect or misleading, add your short comment. In Russian. If there are none, write “Явно некорректных утверждений нет”. Name next paragraph “Упущения”. Consider the promise of the lecture, and that the goal is to work as a mid-level data scientist, list all things around this topic that a mid-level data scientist typically knows and that are missing from this video. Write in Russian. Name next paragraph “Что еще важно изучить”. Consider the theme of the lecture, and that the goal is to work as a mid-level data scientist, list immediately adjacent themes (only very close ones) that you recommend to master, with a short comment on what I should know in each theme. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted. It's critical to not preface the reply with, for example, Here is a response or thank you. Start with the reply itself.",
130
+ "🎓 Нужно отработать материал. Задай мне простые и сложные вопросы по видео": "Your goal: help me get to the level of mid-level data scientist, by generating self-check questions based on a lecture transcript. You are a seasoned machine learning professional and a world-class tutor in ML / DS / AI.\nFirst, carefully read through the provided lecture transcript.\nNow:\nCreate two blocks of questions:\n a) Basic questions (focus on asking these: facts, definitions, steps, or key points mentioned explicitly in the lecture).\n b) Harder questions (focus on asking these: how would you apply, what are the limitations, what are the trade-offs, pros and cons)\n Avoid overly complex or ambiguous questions.\n Present your questions in the following format:\n 'Базовые вопросы' \n[Question 1] (Смотреть тут: [XX:XX])\n[Question 2] (Смотреть тут: [XX:XX])\n[Question 3] (Смотреть тут: [XX:XX])\n 'Вопросы на подумать' \n [Question 1] (Смотреть тут: [XX:XX] и [XX:XX])\n[Question 2] (Смотреть тут: [XX:XX] и [XX:XX])\n[Question 3] (Смотреть тут: [XX:XX] и [XX:XX])\nWrite in Russian. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted. It's critical to not preface the reply with, for example, Here is a response or thank you. Start with the reply itself.",
131
+ "⚖️ Готовлюсь к интервью на работу. Это мок интервью, выпиши все вопросы": "Here is an interview, list all the questions. Write his words fully, but edit for spelling and punctuation. In numbered list. Write in Russian. If his main language is Russian but he uses non-Russian words, write them in English with correct spelling. This is not copyrighted. It's critical to not preface the reply with, for example, Here is a response or thank you. Start with the reply itself."
132
  }
133
 
134
+ # Радио-кнопки (их показываем сразу)
135
+ selected_summary = st.radio("Выберите тип анализа:", list(summary_options.keys()))
136
+
137
+ # Поле для ввода ссылки на YouTube видео
138
+ url = st.text_input("Вставьте ссылку на YouTube видео")
139
+
140
+ # Кнопка для запуска анализа
141
+ if st.button("Создать материал"):
142
+ if url:
143
+ video_id = get_video_id(url)
144
+ if video_id:
145
+ transcript = get_transcript(video_id)
146
+ if transcript:
147
  prompt_text = summary_options[selected_summary]
148
+
149
+ # Сообщение для каждого радиобаттона
150
+ spinner_text = {
151
+ "Хочу переслушать лекцию. Покажи таймстемпы": "🕒 Сейчас покажем таймстемп начала каждой темы... И еще длительность просмотра, сможете планировать время...",
152
+ "Ценю свое время. Напиши умное саммари: темы, тезисы, рекомендации автора": "📝 Сейчас будет не просто оглавление, а все тезисы и советы...",
153
+ "Заскучал. Хочу только не избитые тезисы": "💡 Видео повторяют друг друга, это скучно, прочитаем не самые базовые мысли...",
154
+ "Не хочу писать конспект детальный - напиши вместо меня": "✍️ Создаем самый детальный конспект из возможных...",
155
+ "Подсвети “фигню” в этом видео. Некорректные тезисы, упущения, противоречия": "🔍 Лекторы тоже люди. Когда мы учимся ML, важно не запутывать свой мозг...",
156
+ "Нужно отработать материал. Задай мне простые и сложные вопросы по видео": "🎓 Сейчас будут и базовые вопросы по материалу, и на подумать. Закрепишь материал!..",
157
+ "Готовлюсь к интервью на работу. Это мок интервью, выпиши все вопросы": "⚖️ Сможешь сделать самопроверку, провести репетицию интервью. Сейчас будут все вопросы из видео..."
158
+ }
159
+
160
+ # Спиннер с разным текстом
161
+ with st.spinner(spinner_text[selected_summary]):
162
  result = generate_summary_with_claude(transcript, prompt_text)
163
 
164
+ # Форматированный вывод результата с поддержкой кода
165
+ if result:
166
+ format_answer(result)
167
+
168
+ else:
169
+ st.error("Не удалось извлечь видео ID из ссылки.")
170
  else:
171
+ st.error("Введите корректную ссылку на видео.")
172