Rulga commited on
Commit
e1600e7
·
unverified ·
1 Parent(s): f786c7e

Create two-in-one.py

Browse files

The logic for creating a knowledge base and working with the bot is separated

Files changed (1) hide show
  1. two-in-one.py +150 -0
two-in-one.py ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ from langchain_groq import ChatGroq
4
+ from langchain_huggingface import HuggingFaceEmbeddings
5
+ from langchain_community.vectorstores import FAISS
6
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
7
+ from langchain_community.document_loaders import WebBaseLoader
8
+ from langchain_core.prompts import PromptTemplate
9
+ from langchain_core.output_parsers import StrOutputParser
10
+ from langchain_core.runnables import RunnablePassthrough, RunnableLambda
11
+ from requests.exceptions import RequestException, Timeout
12
+
13
+ # Загрузка переменных окружения
14
+ if os.path.exists(".env"):
15
+ load_dotenv(verbose=True)
16
+
17
+ # Загрузка API-ключей
18
+ try:
19
+ GROQ_API_KEY = st.secrets["GROQ_API_KEY"]
20
+ USER_AGENT = st.secrets["USER_AGENT"]
21
+ LANGSMITH_TRACING = st.secrets["LANGSMITH_TRACING"]
22
+ LANGSMITH_ENDPOINT = st.secrets["LANGSMITH_ENDPOINT"]
23
+ LANGSMITH_API_KEY = st.secrets["LANGSMITH_API_KEY"]
24
+ LANGSMITH_PROJECT = st.secrets["LANGSMITH_PROJECT"]
25
+ OPENAI_API_KEY = st.secrets["OPENAI_API_KEY"]
26
+ except FileNotFoundError:
27
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
28
+ USER_AGENT = os.getenv("USER_AGENT")
29
+ LANGSMITH_TRACING = os.getenv("LANGSMITH_TRACING")
30
+ LANGSMITH_ENDPOINT = os.getenv("LANGSMITH_ENDPOINT")
31
+ LANGSMITH_API_KEY = os.getenv("LANGSMITH_API_KEY")
32
+ LANGSMITH_PROJECT = os.getenv("LANGSMITH_PROJECT")
33
+ OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
34
+
35
+ # Проверка API-ключей
36
+ if not all([GROQ_API_KEY, USER_AGENT, LANGSMITH_TRACING, LANGSMITH_ENDPOINT, LANGSMITH_API_KEY, LANGSMITH_PROJECT, OPENAI_API_KEY]):
37
+ st.error("Ошибка: Не все переменные окружения заданы.")
38
+ st.stop()
39
+
40
+ # Инициализация LLM
41
+ try:
42
+ llm = ChatGroq(model_name="llama-3.3-70b-versatile", temperature=0.6, api_key=GROQ_API_KEY)
43
+ print("[DEBUG] LLM успешно инициализирован")
44
+ except Exception as e:
45
+ st.error(f"Ошибка инициализации LLM: {e}")
46
+ st.stop()
47
+
48
+ # Инициализация эмбеддингов
49
+ embeddings_model = HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-large-instruct")
50
+ print("[DEBUG] Модель эмбеддингов загружена")
51
+
52
+ # Список страниц для анализа
53
+ urls = [
54
+ "https://status.law",
55
+ "https://status.law/about",
56
+ "https://status.law/careers",
57
+ "https://status.law/challenging-sanctions",
58
+ "https://status.law/contact",
59
+ "https://status.law/cross-border-banking-legal-issues",
60
+ "https://status.law/extradition-defense",
61
+ "https://status.law/international-prosecution-protection",
62
+ "https://status.law/interpol-red-notice-removal",
63
+ "https://status.law/practice-areas",
64
+ "https://status.law/reputation-protection",
65
+ "https://status.law/faq"
66
+ ]
67
+
68
+ # Путь к файлу векторного хранилища
69
+ VECTOR_STORE_PATH = "vector_store"
70
+
71
+ # Функция для создания базы знаний
72
+ def build_knowledge_base():
73
+ documents = []
74
+ for url in urls:
75
+ try:
76
+ loader = WebBaseLoader(url)
77
+ documents.extend(loader.load(timeout=10))
78
+ st.write(f"[DEBUG] Загружен контент с {url}")
79
+ except (RequestException, Timeout) as e:
80
+ st.write(f"[ERROR] Ошибка загрузки страницы {url}: {e}")
81
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)
82
+ chunks = text_splitter.split_documents(documents)
83
+ st.write(f"[DEBUG] Разбито на {len(chunks)} фрагментов")
84
+ vector_store = FAISS.from_documents(chunks, embeddings_model)
85
+ vector_store.save_local(VECTOR_STORE_PATH)
86
+ st.write("[DEBUG] Векторное хранилище создано и сохранено")
87
+ return vector_store
88
+
89
+ # Функция для загрузки базы знаний
90
+ @st.cache_resource
91
+ def load_knowledge_base():
92
+ if os.path.exists(VECTOR_STORE_PATH):
93
+ st.write("[DEBUG] Загрузка существующего векторного хранилища")
94
+ return FAISS.load_local(VECTOR_STORE_PATH, embeddings_model)
95
+ else:
96
+ st.write("[DEBUG] Векторное хранилище не найдено, создание нового")
97
+ return build_knowledge_base()
98
+
99
+ # Загрузка или создание базы знаний
100
+ vector_store = load_knowledge_base()
101
+
102
+ # Промпт для бота
103
+ template = """
104
+ You are a helpful legal assistant that answers questions based on information from status.law.
105
+ Answer accurately and concisely.
106
+ Question: {question}
107
+ Only use the provided context to answer the question.
108
+ Context: {context}
109
+ """
110
+ prompt = PromptTemplate.from_template(template)
111
+
112
+ # Инициализация цепочки обработки запроса
113
+ if "chain" not in st.session_state:
114
+ st.session_state.chain = (
115
+ RunnableLambda(lambda x: {"context": x["context"], "question": x["question"]})
116
+ | prompt
117
+ | llm
118
+ | StrOutputParser()
119
+ )
120
+ chain = st.session_state.chain
121
+
122
+ # Интерфейс Streamlit
123
+ st.set_page_config(page_title="Legal Chatbot", page_icon="🤖")
124
+ st.title("🤖 Legal Chatbot")
125
+ st.write("Этот бот отвечает на юридические вопросы, используя информацию с сайта status.law.")
126
+
127
+ # Поле для ввода вопроса
128
+ user_input = st.text_input("Введите ваш вопрос:")
129
+ if st.button("Отправить") and user_input:
130
+ # Поиск релевантных документов
131
+ retrieved_docs = vector_store.similarity_search(user_input)
132
+ context_text = "\n\n".join([doc.page_content for doc in retrieved_docs])
133
+
134
+ # Генерация ответа
135
+ response = chain.invoke({"question": user_input, "context": context_text})
136
+
137
+ # Сохранение истории сообщений
138
+ if "message_history" not in st.session_state:
139
+ st.session_state.message_history = []
140
+ st.session_state.message_history.append({"question": user_input, "answer": response})
141
+
142
+ # Вывод ответа
143
+ st.write(response)
144
+
145
+ # Вывод истории сообщений
146
+ if "message_history" in st.session_state:
147
+ st.write("### История сообщений")
148
+ for msg in st.session_state.message_history:
149
+ st.write(f"**User:** {msg['question']}")
150
+ st.write(f"**Bot:** {msg['answer']}")