Alibrown commited on
Commit
74a0fdb
·
verified ·
1 Parent(s): a43dae1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +72 -198
app.py CHANGED
@@ -16,7 +16,7 @@ from datasets import load_dataset, Dataset, concatenate_datasets
16
 
17
  # ------------------ Logging konfigurieren ------------------
18
  logging.basicConfig(
19
- level=logging.INFO, # Log-Level auf INFO setzen
20
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
21
  )
22
  logger = logging.getLogger(__name__)
@@ -33,234 +33,108 @@ else:
33
  DATASET_REPO = "AiCodeCarft/customer_memory"
34
 
35
  def load_memory_dataset():
36
- """
37
- Versucht, das Memory-Dataset vom HF Hub zu laden.
38
- Falls nicht vorhanden, wird ein leeres Dataset mit den Spalten
39
- 'user_id', 'query' und 'response' erstellt und gepusht.
40
- """
41
  try:
42
  ds = load_dataset(DATASET_REPO, split="train")
43
- st.write("Dataset loaded from HF Hub.")
44
  logger.info("Dataset erfolgreich vom HF Hub geladen.")
45
  except Exception as e:
46
- st.write("Dataset not found on HF Hub. Creating a new one...")
47
  logger.info("Kein Dataset gefunden. Erstelle ein neues Dataset...")
48
  data = {"user_id": [], "query": [], "response": []}
49
  ds = Dataset.from_dict(data)
50
  ds.push_to_hub(DATASET_REPO)
51
- st.write("New dataset created and pushed to HF Hub.")
52
  logger.info("Neues Dataset erfolgreich erstellt und gepusht.")
53
  return ds
54
 
55
  def add_to_memory(user_id, query, response):
56
- """
57
- Fügt einen neuen Eintrag (Query und Antwort) zum Memory-Dataset hinzu
58
- und pusht das aktualisierte Dataset an den HF Hub.
59
- """
60
  ds = load_memory_dataset()
61
- # Neuer Eintrag als kleines Dataset
62
  new_entry = Dataset.from_dict({
63
  "user_id": [user_id],
64
  "query": [query],
65
  "response": [response]
66
  })
67
- # Bestehendes Dataset mit dem neuen Eintrag zusammenführen
68
  updated_ds = concatenate_datasets([ds, new_entry])
69
- # Push updated dataset to HF Hub
70
  updated_ds.push_to_hub(DATASET_REPO)
71
- st.write("Memory updated.")
72
  logger.info("Memory-Dataset erfolgreich aktualisiert.")
73
 
74
  def get_memory(user_id):
75
- """
76
- Filtert das Memory-Dataset nach der angegebenen Customer ID
77
- und gibt alle Einträge (Query und Antwort) zurück.
78
- """
79
  ds = load_memory_dataset()
80
  filtered_ds = ds.filter(lambda x: x["user_id"] == user_id)
81
  logger.info(f"Memory für User {user_id} abgerufen. {len(filtered_ds)} Einträge gefunden.")
82
  return filtered_ds
83
 
84
- # ------------------ OpenAI GPT-4 API-Anbindung ------------------
85
- def generate_response(prompt):
86
- """
87
- Sendet den Prompt an die OpenAI API und gibt die Antwort zurück.
88
- """
89
- response = openai.ChatCompletion.create(
90
- model="gpt-3.5-turbo",
91
- messages=[
92
- {"role": "system", "content": "You are a customer support AI for TechGadgets.com."},
93
- {"role": "user", "content": prompt}
94
- ]
95
- )
96
- logger.info("Antwort von OpenAI erhalten.")
97
- return response.choices[0].message.content
98
-
99
  # ------------------ Streamlit App UI ------------------
100
  st.title("AI Customer Support Agent with Memory 🛒")
101
  st.caption("Chat with a customer support assistant who remembers your past interactions.")
102
 
103
- # Eingabe des OpenAI API Keys
104
  openai_api_key = st.text_input("Enter OpenAI API Key", type="password")
105
- if openai_api_key:
106
- os.environ['OPENAI_API_KEY'] = openai_api_key
107
- openai.api_key = openai_api_key
108
- logger.info("OpenAI API Key gesetzt.")
109
-
110
- # ------------------ Klasse: CustomerSupportAIAgent ------------------
111
- class CustomerSupportAIAgent:
112
- def __init__(self):
113
- # Wir nutzen hier die HF Dataset Funktionen als Memory-Speicher
114
- self.client = openai # OpenAI Client
115
- self.app_id = "customer-support"
116
-
117
- def handle_query(self, query, user_id=None):
118
- try:
119
- # Hole relevante Erinnerungen aus dem HF Dataset
120
- memories = get_memory(user_id)
121
- context = "Relevant past information:\n"
122
- # Falls Einträge vorhanden sind, baue den Kontext
123
- if len(memories) > 0:
124
- for entry in memories:
125
- context += f"- Query: {entry['query']}\n Response: {entry['response']}\n"
126
- logger.info("Kontext aus Memory-Dataset erstellt.")
127
-
128
- # Kombiniere Kontext und aktuelle Anfrage
129
- full_prompt = f"{context}\nCustomer: {query}\nSupport Agent:"
130
- logger.info("Vollständiger Prompt für OpenAI erstellt.")
131
-
132
- # Generiere Antwort mit OpenAI
133
- answer = generate_response(full_prompt)
134
-
135
- # Speicher die Interaktion im Memory-Dataset
136
- add_to_memory(user_id, query, answer)
137
- logger.info("Interaktion im Memory-Dataset gespeichert.")
138
-
139
- return answer
140
- except Exception as e:
141
- logger.error(f"Fehler bei handle_query: {e}")
142
- st.error(f"An error occurred while handling the query: {e}")
143
- return "Sorry, I encountered an error. Please try again later."
144
-
145
- def generate_synthetic_data(self, user_id: str) -> dict | None:
146
- try:
147
- today = datetime.datetime.now()
148
- order_date = (today - timedelta(days=10)).strftime("%B %d, %Y")
149
- expected_delivery = (today + timedelta(days=2)).strftime("%B %d, %Y")
150
-
151
- # Prompt zur Generierung synthetischer Kundendaten für einen Lieferservice
152
- prompt = f"""Generate a detailed customer profile and order history for a DeliverItExpress customer with ID {user_id}. Include:
153
- 1. Customer name and basic info (age, gender, and contact details)
154
- 2. A recent order of a gourmet meal (placed on {order_date} and delivered by {expected_delivery})
155
- 3. Order details including food items, total price, and order number
156
- 4. Customer's delivery address
157
- 5. 2-3 previous orders from the past year with different types of cuisines
158
- 6. 2-3 customer service interactions regarding delivery issues (e.g., late delivery, missing items)
159
- 7. Any preferences or patterns in their ordering behavior (e.g., favorite cuisines, peak ordering times)
160
-
161
- Format the output as a JSON object."""
162
- logger.info("Prompt for generating synthetic delivery service data created.")
163
-
164
- response = self.client.ChatCompletion.create(
165
- model="gpt-4",
166
- messages=[
167
- {"role": "system", "content": "You are a data generation AI that creates realistic customer profiles and order histories. Always respond with valid JSON."},
168
- {"role": "user", "content": prompt}
169
- ]
170
- )
171
- logger.info("Antwort für synthetische Daten von OpenAI erhalten.")
172
- customer_data = json.loads(response.choices[0].message.content)
173
-
174
- # Optional: Speichere auch diese Daten im Memory-Dataset
175
- for key, value in customer_data.items():
176
- if isinstance(value, list):
177
- for item in value:
178
- add_to_memory(user_id, f"{key} item", json.dumps(item))
179
- else:
180
- add_to_memory(user_id, key, json.dumps(value))
181
- logger.info("Synthetische Daten im Memory-Dataset gespeichert.")
182
- return customer_data
183
- except Exception as e:
184
- logger.error(f"Fehler bei generate_synthetic_data: {e}")
185
- st.error(f"Failed to generate synthetic data: {e}")
186
- return None
187
 
188
- # ------------------ Initialisierung des CustomerSupportAIAgent ------------------
189
- support_agent = CustomerSupportAIAgent()
190
-
191
- # ------------------ Sidebar: Customer ID und Optionen ------------------
192
- st.sidebar.title("Enter your Customer ID:")
193
- previous_customer_id = st.session_state.get("previous_customer_id", None)
194
- customer_id = st.sidebar.text_input("Enter your Customer ID")
195
-
196
- if customer_id != previous_customer_id:
197
- st.session_state.messages = []
198
- st.session_state.previous_customer_id = customer_id
199
- st.session_state.customer_data = None
200
- logger.info("Neue Customer ID erkannt – Chatverlauf und synthetische Daten zurückgesetzt.")
201
-
202
- # Button: Synthetische Daten generieren
203
- if st.sidebar.button("Generate Synthetic Data"):
204
- if customer_id:
205
- with st.spinner("Generating customer data..."):
206
- st.session_state.customer_data = support_agent.generate_synthetic_data(customer_id)
207
- if st.session_state.customer_data:
208
- st.sidebar.success("Synthetic data generated successfully!")
209
- logger.info("Synthetische Daten erfolgreich generiert.")
210
- else:
211
- st.sidebar.error("Failed to generate synthetic data.")
212
- logger.error("Fehler beim Generieren synthetischer Daten.")
213
- else:
214
- st.sidebar.error("Please enter a customer ID first.")
215
- logger.warning("Kein Customer ID eingegeben beim Versuch, synthetische Daten zu generieren.")
216
-
217
- # Button: Customer Profile anzeigen
218
- if st.sidebar.button("View Customer Profile"):
219
- if st.session_state.customer_data:
220
- st.sidebar.json(st.session_state.customer_data)
221
- else:
222
- st.sidebar.info("No customer data generated yet. Click 'Generate Synthetic Data' first.")
223
-
224
- # Button: Memory-Info anzeigen
225
- if st.sidebar.button("View Memory Info"):
226
- if customer_id:
227
- memories = get_memory(customer_id)
228
- st.sidebar.write(f"Memory for customer **{customer_id}**:")
229
- for mem in memories:
230
- st.sidebar.write(f"**Query:** {mem['query']}\n**Response:** {mem['response']}\n---")
231
- else:
232
- st.sidebar.error("Please enter a customer ID.")
233
-
234
- # ------------------ Chatverlauf initialisieren und anzeigen ------------------
235
- if "messages" not in st.session_state:
236
- st.session_state.messages = []
237
-
238
- # Vorherige Nachrichten anzeigen
239
- for message in st.session_state.messages:
240
- with st.chat_message(message["role"]):
241
- st.markdown(message["content"])
242
-
243
- # ------------------ Haupt-Chat: Benutzereingabe ------------------
244
- query = st.chat_input("How can I assist you today?")
245
- if query and customer_id:
246
- # Benutzeranfrage zum Chatverlauf hinzufügen
247
- st.session_state.messages.append({"role": "user", "content": query})
248
- with st.chat_message("user"):
249
- st.markdown(query)
250
- logger.info("Benutzeranfrage hinzugefügt.")
251
-
252
- # Generiere Antwort und zeige sie an
253
- with st.spinner("Generating response..."):
254
- answer = support_agent.handle_query(query, user_id=customer_id)
255
- st.session_state.messages.append({"role": "assistant", "content": answer})
256
- with st.chat_message("assistant"):
257
- st.markdown(answer)
258
- logger.info("Antwort des Assistenten hinzugefügt.")
259
-
260
- elif query and not customer_id:
261
- st.error("Please enter a customer ID to start the chat.")
262
- logger.warning("Chat gestartet ohne Customer ID.")
263
-
264
- else:
265
- st.warning("Please enter your OpenAI API key to use the customer support agent.")
266
- logger.info("Warte auf Eingabe des OpenAI API Keys.")
 
16
 
17
  # ------------------ Logging konfigurieren ------------------
18
  logging.basicConfig(
19
+ level=logging.INFO,
20
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
21
  )
22
  logger = logging.getLogger(__name__)
 
33
  DATASET_REPO = "AiCodeCarft/customer_memory"
34
 
35
  def load_memory_dataset():
 
 
 
 
 
36
  try:
37
  ds = load_dataset(DATASET_REPO, split="train")
 
38
  logger.info("Dataset erfolgreich vom HF Hub geladen.")
39
  except Exception as e:
 
40
  logger.info("Kein Dataset gefunden. Erstelle ein neues Dataset...")
41
  data = {"user_id": [], "query": [], "response": []}
42
  ds = Dataset.from_dict(data)
43
  ds.push_to_hub(DATASET_REPO)
 
44
  logger.info("Neues Dataset erfolgreich erstellt und gepusht.")
45
  return ds
46
 
47
  def add_to_memory(user_id, query, response):
 
 
 
 
48
  ds = load_memory_dataset()
 
49
  new_entry = Dataset.from_dict({
50
  "user_id": [user_id],
51
  "query": [query],
52
  "response": [response]
53
  })
 
54
  updated_ds = concatenate_datasets([ds, new_entry])
 
55
  updated_ds.push_to_hub(DATASET_REPO)
 
56
  logger.info("Memory-Dataset erfolgreich aktualisiert.")
57
 
58
  def get_memory(user_id):
 
 
 
 
59
  ds = load_memory_dataset()
60
  filtered_ds = ds.filter(lambda x: x["user_id"] == user_id)
61
  logger.info(f"Memory für User {user_id} abgerufen. {len(filtered_ds)} Einträge gefunden.")
62
  return filtered_ds
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  # ------------------ Streamlit App UI ------------------
65
  st.title("AI Customer Support Agent with Memory 🛒")
66
  st.caption("Chat with a customer support assistant who remembers your past interactions.")
67
 
68
+ # OpenAI API Key Eingabe oben in der Haupt-UI
69
  openai_api_key = st.text_input("Enter OpenAI API Key", type="password")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
+ if not openai_api_key:
72
+ st.warning("⚠️ Please enter your OpenAI API key to continue.")
73
+ st.stop()
74
+
75
+ openai.api_key = openai_api_key # Direktes Setzen des API-Keys
76
+
77
+ # ------------------ Klasse: CustomerSupportAIAgent ------------------
78
+ class CustomerSupportAIAgent:
79
+ def __init__(self):
80
+ self.client = openai
81
+ self.app_id = "customer-support"
82
+
83
+ def handle_query(self, query, user_id=None):
84
+ try:
85
+ memories = get_memory(user_id)
86
+ context = "Relevant past information:\n"
87
+ if len(memories) > 0:
88
+ for entry in memories:
89
+ context += f"- Query: {entry['query']}\n Response: {entry['response']}\n"
90
+
91
+ full_prompt = f"{context}\nCustomer: {query}\nSupport Agent:"
92
+
93
+ # API-Key wird direkt übergeben
94
+ answer = self.client.ChatCompletion.create(
95
+ model="gpt-3.5-turbo",
96
+ messages=[
97
+ {"role": "system", "content": "You are a customer support AI for TechGadgets.com."},
98
+ {"role": "user", "content": full_prompt}
99
+ ]
100
+ ).choices[0].message.content
101
+
102
+ add_to_memory(user_id, query, answer)
103
+ return answer
104
+ except Exception as e:
105
+ logger.error(f"Fehler bei handle_query: {e}")
106
+ return "Sorry, I encountered an error. Please try again later."
107
+
108
+ # ------------------ Initialisierung ------------------
109
+ support_agent = CustomerSupportAIAgent()
110
+
111
+ # ------------------ Sidebar-Komponenten ------------------
112
+ with st.sidebar:
113
+ st.title("Customer ID")
114
+ customer_id = st.text_input("Enter your Customer ID", key="customer_id")
115
+
116
+ if 'customer_id' in st.session_state and st.session_state.customer_id:
117
+ if st.button("Generate Synthetic Data"):
118
+ # ... (deine bestehende Synthetic Data Logik)
119
+
120
+ # ------------------ Chat-History Management ------------------
121
+ if "messages" not in st.session_state:
122
+ st.session_state.messages = []
123
+
124
+ # ------------------ Chat-Eingabe ------------------
125
+ if prompt := st.chat_input("How can I assist you today?"):
126
+ if not customer_id:
127
+ st.error(" Please enter a customer ID first")
128
+ st.stop()
129
+
130
+ st.session_state.messages.append({"role": "user", "content": prompt})
131
+
132
+ with st.spinner("Generating response..."):
133
+ response = support_agent.handle_query(prompt, customer_id)
134
+
135
+ st.session_state.messages.append({"role": "assistant", "content": response})
136
+
137
+ # ------------------ Nachrichten anzeigen ------------------
138
+ for message in st.session_state.messages:
139
+ with st.chat_message(message["role"]):
140
+ st.markdown(message["content"])