k96beni commited on
Commit
794b24d
·
verified ·
1 Parent(s): b0b31a7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -87
app.py CHANGED
@@ -2,13 +2,9 @@ import os
2
  import json
3
  import time
4
  import requests
5
- # Lägg till Anthropic import
6
  from anthropic import Anthropic
7
  from openai import OpenAI
8
  import gradio as gr
9
- from sentence_transformers import SentenceTransformer
10
- import numpy as np
11
- import faiss
12
  import pandas as pd
13
  from huggingface_hub import CommitScheduler
14
  from datetime import datetime, timedelta
@@ -19,8 +15,6 @@ import threading
19
 
20
  # --- Konfiguration ---
21
  CHARGENODE_URL = "https://www.chargenode.eu"
22
- MAX_CHUNK_SIZE = 1024
23
- RETRIEVAL_K = 3
24
 
25
  # Kontrollera om vi kör i Hugging Face-miljön
26
  IS_HUGGINGFACE = os.environ.get("SPACE_ID") is not None
@@ -61,9 +55,9 @@ scheduler = CommitScheduler(
61
  token=hf_token
62
  )
63
 
64
-
65
  # --- Globala variabler ---
66
  last_log = None # Sparar loggdata från senaste svar för feedback
 
67
 
68
  # --- Förbättrad loggfunktion ---
69
  def safe_append_to_log(log_entry):
@@ -99,6 +93,7 @@ def safe_append_to_log(log_entry):
99
 
100
  # --- Laddar textkällor ---
101
  def load_local_files():
 
102
  uploaded_text = ""
103
  allowed = [".txt", ".docx", ".pdf", ".csv", ".xls", ".xlsx"]
104
  excluded = ["requirements.txt", "app.py", "conversation_log.txt", "conversation_log_v2.txt", "secrets"]
@@ -132,114 +127,59 @@ def load_local_files():
132
  print(f"Fel vid läsning av {file}: {str(e)}")
133
  return uploaded_text.strip()
134
 
 
135
  def load_prompt():
 
136
  try:
137
  with open("prompt.txt", "r", encoding="utf-8") as f:
138
- return f.read().strip()
 
 
 
 
 
 
 
139
  except Exception as e:
140
- print(f"Fel vid prompt.txt: {e}")
141
- return ""
142
-
143
  prompt_template = load_prompt()
144
 
145
- # Förbered textsegment
146
- def prepare_chunks(text_data):
147
- chunks, sources = [], []
148
- for source, text in text_data.items():
149
- paragraphs = [p for p in text.split("\n") if p.strip()]
150
- chunk = ""
151
- for para in paragraphs:
152
- if len(chunk) + len(para) + 1 <= MAX_CHUNK_SIZE:
153
- chunk += " " + para
154
- else:
155
- if chunk.strip():
156
- chunks.append(chunk.strip())
157
- sources.append(source)
158
- chunk = para
159
- if chunk.strip():
160
- chunks.append(chunk.strip())
161
- sources.append(source)
162
- return chunks, sources
163
-
164
- # Lazy-laddning av SentenceTransformer
165
- embedder = None
166
- embeddings = None
167
- index = None
168
-
169
- def initialize_embeddings():
170
- """Initierar SentenceTransformer och FAISS-index vid första anrop."""
171
- global embedder, embeddings, index, chunks, chunk_sources
172
-
173
- if embedder is None:
174
- print("Initierar SentenceTransformer och FAISS-index...")
175
- # Ladda och förbered lokal data
176
- print("Laddar textdata...")
177
- text_data = {"local_files": load_local_files()}
178
- print("Förbereder textsegment...")
179
- chunks, chunk_sources = prepare_chunks(text_data)
180
- print(f"{len(chunks)} segment laddade")
181
-
182
- print("Skapar embeddings...")
183
- embedder = SentenceTransformer('all-MiniLM-L6-v2')
184
- embeddings = embedder.encode(chunks, convert_to_numpy=True)
185
- embeddings /= np.linalg.norm(embeddings, axis=1, keepdims=True)
186
- index = faiss.IndexFlatIP(embeddings.shape[1])
187
- index.add(embeddings)
188
- print("FAISS-index klart")
189
-
190
- def retrieve_context(query, k=RETRIEVAL_K):
191
- """Hämtar relevant kontext för frågor."""
192
- # Säkerställ att modeller är laddade
193
- initialize_embeddings()
194
-
195
- query_embedding = embedder.encode([query], convert_to_numpy=True)
196
- query_embedding /= np.linalg.norm(query_embedding)
197
- D, I = index.search(query_embedding, k)
198
- retrieved, sources = [], set()
199
- for idx in I[0]:
200
- if idx < len(chunks):
201
- retrieved.append(chunks[idx])
202
- sources.add(chunk_sources[idx])
203
- return " ".join(retrieved), list(sources)
204
-
205
- # Ändra modellsträngen i generate_answer-funktionen:
206
-
207
  def generate_answer(query):
208
- """Genererar svar baserat på fråga med hela kontexten."""
209
  # Hämta hela kontexten
210
  context = load_full_context()
211
 
212
  if not context.strip():
213
  return "Jag hittar ingen relevant information i mina källor.\n\nDetta är ett AI genererat svar."
214
 
215
- # System-prompts och användarfråga
216
- prompt = f"""{prompt_template}
217
 
218
- Hela dataunderlaget:
 
 
 
219
  {context}
220
 
221
- Fråga: {query}
222
- Svar (baserat enbart på den tillhandahållna datan):"""
223
 
224
  try:
225
- # Använd Claude Haiku med hela kontexten
226
- # Ändra modellsträngen till den korrekta
227
  response = anthropic_client.messages.create(
228
- model="claude-3-haiku-20240307", # Korrigerad modellsträng
229
  max_tokens=500,
230
  temperature=0.2,
231
- system=("Du är en expert på ChargeNodes produkter och tjänster. "
232
- "Svara enbart baserat på den information som finns i den tillhandahållna datan."),
233
  messages=[
234
- {"role": "user", "content": prompt}
235
  ]
236
  )
237
  answer = response.content[0].text
238
  return answer + "\n\nAI-genererat. Otillräcklig hjälp? Kontakta support@chargenode.eu eller 010-2051055"
239
  except Exception as e:
240
  return f"Tekniskt fel: {str(e)}\n\nAI-genererat. Kontakta support@chargenode.eu eller 010-2051055"
241
-
242
- # Resten av koden lämnas oförändrad...
243
  # --- Slack Integration ---
244
  def send_to_slack(subject, content, color="#2a9d8f"):
245
  """Basfunktion för att skicka meddelanden till Slack."""
@@ -836,5 +776,10 @@ with gr.Blocks(css=custom_css, title="ChargeNode Kundtjänst") as app:
836
  [chat_interface, support_interface, success_interface, chat_preview]
837
  )
838
 
 
 
 
 
 
839
  if __name__ == "__main__":
840
  app.launch(share=True)
 
2
  import json
3
  import time
4
  import requests
 
5
  from anthropic import Anthropic
6
  from openai import OpenAI
7
  import gradio as gr
 
 
 
8
  import pandas as pd
9
  from huggingface_hub import CommitScheduler
10
  from datetime import datetime, timedelta
 
15
 
16
  # --- Konfiguration ---
17
  CHARGENODE_URL = "https://www.chargenode.eu"
 
 
18
 
19
  # Kontrollera om vi kör i Hugging Face-miljön
20
  IS_HUGGINGFACE = os.environ.get("SPACE_ID") is not None
 
55
  token=hf_token
56
  )
57
 
 
58
  # --- Globala variabler ---
59
  last_log = None # Sparar loggdata från senaste svar för feedback
60
+ full_context = None # Används för att spara hela kontexten
61
 
62
  # --- Förbättrad loggfunktion ---
63
  def safe_append_to_log(log_entry):
 
93
 
94
  # --- Laddar textkällor ---
95
  def load_local_files():
96
+ """Laddar alla lokala filer och returnerar som en sammanhängande text."""
97
  uploaded_text = ""
98
  allowed = [".txt", ".docx", ".pdf", ".csv", ".xls", ".xlsx"]
99
  excluded = ["requirements.txt", "app.py", "conversation_log.txt", "conversation_log_v2.txt", "secrets"]
 
127
  print(f"Fel vid läsning av {file}: {str(e)}")
128
  return uploaded_text.strip()
129
 
130
+ # Uppdatera load_prompt-funktionen för bättre felhantering
131
  def load_prompt():
132
+ """Läser in system-prompts från prompt.txt med bättre felhantering."""
133
  try:
134
  with open("prompt.txt", "r", encoding="utf-8") as f:
135
+ prompt_content = f.read().strip()
136
+ if not prompt_content:
137
+ print("Varning: prompt.txt är tom, använder standardprompt")
138
+ return "Du är ChargeNode's AI-assistent. Svara på frågor om ChargeNode's produkter och tjänster baserat på den tillhandahållna informationen."
139
+ return prompt_content
140
+ except FileNotFoundError:
141
+ print("Varning: prompt.txt hittades inte, använder standardprompt")
142
+ return "Du är ChargeNode's AI-assistent. Svara på frågor om ChargeNode's produkter och tjänster baserat på den tillhandahållna informationen."
143
  except Exception as e:
144
+ print(f"Fel vid inläsning av prompt.txt: {e}, använder standardprompt")
145
+ return "Du är ChargeNode's AI-assistent. Svara på frågor om ChargeNode's produkter och tjänster baserat på den tillhandahållna informationen."
146
+ # Ladda prompt template
147
  prompt_template = load_prompt()
148
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  def generate_answer(query):
150
+ """Genererar svar baserat på fråga med hela kontexten och system-prompt från prompt.txt."""
151
  # Hämta hela kontexten
152
  context = load_full_context()
153
 
154
  if not context.strip():
155
  return "Jag hittar ingen relevant information i mina källor.\n\nDetta är ett AI genererat svar."
156
 
157
+ # Använd prompt_template som system-prompt istället för att lägga den i användarens meddelande
158
+ system_prompt = prompt_template
159
 
160
+ # Skapa ett renare användarmeddelande
161
+ user_message = f"""Jag har en fråga om ChargeNode.
162
+
163
+ Hela dataunderlaget du kan använda för att svara:
164
  {context}
165
 
166
+ Min fråga är: {query}"""
 
167
 
168
  try:
169
+ # Använd Claude Haiku med hela kontexten och system-prompt
 
170
  response = anthropic_client.messages.create(
171
+ model="claude-3-haiku-20240307",
172
  max_tokens=500,
173
  temperature=0.2,
174
+ system=system_prompt, # Använd prompt.txt som system-prompt
 
175
  messages=[
176
+ {"role": "user", "content": user_message}
177
  ]
178
  )
179
  answer = response.content[0].text
180
  return answer + "\n\nAI-genererat. Otillräcklig hjälp? Kontakta support@chargenode.eu eller 010-2051055"
181
  except Exception as e:
182
  return f"Tekniskt fel: {str(e)}\n\nAI-genererat. Kontakta support@chargenode.eu eller 010-2051055"
 
 
183
  # --- Slack Integration ---
184
  def send_to_slack(subject, content, color="#2a9d8f"):
185
  """Basfunktion för att skicka meddelanden till Slack."""
 
776
  [chat_interface, support_interface, success_interface, chat_preview]
777
  )
778
 
779
+ # Ladda kontexten direkt vid uppstart
780
+ print("Förbereder hela kontexten vid uppstart...")
781
+ load_full_context()
782
+ print("Kontext laddad och redo!")
783
+
784
  if __name__ == "__main__":
785
  app.launch(share=True)