import os import json import time import random import google.generativeai as genai from google.api_core import exceptions # ตัวแปรสำหรับเก็บโมเดล Gemini model = None # ตั้งค่า API Key และโมเดล try: # อ่าน API Key จาก Environment Secret GEMINI_API_KEY = os.environ.get('GEMINI_API_KEY') if not GEMINI_API_KEY: # ข้อความภาษาไทยที่แก้ไขแล้ว raise ValueError("ไม่พบ GEMINI_API_KEY ใน Environment Secret") genai.configure(api_key=GEMINI_API_KEY) # ใช้ gemini-1.5-flash เพื่อความรวดเร็วในการประมวลผล NLU model = genai.GenerativeModel('gemini-1.5-flash') except Exception as e: # ข้อความภาษาไทยที่แก้ไขแล้ว print(f"เกิดข้อผิดพลาดร้ายแรงตอนตั้งค่า Gemini: {e}") model = None def generate_with_retry(model, prompt, max_retries=5): """เรียกใช้ Gemini API พร้อมกลไกการลองซ้ำ (retry) และ Exponential Backoff""" if not model: # ข้อความภาษาไทยที่แก้ไขแล้ว return {"intent": "error", "message": "Gemini model ไม่ได้ถูกตั้งค่าอย่างถูกต้อง"} attempt = 0 wait_time = 1 # กำหนดโครงสร้าง JSON และ System Instruction สำหรับ NLU config = { "generation_config": { "response_mime_type": "application/json", }, "safety_settings": [ {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"}, {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"}, {"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_NONE"}, {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"}, ] } system_instruction = """คุณคือ Natural Language Understanding (NLU) Processor ที่เก่งภาษาไทย หน้าที่ของคุณคือแปลงข้อความของผู้ใช้ให้เป็น JSON ที่มี intent และ entities เท่านั้น - intent: คือเจตนาหลักของผู้ใช้ - entities: คือข้อมูลสำคัญที่สกัดได้จากข้อความ ห้ามเพิ่มข้อความอธิบายอื่นใดนอกเหนือจาก JSON object ที่ร้องขอ ตัวอย่าง: - ข้อความ: \"อยากจองห้องพักสำหรับ 2 คน วันที่ 25 ธันวา\" - ผลลัพธ์ JSON: {\"intent\": \"create_booking\", \"entities\": {\"guests\": 2, \"date\": \"25-12\"}} - ข้อความ: \"ขอดูข้อมูลผู้เช่าห้อง A101\" - ผลลัพธ์ JSON: {\"intent\": \"get_renter\", \"entities\": {\"room_number\": \"A101\"}} """ while attempt < max_retries: try: response = model.generate_content( [system_instruction, prompt], generation_config=config["generation_config"], safety_settings=config["safety_settings"] ) return response except exceptions.ResourceExhausted as e: # ข้อความภาษาไทยที่แก้ไขแล้ว print(f"Too Many Requests, กำลังลองใหม่ใน {wait_time} วินาที...") time.sleep(wait_time + random.uniform(0, 1)) wait_time *= 2 attempt += 1 except Exception as e: # ข้อความภาษาไทยที่แก้ไขแล้ว print(f"เกิดข้อผิดพลาดที่ไม่คาดคิดขณะเรียก Gemini: {e}") return None print("ไม่สามารถรับการตอบกลับได้หลังจากการพยายามหลายครั้ง") return None def process_user_message(user_message): """ประมวลผลข้อความของผู้ใช้เพื่อแยก Intent และ Entities""" # ใช้ Prompt ที่เรียบง่ายเนื่องจาก System Instruction กำหนดรูปแบบเอาไว้แล้ว prompt = f"ข้อความของผู้ใช้: '{user_message}'" response = generate_with_retry(model, prompt) if response and response.text: try: # โมเดลถูกบังคับให้ตอบกลับเป็น JSON ด้วย response_mime_type return json.loads(response.text) except json.JSONDecodeError: # ข้อความภาษาไทยที่แก้ไขแล้ว return {"intent": "error", "message": f"ผลลัพธ์ไม่ใช่ JSON ที่ถูกต้อง: {response.text}"} else: # ข้อความภาษาไทยที่แก้ไขแล้ว return {"intent": "error", "message": "ไม่ได้รับการตอบกลับจาก Gemini หรือข้อความว่างเปล่า"} # ตัวอย่างการใช้งาน (สำหรับทดสอบ) if __name__ == '__main__': # รันโค้ดนี้เมื่อไฟล์ถูกเรียกใช้โดยตรง print("--- ทดสอบ NLU Processor ---") test_message_1 = "ฉันอยากจองตั๋วรถไฟไปหัวหินวันที่ 25 ธันวาคม" print(f"\nข้อความที่ 1: {test_message_1}") result_1 = process_user_message(test_message_1) # ใช้ ensure_ascii=False เพื่อแสดงผลภาษาไทยใน JSON print(json.dumps(result_1, indent=4, ensure_ascii=False)) test_message_2 = "สวัสดีครับ" print(f"\nข้อความที่ 2: {test_message_2}") result_2 = process_user_message(test_message_2) print(json.dumps(result_2, indent=4, ensure_ascii=False))