diff --git a/app/frontend.py b/app/frontend.py new file mode 100644 index 0000000..31f1d1b --- /dev/null +++ b/app/frontend.py @@ -0,0 +1,132 @@ +import streamlit as st +import sqlite3 +from database import semantic_search as ss +from chatgpt import chatgpt as gpt +# Для оформления + +left1_column, right2_column = st.columns([1, 4]) +inside_left, inside_right = right2_column.columns([4, 1]) + +st.markdown( + """ + + """, + unsafe_allow_html=True +) + +results = '' +ResultsList = [] +ResultsListSub = [] + +st.sidebar.image("logo.png") + + + +# обработка пользовательского запроса +def process_query(query): + global results + right2_column.write(f'Вы ввели запрос: {query}') + nglobal_results = ss.elastic_output(query) + for result in nglobal_results: + ResultsList.append(result['articles']) + ResultsListSub.append([result['subcategory'], result['subsubcategory']]) + +# сохранение состояния сессии +def save_session_state(selected_category, selected_subcategory, selected_content): + session_state = { + 'selected_category': selected_category, + 'selected_subcategory': selected_subcategory, + 'selected_content': selected_content + } + return session_state + +# восстановление состояния сессии +def restore_session_state(): + session_state = st.session_state.get('session_state', None) + if session_state: + return session_state['selected_category'], session_state['selected_subcategory'], session_state['selected_content'] + else: + return None, None, None + +# чтение базы данных +def read_database(): + conn = sqlite3.connect('database/knowledge_base.db') + cursor = conn.cursor() + + cursor.execute("SELECT categories.name, subcategories.name, subsubcategories.name, articles.content " + "FROM categories " + "JOIN subcategories ON categories.id = subcategories.category_id " + "JOIN subsubcategories ON subcategories.id = subsubcategories.subcategory_id " + "JOIN articles ON subsubcategories.id = articles.subsubcategory_id") + + rows = cursor.fetchall() + + hierarchy = {} + for row in rows: + category = row[0] + subcategory = row[1] + subsubcategory = row[2] + content = row[3] + + if category not in hierarchy: + hierarchy[category] = {} + + if subcategory not in hierarchy[category]: + hierarchy[category][subcategory] = [] + + if content not in hierarchy[category][subcategory]: + hierarchy[category][subcategory].append(content) + + return hierarchy + +# Восстановление состояния сессии +selected_category, selected_subcategory, selected_content = restore_session_state() + +# Чтение базы данных +hierarchy = read_database() + +st.sidebar.title('Категории') + +query = st.sidebar.text_input('', label_visibility='collapsed') +if st.sidebar.button('🔍', key="my-button"): + process_query(query) + st.write("------------------") + try: + st.write('Краткий ответ: ', gpt.fetch_gpt_response(query, ResultsList[0]+ResultsList[1]+ResultsList[2])) + except: + st.write('Краткий ответ: ', gpt.fetch_gpt_response(query, ResultsList[0])) + + st.write("------------------") + st.write('Найденная информация: ', ) + + for i in range(len(ResultsList)): + expName = ResultsListSub[i][0] + ' - ' + ResultsListSub[i][1] + currentEsp = st.expander(expName, expanded=True) + with currentEsp: + st.write(ResultsList[i]) + st.write("------------------") + st.write('Информация из выбранных категорий: ', ) + + +# Выбор категории +selected_category = st.sidebar.selectbox('Выберите категорию', list(hierarchy.keys()), index=list(hierarchy.keys()).index(selected_category) if selected_category else 0) + +if selected_category in hierarchy and hierarchy[selected_category]: + subcategories = list(hierarchy[selected_category].keys()) + selected_subcategory = st.sidebar.selectbox('Выберите подкатегорию', subcategories, index=subcategories.index(selected_subcategory) if selected_subcategory in subcategories else 0) + +if selected_subcategory: + for content in hierarchy[selected_category][selected_subcategory]: + expName = selected_category + ' - ' + selected_subcategory + currentEsp = st.expander(expName, expanded=True) + with currentEsp: + st.write(content) + +# Сохранение состояния сессии +session_state = save_session_state(selected_category, selected_subcategory, selected_content) +st.session_state['session_state'] = session_state + diff --git a/app/streamlit.py b/app/streamlit.py deleted file mode 100644 index c8923ac..0000000 --- a/app/streamlit.py +++ /dev/null @@ -1,11 +0,0 @@ -from search import semantic_search as ss -from app import streamlit as st - -st.title('Умный ассистент') -query = st.text_input('Введите ваш запрос:') -def process_query(query): - st.write(f'Вы ввели запрос: {query}') - st.write(ss.SemanticSearch(query)) - -if st.button('Отправить запрос'): - process_query(query) \ No newline at end of file diff --git a/chatgpt/chatgpt.py b/chatgpt/chatgpt.py new file mode 100644 index 0000000..35a5e9e --- /dev/null +++ b/chatgpt/chatgpt.py @@ -0,0 +1,18 @@ +from openai import OpenAI + +api_key = '' + +client = OpenAI(api_key=api_key) + + +def fetch_gpt_response(question, answer): + messages = [{"role": "system", + "content": f"Дай ответ на вопрос {question} согласно контексту из базы знаний. Не придумывай лишней информации. Использую только то, что есть в базе знаний. Ответ дай максимально краткий."}, + {"role": "user", "content": answer}] + + gpt_response = client.chat.completions.create( + model="gpt-3.5-turbo", # gpt-4-turbo-preview + messages=messages + ) + + return gpt_response.choices[0].message.content \ No newline at end of file diff --git a/chatgpt/gpt_manager.py b/chatgpt/gpt_manager.py deleted file mode 100644 index feaef08..0000000 --- a/chatgpt/gpt_manager.py +++ /dev/null @@ -1,20 +0,0 @@ -from openai import OpenAI - -api_key = '' - -client = OpenAI(api_key=api_key) - - -def fetch_gpt_response(question_and_answer=None): - messages = [{"role": "system", - "content": "Ты должен опираясь на ответ из базы знаний ( данные хранятся в формате вопрос ; ответ) дать логичный ответ на поставленный вопрос пользователя. Не придумывай лишней информации. Использую только то, что есть в базе знаний. Можно переформулировать ответ."}, - {"role": "user", "content": question_and_answer}] - - gpt_response = client.chat.completions.create( - model="gpt-3.5-turbo", # gpt-4-turbo-preview - messages=messages - ) - # Вывод ответа модели - return gpt_response -s=str(input()) -print(fetch_gpt_response(s)) \ No newline at end of file diff --git a/database/knowledge_base.db b/database/knowledge_base.db index 798a35d..a7bae27 100644 Binary files a/database/knowledge_base.db and b/database/knowledge_base.db differ diff --git a/search/__init__.py b/elastic_search/__init__.py similarity index 100% rename from search/__init__.py rename to elastic_search/__init__.py diff --git a/search/semantic_search.py b/elastic_search/semantic_search.py similarity index 75% rename from search/semantic_search.py rename to elastic_search/semantic_search.py index 7e11f8e..a114325 100644 --- a/search/semantic_search.py +++ b/elastic_search/semantic_search.py @@ -21,6 +21,9 @@ } }, "filter": { + "lowercase": { + "type": "lowercase" + }, "russian_stop": { "type": "stop", "stopwords": "_russian_" @@ -28,6 +31,10 @@ "russian_stemmer": { "type": "stemmer", "language": "russian" + }, + "synonym_filter": { + "type": "synonym", + "synonyms": [] } } } @@ -37,6 +44,18 @@ "articles": { "type": "text", "analyzer": "russian_analyzer" + }, + "subsubcategory": { + "type": "text", + "analyzer": "russian_analyzer" + }, + "subcategory": { + "type": "text", + "analyzer": "russian_analyzer" + }, + "category": { + "type": "text", + "analyzer": "russian_analyzer" } } } @@ -44,8 +63,9 @@ def create_actions(rows, index_name): - actions = [ - { + actions = [] + for row in rows: + actions.append({ "_index": index_name, "_id": row[0], "_source": { @@ -54,9 +74,7 @@ def create_actions(rows, index_name): "subcategory": row[3], "category": row[4] } - } - for row in rows - ] + }) return actions @@ -66,11 +84,13 @@ def create_actions(rows, index_name): db_manager.close_connection() + def search_articles(query, index_name): search_query = { "query": { - "match": { - "articles": query + "multi_match": { + "query": query, + "fields": ["articles", "subsubcategory", "subcategory", "category"] } } } @@ -98,7 +118,7 @@ def process_search_results(response): return results -query = "технологий" +query = "управление проектами" response = search_articles(query, index_name) print(response) results = process_search_results(response)