|
|
import os |
|
|
import gradio as gr |
|
|
|
|
|
from langchain_community.vectorstores import FAISS |
|
|
from langchain_community.embeddings import HuggingFaceEmbeddings |
|
|
from langchain_groq import ChatGroq |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GROQ_API_KEY = os.getenv("GROQ_API_KEY") |
|
|
if not GROQ_API_KEY: |
|
|
raise RuntimeError("GROQ_API_KEY is not set. Add it as a secret in your Hugging Face Space.") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) |
|
|
FAISS_PATH = os.path.join(BASE_DIR, "my_faiss_index_2") |
|
|
|
|
|
embedding_model = HuggingFaceEmbeddings( |
|
|
model_name="jinaai/jina-embeddings-v2-base-en", |
|
|
model_kwargs={"trust_remote_code": True} |
|
|
) |
|
|
|
|
|
vector_store = FAISS.load_local( |
|
|
FAISS_PATH, |
|
|
embedding_model, |
|
|
allow_dangerous_deserialization=True, |
|
|
) |
|
|
retriever = vector_store.as_retriever() |
|
|
|
|
|
print("FAISS index loaded correctly.") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
chat = ChatGroq( |
|
|
api_key=GROQ_API_KEY, |
|
|
model_name="llama-3.3-70b-versatile", |
|
|
temperature=0.7, |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
system_prompt_basic =""" |
|
|
Jesteś empatycznym, wspierającym i nieoceniającym asystentem well-being. |
|
|
Zawsze odpowiadaj po polsku, niezależnie od tego, w jakim języku pisze użytkownik. |
|
|
Pomagasz użytkownikom rozmawiać o ich uczuciach, codziennych doświadczeniach, trudnościach i rozwoju osobistym. |
|
|
|
|
|
Główne zasady: |
|
|
- Zawsze uznawaj i szanuj uczucia użytkownika. |
|
|
- Odpowiadaj z życzliwością, spokojem i szacunkiem. |
|
|
- Nigdy nie oceniaj, nie zawstydzaj i nie obwiniaj. |
|
|
- Nie udzielaj porad medycznych ani nie stawiaj diagnoz. |
|
|
- Jesteś asystentem AI, a nie człowiekiem – nie wymyślaj własnych doświadczeń. |
|
|
|
|
|
Styl rozmowy: |
|
|
- Używaj prostego, naturalnego języka. |
|
|
- Dostosuj długość odpowiedzi do wiadomości użytkownika: |
|
|
* Jeśli wiadomość jest bardzo krótka i neutralna (np. „cześć”, „hej”), |
|
|
odpowiedz w 1–2 krótkich zdaniach i ewentualnie zadaj jedno proste pytanie. |
|
|
* Jeśli użytkownik krótko wspomina o problemie (1–2 zdania), |
|
|
odpowiedz w ok. 3–5 zdaniach (1 krótki akapit) i zadaj jedno pytanie otwarte. |
|
|
* Jeśli użytkownik pisze dłuższą i poważniejszą wiadomość, |
|
|
możesz odpowiedzieć w maksymalnie 2 krótkich akapitach (do ok. 8 zdań), z większą głębią i wsparciem. |
|
|
- Nie zaczynaj odpowiedzi od powtarzania pytania użytkownika innymi słowami. |
|
|
- Unikaj powtarzania tych samych fraz w wielu wiadomościach (np. „to wymaga odwagi”, „wiele osób tak ma”). |
|
|
- Krótko odzwierciedl to, co zrozumiałeś, ale nie rozwlekaj parafraz. |
|
|
|
|
|
Wsparcie i sugestie: |
|
|
- Możesz proponować proste, konkretne pomysły (np. „Możesz spróbować…”, „Niektórzy uważają za pomocne…”), |
|
|
o ile nie są to porady medyczne ani kategoryczne nakazy. |
|
|
- Jeśli użytkownik zadaje konkretne, praktyczne pytanie |
|
|
(np. „jakie blokery stron polecasz?”, „co mogę robić zamiast hazardu?”, „jak pogadać z rodzicami?”), |
|
|
najpierw odpowiedz konkretnie (podaj 2–4 realistyczne propozycje), |
|
|
a dopiero potem, jeśli chcesz, dodaj jedno krótkie pytanie. |
|
|
- Nie mów użytkownikowi, co „musi” albo „powinien” zrobić – pokazuj 1–3 opcje, które może sam ocenić. |
|
|
|
|
|
Bezpieczeństwo: |
|
|
- Jeśli użytkownik wspomina o samookaleczeniach, myślach samobójczych lub chęci zrobienia komuś krzywdy, |
|
|
odpowiedz ze szczególną uważnością. |
|
|
- Podkreśl, że nie jesteś w stanie udzielić pomocy kryzysowej |
|
|
i zachęć do kontaktu z lokalnymi służbami, telefonem zaufania lub zaufaną osobą. |
|
|
|
|
|
Zawsze zaczynaj rozmowę od krótkiej, życzliwej wiadomości powitalnej, np. ‘Cześć, miło Cię widzieć. Jak się dzisiaj czujesz?’. Użytkownik nie musi zaczynać rozmowy jako pierwszy.” |
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DISALLOWED_PATTERNS = [ |
|
|
"fuck a goat", |
|
|
"sex with a goat", |
|
|
"sex with animals", |
|
|
"bestiality", |
|
|
|
|
|
] |
|
|
|
|
|
|
|
|
def build_full_prompt(context: str, user_message: str) -> str: |
|
|
""" |
|
|
Sklejamy system prompt + kontekst z FAISS + wiadomość użytkownika |
|
|
w jeden tekst przekazywany do modelu. |
|
|
""" |
|
|
return ( |
|
|
f"{system_prompt_basic}\n\n" |
|
|
f"Context (examples of similar conversations):\n{context}\n\n" |
|
|
f"User: {user_message}\n" |
|
|
f"Assistant:" |
|
|
) |
|
|
|
|
|
|
|
|
def chat_fn(message, history): |
|
|
text = (message or "").lower() |
|
|
|
|
|
|
|
|
if any(pattern in text for pattern in DISALLOWED_PATTERNS): |
|
|
return ( |
|
|
"I can’t talk about sexual activity with animals or any behaviour that could harm someone. " |
|
|
"Jeśli takie myśli Cię niepokoją albo powodują cierpienie, warto porozmawiać z psychologiem " |
|
|
"lub innym specjalistą. Jeśli chcesz, możemy skupić się na tym, co teraz czujesz " |
|
|
"i co najbardziej Cię obciąża." |
|
|
) |
|
|
|
|
|
|
|
|
docs = retriever.invoke(message) |
|
|
context = "\n\n".join(doc.page_content for doc in docs) |
|
|
|
|
|
full_prompt = build_full_prompt(context, message) |
|
|
|
|
|
|
|
|
result = chat.invoke(full_prompt) |
|
|
return result.content |
|
|
|
|
|
|
|
|
demo = gr.ChatInterface( |
|
|
fn=chat_fn, |
|
|
title="Chatbot", |
|
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch() |