Działający zestaw
Browse files- .DS_Store +0 -0
- .gradio/certificate.pem +31 -0
- README.md +83 -1
- app.py +30 -25
.DS_Store
ADDED
|
Binary file (6.15 kB). View file
|
|
|
.gradio/certificate.pem
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-----BEGIN CERTIFICATE-----
|
| 2 |
+
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
|
| 3 |
+
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
| 4 |
+
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
|
| 5 |
+
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
|
| 6 |
+
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
|
| 7 |
+
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
|
| 8 |
+
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
|
| 9 |
+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
|
| 10 |
+
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
|
| 11 |
+
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
|
| 12 |
+
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
|
| 13 |
+
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
|
| 14 |
+
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
|
| 15 |
+
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
|
| 16 |
+
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
|
| 17 |
+
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
|
| 18 |
+
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
|
| 19 |
+
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
|
| 20 |
+
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
|
| 21 |
+
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
|
| 22 |
+
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
|
| 23 |
+
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
|
| 24 |
+
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
|
| 25 |
+
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
|
| 26 |
+
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
|
| 27 |
+
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
|
| 28 |
+
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
|
| 29 |
+
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
|
| 30 |
+
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
|
| 31 |
+
-----END CERTIFICATE-----
|
README.md
CHANGED
|
@@ -10,5 +10,87 @@ pinned: false
|
|
| 10 |
license: cc-by-4.0
|
| 11 |
short_description: Chatbot korzystający z zasobów serwisu mojaszuflada.pl
|
| 12 |
---
|
|
|
|
|
|
|
| 13 |
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
license: cc-by-4.0
|
| 11 |
short_description: Chatbot korzystający z zasobów serwisu mojaszuflada.pl
|
| 12 |
---
|
| 13 |
+
|
| 14 |
+
# Szuflada
|
| 15 |
|
| 16 |
+
Czatbot korzystający z zasobów serwisu [mojaszuflada.pl](https://mojaszuflada.pl), wykorzystujący Gradio oraz RAG z lokalną bazą Chroma i Hugging Face Inference API.
|
| 17 |
+
|
| 18 |
+
## Instalacja
|
| 19 |
+
|
| 20 |
+
1. Sklonuj repozytorium:
|
| 21 |
+
|
| 22 |
+
```bash
|
| 23 |
+
git clone https://github.com/<użytkownik>/szuflada.git
|
| 24 |
+
cd szuflada
|
| 25 |
+
```
|
| 26 |
+
|
| 27 |
+
2. Utwórz i aktywuj środowisko wirtualne:
|
| 28 |
+
|
| 29 |
+
```bash
|
| 30 |
+
python3 -m venv venv
|
| 31 |
+
source venv/bin/activate # Linux/macOS
|
| 32 |
+
venv\Scripts\activate # Windows
|
| 33 |
+
```
|
| 34 |
+
|
| 35 |
+
3. Zainstaluj zależności:
|
| 36 |
+
|
| 37 |
+
```bash
|
| 38 |
+
pip install -r requirements.txt
|
| 39 |
+
```
|
| 40 |
+
|
| 41 |
+
4. Zaloguj się do Hugging Face (jeśli korzystasz z API):
|
| 42 |
+
|
| 43 |
+
```bash
|
| 44 |
+
huggingface-cli login
|
| 45 |
+
```
|
| 46 |
+
|
| 47 |
+
5. (Opcjonalnie) Ustaw zmienną środowiskową z tokenem:
|
| 48 |
+
|
| 49 |
+
```bash
|
| 50 |
+
export HUGGINGFACEHUB_API_TOKEN=Twój_Token
|
| 51 |
+
```
|
| 52 |
+
|
| 53 |
+
## Użycie
|
| 54 |
+
|
| 55 |
+
Uruchom aplikację lokalnie:
|
| 56 |
+
|
| 57 |
+
```bash
|
| 58 |
+
python app.py
|
| 59 |
+
```
|
| 60 |
+
|
| 61 |
+
Aplikacja będzie dostępna pod adresem <http://localhost:7860>. Otwórz tę stronę w przeglądarce, aby rozpocząć czat.
|
| 62 |
+
|
| 63 |
+
## Osadzanie na innych stronach internetowych
|
| 64 |
+
|
| 65 |
+
### Metoda 1: iframe
|
| 66 |
+
|
| 67 |
+
```html
|
| 68 |
+
<iframe src="http://adres_twojej_aplikacji:7860" width="700" height="800" frameborder="0"></iframe>
|
| 69 |
+
```
|
| 70 |
+
|
| 71 |
+
### Metoda 2: Embed Gradio (Hugging Face Spaces)
|
| 72 |
+
|
| 73 |
+
Jeśli aplikacja jest wdrożona jako Space na Hugging Face, użyj oficjalnego skryptu:
|
| 74 |
+
|
| 75 |
+
```html
|
| 76 |
+
<script src="https://cdn.jsdelivr.net/npm/@gradio/embed"></script>
|
| 77 |
+
<gradio-embed
|
| 78 |
+
src="username/szuflada" <!-- zastąp username swoją nazwą użytkownika/Space -->
|
| 79 |
+
width="700"
|
| 80 |
+
height="800"
|
| 81 |
+
></gradio-embed>
|
| 82 |
+
```
|
| 83 |
+
|
| 84 |
+
### Metoda 3: JavaScript SDK
|
| 85 |
+
|
| 86 |
+
```html
|
| 87 |
+
<script type="module">
|
| 88 |
+
import Gradio from "https://cdn.jsdelivr.net/npm/@gradio/embed@2.0.0/+esm";
|
| 89 |
+
new Gradio.Embed("https://huggingface.co/embed/username/szuflada", {
|
| 90 |
+
container: document.getElementById("gradio-container"),
|
| 91 |
+
width: 700,
|
| 92 |
+
height: 800
|
| 93 |
+
});
|
| 94 |
+
</script>
|
| 95 |
+
<div id="gradio-container"></div>
|
| 96 |
+
```
|
app.py
CHANGED
|
@@ -10,8 +10,10 @@ from langchain_community.chat_message_histories import ChatMessageHistory
|
|
| 10 |
from langchain_core.runnables.history import RunnableWithMessageHistory
|
| 11 |
|
| 12 |
# --- 1. Inicjalizacja modeli i retrievera ---
|
| 13 |
-
|
|
|
|
| 14 |
embedder = OpenAIEmbeddings(model="text-embedding-3-small")
|
|
|
|
| 15 |
baza = Chroma(
|
| 16 |
collection_name="szuflada",
|
| 17 |
embedding_function=embedder,
|
|
@@ -22,13 +24,13 @@ baza = Chroma(
|
|
| 22 |
# - "mmr" (Maximal Marginal Relevance)
|
| 23 |
# - "similarity_score_threshold" (z progiem score_threshold)
|
| 24 |
|
| 25 |
-
#
|
| 26 |
retriever = baza.as_retriever(
|
| 27 |
-
|
| 28 |
-
search_kwargs={"k": 5}
|
| 29 |
)
|
| 30 |
|
| 31 |
# --- 2. Tworzenie łańcucha RAG z historią ---
|
|
|
|
| 32 |
contextualize_q_system_prompt = (
|
| 33 |
"Biorąc pod uwagę historię czatu i ostatnie pytanie użytkownika, "
|
| 34 |
"które może odnosić się do kontekstu w historii czatu, "
|
|
@@ -43,15 +45,17 @@ contextualize_q_prompt = ChatPromptTemplate.from_messages(
|
|
| 43 |
("human", "{input}"),
|
| 44 |
]
|
| 45 |
)
|
|
|
|
| 46 |
history_aware_retriever = create_history_aware_retriever(
|
| 47 |
llm, retriever, contextualize_q_prompt
|
| 48 |
)
|
| 49 |
|
|
|
|
| 50 |
qa_system_prompt = (
|
| 51 |
"Jesteś asystentem do zadawania pytań i odpowiedzi na temat treści ze strony mojaszuflada.pl. "
|
| 52 |
"Użyj poniższych fragmentów odzyskanego kontekstu, aby odpowiedzieć na pytanie. "
|
| 53 |
"Odpowiadaj zawsze w języku polskim. "
|
| 54 |
-
"Jeśli nie znasz odpowiedzi, po prostu powiedz, że nie wiesz. "
|
| 55 |
"Zachowaj zwięzłość odpowiedzi, ale bądź pomocny i przyjazny."
|
| 56 |
"\n\n{context}"
|
| 57 |
)
|
|
@@ -62,17 +66,22 @@ qa_prompt = ChatPromptTemplate.from_messages(
|
|
| 62 |
("human", "{input}"),
|
| 63 |
]
|
| 64 |
)
|
|
|
|
| 65 |
question_answer_chain = create_stuff_documents_chain(llm, qa_prompt)
|
| 66 |
|
|
|
|
| 67 |
rag_chain = create_retrieval_chain(history_aware_retriever, question_answer_chain)
|
| 68 |
|
|
|
|
| 69 |
store = {}
|
| 70 |
|
| 71 |
def get_session_history(session_id: str) -> BaseChatMessageHistory:
|
|
|
|
| 72 |
if session_id not in store:
|
| 73 |
store[session_id] = ChatMessageHistory()
|
| 74 |
return store[session_id]
|
| 75 |
|
|
|
|
| 76 |
conversational_rag_chain = RunnableWithMessageHistory(
|
| 77 |
rag_chain,
|
| 78 |
get_session_history,
|
|
@@ -83,8 +92,9 @@ conversational_rag_chain = RunnableWithMessageHistory(
|
|
| 83 |
|
| 84 |
# --- 3. Funkcje pomocnicze dla Gradio ---
|
| 85 |
def format_sources(source_docs):
|
|
|
|
| 86 |
if not source_docs:
|
| 87 |
-
return "
|
| 88 |
|
| 89 |
sources = []
|
| 90 |
for doc in source_docs:
|
|
@@ -98,8 +108,6 @@ def format_sources(source_docs):
|
|
| 98 |
sources.append(f"- [{title}]({source_url}) ({pub_date})")
|
| 99 |
else:
|
| 100 |
sources.append(f"- [{title}]({source_url})")
|
| 101 |
-
# Dodaj informację o liczbie chunków (debug)
|
| 102 |
-
sources.append(f"\n_Znaleziono chunków: {len(source_docs)}_")
|
| 103 |
return "\n".join(sources)
|
| 104 |
|
| 105 |
# --- 4. Budowa interfejsu Gradio ---
|
|
@@ -107,15 +115,17 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), title="Szuflada Chatbot
|
|
| 107 |
session_id = gr.State(lambda: str(uuid.uuid4()))
|
| 108 |
|
| 109 |
gr.Markdown(
|
| 110 |
-
"""# Czat z Szufladą\n### Zadaj pytanie na temat treści ze strony [mojaszuflada.pl](https://mojaszuflada.pl)
|
| 111 |
"""
|
| 112 |
)
|
| 113 |
|
|
|
|
| 114 |
chatbot = gr.Chatbot(
|
| 115 |
label="Rozmowa",
|
| 116 |
height=500,
|
| 117 |
)
|
| 118 |
|
|
|
|
| 119 |
with gr.Row():
|
| 120 |
msg = gr.Textbox(
|
| 121 |
show_label=False,
|
|
@@ -125,27 +135,32 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), title="Szuflada Chatbot
|
|
| 125 |
)
|
| 126 |
submit_btn = gr.Button("Wyślij", variant="primary", scale=1)
|
| 127 |
|
|
|
|
| 128 |
def respond(message, chat_history, sess_id):
|
|
|
|
| 129 |
response = conversational_rag_chain.invoke(
|
| 130 |
{"input": message},
|
| 131 |
config={"configurable": {"session_id": sess_id}},
|
| 132 |
)
|
| 133 |
-
# Dodaj logowanie score dla debugowania
|
| 134 |
context_docs = response.get("context", [])
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
|
|
|
| 138 |
sources_md = format_sources(context_docs)
|
| 139 |
-
|
|
|
|
| 140 |
chat_history.append((message, answer_with_sources))
|
| 141 |
return chat_history
|
| 142 |
|
|
|
|
| 143 |
submit_btn.click(
|
| 144 |
respond,
|
| 145 |
[msg, chatbot, session_id],
|
| 146 |
[chatbot]
|
| 147 |
).then(lambda: gr.update(value=""), None, [msg], queue=False)
|
| 148 |
|
|
|
|
| 149 |
msg.submit(
|
| 150 |
respond,
|
| 151 |
[msg, chatbot, session_id],
|
|
@@ -154,15 +169,5 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), title="Szuflada Chatbot
|
|
| 154 |
|
| 155 |
# --- 5. Uruchomienie aplikacji ---
|
| 156 |
if __name__ == "__main__":
|
| 157 |
-
#
|
| 158 |
-
test_query = "test" # <- wpisz tu frazę, która powinna być w bazie
|
| 159 |
-
print("\n=== TEST RETRIEVER ===")
|
| 160 |
-
docs = retriever.get_relevant_documents(test_query)
|
| 161 |
-
print(f"Znaleziono {len(docs)} dokumentów dla zapytania: '{test_query}'")
|
| 162 |
-
for i, doc in enumerate(docs):
|
| 163 |
-
score = doc.metadata.get("score", "brak score")
|
| 164 |
-
print(f"Chunk {i+1}: score={score}, title={doc.metadata.get('title')}, source={doc.metadata.get('source')}")
|
| 165 |
-
print("=== KONIEC TESTU ===\n")
|
| 166 |
-
# --- KONIEC TESTU ---
|
| 167 |
-
|
| 168 |
demo.launch(inbrowser=True)
|
|
|
|
| 10 |
from langchain_core.runnables.history import RunnableWithMessageHistory
|
| 11 |
|
| 12 |
# --- 1. Inicjalizacja modeli i retrievera ---
|
| 13 |
+
# Inicjalizacja modelu językowego oraz embeddera
|
| 14 |
+
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.0)
|
| 15 |
embedder = OpenAIEmbeddings(model="text-embedding-3-small")
|
| 16 |
+
# Inicjalizacja bazy Chroma z embeddingami
|
| 17 |
baza = Chroma(
|
| 18 |
collection_name="szuflada",
|
| 19 |
embedding_function=embedder,
|
|
|
|
| 24 |
# - "mmr" (Maximal Marginal Relevance)
|
| 25 |
# - "similarity_score_threshold" (z progiem score_threshold)
|
| 26 |
|
| 27 |
+
# Retriever do wyszukiwania podobnych fragmentów
|
| 28 |
retriever = baza.as_retriever(
|
| 29 |
+
search_kwargs={"k": 3}
|
|
|
|
| 30 |
)
|
| 31 |
|
| 32 |
# --- 2. Tworzenie łańcucha RAG z historią ---
|
| 33 |
+
# Prompt do kontekstualizacji pytania na podstawie historii czatu
|
| 34 |
contextualize_q_system_prompt = (
|
| 35 |
"Biorąc pod uwagę historię czatu i ostatnie pytanie użytkownika, "
|
| 36 |
"które może odnosić się do kontekstu w historii czatu, "
|
|
|
|
| 45 |
("human", "{input}"),
|
| 46 |
]
|
| 47 |
)
|
| 48 |
+
# Łańcuch do kontekstualizacji pytania z historią
|
| 49 |
history_aware_retriever = create_history_aware_retriever(
|
| 50 |
llm, retriever, contextualize_q_prompt
|
| 51 |
)
|
| 52 |
|
| 53 |
+
# Prompt do generowania odpowiedzi na podstawie kontekstu
|
| 54 |
qa_system_prompt = (
|
| 55 |
"Jesteś asystentem do zadawania pytań i odpowiedzi na temat treści ze strony mojaszuflada.pl. "
|
| 56 |
"Użyj poniższych fragmentów odzyskanego kontekstu, aby odpowiedzieć na pytanie. "
|
| 57 |
"Odpowiadaj zawsze w języku polskim. "
|
| 58 |
+
"Jeśli nie znasz odpowiedzi, po prostu powiedz, że tego nie wiesz. "
|
| 59 |
"Zachowaj zwięzłość odpowiedzi, ale bądź pomocny i przyjazny."
|
| 60 |
"\n\n{context}"
|
| 61 |
)
|
|
|
|
| 66 |
("human", "{input}"),
|
| 67 |
]
|
| 68 |
)
|
| 69 |
+
# Łańcuch generujący odpowiedź na podstawie dokumentów
|
| 70 |
question_answer_chain = create_stuff_documents_chain(llm, qa_prompt)
|
| 71 |
|
| 72 |
+
# Połączenie retrievera z generatorem odpowiedzi
|
| 73 |
rag_chain = create_retrieval_chain(history_aware_retriever, question_answer_chain)
|
| 74 |
|
| 75 |
+
# Słownik do przechowywania historii czatu dla sesji
|
| 76 |
store = {}
|
| 77 |
|
| 78 |
def get_session_history(session_id: str) -> BaseChatMessageHistory:
|
| 79 |
+
# Zwraca historię czatu dla danej sesji (tworzy jeśli nie istnieje)
|
| 80 |
if session_id not in store:
|
| 81 |
store[session_id] = ChatMessageHistory()
|
| 82 |
return store[session_id]
|
| 83 |
|
| 84 |
+
# Łańcuch RAG z obsługą historii wiadomości
|
| 85 |
conversational_rag_chain = RunnableWithMessageHistory(
|
| 86 |
rag_chain,
|
| 87 |
get_session_history,
|
|
|
|
| 92 |
|
| 93 |
# --- 3. Funkcje pomocnicze dla Gradio ---
|
| 94 |
def format_sources(source_docs):
|
| 95 |
+
# Formatuje listę źródeł do wyświetlenia w odpowiedzi
|
| 96 |
if not source_docs:
|
| 97 |
+
return "?"
|
| 98 |
|
| 99 |
sources = []
|
| 100 |
for doc in source_docs:
|
|
|
|
| 108 |
sources.append(f"- [{title}]({source_url}) ({pub_date})")
|
| 109 |
else:
|
| 110 |
sources.append(f"- [{title}]({source_url})")
|
|
|
|
|
|
|
| 111 |
return "\n".join(sources)
|
| 112 |
|
| 113 |
# --- 4. Budowa interfejsu Gradio ---
|
|
|
|
| 115 |
session_id = gr.State(lambda: str(uuid.uuid4()))
|
| 116 |
|
| 117 |
gr.Markdown(
|
| 118 |
+
"""# Czat z Moją Szufladą\n### Zadaj pytanie na temat treści ze strony [mojaszuflada.pl](https://mojaszuflada.pl)
|
| 119 |
"""
|
| 120 |
)
|
| 121 |
|
| 122 |
+
# Komponent czatu
|
| 123 |
chatbot = gr.Chatbot(
|
| 124 |
label="Rozmowa",
|
| 125 |
height=500,
|
| 126 |
)
|
| 127 |
|
| 128 |
+
# Pole tekstowe i przycisk do wysyłania wiadomości
|
| 129 |
with gr.Row():
|
| 130 |
msg = gr.Textbox(
|
| 131 |
show_label=False,
|
|
|
|
| 135 |
)
|
| 136 |
submit_btn = gr.Button("Wyślij", variant="primary", scale=1)
|
| 137 |
|
| 138 |
+
# Funkcja obsługująca odpowiedź na wiadomość użytkownika
|
| 139 |
def respond(message, chat_history, sess_id):
|
| 140 |
+
# Wywołanie łańcucha RAG z historią
|
| 141 |
response = conversational_rag_chain.invoke(
|
| 142 |
{"input": message},
|
| 143 |
config={"configurable": {"session_id": sess_id}},
|
| 144 |
)
|
|
|
|
| 145 |
context_docs = response.get("context", [])
|
| 146 |
+
# Debug: wypisz poziom podobieństwa dla znalezionych chunków
|
| 147 |
+
debug_scores = baza.similarity_search_with_score(message, k=len(context_docs))
|
| 148 |
+
for i, (doc, score) in enumerate(debug_scores):
|
| 149 |
+
print(f"Chunk {i+1}: similarity_score={score}, title={doc.metadata.get('title')}")
|
| 150 |
sources_md = format_sources(context_docs)
|
| 151 |
+
answer = response.get("answer") or ""
|
| 152 |
+
answer_with_sources = answer + "\n\n**Źródła:**\n" + sources_md
|
| 153 |
chat_history.append((message, answer_with_sources))
|
| 154 |
return chat_history
|
| 155 |
|
| 156 |
+
# Obsługa kliknięcia przycisku "Wyślij"
|
| 157 |
submit_btn.click(
|
| 158 |
respond,
|
| 159 |
[msg, chatbot, session_id],
|
| 160 |
[chatbot]
|
| 161 |
).then(lambda: gr.update(value=""), None, [msg], queue=False)
|
| 162 |
|
| 163 |
+
# Obsługa wysłania wiadomości enterem
|
| 164 |
msg.submit(
|
| 165 |
respond,
|
| 166 |
[msg, chatbot, session_id],
|
|
|
|
| 169 |
|
| 170 |
# --- 5. Uruchomienie aplikacji ---
|
| 171 |
if __name__ == "__main__":
|
| 172 |
+
# Uruchom aplikację Gradio z publicznym linkiem
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
demo.launch(inbrowser=True)
|