LevinAleksey commited on
Commit
cbbdda1
·
verified ·
1 Parent(s): 8c3d8d7

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +102 -0
app.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ from huggingface_hub import InferenceClient
4
+ from qdrant_client import QdrantClient
5
+ from sentence_transformers import SentenceTransformer
6
+
7
+ # --- КОНФИГУРАЦИЯ ---
8
+ st.set_page_config(page_title="AI Assistant RAG", page_icon="🤖", layout="centered")
9
+
10
+ # Настройки API (Берем из секретов)
11
+ HF_TOKEN = os.getenv("HF_TOKEN")
12
+ QDRANT_URL = os.getenv("QDRANT_URL")
13
+ QDRANT_API_KEY = os.getenv("QDRANT_API_KEY")
14
+
15
+ # Модель для чата
16
+ MODEL_ID = "Qwen/Qwen2.5-7B-Instruct"
17
+
18
+ # --- ИНИЦИАЛИЗАЦИЯ ---
19
+ @st.cache_resource
20
+ def load_resources():
21
+ # 1. Клиент HF (Чат)
22
+ hf_client = InferenceClient(MODEL_ID, token=HF_TOKEN)
23
+
24
+ # 2. Клиент Qdrant (База знаний) - инициализируем, если есть ключи
25
+ q_client = None
26
+ if QDRANT_URL and QDRANT_API_KEY:
27
+ try:
28
+ q_client = QdrantClient(url=QDRANT_URL, api_key=QDRANT_API_KEY)
29
+ except:
30
+ pass
31
+
32
+ # 3. Модель для векторизации (чтобы искать в базе)
33
+ # Используем маленькую и быструю модель, она скачается сама
34
+ encoder = SentenceTransformer('all-MiniLM-L6-v2')
35
+
36
+ return hf_client, q_client, encoder
37
+
38
+ client, qdrant, encoder = load_resources()
39
+
40
+ # --- ЛОГИКА RAG (ПОИСК В БАЗЕ) ---
41
+ def get_context(query):
42
+ if not qdrant:
43
+ return "" # Если база не подключена, возвращаем пустоту
44
+
45
+ try:
46
+ # Превращаем вопрос пользователя в цифры (вектор)
47
+ vector = encoder.encode(query).tolist()
48
+
49
+ # Ищем похожие куски в базе (коллекция должна называться "knowledge_base")
50
+ search_result = qdrant.search(
51
+ collection_name="knowledge_base",
52
+ query_vector=vector,
53
+ limit=3
54
+ )
55
+
56
+ # Собираем найденный текст
57
+ context_text = "\n\n".join([hit.payload.get("text", "") for hit in search_result])
58
+ return context_text
59
+ except Exception as e:
60
+ return ""
61
+
62
+ # --- ИНТЕРФЕЙС (КАК ПО ССЫЛКЕ) ---
63
+ st.title("🤖 AI Assistant (RAG)")
64
+ st.caption("Чат с базой знаний на Qwen 2.5")
65
+
66
+ if "messages" not in st.session_state:
67
+ st.session_state.messages = [{"role": "assistant", "content": "Привет! Я готов к работе. Чем помочь?"}]
68
+
69
+ # Показываем историю
70
+ for msg in st.session_state.messages:
71
+ st.chat_message(msg["role"]).write(msg["content"])
72
+
73
+ # Поле ввода
74
+ if prompt := st.chat_input():
75
+ st.session_state.messages.append({"role": "user", "content": prompt})
76
+ st.chat_message("user").write(prompt)
77
+
78
+ # 1. ИЩЕМ ИНФУ В QDRANT
79
+ context = get_context(prompt)
80
+
81
+ # 2. ФОРМИРУЕМ ПРОМПТ
82
+ system_msg = """Ты полезный ассистент.
83
+ Используй информацию из КОНТЕКСТА ниже, чтобы ответить на вопрос.
84
+ Если в контексте нет ответа, отвечай опираясь на свои знания, но предупреди об этом.
85
+ """
86
+
87
+ if context:
88
+ final_prompt = f"КОНТЕКСТ:\n{context}\n\nВОПРОС: {prompt}"
89
+ else:
90
+ final_prompt = prompt
91
+
92
+ messages_api = [
93
+ {"role": "system", "content": system_msg},
94
+ {"role": "user", "content": final_prompt}
95
+ ]
96
+
97
+ # 3. ГЕНЕРИРУЕМ ОТВЕТ
98
+ with st.chat_message("assistant"):
99
+ stream = client.chat_completion(messages_api, max_tokens=1024, stream=True)
100
+ response = st.write_stream(stream)
101
+
102
+ st.session_state.messages.append({"role": "assistant", "content": response})