dammmmmmmmm commited on
Commit
8cd0715
·
verified ·
1 Parent(s): b47c60d

Upload strategy_network.py

Browse files
backend/ai/strategy/strategy_network.py CHANGED
@@ -1,80 +1,100 @@
1
- import time
2
-
3
- class NetworkStrategy:
4
- def __init__(self, llm_client, data_engine):
5
- self.llm_client = llm_client
6
- self.data_engine = data_engine
7
-
8
- # --- KỊCH BẢN "VĂN NÓI" (HUMANIZED SCRIPT) ---
9
- # Chuyển đổi từ mẫu gốc sang văn phong chia sẻ, thêm từ nối:
10
- # "Thực sự", "Bởi vì", "Do đó", "Cứ để em", "Thực sự xứng đáng".
11
- CORE_MESSAGE = (
12
- "Thực sự em rất xin lỗi trải nghiệm vừa qua chưa tương xứng với mức phí mà mình đang sử dụng ạ.\n\n"
13
- "Bởi với gói cước hiện tại, đúng ra chất lượng đường truyền cần phải ổn định hơn, "
14
- "Em xin phép giải thích một số nguyên nhân khiến tốc độ mạng chưa ổn định như mong đợi.\n\n"
15
- "Thiết độ của mình có thể đang bật chế độ tiết kiệm pin hoặc tiết kiệm data.Hoặc có thể thiết bị của mình để nhiều ứng dụng chạy ngầm (mạng xã hội, email, sao lưu ảnh,...) "
16
- "Gói hiện tại của hình hiện tại đang ưu tiên data theo ứng dụng. Khi phần data tốc độ cao sử dụng hết, hệ thống sẽ tự động chuyển sang data tốc độ thấp hoặc data miễn phí cho mạng xã hội. "
17
- "Nếu nhu cầu của anh chị là dùng mạng ổn định cho công việc, học tập hoặc giải trí liên tục, anh chị có thể cân nhắc chuyển sang các gói data dung lượng cố định, tốc độ cao không giới hạn theo ứng dụng. "
18
- "Gói này sẽ giúp các anh chị dùng ổn định cả ngày không lo chậm vào giờ cao điểm.\n\n"
19
- "Chi phí chênh lệch không nhiều nhưng trải nghiệm tốt hơn đáng kể đấy . "
20
- " Anh chị muốn nghe vấn thêm về các gói cụ thể không ạ?"
21
- )
22
-
23
- def execute(self, customer_id, complaint_text):
24
- # 1. TRÍCH XUẤT DỮ LIỆU
25
- ctx = self.data_engine.get_full_context(customer_id)
26
- if not ctx: return "Lỗi: Không tìm thấy khách hàng."
27
-
28
- # Log kiểm tra
29
- print(f" ⚡ [Strategy Network] ID {customer_id}: Input: '{complaint_text}'")
30
-
31
- # 2. XÂY DỰNG PROMPT
32
- prompt = f"""
33
- VAI TRÒ: Bạn là Chuyên viên Kỹ thuật & CSKH tận tâm, biết lắng nghe.
34
-
35
- DỮ LIỆU ĐẦU VÀO:
36
- - Phàn nàn của khách: "{complaint_text}"
37
- - Nội dung cốt lõi (CORE MESSAGE):
38
- '''
39
- {self.CORE_MESSAGE}
40
- '''
41
-
42
- NHIỆM VỤ:
43
- Phản hồi khách hàng dựa trên CORE MESSAGE.
44
-
45
- YÊU CẦU VỀ GIỌNG ĐIỆU (TONE & VOICE):
46
- 1. **Mở đầu:** Nhận lỗi chân thành về việc "Tiền nào của nấy" (Giá cao mà mạng lag).
47
- 2. **Thân bài:** Sử dụng nguyên văn CORE MESSAGE để đảm bảo đúng quy trình kỹ thuật.
48
- - Giữ các từ đệm: "Thực sự", "Bởi vì", "Do đó", "Cứ để em".
49
-
50
- QUY TẮC AN TOÀN (ANTI-HALLUCINATION):
51
- - Tuyệt đối KHÔNG bịa đặt nguyên nhân kỹ thuật (cá mập cắn cáp, đứt cáp quang biển...) nếu hệ thống không báo.
52
- - Tuyệt đối KHÔNG hứa đền bù tiền mặt.
53
- - Xưng hô: BẮT BUỘC dùng "Mình" và "Em".
54
-
55
- OUTPUT:
56
- Trả về đoạn hội thoại hoàn chỉnh.
57
- """
58
-
59
- # 3. GỌI LLM
60
- if self.llm_client:
61
- try:
62
- response = self.llm_client.generate_content(prompt)
63
-
64
- # Hậu xử lý: Lớp bảo vệ cuối cùng cho xưng hô
65
- final_text = response.text
66
- replacements = {
67
- "Anh": "Mình", "Chị": "Mình", "Quý khách": "Mình",
68
- "anh": "mình", "chị": "mình",
69
- "khu vực sử dụng": "khu vực nhà mình", # Làm cho câu văn ấm áp hơn
70
- "chi phí đã bỏ ra": "chi phí mình đã bỏ ra"
71
- }
72
- for old, new in replacements.items():
73
- final_text = final_text.replace(old, new)
74
-
75
- return final_text
76
- except Exception as e:
77
- # Fallback: Trả về kịch bản cứng nếu API lỗi
78
- return self.CORE_MESSAGE
79
- else:
80
- return "Lỗi: Chưa kết nối LLM Client."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import re
3
+ import asyncio
4
+
5
+ class NetworkStrategy:
6
+ def __init__(self, llm_client, data_engine):
7
+ self.llm_client = llm_client
8
+ self.data_engine = data_engine
9
+
10
+ # [OPTIMIZATION 1] Pre-compile Regex
11
+ self.cleaner_regex = re.compile(
12
+ r"^(.*?>>>|dưới đây là.*?|sau đây là.*?|câu trả lời.*?|đoạn văn.*?|viết lại.*?|output:)",
13
+ re.IGNORECASE | re.MULTILINE | re.DOTALL
14
+ )
15
+
16
+ # --- KỊCH BẢN GỐC (SOURCE OF TRUTH) ---
17
+ CORE_MESSAGE = (
18
+ "Thực sự em rất xin lỗi trải nghiệm vừa qua chưa tương xứng với mức phí mình đang sử dụng ạ. "
19
+ "Bởi với gói cước hiện tại, đúng ra chất lượng đường truyền cần phải ổn định hơn. "
20
+ "Em xin phép giải thích một số nguyên nhân khiến tốc độ mạng chưa ổn định như mong đợi. "
21
+ "Thiết bị của mình có thể đang bật chế độ tiết kiệm pin hoặc tiết kiệm data. Hoặc có thể thiết bị của mình để nhiều ứng dụng chạy ngầm như mạng xã hội, email, sao lưu ảnh làm ảnh hưởng tốc độ. "
22
+ "Gói hiện tại của mình đang ưu tiên data theo ứng dụng, nên khi phần data tốc độ cao sử dụng hết, hệ thống sẽ tự động chuyển sang data tốc độ thấp. "
23
+ "Nếu nhu cầu của mình là dùng mạng ổn định cho công việc, học tập hoặc giải trí liên tục, mình có thể cân nhắc chuyển sang các gói data dung lượng cố định, tốc độ cao không giới hạn theo ứng dụng. "
24
+ "Gói này sẽ giúp mình dùng ổn định cả ngày mà không lo chậm vào giờ cao điểm. "
25
+ "Chi phí chênh lệch không nhiều nhưng trải nghiệm tốt hơn đáng kể đấy ạ. "
26
+ "Mình muốn nghe em vấn thêm về các gói cụ thể không ạ?"
27
+ )
28
+
29
+ # --- HÀM BLOCKING (Dùng cho Fallback hoặc Logic cũ) ---
30
+ def execute(self, customer_id, complaint_text):
31
+ ctx = self.data_engine.get_full_context(customer_id)
32
+ if not ctx: return "Lỗi: Không tìm thấy khách hàng."
33
+
34
+ print(f" ⚡ [Strategy Network] ID {customer_id}: Input: '{complaint_text}'")
35
+
36
+ prompt = f"""
37
+ Nhiệm vụ: Đóng vai nhân viên CSKH, nói lại nội dung sau với khách (Xưng Em - Mình).
38
+ NỘI DUNG GỐC: "{self.CORE_MESSAGE}"
39
+ YÊU CẦU:
40
+ - Bỏ qua mọi lời chào hỏi, giải thích.
41
+ - Bắt đầu ngay lập tức bằng nội dung hội thoại.
42
+ - KHÔNG xuống dòng.
43
+ BẮT ĐẦU TRẢ LỜI NGAY SAU DẤU MŨI TÊN:
44
+ >>> """
45
+
46
+ if self.llm_client:
47
+ try:
48
+ response = self.llm_client.generate_content(prompt)
49
+ raw_text = response.text.strip()
50
+
51
+ # Cleaning Logic
52
+ if ">>>" in raw_text:
53
+ final_text = raw_text.split(">>>")[-1].strip()
54
+ else:
55
+ final_text = self.cleaner_regex.sub("", raw_text).strip()
56
+
57
+ if "\n" in final_text:
58
+ final_text = " ".join([l.strip() for l in final_text.split('\n') if l.strip()])
59
+
60
+ replacements = { "Anh/Chị": "Mình", "Quý khách": "Mình", "Anh": "Mình", "Chị": "Mình", "anh": "mình", "chị": "mình", "bạn": "mình" }
61
+ for old, new in replacements.items():
62
+ if old in final_text or old.lower() in final_text.lower():
63
+ final_text = final_text.replace(old, new)
64
+
65
+ if not final_text: return self.CORE_MESSAGE.replace("\n", " ")
66
+ return final_text
67
+ except Exception as e:
68
+ print(f" [ERROR] Network Strategy: {e}")
69
+ return self.CORE_MESSAGE.replace("\n", " ")
70
+ else:
71
+ return "Lỗi: Chưa kết nối LLM Client."
72
+
73
+ # --- [NEW] HÀM STREAMING (Dùng cho Pipeline Gối đầu) ---
74
+ async def execute_stream_gen(self, customer_id, complaint_text):
75
+ print(f" 🌊 [Stream Network] ID {customer_id}")
76
+
77
+ prompt = f"""
78
+ Nhiệm vụ: Đóng vai nhân viên CSKH, nói lại nội dung sau với khách (Xưng Em - Mình).
79
+ NỘI DUNG GỐC: "{self.CORE_MESSAGE}"
80
+ YÊU CẦU:
81
+ - Bắt đầu ngay lập tức bằng nội dung hội thoại.
82
+ - KHÔNG có lời dẫn.
83
+ BẮT ĐẦU TRẢ LỜI NGAY SAU DẤU MŨI TÊN:
84
+ >>> """
85
+
86
+ if self.llm_client and hasattr(self.llm_client, 'ai_service'):
87
+ try:
88
+ # Gọi thẳng vào Service để lấy Generator
89
+ async for chunk in self.llm_client.ai_service.chat_gemini_stream(prompt):
90
+ # Lọc sơ bộ dấu >>> nếu nó xuất hiện trong stream
91
+ if ">>>" in chunk:
92
+ chunk = chunk.replace(">>>", "")
93
+
94
+ # Yield từng mảnh để Logic Flow xử lý cắt câu
95
+ yield chunk
96
+ except Exception as e:
97
+ print(f"Stream Error: {e}")
98
+ yield self.CORE_MESSAGE
99
+ else:
100
+ yield self.CORE_MESSAGE