Vighnesh commited on
Commit
b7372b5
·
1 Parent(s): 97ddb7d

Expand to 50 tickets with resolution_hints — tickets.py and notebook ALL_TICKETS in sync

Browse files
Files changed (2) hide show
  1. tickets.py +326 -33
  2. train_grpo.ipynb +1 -140
tickets.py CHANGED
@@ -2,82 +2,375 @@
2
  Realistic support ticket dataset with ground-truth labels.
3
  Each ticket includes:
4
  - id
5
- - text : customer message
6
- - category : ground-truth category
7
- - correct_action : best first action ("reply" | "escalate" | "close")
8
- - resolution_hint : ideal reply / close reason (used for reward scoring)
 
 
 
 
9
  """
10
 
11
  TICKETS = [
 
12
  {
13
- "id": "T001",
14
- "text": "Hi, I was charged twice for my subscription this month. Please help!",
15
  "category": "billing",
16
  "correct_action": "reply",
17
- "resolution_hint": "apologize and initiate refund for duplicate charge",
18
  },
19
  {
20
- "id": "T002",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  "text": "I cannot log into my account. The password reset email never arrives.",
22
  "category": "account",
23
  "correct_action": "reply",
24
- "resolution_hint": "guide user to check spam folder and verify email address",
25
  },
26
  {
27
- "id": "T003",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  "text": "Your app crashes every time I try to upload a file larger than 10 MB.",
29
  "category": "technical",
30
  "correct_action": "escalate",
31
- "resolution_hint": "escalate to engineering team with crash details",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  },
33
  {
34
  "id": "T004",
35
- "text": "I'd like a full refund. I haven't used the service at all this month.",
36
- "category": "refund",
37
- "correct_action": "reply",
38
- "resolution_hint": "verify account activity and process refund per policy",
39
  },
40
  {
41
  "id": "T005",
42
- "text": "What are your business hours and do you have a phone number I can call?",
43
- "category": "general",
44
- "correct_action": "reply",
45
- "resolution_hint": "provide business hours and contact information",
46
  },
47
  {
48
  "id": "T006",
49
- "text": "My invoice shows a charge for a plan I never subscribed to.",
50
- "category": "billing",
51
  "correct_action": "escalate",
52
- "resolution_hint": "escalate potential fraudulent charge to billing team",
53
  },
54
  {
55
  "id": "T007",
56
- "text": "How do I cancel my subscription? I can't find the option anywhere.",
57
- "category": "account",
58
- "correct_action": "reply",
59
- "resolution_hint": "guide user to account settings > subscription > cancel",
60
  },
61
  {
62
  "id": "T008",
63
- "text": "The API is returning 500 errors intermittently for the past 2 hours.",
64
  "category": "technical",
65
  "correct_action": "escalate",
66
- "resolution_hint": "escalate to on-call engineering with timestamps",
67
  },
68
  {
69
  "id": "T009",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  "text": "Thank you! The issue has been resolved. You guys are awesome.",
71
  "category": "general",
72
  "correct_action": "close",
73
- "resolution_hint": "acknowledge and close the ticket",
74
  },
75
  {
76
- "id": "T010",
77
- "text": "I need an itemised invoice for my company's accounting department.",
78
- "category": "billing",
 
 
 
 
 
 
 
79
  "correct_action": "reply",
80
- "resolution_hint": "generate and send itemised invoice to customer email",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  },
82
  ]
83
 
 
2
  Realistic support ticket dataset with ground-truth labels.
3
  Each ticket includes:
4
  - id
5
+ - text : customer message
6
+ - category : ground-truth category
7
+ - correct_action : best first action ("reply" | "escalate" | "close")
8
+ - resolution_hint : specific resolution keywords used for reply quality scoring
9
+ (two-tier: category keywords @0.03, hint keywords @0.05)
10
+
11
+ Distribution: 10 per category x 5 categories = 50 tickets
12
+ Difficulty varies within each category from straightforward to complex/ambiguous.
13
  """
14
 
15
  TICKETS = [
16
+ # ── billing (12) ──────────────────────────────────────────────────────────
17
  {
18
+ "id": "B001",
19
+ "text": "I was charged twice for my subscription this month. Please help!",
20
  "category": "billing",
21
  "correct_action": "reply",
22
+ "resolution_hint": "apologize for duplicate charge and initiate refund to original payment method within 3-5 days",
23
  },
24
  {
25
+ "id": "B002",
26
+ "text": "My invoice shows a charge for a plan I never subscribed to.",
27
+ "category": "billing",
28
+ "correct_action": "escalate",
29
+ "resolution_hint": "escalate potential unauthorized plan charge to billing team for investigation and correction",
30
+ },
31
+ {
32
+ "id": "B003",
33
+ "text": "I need an itemised invoice for my company's accounting department.",
34
+ "category": "billing",
35
+ "correct_action": "reply",
36
+ "resolution_hint": "generate itemised invoice with line-item breakdown and email to customer accounting address",
37
+ },
38
+ {
39
+ "id": "B004",
40
+ "text": "Why was I charged before my trial period ended?",
41
+ "category": "billing",
42
+ "correct_action": "reply",
43
+ "resolution_hint": "verify trial end date in billing system and issue refund for premature charge before expiry",
44
+ },
45
+ {
46
+ "id": "B005",
47
+ "text": "I switched plans but was still billed at the old rate.",
48
+ "category": "billing",
49
+ "correct_action": "reply",
50
+ "resolution_hint": "confirm plan switch date in system and issue prorated credit for overcharge at old rate",
51
+ },
52
+ {
53
+ "id": "B006",
54
+ "text": "My payment method was charged three times in one day.",
55
+ "category": "billing",
56
+ "correct_action": "escalate",
57
+ "resolution_hint": "escalate triple charge incident to billing fraud team and freeze further charges pending review",
58
+ },
59
+ {
60
+ "id": "B007",
61
+ "text": "I cancelled my plan but the charge still appeared this month.",
62
+ "category": "billing",
63
+ "correct_action": "reply",
64
+ "resolution_hint": "verify cancellation timestamp confirm post-cancel charge and process refund for final month",
65
+ },
66
+ {
67
+ "id": "B008",
68
+ "text": "Can you send me a receipt for my last payment?",
69
+ "category": "billing",
70
+ "correct_action": "reply",
71
+ "resolution_hint": "locate last successful payment record and email PDF receipt to customer registered address",
72
+ },
73
+ {
74
+ "id": "B009",
75
+ "text": "I was charged in USD but I signed up for GBP billing.",
76
+ "category": "billing",
77
+ "correct_action": "reply",
78
+ "resolution_hint": "identify currency mismatch at signup and issue credit note for exchange rate difference",
79
+ },
80
+ {
81
+ "id": "B010",
82
+ "text": "The discount code I applied is not reflected in my invoice.",
83
+ "category": "billing",
84
+ "correct_action": "reply",
85
+ "resolution_hint": "locate discount code application log verify failure reason and apply credit to next invoice",
86
+ },
87
+ {
88
+ "id": "B011",
89
+ "text": "I need to update my billing address on the invoice.",
90
+ "category": "billing",
91
+ "correct_action": "reply",
92
+ "resolution_hint": "update billing address in account settings and reissue corrected invoice for their records",
93
+ },
94
+ {
95
+ "id": "B012",
96
+ "text": "My credit card was charged even though a payment failed notification was sent.",
97
+ "category": "billing",
98
+ "correct_action": "escalate",
99
+ "resolution_hint": "escalate ghost charge to payments team attach failed payment notification as evidence for review",
100
+ },
101
+
102
+ # ── account (10) ──────────────────────────────────────────────────���───────
103
+ {
104
+ "id": "A001",
105
  "text": "I cannot log into my account. The password reset email never arrives.",
106
  "category": "account",
107
  "correct_action": "reply",
108
+ "resolution_hint": "check spam folder verify registered email address resend password reset link account locked",
109
  },
110
  {
111
+ "id": "A002",
112
+ "text": "How do I cancel my subscription? I can't find the option anywhere.",
113
+ "category": "account",
114
+ "correct_action": "reply",
115
+ "resolution_hint": "navigate account settings subscription tab locate cancel option confirm cancellation effective date",
116
+ },
117
+ {
118
+ "id": "A003",
119
+ "text": "I want to change my email address associated with the account.",
120
+ "category": "account",
121
+ "correct_action": "reply",
122
+ "resolution_hint": "verify identity via security question update email address send confirmation to both old and new",
123
+ },
124
+ {
125
+ "id": "A004",
126
+ "text": "My account was locked after too many failed login attempts.",
127
+ "category": "account",
128
+ "correct_action": "reply",
129
+ "resolution_hint": "unlock account after failed login attempts verify identity via backup code or support email",
130
+ },
131
+ {
132
+ "id": "A005",
133
+ "text": "I accidentally deleted my account. Can it be restored?",
134
+ "category": "account",
135
+ "correct_action": "reply",
136
+ "resolution_hint": "check account deletion grace period restore from backup if within 30 days confirm data intact",
137
+ },
138
+ {
139
+ "id": "A006",
140
+ "text": "I need to transfer my account to a different email.",
141
+ "category": "account",
142
+ "correct_action": "reply",
143
+ "resolution_hint": "verify ownership of both accounts initiate transfer request update billing and login credentials",
144
+ },
145
+ {
146
+ "id": "A007",
147
+ "text": "Two-factor authentication is not working for my account.",
148
+ "category": "account",
149
+ "correct_action": "reply",
150
+ "resolution_hint": "verify 2FA device registration resync authenticator app or issue backup recovery codes immediately",
151
+ },
152
+ {
153
+ "id": "A008",
154
+ "text": "I can't find where to download my data for GDPR purposes.",
155
+ "category": "account",
156
+ "correct_action": "reply",
157
+ "resolution_hint": "provide GDPR data export link in account privacy settings confirm 30-day download window",
158
+ },
159
+ {
160
+ "id": "A009",
161
+ "text": "My username was changed without my permission.",
162
+ "category": "account",
163
+ "correct_action": "escalate",
164
+ "resolution_hint": "escalate unauthorized username change to security team flag for account compromise investigation",
165
+ },
166
+ {
167
+ "id": "A010",
168
+ "text": "I want to upgrade my account from free to premium.",
169
+ "category": "account",
170
+ "correct_action": "reply",
171
+ "resolution_hint": "confirm current free plan limits explain premium features and provide upgrade link with pricing",
172
+ },
173
+
174
+ # ── technical (10) ────────────────────────────────────────────────────────
175
+ {
176
+ "id": "T001",
177
  "text": "Your app crashes every time I try to upload a file larger than 10 MB.",
178
  "category": "technical",
179
  "correct_action": "escalate",
180
+ "resolution_hint": "escalate to engineering with file size limit crash reproduction steps and device logs attached",
181
+ },
182
+ {
183
+ "id": "T002",
184
+ "text": "The API is returning 500 errors intermittently for the past 2 hours.",
185
+ "category": "technical",
186
+ "correct_action": "escalate",
187
+ "resolution_hint": "escalate API 500 errors to on-call engineering with timestamps error codes and affected endpoints",
188
+ },
189
+ {
190
+ "id": "T003",
191
+ "text": "The dashboard is completely blank after the latest update.",
192
+ "category": "technical",
193
+ "correct_action": "escalate",
194
+ "resolution_hint": "escalate blank dashboard to engineering with browser version last working date and console errors",
195
  },
196
  {
197
  "id": "T004",
198
+ "text": "Export to CSV is broken it downloads an empty file.",
199
+ "category": "technical",
200
+ "correct_action": "escalate",
201
+ "resolution_hint": "escalate empty CSV export bug to engineering with sample dataset and export configuration used",
202
  },
203
  {
204
  "id": "T005",
205
+ "text": "Notifications are not being delivered to my email or phone.",
206
+ "category": "technical",
207
+ "correct_action": "escalate",
208
+ "resolution_hint": "escalate notification delivery failure to infrastructure team check email provider and push config",
209
  },
210
  {
211
  "id": "T006",
212
+ "text": "The mobile app freezes on the login screen on iOS 17.",
213
+ "category": "technical",
214
  "correct_action": "escalate",
215
+ "resolution_hint": "escalate iOS 17 freeze to mobile engineering with device model OS version and crash report",
216
  },
217
  {
218
  "id": "T007",
219
+ "text": "Search functionality returns no results for any query.",
220
+ "category": "technical",
221
+ "correct_action": "escalate",
222
+ "resolution_hint": "escalate search returning no results to engineering with query examples and index rebuild request",
223
  },
224
  {
225
  "id": "T008",
226
+ "text": "Data sync between devices stopped working 3 days ago.",
227
  "category": "technical",
228
  "correct_action": "escalate",
229
+ "resolution_hint": "escalate device sync failure to backend team with affected device IDs and last sync timestamp",
230
  },
231
  {
232
  "id": "T009",
233
+ "text": "The webhook integration keeps timing out and losing events.",
234
+ "category": "technical",
235
+ "correct_action": "escalate",
236
+ "resolution_hint": "escalate webhook timeout to integrations team with endpoint URL payload size and retry logs",
237
+ },
238
+ {
239
+ "id": "T010",
240
+ "text": "Browser extension throws a JavaScript error on every page load.",
241
+ "category": "technical",
242
+ "correct_action": "escalate",
243
+ "resolution_hint": "escalate browser extension JavaScript error to frontend team with browser version and error stack",
244
+ },
245
+
246
+ # ── refund (8) ────────────────────────────────────────────────────────────
247
+ {
248
+ "id": "R001",
249
+ "text": "I'd like a full refund. I haven't used the service at all this month.",
250
+ "category": "refund",
251
+ "correct_action": "reply",
252
+ "resolution_hint": "confirm zero usage this billing period process full refund within 5-7 business days to original payment method",
253
+ },
254
+ {
255
+ "id": "R002",
256
+ "text": "I was double charged and need a refund for the extra payment.",
257
+ "category": "refund",
258
+ "correct_action": "reply",
259
+ "resolution_hint": "verify double charge in payment gateway logs process refund for duplicate amount to card on file",
260
+ },
261
+ {
262
+ "id": "R003",
263
+ "text": "The product did not work as advertised. I want my money back.",
264
+ "category": "refund",
265
+ "correct_action": "reply",
266
+ "resolution_hint": "review product description versus delivered functionality confirm mismatch and process refund",
267
+ },
268
+ {
269
+ "id": "R004",
270
+ "text": "I cancelled within the 30-day window but have not received my refund.",
271
+ "category": "refund",
272
+ "correct_action": "reply",
273
+ "resolution_hint": "verify cancellation date within refund window locate delayed refund in processor and escalate",
274
+ },
275
+ {
276
+ "id": "R005",
277
+ "text": "I would like a partial refund for the unused months of my annual plan.",
278
+ "category": "refund",
279
+ "correct_action": "reply",
280
+ "resolution_hint": "calculate unused months on annual plan process prorated refund for remaining subscription period",
281
+ },
282
+ {
283
+ "id": "R006",
284
+ "text": "A refund was promised by your support agent 2 weeks ago but never arrived.",
285
+ "category": "refund",
286
+ "correct_action": "escalate",
287
+ "resolution_hint": "escalate undelivered promised refund to billing manager attach original support agent transcript",
288
+ },
289
+ {
290
+ "id": "R007",
291
+ "text": "I need a refund processed urgently as it was a fraudulent charge.",
292
+ "category": "refund",
293
+ "correct_action": "escalate",
294
+ "resolution_hint": "escalate fraudulent charge to payments fraud team freeze account initiate chargeback process",
295
+ },
296
+ {
297
+ "id": "R008",
298
+ "text": "How long does a refund take to appear on my credit card?",
299
+ "category": "refund",
300
+ "correct_action": "reply",
301
+ "resolution_hint": "explain refund timeline 5-7 business days for credit card 1-3 days for original payment method",
302
+ },
303
+
304
+ # ── general (10) ──────────────────────────────────────────────────────────
305
+ {
306
+ "id": "G001",
307
+ "text": "What are your business hours and do you have a phone number I can call?",
308
+ "category": "general",
309
+ "correct_action": "reply",
310
+ "resolution_hint": "provide support hours 9am-6pm weekdays toll free number and link to contact page for phone",
311
+ },
312
+ {
313
+ "id": "G002",
314
  "text": "Thank you! The issue has been resolved. You guys are awesome.",
315
  "category": "general",
316
  "correct_action": "close",
317
+ "resolution_hint": "acknowledge resolution thank customer for positive feedback and close ticket with satisfaction note",
318
  },
319
  {
320
+ "id": "G003",
321
+ "text": "Do you offer a student discount or non-profit pricing?",
322
+ "category": "general",
323
+ "correct_action": "reply",
324
+ "resolution_hint": "confirm student discount eligibility criteria provide non-profit pricing page and application form",
325
+ },
326
+ {
327
+ "id": "G004",
328
+ "text": "Where can I find your terms of service and privacy policy?",
329
+ "category": "general",
330
  "correct_action": "reply",
331
+ "resolution_hint": "share direct links to terms of service privacy policy and data processing agreement documents",
332
+ },
333
+ {
334
+ "id": "G005",
335
+ "text": "Is your service available in my country? I am based in Brazil.",
336
+ "category": "general",
337
+ "correct_action": "reply",
338
+ "resolution_hint": "confirm service availability in Brazil note any regional restrictions and provide local pricing",
339
+ },
340
+ {
341
+ "id": "G006",
342
+ "text": "Can I use your product for commercial purposes?",
343
+ "category": "general",
344
+ "correct_action": "reply",
345
+ "resolution_hint": "confirm commercial use rights under current plan outline enterprise licensing for larger usage",
346
+ },
347
+ {
348
+ "id": "G007",
349
+ "text": "Problem resolved, thanks for the quick response!",
350
+ "category": "general",
351
+ "correct_action": "close",
352
+ "resolution_hint": "acknowledge quick resolution compliment note feedback for team performance review close ticket",
353
+ },
354
+ {
355
+ "id": "G008",
356
+ "text": "Do you have an affiliate or referral program?",
357
+ "category": "general",
358
+ "correct_action": "reply",
359
+ "resolution_hint": "provide affiliate program signup link commission structure and referral tracking dashboard access",
360
+ },
361
+ {
362
+ "id": "G009",
363
+ "text": "What integrations do you support with third-party tools?",
364
+ "category": "general",
365
+ "correct_action": "reply",
366
+ "resolution_hint": "list supported third-party integrations provide API docs link and Zapier connector instructions",
367
+ },
368
+ {
369
+ "id": "G010",
370
+ "text": "I just wanted to say your product has been amazing for our team.",
371
+ "category": "general",
372
+ "correct_action": "close",
373
+ "resolution_hint": "acknowledge positive team feedback forward compliment to product team and close with gratitude",
374
  },
375
  ]
376
 
train_grpo.ipynb CHANGED
@@ -345,146 +345,7 @@
345
  "metadata": {},
346
  "outputs": [],
347
  "source": [
348
- "# ─────────────────────────────────────────────────────────────────\n",
349
- "# Build LARGE dataset for GRPOTrainer\n",
350
- "# Strategy:\n",
351
- "# 1. Expanded ticket bank (50 tickets across all categories)\n",
352
- "# 2. All 3 task types x many seeds\n",
353
- "# 3. Multi-step contexts: step-0 (classify) AND step-1 (resolve)\n",
354
- "# 4. Paraphrase augmentation of ticket text\n",
355
- "# Target: ~500+ training samples\n",
356
- "# ─────────────────────────────────────────────────────────────────\n",
357
- "from datasets import Dataset\n",
358
- "\n",
359
- "MAX_STEPS = 6\n",
360
- "TASK_IDS = [1, 2, 3]\n",
361
- "\n",
362
- "# Large seed pool\n",
363
- "SEEDS = list(range(0, 200)) # 200 seeds\n",
364
- "\n",
365
- "# Expanded ticket bank — 50 tickets covering all categories\n",
366
- "ALL_TICKETS = [\n",
367
- " # billing (12)\n",
368
- " {'id':'B001','text':'I was charged twice for my subscription this month.','category':'billing','correct_action':'reply'},\n",
369
- " {'id':'B002','text':'My invoice shows a charge for a plan I never subscribed to.','category':'billing','correct_action':'escalate'},\n",
370
- " {'id':'B003','text':'I need an itemised invoice for my company accounting department.','category':'billing','correct_action':'reply'},\n",
371
- " {'id':'B004','text':'Why was I charged before my trial period ended?','category':'billing','correct_action':'reply'},\n",
372
- " {'id':'B005','text':'I switched plans but was still billed at the old rate.','category':'billing','correct_action':'reply'},\n",
373
- " {'id':'B006','text':'My payment method was charged three times in one day.','category':'billing','correct_action':'escalate'},\n",
374
- " {'id':'B007','text':'I cancelled my plan but the charge still appeared this month.','category':'billing','correct_action':'reply'},\n",
375
- " {'id':'B008','text':'Can you send me a receipt for my last payment?','category':'billing','correct_action':'reply'},\n",
376
- " {'id':'B009','text':'I was charged in USD but I signed up for GBP billing.','category':'billing','correct_action':'reply'},\n",
377
- " {'id':'B010','text':'The discount code I applied is not reflected in my invoice.','category':'billing','correct_action':'reply'},\n",
378
- " {'id':'B011','text':'I need to update my billing address on the invoice.','category':'billing','correct_action':'reply'},\n",
379
- " {'id':'B012','text':'My credit card was charged even though payment failed notification was sent.','category':'billing','correct_action':'escalate'},\n",
380
- " # account (10)\n",
381
- " {'id':'A001','text':'I cannot log into my account. Password reset email never arrives.','category':'account','correct_action':'reply'},\n",
382
- " {'id':'A002','text':'How do I cancel my subscription? I cannot find the option.','category':'account','correct_action':'reply'},\n",
383
- " {'id':'A003','text':'I want to change my email address associated with the account.','category':'account','correct_action':'reply'},\n",
384
- " {'id':'A004','text':'My account was locked after too many failed login attempts.','category':'account','correct_action':'reply'},\n",
385
- " {'id':'A005','text':'I accidentally deleted my account. Can it be restored?','category':'account','correct_action':'reply'},\n",
386
- " {'id':'A006','text':'I need to transfer my account to a different email.','category':'account','correct_action':'reply'},\n",
387
- " {'id':'A007','text':'Two-factor authentication is not working for my account.','category':'account','correct_action':'reply'},\n",
388
- " {'id':'A008','text':'I cannot find where to download my data for GDPR purposes.','category':'account','correct_action':'reply'},\n",
389
- " {'id':'A009','text':'My username was changed without my permission.','category':'account','correct_action':'escalate'},\n",
390
- " {'id':'A010','text':'I want to upgrade my account from free to premium.','category':'account','correct_action':'reply'},\n",
391
- " # technical (10)\n",
392
- " {'id':'T001','text':'Your app crashes every time I upload a file larger than 10 MB.','category':'technical','correct_action':'escalate'},\n",
393
- " {'id':'T002','text':'The API is returning 500 errors intermittently for 2 hours.','category':'technical','correct_action':'escalate'},\n",
394
- " {'id':'T003','text':'The dashboard is completely blank after the latest update.','category':'technical','correct_action':'escalate'},\n",
395
- " {'id':'T004','text':'Export to CSV is broken — it downloads an empty file.','category':'technical','correct_action':'escalate'},\n",
396
- " {'id':'T005','text':'Notifications are not being delivered to my email or phone.','category':'technical','correct_action':'escalate'},\n",
397
- " {'id':'T006','text':'The mobile app freezes on the login screen on iOS 17.','category':'technical','correct_action':'escalate'},\n",
398
- " {'id':'T007','text':'Search functionality returns no results for any query.','category':'technical','correct_action':'escalate'},\n",
399
- " {'id':'T008','text':'Data sync between devices stopped working 3 days ago.','category':'technical','correct_action':'escalate'},\n",
400
- " {'id':'T009','text':'The webhook integration keeps timing out and losing events.','category':'technical','correct_action':'escalate'},\n",
401
- " {'id':'T010','text':'Browser extension throws a JavaScript error on every page load.','category':'technical','correct_action':'escalate'},\n",
402
- " # refund (8)\n",
403
- " {'id':'R001','text':'I want a full refund. I have not used the service at all.','category':'refund','correct_action':'reply'},\n",
404
- " {'id':'R002','text':'I was double charged and need a refund for the extra payment.','category':'refund','correct_action':'reply'},\n",
405
- " {'id':'R003','text':'The product did not work as advertised. I want my money back.','category':'refund','correct_action':'reply'},\n",
406
- " {'id':'R004','text':'I cancelled within the 30-day window but have not received my refund.','category':'refund','correct_action':'reply'},\n",
407
- " {'id':'R005','text':'I would like a partial refund for the unused months of my annual plan.','category':'refund','correct_action':'reply'},\n",
408
- " {'id':'R006','text':'A refund was promised by your support agent 2 weeks ago but never arrived.','category':'refund','correct_action':'escalate'},\n",
409
- " {'id':'R007','text':'I need a refund processed urgently as it was a fraudulent charge.','category':'refund','correct_action':'escalate'},\n",
410
- " {'id':'R008','text':'How long does a refund take to appear on my credit card?','category':'refund','correct_action':'reply'},\n",
411
- " # general (10)\n",
412
- " {'id':'G001','text':'What are your business hours and do you have a phone number?','category':'general','correct_action':'reply'},\n",
413
- " {'id':'G002','text':'Thank you! The issue has been resolved. You guys are awesome.','category':'general','correct_action':'close'},\n",
414
- " {'id':'G003','text':'Do you offer a student discount or non-profit pricing?','category':'general','correct_action':'reply'},\n",
415
- " {'id':'G004','text':'Where can I find your terms of service and privacy policy?','category':'general','correct_action':'reply'},\n",
416
- " {'id':'G005','text':'Is your service available in my country? I am based in Brazil.','category':'general','correct_action':'reply'},\n",
417
- " {'id':'G006','text':'Can I use your product for commercial purposes?','category':'general','correct_action':'reply'},\n",
418
- " {'id':'G007','text':'Problem resolved, thanks for the quick response!','category':'general','correct_action':'close'},\n",
419
- " {'id':'G008','text':'Do you have an affiliate or referral program?','category':'general','correct_action':'reply'},\n",
420
- " {'id':'G009','text':'What integrations do you support with third-party tools?','category':'general','correct_action':'reply'},\n",
421
- " {'id':'G010','text':'I just wanted to say your product has been amazing for our team.','category':'general','correct_action':'close'},\n",
422
- "]\n",
423
- "\n",
424
- "KEYWORD_REWARDS_FULL = {\n",
425
- " 'billing': ['charge','invoice','payment','billing','refund','receipt'],\n",
426
- " 'account': ['password','login','account','cancel','subscription','email'],\n",
427
- " 'technical': ['engineering','escalate','bug','crash','error','fix'],\n",
428
- " 'refund': ['refund','return','credit','process','reimburse'],\n",
429
- " 'general': ['hours','contact','phone','information','help','available'],\n",
430
- "}\n",
431
- "\n",
432
- "def build_grpo_dataset():\n",
433
- " rows = []\n",
434
- " rng = random.Random(2026)\n",
435
- "\n",
436
- " for task_id in TASK_IDS:\n",
437
- " for seed in SEEDS:\n",
438
- " # Pick a ticket deterministically from expanded bank\n",
439
- " ticket = ALL_TICKETS[seed % len(ALL_TICKETS)]\n",
440
- "\n",
441
- " # --- Step 0: classify context ---\n",
442
- " prompt_step0 = make_prompt(\n",
443
- " ticket_text=ticket['text'],\n",
444
- " task_id=task_id,\n",
445
- " current_category=None,\n",
446
- " feedback='New ticket. Classify it first.',\n",
447
- " step=0,\n",
448
- " )\n",
449
- " rows.append({\n",
450
- " 'prompt': prompt_step0,\n",
451
- " 'ticket_text': ticket['text'],\n",
452
- " 'task_id': task_id,\n",
453
- " 'seed': seed,\n",
454
- " 'step': 0,\n",
455
- " })\n",
456
- "\n",
457
- " # --- Step 1: resolve context (tasks 2 & 3 only) ---\n",
458
- " if task_id in (2, 3):\n",
459
- " prompt_step1 = make_prompt(\n",
460
- " ticket_text=ticket['text'],\n",
461
- " task_id=task_id,\n",
462
- " current_category=ticket['category'],\n",
463
- " feedback=f\"Category set to {ticket['category']}. Now resolve the ticket.\",\n",
464
- " step=1,\n",
465
- " )\n",
466
- " rows.append({\n",
467
- " 'prompt': prompt_step1,\n",
468
- " 'ticket_text': ticket['text'],\n",
469
- " 'task_id': task_id,\n",
470
- " 'seed': seed + 10000, # unique seed key for step-1\n",
471
- " 'step': 1,\n",
472
- " })\n",
473
- "\n",
474
- " # Shuffle so tasks/steps are interleaved during training\n",
475
- " rng.shuffle(rows)\n",
476
- " return Dataset.from_list(rows)\n",
477
- "\n",
478
- "grpo_dataset = build_grpo_dataset()\n",
479
- "print(f'Dataset built: {len(grpo_dataset)} samples')\n",
480
- "# breakdown\n",
481
- "from collections import Counter\n",
482
- "task_counts = Counter(grpo_dataset['task_id'])\n",
483
- "step_counts = Counter(grpo_dataset['step'])\n",
484
- "print(f' By task: {dict(task_counts)}')\n",
485
- "print(f' By step: {dict(step_counts)}')\n",
486
- "print('Sample prompt (first 300 chars):')\n",
487
- "print(grpo_dataset[0]['prompt'][:300])"
488
  ]
489
  },
490
  {
 
345
  "metadata": {},
346
  "outputs": [],
347
  "source": [
348
+ "# ─────────────────────────────────────────────────────────────────\n# Build LARGE dataset for GRPOTrainer\n# Strategy:\n# 1. Expanded ticket bank (50 tickets across all categories)\n# 2. All 3 task types x many seeds\n# 3. Multi-step contexts: step-0 (classify) AND step-1 (resolve)\n# 4. Paraphrase augmentation of ticket text\n# Target: ~500+ training samples\n# ─────────────────────────────────────────────────────────────────\nfrom datasets import Dataset\n\nMAX_STEPS = 6\nTASK_IDS = [1, 2, 3]\n\n# Large seed pool\nSEEDS = list(range(0, 200)) # 200 seeds\n\n# Expanded ticket bank — 50 tickets covering all categories\nALL_TICKETS = [\n # billing (12)\n {'id':'B001','text':'I was charged twice for my subscription this month.','category':'billing','correct_action':'reply','resolution_hint':'apologize for duplicate charge and initiate refund to original payment method within 3-5 days'},\n {'id':'B002','text':'My invoice shows a charge for a plan I never subscribed to.','category':'billing','correct_action':'escalate','resolution_hint':'escalate potential unauthorized plan charge to billing team for investigation and correction'},\n {'id':'B003','text':'I need an itemised invoice for my company accounting department.','category':'billing','correct_action':'reply','resolution_hint':'generate itemised invoice with line-item breakdown and email to customer accounting address'},\n {'id':'B004','text':'Why was I charged before my trial period ended?','category':'billing','correct_action':'reply','resolution_hint':'verify trial end date in billing system and issue refund for premature charge before expiry'},\n {'id':'B005','text':'I switched plans but was still billed at the old rate.','category':'billing','correct_action':'reply','resolution_hint':'confirm plan switch date in system and issue prorated credit for overcharge at old rate'},\n {'id':'B006','text':'My payment method was charged three times in one day.','category':'billing','correct_action':'escalate','resolution_hint':'escalate triple charge incident to billing fraud team and freeze further charges pending review'},\n {'id':'B007','text':'I cancelled my plan but the charge still appeared this month.','category':'billing','correct_action':'reply','resolution_hint':'verify cancellation timestamp confirm post-cancel charge and process refund for final month'},\n {'id':'B008','text':'Can you send me a receipt for my last payment?','category':'billing','correct_action':'reply','resolution_hint':'locate last successful payment record and email PDF receipt to customer registered address'},\n {'id':'B009','text':'I was charged in USD but I signed up for GBP billing.','category':'billing','correct_action':'reply','resolution_hint':'identify currency mismatch at signup and issue credit note for exchange rate difference'},\n {'id':'B010','text':'The discount code I applied is not reflected in my invoice.','category':'billing','correct_action':'reply','resolution_hint':'locate discount code application log verify failure reason and apply credit to next invoice'},\n {'id':'B011','text':'I need to update my billing address on the invoice.','category':'billing','correct_action':'reply','resolution_hint':'update billing address in account settings and reissue corrected invoice for their records'},\n {'id':'B012','text':'My credit card was charged even though payment failed notification was sent.','category':'billing','correct_action':'escalate','resolution_hint':'escalate ghost charge to payments team attach failed payment notification as evidence for review'},\n # account (10)\n {'id':'A001','text':'I cannot log into my account. Password reset email never arrives.','category':'account','correct_action':'reply','resolution_hint':'check spam folder verify registered email address resend password reset link account locked'},\n {'id':'A002','text':'How do I cancel my subscription? I cannot find the option.','category':'account','correct_action':'reply','resolution_hint':'navigate account settings subscription tab locate cancel option confirm cancellation effective date'},\n {'id':'A003','text':'I want to change my email address associated with the account.','category':'account','correct_action':'reply','resolution_hint':'verify identity via security question update email address send confirmation to both old and new'},\n {'id':'A004','text':'My account was locked after too many failed login attempts.','category':'account','correct_action':'reply','resolution_hint':'unlock account after failed login attempts verify identity via backup code or support email'},\n {'id':'A005','text':'I accidentally deleted my account. Can it be restored?','category':'account','correct_action':'reply','resolution_hint':'check account deletion grace period restore from backup if within 30 days confirm data intact'},\n {'id':'A006','text':'I need to transfer my account to a different email.','category':'account','correct_action':'reply','resolution_hint':'verify ownership of both accounts initiate transfer request update billing and login credentials'},\n {'id':'A007','text':'Two-factor authentication is not working for my account.','category':'account','correct_action':'reply','resolution_hint':'verify 2FA device registration resync authenticator app or issue backup recovery codes immediately'},\n {'id':'A008','text':'I cannot find where to download my data for GDPR purposes.','category':'account','correct_action':'reply','resolution_hint':'provide GDPR data export link in account privacy settings confirm 30-day download window'},\n {'id':'A009','text':'My username was changed without my permission.','category':'account','correct_action':'escalate','resolution_hint':'escalate unauthorized username change to security team flag for account compromise investigation'},\n {'id':'A010','text':'I want to upgrade my account from free to premium.','category':'account','correct_action':'reply','resolution_hint':'confirm current free plan limits explain premium features and provide upgrade link with pricing'},\n # technical (10)\n {'id':'T001','text':'Your app crashes every time I upload a file larger than 10 MB.','category':'technical','correct_action':'escalate','resolution_hint':'escalate to engineering with file size limit crash reproduction steps and device logs attached'},\n {'id':'T002','text':'The API is returning 500 errors intermittently for 2 hours.','category':'technical','correct_action':'escalate','resolution_hint':'escalate API 500 errors to on-call engineering with timestamps error codes and affected endpoints'},\n {'id':'T003','text':'The dashboard is completely blank after the latest update.','category':'technical','correct_action':'escalate','resolution_hint':'escalate blank dashboard to engineering with browser version last working date and console errors'},\n {'id':'T004','text':'Export to CSV is broken — it downloads an empty file.','category':'technical','correct_action':'escalate','resolution_hint':'escalate empty CSV export bug to engineering with sample dataset and export configuration used'},\n {'id':'T005','text':'Notifications are not being delivered to my email or phone.','category':'technical','correct_action':'escalate','resolution_hint':'escalate notification delivery failure to infrastructure team check email provider and push config'},\n {'id':'T006','text':'The mobile app freezes on the login screen on iOS 17.','category':'technical','correct_action':'escalate','resolution_hint':'escalate iOS 17 freeze to mobile engineering with device model OS version and crash report'},\n {'id':'T007','text':'Search functionality returns no results for any query.','category':'technical','correct_action':'escalate','resolution_hint':'escalate search returning no results to engineering with query examples and index rebuild request'},\n {'id':'T008','text':'Data sync between devices stopped working 3 days ago.','category':'technical','correct_action':'escalate','resolution_hint':'escalate device sync failure to backend team with affected device IDs and last sync timestamp'},\n {'id':'T009','text':'The webhook integration keeps timing out and losing events.','category':'technical','correct_action':'escalate','resolution_hint':'escalate webhook timeout to integrations team with endpoint URL payload size and retry logs'},\n {'id':'T010','text':'Browser extension throws a JavaScript error on every page load.','category':'technical','correct_action':'escalate','resolution_hint':'escalate browser extension JavaScript error to frontend team with browser version and error stack'},\n # refund (8)\n {'id':'R001','text':'I want a full refund. I have not used the service at all.','category':'refund','correct_action':'reply','resolution_hint':'confirm zero usage this billing period process full refund within 5-7 business days to original payment method'},\n {'id':'R002','text':'I was double charged and need a refund for the extra payment.','category':'refund','correct_action':'reply','resolution_hint':'verify double charge in payment gateway logs process refund for duplicate amount to card on file'},\n {'id':'R003','text':'The product did not work as advertised. I want my money back.','category':'refund','correct_action':'reply','resolution_hint':'review product description versus delivered functionality confirm mismatch and process refund'},\n {'id':'R004','text':'I cancelled within the 30-day window but have not received my refund.','category':'refund','correct_action':'reply','resolution_hint':'verify cancellation date within refund window locate delayed refund in processor and escalate'},\n {'id':'R005','text':'I would like a partial refund for the unused months of my annual plan.','category':'refund','correct_action':'reply','resolution_hint':'calculate unused months on annual plan process prorated refund for remaining subscription period'},\n {'id':'R006','text':'A refund was promised by your support agent 2 weeks ago but never arrived.','category':'refund','correct_action':'escalate','resolution_hint':'escalate undelivered promised refund to billing manager attach original support agent transcript'},\n {'id':'R007','text':'I need a refund processed urgently as it was a fraudulent charge.','category':'refund','correct_action':'escalate','resolution_hint':'escalate fraudulent charge to payments fraud team freeze account initiate chargeback process'},\n {'id':'R008','text':'How long does a refund take to appear on my credit card?','category':'refund','correct_action':'reply','resolution_hint':'explain refund timeline 5-7 business days for credit card 1-3 days for original payment method'},\n # general (10)\n {'id':'G001','text':'What are your business hours and do you have a phone number?','category':'general','correct_action':'reply','resolution_hint':'provide support hours 9am-6pm weekdays toll free number and link to contact page for phone'},\n {'id':'G002','text':'Thank you! The issue has been resolved. You guys are awesome.','category':'general','correct_action':'close','resolution_hint':'acknowledge resolution thank customer for positive feedback and close ticket with satisfaction note'},\n {'id':'G003','text':'Do you offer a student discount or non-profit pricing?','category':'general','correct_action':'reply','resolution_hint':'confirm student discount eligibility criteria provide non-profit pricing page and application form'},\n {'id':'G004','text':'Where can I find your terms of service and privacy policy?','category':'general','correct_action':'reply','resolution_hint':'share direct links to terms of service privacy policy and data processing agreement documents'},\n {'id':'G005','text':'Is your service available in my country? I am based in Brazil.','category':'general','correct_action':'reply','resolution_hint':'confirm service availability in Brazil note any regional restrictions and provide local pricing'},\n {'id':'G006','text':'Can I use your product for commercial purposes?','category':'general','correct_action':'reply','resolution_hint':'confirm commercial use rights under current plan outline enterprise licensing for larger usage'},\n {'id':'G007','text':'Problem resolved, thanks for the quick response!','category':'general','correct_action':'close','resolution_hint':'acknowledge quick resolution compliment note feedback for team performance review close ticket'},\n {'id':'G008','text':'Do you have an affiliate or referral program?','category':'general','correct_action':'reply','resolution_hint':'provide affiliate program signup link commission structure and referral tracking dashboard access'},\n {'id':'G009','text':'What integrations do you support with third-party tools?','category':'general','correct_action':'reply','resolution_hint':'list supported third-party integrations provide API docs link and Zapier connector instructions'},\n {'id':'G010','text':'I just wanted to say your product has been amazing for our team.','category':'general','correct_action':'close','resolution_hint':'acknowledge positive team feedback forward compliment to product team and close with gratitude'},\n]\n\nKEYWORD_REWARDS_FULL = {\n 'billing': ['charge','invoice','payment','billing','refund','receipt'],\n 'account': ['password','login','account','cancel','subscription','email'],\n 'technical': ['engineering','escalate','bug','crash','error','fix'],\n 'refund': ['refund','return','credit','process','reimburse'],\n 'general': ['hours','contact','phone','information','help','available'],\n}\n\ndef build_grpo_dataset():\n rows = []\n rng = random.Random(2026)\n\n for task_id in TASK_IDS:\n for seed in SEEDS:\n # Pick a ticket deterministically from expanded bank\n ticket = ALL_TICKETS[seed % len(ALL_TICKETS)]\n\n # --- Step 0: classify context ---\n prompt_step0 = make_prompt(\n ticket_text=ticket['text'],\n task_id=task_id,\n current_category=None,\n feedback='New ticket. Classify it first.',\n step=0,\n )\n rows.append({\n 'prompt': prompt_step0,\n 'ticket_text': ticket['text'],\n 'task_id': task_id,\n 'seed': seed,\n 'step': 0,\n })\n\n # --- Step 1: resolve context (tasks 2 & 3 only) ---\n if task_id in (2, 3):\n prompt_step1 = make_prompt(\n ticket_text=ticket['text'],\n task_id=task_id,\n current_category=ticket['category'],\n feedback=f\"Category set to {ticket['category']}. Now resolve the ticket.\",\n step=1,\n )\n rows.append({\n 'prompt': prompt_step1,\n 'ticket_text': ticket['text'],\n 'task_id': task_id,\n 'seed': seed + 10000, # unique seed key for step-1\n 'step': 1,\n })\n\n # Shuffle so tasks/steps are interleaved during training\n rng.shuffle(rows)\n return Dataset.from_list(rows)\n\ngrpo_dataset = build_grpo_dataset()\nprint(f'Dataset built: {len(grpo_dataset)} samples')\n# breakdown\nfrom collections import Counter\ntask_counts = Counter(grpo_dataset['task_id'])\nstep_counts = Counter(grpo_dataset['step'])\nprint(f' By task: {dict(task_counts)}')\nprint(f' By step: {dict(step_counts)}')\nprint('Sample prompt (first 300 chars):')\nprint(grpo_dataset[0]['prompt'][:300])"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
  ]
350
  },
351
  {