chat / app.py
blech66's picture
Update app.py
003b5dc verified
import os
import gradio as gr
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_groq import ChatGroq
# ---------- Konfiguracja API Groq ----------
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.")
# ---------- Ładowanie FAISS i embeddingów ----------
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.")
# ---------- Model Groq ----------
chat = ChatGroq(
api_key=GROQ_API_KEY,
model_name="llama-3.3-70b-versatile",
temperature=0.7,
)
# ---------- System prompt dla bota BASIC (bez SPT) ----------
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.”
"""
# ---------- Prosty filtr bezpieczeństwa ----------
DISALLOWED_PATTERNS = [
"fuck a goat",
"sex with a goat",
"sex with animals",
"bestiality",
# dodaj inne oczywiste warianty, jeśli chcesz
]
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()
# filtr na szkodliwe treści seksualne
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."
)
# RAG: pobierz dokumenty z FAISS
docs = retriever.invoke(message)
context = "\n\n".join(doc.page_content for doc in docs)
full_prompt = build_full_prompt(context, message)
# wywołanie modelu Groq
result = chat.invoke(full_prompt)
return result.content
demo = gr.ChatInterface(
fn=chat_fn,
title="Chatbot",
)
if __name__ == "__main__":
demo.launch()