Mr-Help commited on
Commit
0c83b5e
·
verified ·
1 Parent(s): 3ecfbbf

Create classifier_prompt.py

Browse files
Files changed (1) hide show
  1. knowledge/classifier_prompt.py +189 -0
knowledge/classifier_prompt.py ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict, List
2
+
3
+
4
+ GLOBAL_INTENTS = [
5
+ "restart",
6
+ "new_topic",
7
+ "complaint",
8
+ "direct_support",
9
+ "courses_info",
10
+ "children_courses",
11
+ "adults_courses",
12
+ "new_student",
13
+ "current_student",
14
+ "unclear",
15
+ ]
16
+
17
+ STATE_ALLOWED_INTENTS: Dict[str, List[str]] = {
18
+ "WAITING_MAIN_MENU": [
19
+ "new_student",
20
+ "current_student",
21
+ "courses_info",
22
+ "complaint",
23
+ "direct_support",
24
+ ],
25
+ "WAITING_USER_TYPE": [
26
+ "new_student",
27
+ "current_student",
28
+ ],
29
+ "WAITING_AUDIENCE": [
30
+ "adults",
31
+ "children",
32
+ ],
33
+ "WAITING_PRIOR_STUDY": [
34
+ "prior_study_yes",
35
+ "prior_study_no",
36
+ ],
37
+ "WAITING_BEGINNER_SCHEDULE_CHOICE": [
38
+ "confirm_schedule_reviewed",
39
+ "proceed_booking",
40
+ "switch_to_prior_study_true",
41
+ "switch_to_prior_study_false",
42
+ "support_needed",
43
+ ],
44
+ "WAITING_PDF_102_CONFIRMATION": [
45
+ "confirm_pdf_reviewed",
46
+ "switch_to_prior_study_true",
47
+ "switch_to_prior_study_false",
48
+ "support_needed",
49
+ ],
50
+ "WAITING_PLACEMENT_TEST_CONFIRMATION": [
51
+ "confirm_placement_test_reviewed",
52
+ "switch_to_prior_study_true",
53
+ "switch_to_prior_study_false",
54
+ "support_needed",
55
+ ],
56
+ "WAITING_CURRENT_STUDENT_ACTION": [
57
+ "current_student_support",
58
+ "current_student_next_level",
59
+ ],
60
+ "WAITING_SUPPORT_QUESTION": [
61
+ "support_question_text",
62
+ ],
63
+ "WAITING_LEVEL_SELECTION": [
64
+ "level_selected",
65
+ "support_needed",
66
+ ],
67
+ "WAITING_PAYMENT_METHOD": [
68
+ "payment_method_selected",
69
+ "support_needed",
70
+ ],
71
+ "WAITING_COMPLAINT_FORM": [
72
+ "complaint_form_submitted",
73
+ ],
74
+ "HANDOFF_DONE": [
75
+ "thanks",
76
+ "courses_info",
77
+ "children_courses",
78
+ "adults_courses",
79
+ "new_student",
80
+ "current_student",
81
+ "direct_support",
82
+ "complaint",
83
+ "restart",
84
+ "new_topic",
85
+ ],
86
+ }
87
+
88
+ INTENT_DESCRIPTIONS: Dict[str, str] = {
89
+ "restart": "The user wants to restart the conversation from the beginning.",
90
+ "new_topic": "The user explicitly wants to ask about something else or start a new topic.",
91
+ "complaint": "The user is making or asking to make a complaint.",
92
+ "direct_support": "The user wants to talk to customer support or service directly.",
93
+ "courses_info": "The user is asking generally about available courses.",
94
+ "children_courses": "The user is asking about children courses.",
95
+ "adults_courses": "The user is asking about adult courses.",
96
+ "new_student": "The user indicates they are a new student.",
97
+ "current_student": "The user indicates they are a current student.",
98
+ "adults": "Direct answer: adults.",
99
+ "children": "Direct answer: children.",
100
+ "prior_study_yes": "Direct answer: user studied German before.",
101
+ "prior_study_no": "Direct answer: user did not study German before.",
102
+ "confirm_schedule_reviewed": "The user confirms they reviewed the beginner schedule.",
103
+ "proceed_booking": "The user wants to proceed with booking.",
104
+ "switch_to_prior_study_true": "The user changes to the path where they studied German before.",
105
+ "switch_to_prior_study_false": "The user changes to the beginner path.",
106
+ "support_needed": "The user needs help or wants support within the current topic.",
107
+ "confirm_pdf_reviewed": "The user confirms they reviewed the PDF/details file.",
108
+ "confirm_placement_test_reviewed": "The user confirms they reviewed placement test details.",
109
+ "current_student_support": "Current student wants support or has a question.",
110
+ "current_student_next_level": "Current student wants to book the next level.",
111
+ "support_question_text": "The message itself is the support question text.",
112
+ "level_selected": "The user selected a course level.",
113
+ "payment_method_selected": "The user selected a payment method.",
114
+ "complaint_form_submitted": "The user says they submitted the complaint form.",
115
+ "thanks": "The user is thanking the bot.",
116
+ "unclear": "The message is unclear and should not be confidently routed.",
117
+ }
118
+
119
+
120
+ def get_allowed_intents_for_state(state: str) -> List[str]:
121
+ state_specific = STATE_ALLOWED_INTENTS.get(state, [])
122
+ final = []
123
+ for item in GLOBAL_INTENTS + state_specific:
124
+ if item not in final:
125
+ final.append(item)
126
+ return final
127
+
128
+
129
+ def _summarize_flow_data(flow_data: dict) -> str:
130
+ if not flow_data:
131
+ return "No extra context."
132
+
133
+ fields = []
134
+ for key in [
135
+ "customer_type",
136
+ "audience",
137
+ "prior_study",
138
+ "selected_level",
139
+ "payment_method",
140
+ "gender",
141
+ ]:
142
+ if key in flow_data and flow_data[key] is not None:
143
+ fields.append(f"{key}={flow_data[key]}")
144
+
145
+ return ", ".join(fields) if fields else "No extra context."
146
+
147
+
148
+ def build_system_prompt(state: str, flow_data: dict, allowed_intents: List[str]) -> str:
149
+ descriptions = []
150
+ for intent in allowed_intents:
151
+ desc = INTENT_DESCRIPTIONS.get(intent, "")
152
+ descriptions.append(f"- {intent}: {desc}")
153
+
154
+ description_block = "\n".join(descriptions)
155
+
156
+ context_summary = _summarize_flow_data(flow_data)
157
+
158
+ return f"""
159
+ You are a state-aware intent classifier for an Arabic WhatsApp bot.
160
+
161
+ Your task:
162
+ - Read the user's Arabic message.
163
+ - Understand the CURRENT conversation state.
164
+ - Choose exactly ONE intent label from the allowed list.
165
+ - Return ONLY the label.
166
+ - Do not explain.
167
+ - Do not add punctuation.
168
+ - Do not add extra words.
169
+
170
+ Current state:
171
+ {state}
172
+
173
+ Known context:
174
+ {context_summary}
175
+
176
+ Allowed intent labels:
177
+ {", ".join(allowed_intents)}
178
+
179
+ Intent descriptions:
180
+ {description_block}
181
+
182
+ Decision rules:
183
+ - If the message is a direct answer to the current question, choose the direct answer label.
184
+ - If the user changes path but stays in the same broad topic, choose the appropriate state-switch label.
185
+ - If the user changes to a new topic, choose the correct topic-switch label.
186
+ - If you are not confident, return: unclear
187
+
188
+ Return only one label from the allowed list.
189
+ """.strip()