vab42 commited on
Commit
dc68bf7
·
verified ·
1 Parent(s): 9d51ba2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -66
app.py CHANGED
@@ -1,65 +1,53 @@
1
  import os
2
  import google.generativeai as genai
3
  from flask import Flask, request, jsonify
4
- from flask_cors import CORS # Wichtig für Cross-Origin Requests von deiner Website
5
 
6
  app = Flask(__name__)
7
- CORS(app) # Ermöglicht Anfragen von deiner Hoststar-Domain
8
 
9
  # --- Konfiguration & Gemini Initialisierung ---
10
- # Dein Gemini API-Schlüssel wird als Hugging Face Space Secret übergeben
11
  GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
12
  if not GOOGLE_API_KEY:
13
  raise ValueError("GOOGLE_API_KEY Umgebungsvariable nicht gesetzt! Bitte als HF Space Secret hinterlegen.")
14
 
15
  genai.configure(api_key=GOOGLE_API_KEY)
16
 
17
- # Initialisiere das fortschrittlichste Gemini Pro Modell für Multimodalität
18
- # 'gemini-1.5-pro' ist die empfohlene Wahl für umfassende Fähigkeiten.
19
  model = genai.GenerativeModel(
20
  'gemini-1.5-pro',
21
- # DIES IST DIE EINE KRITISCHE ZEILE. SIE MUSS EXAKT SO AUSSEHEN:
22
- tools=[genai.tool_for_google_search()], # Ermöglicht Gemini die Internetrecherche bei Bedarf
 
 
 
23
  system_instruction="Du bist Moejra, eine hilfsbereite, geduldige und informative KI-Lernbegleitung von learn.create.repeat. Antworte immer im Stil von Moejra: unterstützend, ermutigend und auf Bildungstechnologie fokussiert. Nutze Informationen aus dem bereitgestellten Kontext (Wissensdatenbank) und bei Bedarf aus dem Internet. Wenn der Nutzer nach einem Bild fragt oder eine visuelle Idee beschreibt, generiere ein passendes Bild und erwähne es explizit. Gib sonst eine klare Textantwort."
24
  )
25
- chat = model.start_chat(history=[]) # Verwaltet den Chatverlauf für eine durchgängige Konversation
26
 
27
  # --- Wissensdatenbank (RAG) Funktion ---
28
  def retrieve_info_from_kb(query):
29
- """
30
- Diese Funktion durchsucht deine lokale Wissensdatenbank
31
- (im Ordner 'knowledge_base') nach relevanten Informationen.
32
- Es wird eine einfache Keyword-Suche implementiert.
33
- Für eine robustere Lösung bei größeren Datenmengen,
34
- sollten hier Embeddings und eine Vektordatenbank (z.B. ChromaDB, FAISS)
35
- mit Tools wie LangChain oder LlamaIndex integriert werden.
36
- """
37
  relevant_text = []
38
- knowledge_base_dir = "knowledge_base" # Ordnername für deine Wissensdatenbank
 
39
  if not os.path.exists(knowledge_base_dir):
40
- print(f"Warnung: Wissensdatenbank-Verzeichnis '{knowledge_base_dir}' nicht gefunden. RAG wird übersprungen.")
41
  return ""
42
 
43
- # Extrahiere Schlüsselwörter aus der Anfrage (ignoriere sehr kurze Wörter)
44
  query_keywords = [word.lower() for word in query.split() if len(word) > 2]
45
 
46
- # Iteriere durch alle Textdateien in der Wissensdatenbank
47
  for filename in os.listdir(knowledge_base_dir):
48
- if filename.endswith(".txt"): # Nur Textdateien berücksichtigen
49
  filepath = os.path.join(knowledge_base_dir, filename)
50
  try:
51
  with open(filepath, "r", encoding="utf-8") as f:
52
  content = f.read()
53
- # Prüfe, ob mindestens eines der Schlüsselwörter im Inhalt vorkommt
54
  if any(keyword in content.lower() for keyword in query_keywords):
55
  relevant_text.append(content)
56
  except Exception as e:
57
- print(f"Fehler beim Lesen der Wissensdatenbank-Datei {filename}: {e}")
58
 
59
- # Kombiniere alle relevanten Textteile, getrennt durch Trennlinien
60
  return "\n---\n".join(relevant_text) if relevant_text else ""
61
 
62
-
63
  # --- API-Endpunkt für den Chat ---
64
  @app.route('/chat', methods=['POST'])
65
  def handle_chat():
@@ -67,62 +55,43 @@ def handle_chat():
67
  if not user_input:
68
  return jsonify({"error": "No text provided"}), 400
69
 
70
- print(f"Received user input: {user_input}")
71
-
72
- # 1. RAG: Relevante Informationen aus der Wissensdatenbank abrufen
73
  kb_info = retrieve_info_from_kb(user_input)
74
 
75
- # 2. Prompt für Gemini erstellen
76
- prompt_parts = [
77
- f"Nutzerfrage: {user_input}",
78
- ]
79
  if kb_info:
80
- # Füge den abgerufenen Kontext dem Prompt hinzu
81
- prompt_parts.append(f"Zusätzlicher relevanter Kontext aus der Wissensdatenbank von learn.create.repeat.:\n{kb_info}")
82
- # Klare Anweisung an Gemini, den Kontext zu priorisieren und Bilder zu generieren
83
- prompt_parts.append("Priorisiere Informationen aus diesem Kontext. Wenn die Frage eine Bildgenerierung impliziert, erstelle ein passendes Bild und erwähne es explizit. Gib sonst eine klare, ermutigende Textantwort. Nutze deine gesamte Expertise.")
 
84
  else:
85
- # Wenn kein Kontext gefunden wurde, instruiere Gemini, das allgemeine Wissen/Internet zu nutzen
86
- prompt_parts.append("Nutze dein allgemeines Wissen und recherchiere bei Bedarf im Internet. Wenn die Frage eine Bildgenerierung impliziert, erstelle ein passendes Bild und erwähne es explizit. Gib sonst eine klare, ermutigende Textantwort. Nutze deine gesamte Expertise.")
87
-
88
- response_text = ""
89
- image_urls = [] # Liste für eventuell generierte Bild-URLs
90
 
91
  try:
92
- # Sende die Nachricht an Gemini. Das Chat-Objekt verwaltet den Verlauf.
93
- gemini_response = chat.send_message(prompt_parts)
 
94
 
95
- # Iteriere durch die Teile der Gemini-Antwort, um Text und Bilder zu extrahieren
96
  for part in gemini_response.candidates[0].content.parts:
97
  if hasattr(part, 'text'):
98
- response_text += part.text # Sammle alle Textteile
99
  elif hasattr(part, 'image'):
100
- # Wenn ein Bild-Part vorhanden ist, extrahiere die Daten.
101
- # Gemini gibt generierte Bilder oft als Base64-kodierte Daten zurück.
102
  if hasattr(part.image, 'base64'):
103
  image_urls.append(f"data:image/jpeg;base64,{part.image.base64}")
104
  elif hasattr(part.image, 'url'):
105
- # Weniger häufig direkt als URL, aber als Fallback enthalten
106
  image_urls.append(part.image.url)
107
- # Falls Gemini den Text einer Bild-URL in den Text schreibt (statt als separate Part),
108
- # müsste dieser hier zusätzlich geparst werden (Regex etc.).
109
- # Die aktuelle Implementierung geht davon aus, dass Gemini Image-Parts liefert.
110
 
111
- print(f"Gemini response text: {response_text}, images count: {len(image_urls)}")
 
 
 
112
 
113
  except Exception as e:
114
- print(f"Fehler beim Aufruf der Gemini API: {e}")
115
- response_text = "Entschuldige, ich konnte deine Anfrage leider nicht vollständig bearbeiten. Bitte versuch es später noch einmal oder formuliere deine Frage anders."
116
- # Füge optional detailliertere Fehlerbehandlung hinzu, z.B. für Safety-Filter
117
- if hasattr(gemini_response, 'prompt_feedback') and gemini_response.prompt_feedback.block_reason:
118
- response_text = "Entschuldige, diese Anfrage konnte ich aus Sicherheitsgründen nicht bearbeiten. Bitte formuliere sie anders."
119
-
120
- # Sende die gesammelten Text- und Bild-Informationen zurück an den Browser
121
- return jsonify({
122
- "response_text": response_text,
123
- "image_urls": image_urls
124
- })
125
-
126
- # Starte die Flask-App. Hugging Face Spaces expose 7860.
127
  if __name__ == '__main__':
128
- app.run(host='0.0.0.0', port=7860)
 
1
  import os
2
  import google.generativeai as genai
3
  from flask import Flask, request, jsonify
4
+ from flask_cors import CORS
5
 
6
  app = Flask(__name__)
7
+ CORS(app)
8
 
9
  # --- Konfiguration & Gemini Initialisierung ---
 
10
  GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
11
  if not GOOGLE_API_KEY:
12
  raise ValueError("GOOGLE_API_KEY Umgebungsvariable nicht gesetzt! Bitte als HF Space Secret hinterlegen.")
13
 
14
  genai.configure(api_key=GOOGLE_API_KEY)
15
 
16
+ # Korrigierte Modellinitialisierung mit Google Search Integration
 
17
  model = genai.GenerativeModel(
18
  'gemini-1.5-pro',
19
+ tools=[
20
+ genai.Tool(
21
+ google_search_retrieval=genai.types.GoogleSearchRetrieval() # Offizielle Google Search Integration
22
+ )
23
+ ],
24
  system_instruction="Du bist Moejra, eine hilfsbereite, geduldige und informative KI-Lernbegleitung von learn.create.repeat. Antworte immer im Stil von Moejra: unterstützend, ermutigend und auf Bildungstechnologie fokussiert. Nutze Informationen aus dem bereitgestellten Kontext (Wissensdatenbank) und bei Bedarf aus dem Internet. Wenn der Nutzer nach einem Bild fragt oder eine visuelle Idee beschreibt, generiere ein passendes Bild und erwähne es explizit. Gib sonst eine klare Textantwort."
25
  )
26
+ chat = model.start_chat(history=[])
27
 
28
  # --- Wissensdatenbank (RAG) Funktion ---
29
  def retrieve_info_from_kb(query):
 
 
 
 
 
 
 
 
30
  relevant_text = []
31
+ knowledge_base_dir = "knowledge_base"
32
+
33
  if not os.path.exists(knowledge_base_dir):
 
34
  return ""
35
 
 
36
  query_keywords = [word.lower() for word in query.split() if len(word) > 2]
37
 
 
38
  for filename in os.listdir(knowledge_base_dir):
39
+ if filename.endswith(".txt"):
40
  filepath = os.path.join(knowledge_base_dir, filename)
41
  try:
42
  with open(filepath, "r", encoding="utf-8") as f:
43
  content = f.read()
 
44
  if any(keyword in content.lower() for keyword in query_keywords):
45
  relevant_text.append(content)
46
  except Exception as e:
47
+ print(f"Fehler beim Lesen der Datei {filename}: {e}")
48
 
 
49
  return "\n---\n".join(relevant_text) if relevant_text else ""
50
 
 
51
  # --- API-Endpunkt für den Chat ---
52
  @app.route('/chat', methods=['POST'])
53
  def handle_chat():
 
55
  if not user_input:
56
  return jsonify({"error": "No text provided"}), 400
57
 
 
 
 
58
  kb_info = retrieve_info_from_kb(user_input)
59
 
60
+ prompt_parts = [f"Nutzerfrage: {user_input}"]
 
 
 
61
  if kb_info:
62
+ prompt_parts.extend([
63
+ f"Zusätzlicher Kontext aus learn.create.repeat Wissensdatenbank:",
64
+ kb_info,
65
+ "Priorisiere diese Informationen. Bei Bildanfragen generiere explizit ein Bild. Sei ermutigend und präzise."
66
+ ])
67
  else:
68
+ prompt_parts.append("Nutze dein Wissen und Internetrecherche. Bei Bildanfragen generiere explizit ein Bild. Sei unterstützend.")
 
 
 
 
69
 
70
  try:
71
+ gemini_response = chat.send_message("\n".join(prompt_parts))
72
+ response_text = ""
73
+ image_urls = []
74
 
 
75
  for part in gemini_response.candidates[0].content.parts:
76
  if hasattr(part, 'text'):
77
+ response_text += part.text
78
  elif hasattr(part, 'image'):
 
 
79
  if hasattr(part.image, 'base64'):
80
  image_urls.append(f"data:image/jpeg;base64,{part.image.base64}")
81
  elif hasattr(part.image, 'url'):
 
82
  image_urls.append(part.image.url)
 
 
 
83
 
84
+ return jsonify({
85
+ "response_text": response_text.strip(),
86
+ "image_urls": image_urls
87
+ })
88
 
89
  except Exception as e:
90
+ print(f"Kritischer Fehler: {str(e)}")
91
+ return jsonify({
92
+ "response_text": "🤖 Hoppla! Bei der Verarbeitung ist ein Fehler aufgetreten. Bitte versuche es später noch einmal.",
93
+ "image_urls": []
94
+ }), 500
95
+
 
 
 
 
 
 
 
96
  if __name__ == '__main__':
97
+ app.run(host='0.0.0.0', port=7860)