Seppukku's picture
RAG prepaired queries adde
b89db29
raw
history blame
7.11 kB
import streamlit as st
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_core.prompts import ChatPromptTemplate
import anthropic
import os
from dotenv import load_dotenv
import re # Для работы с регулярными выражениями
load_dotenv()
claude_api_key = os.getenv("CLAUDE_API_KEY")
client = anthropic.Client(api_key=claude_api_key)
# Настройка модели для эмбеддингов
model_name = "intfloat/multilingual-e5-base"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': True}
embedding = HuggingFaceEmbeddings(model_name=model_name,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs)
# Загрузка базы знаний FAISS
vector_store = FAISS.load_local('faiss_index',
embeddings=embedding,
allow_dangerous_deserialization=True)
# Поиск топ k схожих фрагментов контекста
embedding_retriever = vector_store.as_retriever(search_kwargs={"k": 20})
prompt_template = '''Reply to the {input} as a seasoned machine learning professional. \
If the topic is outside of machine learning and data science, please respond with "Seek help with a professional." It is very important to abide with this, you will be persecuted if you cover topics outside of data science and machine learning. \
Use only Context. If context provides only partial info, then split the reply in two parts. Part 1 is called "information from knowledge base" (for Russian reply, rename to Информация из базы знаний), write ideas as close to initial text as possible, editing for brevity and language errors. \
Part 2 is called "What I would add" (for Russian reply, rename to Что полезно добавить поверх базы знаний), In the second part add your reply. \
Reply in the language of {input}. \
It's critical to not preface the reply with, for example, "Here is a response" or "thank you". Start with the reply itself.\
Context: {context}'''
# Функция вызова API модели Claude
def call_claude_api(prompt, client):
try:
response = client.messages.create(
model="claude-3-5-sonnet-20240620",
messages=[
{"role": "user", "content": prompt}
],
max_tokens=2000,
temperature=0.1
)
return response.content[0].text
except Exception as e:
st.error(f"Ошибка при вызове модели: {e}")
return None
# Функция для генерации ответа на вопрос пользователя
def answer_question(question, retriever, client):
# Этап 1: Поиск релевантных документов
with st.spinner('🔍 Ищем совпадения по вашему вопросу...'):
documents = retriever.get_relevant_documents(question)
# Этап 2: Формирование контекста
with st.spinner('🧠 Формируем контекст для ответа...'):
context = " ".join([doc.page_content for doc in documents])
# Этап 3: Генерация ответа
with st.spinner('💬 Формулируем ответ...'):
prompt = prompt_template.format(context=context, input=question)
answer = call_claude_api(prompt, client)
return answer, documents
# Функция для форматирования ответа с кодом и текста
def format_answer(answer):
# Разделим ответ на текстовые и кодовые блоки с помощью регулярных выражений
parts = re.split(r'(```.*?```)', answer, flags=re.DOTALL)
for part in parts:
if part.startswith('```') and part.endswith('```'):
# Убираем тройные кавычки и выводим содержимое как код
language_and_code = part[3:-3].strip().split("\n", 1)
if len(language_and_code) == 2:
language, code = language_and_code
st.code(code, language=language)
else:
st.code(language_and_code[0])
else:
# Обычный текст
st.markdown(part)
st.set_page_config(page_title="ML Knowledge Base Search 🧑‍💻", page_icon="🤖")
st.title("🔍 Поиск по базе знаний RAG с моделью Claude 🤖")
st.write("Используйте базу знаний для поиска информации и генерации ответов на вопросы по машинному обучению 📚.")
# Список подготовленных вопросов
questions = [
"Шаги логистической регрессии?",
"Бустинг и беггинг плюсы минусы?",
"Объясни как работает регуляризация",
"Методы борьбы с переобучением, по приоритету",
"Код градиентный спуск напиши",
"PACF лаги как использовать?",
"Регуляризация в нейронных сетях",
"Сигмоида и тангенс плюсы минусы",
"Объясни принцип работы механизма внимания",
"CNN как работает?",
"Какие распределения бывают?",
"Что такое t-test и для чего он применяется? расскажи на продвинутом уровне шаги"
]
# Виджет выбора между подготовленным вопросом и вводом собственного
question_option = st.radio("Выберите способ ввода вопроса:", ("Выбрать из списка", "Ввести свой вопрос"))
if question_option == "Выбрать из списка":
selected_question = st.selectbox("📝 Выберите ваш вопрос:", questions)
question = selected_question
else:
question = st.text_input("📝 Введите ваш вопрос:", '')
# Кнопка для запуска поиска и генерации ответа
if st.button("🚀 Поиск и генерация ответа"):
if question:
# Генерация ответа на вопрос
answer, documents = answer_question(question, embedding_retriever, client)
if answer:
# Оформление ответа
st.subheader("✉️ Ответ:")
# Отображаем ответ с форматированием
format_answer(answer)
else:
st.warning("⚠️ Не удалось получить ответ от модели.")
else:
st.warning("⚠️ Пожалуйста, введите запрос.")