Spaces:
Runtime error
Runtime error
import os | |
import pickle | |
import requests | |
import faiss | |
import numpy as np | |
from sentence_transformers import SentenceTransformer | |
from dotenv import load_dotenv | |
from openai import OpenAI | |
from groq import Groq | |
# === API Keys laden === | |
load_dotenv() | |
openai_key = os.getenv("OPENAI_API_KEY") | |
groq_key = os.getenv("GROQ_API_KEY") | |
openai_client = OpenAI(api_key=openai_key) if openai_key else None | |
groq_client = Groq(api_key=groq_key) if groq_key else None | |
# === Modell laden === | |
print("🧠 Lade SentenceTransformer...") | |
model = SentenceTransformer("Sahajtomar/German-semantic") | |
# === Google Drive Direktlinks | |
url_index = "https://drive.google.com/uc?export=download&id=1QBg4vjitJ2xHEyp3Ae8TWJHwEHjbwgOO" | |
url_chunks = "https://drive.google.com/uc?export=download&id=1nsrAm_ozsK4GlmMui9yqZBjmgUfqU2qa" | |
local_index = "faiss_index.index" | |
local_chunks = "chunks_mapping.pkl" | |
# === Datei-Download bei Bedarf | |
def download_if_missing(url, path): | |
if not os.path.exists(path): | |
print(f"⬇️ Lade {path} von Google Drive...") | |
r = requests.get(url) | |
if r.status_code == 200: | |
with open(path, "wb") as f: | |
f.write(r.content) | |
print(f"✅ Heruntergeladen: {path}") | |
else: | |
raise Exception(f"❌ Fehler beim Herunterladen von {path}") | |
download_if_missing(url_index, local_index) | |
download_if_missing(url_chunks, local_chunks) | |
# === FAISS laden | |
print("📂 Lade FAISS & Chunks...") | |
with open(local_chunks, "rb") as f: | |
token_split_texts = pickle.load(f) | |
print(f"✅ {len(token_split_texts)} Chunks geladen.") | |
chunk_embeddings = model.encode(token_split_texts, convert_to_numpy=True) | |
d = chunk_embeddings.shape[1] | |
index = faiss.IndexFlatL2(d) | |
index.add(chunk_embeddings) | |
print(f"✅ FAISS Index mit {index.ntotal} Einträgen.") | |
# === Ähnliche Chunks abrufen + Distanzen mitgeben | |
def retrieve(query, k=5): | |
query_embedding = model.encode([query], convert_to_numpy=True) | |
distances, indices = index.search(query_embedding, k) | |
safe_indices = [i for i in indices[0] if i < len(token_split_texts)] | |
retrieved_texts = [token_split_texts[i] for i in safe_indices] | |
return retrieved_texts, distances[0] | |
# === Prompt zusammenbauen | |
def build_prompt(query, texts): | |
context = "\n\n".join(texts) | |
return f"""Beantworte die folgende Frage basierend auf dem Kontext. | |
Kontext: | |
{context} | |
Frage: | |
{query} | |
""" | |
# === Anfrage an OpenAI | |
def ask_openai(prompt): | |
if not openai_client: | |
return "❌ Kein OpenAI API Key gefunden" | |
res = openai_client.chat.completions.create( | |
model="gpt-4", | |
messages=[ | |
{"role": "system", "content": "Du bist ein hilfsbereiter Catan-Regel-Experte."}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return res.choices[0].message.content.strip() | |
# === Anfrage an Groq | |
def ask_groq(prompt): | |
if not groq_client: | |
return "❌ Kein Groq API Key gefunden" | |
res = groq_client.chat.completions.create( | |
model="llama3-70b-8192", | |
messages=[ | |
{"role": "system", "content": "Du bist ein hilfsbereiter Catan-Regel-Experte."}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return res.choices[0].message.content.strip() | |
# === Hauptfunktion mit FAISS-Distanzfilter | |
def run_qa_pipeline(query, k=5): | |
try: | |
retrieved, distances = retrieve(query, k) | |
if not retrieved: | |
return "⚠️ Keine relevanten Textstellen gefunden." | |
max_dist = max(distances) | |
print(f"ℹ️ Höchste FAISS-Distanz: {max_dist:.4f}") | |
# 🔒 Schwelle für Relevanz (anpassbar) | |
if max_dist > 1.0: | |
return "🚫 Diese Frage scheint nichts mit Catan zu tun zu haben." | |
prompt = build_prompt(query, retrieved) | |
print("📨 Prompt gesendet...") | |
if openai_client: | |
answer = ask_openai(prompt) | |
elif groq_client: | |
answer = ask_groq(prompt) | |
else: | |
return "⚠️ Kein LLM API-Key vorhanden. Bitte OPENAI_API_KEY oder GROQ_API_KEY hinterlegen." | |
return f"📌 Frage: {query}\n\n📖 Antwort:\n{answer}" | |
except Exception as e: | |
return f"❌ Fehler beim Verarbeiten der Anfrage:\n{str(e)}"def build_prompt(query, texts): | |
context = "\n\n".join(texts) | |
return f"""Beantworte die folgende Frage basierend auf dem Kontext. | |
Kontext: | |
{context} | |
Frage: | |
{query} | |
""" | |
# === Anfrage an OpenAI | |
def ask_openai(prompt): | |
if not openai_client: | |
return "❌ Kein OpenAI API Key gefunden" | |
res = openai_client.chat.completions.create( | |
model="gpt-4", | |
messages=[ | |
{"role": "system", "content": "Du bist ein hilfsbereiter Catan-Regel-Experte."}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return res.choices[0].message.content.strip() | |
# === Anfrage an Groq | |
def ask_groq(prompt): | |
if not groq_client: | |
return "❌ Kein Groq API Key gefunden" | |
res = groq_client.chat.completions.create( | |
model="llama3-70b-8192", | |
messages=[ | |
{"role": "system", "content": "Du bist ein hilfsbereiter Catan-Regel-Experte."}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return res.choices[0].message.content.strip() | |
# === Hauptfunktion mit FAISS-Distanzfilter | |
def run_qa_pipeline(query, k=5): | |
try: | |
retrieved, distances = retrieve(query, k) | |
if not retrieved: | |
return "⚠️ Keine relevanten Textstellen gefunden." | |
max_dist = max(distances) | |
print(f"ℹ️ Höchste FAISS-Distanz: {max_dist:.4f}") | |
# 🔒 Schwelle für Relevanz | |
if max_dist > 1.0: | |
return "🚫 Diese Frage scheint nichts mit Catan zu tun zu haben." | |
prompt = build_prompt(query, retrieved) | |
print("📨 Prompt gesendet...") | |
if openai_client: | |
answer = ask_openai(prompt) | |
elif groq_client: | |
answer = ask_groq(prompt) | |
else: | |
return "⚠️ Kein LLM API-Key vorhanden. Bitte OPENAI_API_KEY oder GROQ_API_KEY hinterlegen." | |
return f"📌 Frage: {query}\n\n📖 Antwort:\n{answer}" | |
except Exception as e: | |
return f"❌ Fehler beim Verarbeiten der Anfrage:\n{str(e)}"def build_prompt(query, texts): | |
context = "\n\n".join(texts) | |
return f"""Beantworte die folgende Frage basierend auf dem Kontext. | |
Kontext: | |
{context} | |
Frage: | |
{query} | |
""" | |
# === Anfrage an OpenAI | |
def ask_openai(prompt): | |
if not openai_client: | |
return "❌ Kein OpenAI API Key gefunden" | |
res = openai_client.chat.completions.create( | |
model="gpt-4", | |
messages=[ | |
{"role": "system", "content": "Du bist ein hilfsbereiter Catan-Regel-Experte."}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return res.choices[0].message.content.strip() | |
# === Anfrage an Groq | |
def ask_groq(prompt): | |
if not groq_client: | |
return "❌ Kein Groq API Key gefunden" | |
res = groq_client.chat.completions.create( | |
model="llama3-70b-8192", | |
messages=[ | |
{"role": "system", "content": "Du bist ein hilfsbereiter Catan-Regel-Experte."}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return res.choices[0].message.content.strip() | |
# === Hauptfunktion mit FAISS-Distanzfilter | |
def run_qa_pipeline(query, k=5): | |
try: | |
retrieved, distances = retrieve(query, k) | |
if not retrieved: | |
return "⚠️ Keine relevanten Textstellen gefunden." | |
max_dist = max(distances) | |
print(f"ℹ️ Höchste FAISS-Distanz: {max_dist:.4f}") | |
# 🔒 Schwelle für Relevanz (anpassbar) | |
if max_dist > 1.0: | |
return "🚫 Diese Frage scheint nichts mit Catan zu tun zu haben." | |
prompt = build_prompt(query, retrieved) | |
print("📨 Prompt gesendet...") | |
if openai_client: | |
answer = ask_openai(prompt) | |
elif groq_client: | |
answer = ask_groq(prompt) | |
else: | |
return "⚠️ Kein LLM API-Key vorhanden. Bitte OPENAI_API_KEY oder GROQ_API_KEY hinterlegen." | |
return f"📌 Frage: {query}\n\n📖 Antwort:\n{answer}" | |
except Exception as e: | |
return f"❌ Fehler beim Verarbeiten der Anfrage:\n{str(e)}"def build_prompt(query, texts): | |
context = "\n\n".join(texts) | |
return f"""Beantworte die folgende Frage basierend auf dem Kontext. | |
Kontext: | |
{context} | |
Frage: | |
{query} | |
""" | |
# === Anfrage an OpenAI | |
def ask_openai(prompt): | |
if not openai_client: | |
return "❌ Kein OpenAI API Key gefunden" | |
res = openai_client.chat.completions.create( | |
model="gpt-4", | |
messages=[ | |
{"role": "system", "content": "Du bist ein hilfsbereiter Catan-Regel-Experte."}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return res.choices[0].message.content.strip() | |
# === Anfrage an Groq | |
def ask_groq(prompt): | |
if not groq_client: | |
return "❌ Kein Groq API Key gefunden" | |
res = groq_client.chat.completions.create( | |
model="llama3-70b-8192", | |
messages=[ | |
{"role": "system", "content": "Du bist ein hilfsbereiter Catan-Regel-Experte."}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return res.choices[0].message.content.strip() | |
# === Hauptfunktion mit FAISS-Distanzfilter | |
def run_qa_pipeline(query, k=5): | |
try: | |
retrieved, distances = retrieve(query, k) | |
if not retrieved: | |
return "⚠️ Keine relevanten Textstellen gefunden." | |
max_dist = max(distances) | |
print(f"ℹ️ Höchste FAISS-Distanz: {max_dist:.4f}") | |
# 🔒 Schwelle für Relevanz (anpassbar) | |
if max_dist > 1.0: | |
return "🚫 Diese Frage scheint nichts mit Catan zu tun zu haben." | |
prompt = build_prompt(query, retrieved) | |
print("📨 Prompt gesendet...") | |
if openai_client: | |
answer = ask_openai(prompt) | |
elif groq_client: | |
answer = ask_groq(prompt) | |
else: | |
return "⚠️ Kein LLM API-Key vorhanden. Bitte OPENAI_API_KEY oder GROQ_API_KEY hinterlegen." | |
return f"📌 Frage: {query}\n\n📖 Antwort:\n{answer}" | |
except Exception as e: | |
return f"❌ Fehler beim Verarbeiten der Anfrage:\n{str(e)}"def build_prompt(query, texts): | |
context = "\n\n".join(texts) | |
return f"""Beantworte die folgende Frage basierend auf dem Kontext. | |
Kontext: | |
{context} | |
Frage: | |
{query} | |
""" | |
# === Anfrage an OpenAI | |
def ask_openai(prompt): | |
if not openai_client: | |
return "❌ Kein OpenAI API Key gefunden" | |
res = openai_client.chat.completions.create( | |
model="gpt-4", | |
messages=[ | |
{"role": "system", "content": "Du bist ein hilfsbereiter Catan-Regel-Experte."}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return res.choices[0].message.content.strip() | |
# === Anfrage an Groq | |
def ask_groq(prompt): | |
if not groq_client: | |
return "❌ Kein Groq API Key gefunden" | |
res = groq_client.chat.completions.create( | |
model="llama3-70b-8192", | |
messages=[ | |
{"role": "system", "content": "Du bist ein hilfsbereiter Catan-Regel-Experte."}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return res.choices[0].message.content.strip() | |
# === Hauptfunktion mit FAISS-Distanzfilter | |
def run_qa_pipeline(query, k=5): | |
try: | |
retrieved, distances = retrieve(query, k) | |
if not retrieved: | |
return "⚠️ Keine relevanten Textstellen gefunden." | |
max_dist = max(distances) | |
print(f"ℹ️ Höchste FAISS-Distanz: {max_dist:.4f}") | |
# 🔒 Schwelle für Relevanz (je nach Modell ggf. anpassen) | |
if max_dist > 1.0: | |
return "🚫 Deine Frage passt wahrscheinlich nicht zu den Catan-Regeln. Bitte stelle eine spezifischere Frage." | |
prompt = build_prompt(query, retrieved) | |
print("📨 Prompt gesendet...") | |
if openai_client: | |
answer = ask_openai(prompt) | |
elif groq_client: | |
answer = ask_groq(prompt) | |
else: | |
return "⚠️ Kein LLM API-Key vorhanden. Bitte OPENAI_API_KEY oder GROQ_API_KEY hinterlegen." | |
return f"📌 Frage: {query}\n\n📖 Antwort:\n{answer}" | |
except Exception as e: | |
return f"❌ Fehler beim Verarbeiten der Anfrage:\n{str(e)}" context = "\n\n".join(texts) | |
return f"""Beantworte die folgende Frage basierend auf dem Kontext. | |
Kontext: | |
{context} | |
Frage: | |
{query} | |
""" | |
# === Anfrage an OpenAI | |
def ask_openai(prompt): | |
if not openai_client: | |
return "❌ Kein OpenAI API Key gefunden" | |
res = openai_client.chat.completions.create( | |
model="gpt-4", | |
messages=[ | |
{"role": "system", "content": "Du bist ein hilfsbereiter Catan-Regel-Experte."}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return res.choices[0].message.content.strip() | |
# === Anfrage an Groq | |
def ask_groq(prompt): | |
if not groq_client: | |
return "❌ Kein Groq API Key gefunden" | |
res = groq_client.chat.completions.create( | |
model="llama3-70b-8192", | |
messages=[ | |
{"role": "system", "content": "Du bist ein hilfsbereiter Catan-Regel-Experte."}, | |
{"role": "user", "content": prompt} | |
] | |
) | |
return res.choices[0].message.content.strip() | |
# === Hauptfunktion für Gradio | |
def run_qa_pipeline(query, k=5): | |
try: | |
retrieved = retrieve(query, k) | |
if not retrieved: | |
return "⚠️ Keine relevanten Textstellen gefunden." | |
prompt = build_prompt(query, retrieved) | |
print("📨 Prompt gesendet...") | |
if openai_client: | |
answer = ask_openai(prompt) | |
elif groq_client: | |
answer = ask_groq(prompt) | |
else: | |
return "⚠️ Kein LLM API-Key vorhanden. Bitte OPENAI_API_KEY oder GROQ_API_KEY hinterlegen." | |
return f"📌 Frage: {query}\n\n📖 Antwort:\n{answer}" | |
except Exception as e: | |
return f"❌ Fehler beim Verarbeiten der Anfrage:\n{str(e)}" |