Rulga commited on
Commit
e26e304
·
unverified ·
0 Parent(s):

Add files via upload

Browse files
Files changed (5) hide show
  1. README.md +14 -0
  2. app.py +158 -0
  3. gitattributes +44 -0
  4. gitignore +4 -0
  5. requirements.txt +7 -0
README.md ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: LS Chat App
3
+ emoji: 🔍
4
+ colorFrom: blue
5
+ colorTo: blue
6
+ sdk: streamlit
7
+ sdk_version: 1.42.0
8
+ app_file: app.py
9
+ pinned: false
10
+ ---
11
+
12
+ # LS Chat App
13
+
14
+ It is a chat app built using Streamlit that allows users to interact with an AI model to communicate about www.Status.law
app.py ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ from dotenv import load_dotenv
4
+ from langchain_groq import ChatGroq
5
+ from langchain_huggingface import HuggingFaceEmbeddings
6
+ from langchain_community.vectorstores import InMemoryVectorStore
7
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
8
+ from langchain_community.document_loaders import WebBaseLoader
9
+ from langchain_core.prompts import PromptTemplate
10
+ from langchain_core.output_parsers import StrOutputParser
11
+ from langchain_core.runnables import RunnablePassthrough, RunnableLambda
12
+ from requests.exceptions import RequestException
13
+
14
+ # Загружаем переменные окружения (если работаем локально)
15
+ # load_dotenv(verbose=True)
16
+ # Определяем, работает ли код локально (например, если `.env` существует)
17
+ is_local = os.path.exists(".env")
18
+
19
+ # Загружаем переменные окружения, если работаем локально
20
+ if is_local:
21
+ load_dotenv(verbose=True)
22
+
23
+ # Загружаем API-ключи через Streamlit secrets (для облачного запуска)
24
+ try:
25
+ GROQ_API_KEY = st.secrets["GROQ_API_KEY"]
26
+ USER_AGENT = st.secrets["USER_AGENT"]
27
+ LANGSMITH_TRACING = st.secrets["LANGSMITH_TRACING"]
28
+ LANGSMITH_ENDPOINT = st.secrets["LANGSMITH_ENDPOINT"]
29
+ LANGSMITH_API_KEY = st.secrets["LANGSMITH_API_KEY"]
30
+ LANGSMITH_PROJECT = st.secrets["LANGSMITH_PROJECT"]
31
+ OPENAI_API_KEY = st.secrets["OPENAI_API_KEY"]
32
+ except FileNotFoundError:
33
+ # Если secrets.toml не найден, используем переменные окружения
34
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
35
+ USER_AGENT = os.getenv("USER_AGENT")
36
+ LANGSMITH_TRACING = os.getenv("LANGSMITH_TRACING")
37
+ LANGSMITH_ENDPOINT = os.getenv("LANGSMITH_ENDPOINT")
38
+ LANGSMITH_API_KEY = os.getenv("LANGSMITH_API_KEY")
39
+ LANGSMITH_PROJECT = os.getenv("LANGSMITH_PROJECT")
40
+ OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
41
+
42
+ # Проверяем, заданы ли API-ключи
43
+ if not GROQ_API_KEY:
44
+ st.error("Ошибка: GROQ_API_KEY не задана в переменных окружения.")
45
+ st.stop()
46
+ if not USER_AGENT:
47
+ st.error("Ошибка: USER_AGENT не задана в переменных окружения.")
48
+ st.stop()
49
+ if not LANGSMITH_TRACING:
50
+ st.error("Ошибка: LANGSMITH_TRACING не задана в переменных окружения.")
51
+ st.stop()
52
+ if not LANGSMITH_ENDPOINT:
53
+ st.error("Ошибка: LANGSMITH_ENDPOINT не задана в переменных окружения.")
54
+ st.stop()
55
+ if not LANGSMITH_API_KEY:
56
+ st.error("Ошибка: LANGSMITH_API_KEY не задана в переменных окружения.")
57
+ st.stop()
58
+ if not LANGSMITH_PROJECT:
59
+ st.error("Ошибка: LANGSMITH_PROJECT не задана в переменных окружения.")
60
+ st.stop()
61
+ if not OPENAI_API_KEY :
62
+ st.error("Ошибка: OPENAI_API_KEY не задана в переменных окружения.")
63
+ st.stop()
64
+
65
+ # Настройка LLM
66
+ try:
67
+ llm = ChatGroq(
68
+ model_name="llama-3.3-70b-versatile",
69
+ temperature=0.6,
70
+ api_key=GROQ_API_KEY
71
+ )
72
+ print("[DEBUG] LLM успешно инициализирован")
73
+ except Exception as e:
74
+ print(f"[ERROR] Ошибка инициализации LLM: {e}")
75
+
76
+ # Настройка эмбеддингов
77
+ embeddings_model = HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-large-instruct")
78
+ print("[DEBUG] Модель эмбеддингов загружена")
79
+
80
+ # Функция загрузки только англоязычного контента
81
+ def load_english_pages(urls):
82
+ english_docs = []
83
+ for url in urls:
84
+ if not any(lang in url for lang in ["/ru", "/ar", "/es", "/ch"]):
85
+ try:
86
+ loader = WebBaseLoader(url)
87
+ documents = loader.load()
88
+ if documents:
89
+ english_docs.extend(documents)
90
+ print(f"[DEBUG] Загружен контент с {url}")
91
+ except RequestException as e:
92
+ print(f"[ERROR] Ошибка загрузки страницы {url}: {e}")
93
+ return english_docs
94
+
95
+ # Пример URL, где английские страницы без префиксов
96
+ urls = ["https://status.law/about", "https://status.law/", "https://status.law/contact"]
97
+ documents = load_english_pages(urls)
98
+
99
+ # Разбиваем на фрагменты
100
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)
101
+ chunks = text_splitter.split_documents(documents)
102
+ print(f"[DEBUG] Разбито на {len(chunks)} фрагментов")
103
+
104
+ # Создание векторного хранилища
105
+ vector_store = InMemoryVectorStore.from_documents(chunks, embeddings_model)
106
+ retriever = vector_store.as_retriever()
107
+ print("[DEBUG] Векторное хранилище создано")
108
+
109
+ # ��ромпт для бота
110
+ template = """
111
+ You are a helpful legal assistant that answers questions based on information from status.law.
112
+ Answer accurately and concisely.
113
+ Question: {question}
114
+ Only use the provided context to answer the question.
115
+ Context: {context}
116
+ """
117
+ prompt = PromptTemplate.from_template(template)
118
+
119
+ # История сообщений
120
+ def format_history(message_history):
121
+ formatted = ""
122
+ for msg in message_history:
123
+ formatted += f"User: {msg['question']}\nBot: {msg['answer']}\n\n"
124
+ return formatted
125
+
126
+ message_history = []
127
+
128
+ # Интерфейс Streamlit
129
+ st.set_page_config(page_title="Legal Chatbot", page_icon="🤖")
130
+ st.title("🤖 Legal Chatbot")
131
+ st.write("Этот бот отвечает на юридические вопросы, используя информацию с сайта status.law.")
132
+
133
+ # Поле для ввода вопроса
134
+ user_input = st.text_input("Введите ваш вопрос:")
135
+ if st.button("Отправить"):
136
+ if user_input:
137
+ # Получаем релевантные документы из ретривера
138
+ retrieved_docs = retriever.get_relevant_documents(user_input)
139
+
140
+ # Формируем текстовый контекст из документов
141
+ context_text = "\n\n".join([doc.page_content for doc in retrieved_docs])
142
+
143
+ # Создание цепочки обработки запроса
144
+ chain = (
145
+ RunnableLambda(lambda x: {"context": context_text, "question": x["question"]})
146
+ | prompt
147
+ | llm
148
+ | StrOutputParser()
149
+ )
150
+
151
+ # Запуск цепочки
152
+ response = chain.invoke({"question": user_input, "context": context_text})
153
+
154
+ # Добавляем в историю сообщений
155
+ message_history.append({"question": user_input, "answer": response})
156
+
157
+ # Выводим ответ
158
+ st.write(response)
gitattributes ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+
37
+
38
+ * text=auto eol=crlf
39
+
40
+ *.bin binary
41
+
42
+ .gitignore text eol=lf
43
+ .gitattributes text eol=lf
44
+
gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ *.env
2
+
3
+ venv
4
+ .streamlit/secrets.toml
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ langchain-community
3
+ langchain-core
4
+ langchain-huggingface
5
+ langchain-groq
6
+ python-dotenv
7
+ beautifulsoup4