SUMANA SUMANAKUL (ING) commited on
Commit
30adccc
·
1 Parent(s): 8e85b71

first commit

Browse files
.gitignore ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ poc_data/
2
+ raw_data/
3
+ formatted_data/
4
+ __pycache__/
5
+ app/feedback/
6
+
7
+ # Jupyter Notebook
8
+ *.ipynb_checkpoints
9
+ *.ipynb
10
+
11
+ # Environments
12
+ .env
13
+ .venv
14
+ .gradio/
15
+ credentials.json
16
+ env/
17
+ venv/
18
+ ENV/
19
+ env.bak/
20
+ venv.bak/
21
+ secrets/
22
+
23
+ *.DS_Store
app.py CHANGED
@@ -1,70 +1,106 @@
 
1
  import gradio as gr
2
- from huggingface_hub import InferenceClient
3
-
4
-
5
- def respond(
6
- message,
7
- history: list[dict[str, str]],
8
- system_message,
9
- max_tokens,
10
- temperature,
11
- top_p,
12
- hf_token: gr.OAuthToken,
13
- ):
14
- """
15
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
16
- """
17
- client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
18
-
19
- messages = [{"role": "system", "content": system_message}]
20
-
21
- messages.extend(history)
22
-
23
- messages.append({"role": "user", "content": message})
24
-
25
- response = ""
26
-
27
- for message in client.chat_completion(
28
- messages,
29
- max_tokens=max_tokens,
30
- stream=True,
31
- temperature=temperature,
32
- top_p=top_p,
33
- ):
34
- choices = message.choices
35
- token = ""
36
- if len(choices) and choices[0].delta.content:
37
- token = choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- chatbot = gr.ChatInterface(
47
- respond,
48
- type="messages",
49
- additional_inputs=[
50
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
51
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
52
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
53
- gr.Slider(
54
- minimum=0.1,
55
- maximum=1.0,
56
- value=0.95,
57
- step=0.05,
58
- label="Top-p (nucleus sampling)",
59
- ),
60
- ],
61
- )
62
-
63
- with gr.Blocks() as demo:
64
- with gr.Sidebar():
65
- gr.LoginButton()
66
- chatbot.render()
67
-
68
-
69
- if __name__ == "__main__":
70
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
  import gradio as gr
3
+ import uuid
4
+ from app_p.gemini_agent import RabbitLifeAgent # import agent class จากไฟล์ gemini_agent.py
5
+
6
+ # สร้าง instance agent global
7
+ # agent = RabbitLifeAgent()
8
+
9
+ def initialize_session_sync():
10
+ session_id = str(uuid.uuid4())[:8]
11
+ agent_instance = RabbitLifeAgent()
12
+ history = []
13
+ # agent_instance.session_id = session_id
14
+ return "", session_id, agent_instance, history
15
+
16
+ def chat_function(prompt, history, session_id, agent_instance):
17
+ if agent_instance is None:
18
+ return history, "", session_id, agent_instance
19
+
20
+ # Append the user's input to the message history
21
+ history.append({"role": "user", "content": prompt})
22
+ response = agent_instance.start_chat_session(prompt)
23
+
24
+ # Append the assistant's response to the message history
25
+ history.append({"role": "assistant", "content": response})
26
+
27
+ return history, "", session_id, agent_instance
28
+
29
+
30
+ # Function to save feedback with chat history
31
+ async def send_feedback(feedback, history, session_id, agent_instance):
32
+ os.makedirs("app/feedback", exist_ok=True)
33
+ filename = f"app/feedback/feedback_{session_id}.txt"
34
+ with open(filename, "a", encoding="utf-8") as f:
35
+ f.write("=== Feedback Received ===\n")
36
+ f.write(f"Session ID: {session_id}\n")
37
+ f.write(f"Feedback: {feedback}\n")
38
+ f.write("Chat History:\n")
39
+ for msg in history:
40
+ f.write(f"{msg['role']}: {msg['content']}\n")
41
+ f.write("\n--------------------------\n\n")
42
+ return "" # Clear feedback input
43
+
44
+
45
+ # Create the Gradio interface
46
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange")) as demo:
47
+ # with gr.Blocks(theme="Nymbo/gradio_theme_builder") as demo:
48
+ # with gr.Blocks(theme=gr.themes.Citrus(primary_hue="orange")) as demo:
49
+ gr.Markdown("# แรบบิท ไลฟ์ ประกันชีวิต | RABBIT LIFE")
50
+
51
+ # Initialize State
52
+ session_state = gr.State()
53
+ chatbot_instance = gr.State()
54
+ chatbot_history = gr.State([])
55
+
56
+ # Chat UI
57
+ chatbot_interface = gr.Chatbot(type="messages", label="Chat History")
58
+ user_input = gr.Textbox(placeholder="Type your message here...", elem_id="user_input", lines=1)
59
+
60
+ submit_button = gr.Button("Send")
61
+ clear_button = gr.Button("Delete Chat History")
62
+
63
+ # Submit actions
64
+ submit_button.click(
65
+ fn=chat_function,
66
+ inputs=[user_input, chatbot_history, session_state, chatbot_instance],
67
+ outputs=[chatbot_interface, user_input, session_state, chatbot_instance]
68
+ )
69
+
70
+ user_input.submit(
71
+ fn=chat_function,
72
+ inputs=[user_input, chatbot_history, session_state, chatbot_instance],
73
+ outputs=[chatbot_interface, user_input, session_state, chatbot_instance]
74
+ )
75
+
76
+
77
+ with gr.Row():
78
+ feedback_input = gr.Textbox(placeholder="Send us feedback...", label="Feedback")
79
+ send_feedback_button = gr.Button("Send Feedback")
80
+
81
+ send_feedback_button.click(
82
+ fn=send_feedback,
83
+ inputs=[feedback_input, chatbot_history, session_state, chatbot_instance],
84
+ outputs=[feedback_input]
85
+ )
86
+
87
+ demo.load(
88
+ fn=initialize_session_sync,
89
+ inputs=[],
90
+ outputs=[user_input, session_state, chatbot_instance, chatbot_history]
91
+ )
92
+
93
+ clear_button.click(
94
+ fn=initialize_session_sync,
95
+ inputs=[],
96
+ outputs=[user_input, session_state, chatbot_instance, chatbot_history]
97
+ ).then(
98
+ fn=lambda: gr.update(value=[]),
99
+ inputs=[],
100
+ outputs=chatbot_interface
101
+ )
102
+
103
+
104
+ # Launch
105
+ # demo.launch()
106
+ demo.launch(share=True)
app_p/gemini_agent.py ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import google.generativeai as genai
3
+ import pandas as pd
4
+ from google.generativeai.types import StopCandidateException
5
+ import uuid
6
+ from langfuse import observe, get_client
7
+ # import asyncio
8
+
9
+ from .tools import (
10
+ search_general_knowledge,
11
+ query_customer_policy,
12
+ get_new_customer_recommendation,
13
+ recommend_for_existing_customer
14
+ )
15
+
16
+ class RabbitLifeAgent:
17
+ def __init__(self):
18
+ self.session_id = str(uuid.uuid4())
19
+ # print(f"Session ID: {self.session_id}")
20
+ self.current_customer_context: pd.DataFrame | None = None
21
+
22
+ # --- tools ---
23
+ self.tools = [
24
+ search_general_knowledge,
25
+ query_customer_policy,
26
+ get_new_customer_recommendation,
27
+ recommend_for_existing_customer,
28
+ ]
29
+
30
+ self.model = genai.GenerativeModel(
31
+ model_name='gemini-2.5-flash',
32
+ tools=self.tools,
33
+ system_instruction="""
34
+ **//-- Core Persona & Identity --//**
35
+ You are a smart, professional, and friendly AI assistant from "Rabbit Life" insurance.
36
+ - **Language:** You MUST respond in Thai ONLY, using polite female particles like "ค่ะ" and "นะคะ".
37
+ - **Greeting:** When the user greets you for the first time, you MUST respond with: "สวัสดีค่ะ ให้ Rabbit Life ช่วยดูแลคุณนะคะ เราเป็นผู้ช่วย AI ที่พร้อมให้ข้อมูลผลิตภัณฑ์เพื่อช่วยคุณมองหาแผนประกันที่ใช่ ไม่ทราบว่าสนใจสอบถามข้อมูลด้านใดเป็นพิเศษคะ"
38
+ - **Slogan:** You must embody the company's slogan, "ให้ Rabbit Life ช่วยดูแลคุณ" (Let Rabbit Life take care of you). Weave this sentiment into your caring and helpful responses, especially at the end of a successful interaction.
39
+ - **Pronouns:** Refer to yourself as "เรา" or "ทางเรา". Strictly avoid "ดิฉัน" and "ฉัน".
40
+
41
+ **//-- Formatting Rules (CRITICAL) --//**
42
+ - **Use Bullet Points:** You MUST use Markdown bullet points (using `•` or `-`) to present lists of features, benefits, products, or any series of items. This is essential for readability.
43
+ - **Clarity & Tone:** Use clear headings (e.g., **หัวข้อความคุ้มครองหลัก:**) and a caring closing statement.
44
+
45
+ **//-- Primary Directive: Use Your Tools Efficiently --//**
46
+ Your main goal is to understand the user's need and immediately use the appropriate tool.
47
+ - **Be Direct:** If a question matches a tool, use it. Do not ask unnecessary clarifying questions.
48
+ - **Conversational Tone:** For greetings, thanks, or small talk not covered by a tool, maintain a friendly and helpful conversation.
49
+
50
+ **//-- Authoritative Knowledge Scope (Your Product List) --//**
51
+ You have information about these Rabbit Life products. Recognize them when a user mentions them.
52
+ - **ประกันคุ้มครองชีวิต:** Chai Leoy 99/5, Chai Leoy 99/10, Chai Leoy 99/20, High Protect 3/3, Smart Term Bronze 5, Smart Term Bronze 10, Smart Wellness 90/15
53
+ - **ประกันเพื่อการลงทุน:** Jai Jai 15/6, Jai Jai 12/6, Jai Jai 25/9, Sabai Jai 14/5, Protection Plus 18/9
54
+ - **ประกันสุขภาพ:** Health Protect, Health Smile, Worry Free Cancer, HIB 365, OPD, Mental Health, Worry Free 50 Critical Illness
55
+ - **ประกันอุบัติเหตุ:** PA MAX, PA PROMPT, ADD, ADB
56
+
57
+ **//-- Tool Usage Guide (CRITICAL) --//**
58
+ - **`search_general_knowledge`:** Use for questions about products in the list above or general insurance topics (e.g., "how to claim?", "tax deduction?").
59
+
60
+ - **`query_customer_policy`:**
61
+ - **Trigger:** Use when a user wants to check their own policy information (e.g., "check my policy status", "what is my premium?").
62
+ - **Action:** This tool requires a `customer_identifier`. If the user has not provided it, your job is to ask for it.
63
+ - **Identifier Question Rule (IMPORTANT):** When you need to ask for the identifier, you MUST ask for ONLY "ชื่อ-นามสกุล" (full name) OR "เลขบัตรประชาชน 13 หลัก" (13-digit national ID). Do not ask for other information like policy number.
64
+ - **Example of a correct identifier question:** "ได้เลยค่ะ เพื่อตรวจสอบข้อมูล รบกวนขอชื่อ-นามสกุล หรือ��ลขบัตรประชาชน 13 หลักได้ไหมคะ"
65
+
66
+ - **`get_new_customer_recommendation`:**
67
+ - **Trigger:** Use for new users asking for a recommendation (e.g., "recommend a plan for me", "I want to buy insurance").
68
+ - **Action:** You MUST ask for `age`, `gender`, and `salary` one by one if they are missing.
69
+ - **Salary Question Rule (IMPORTANT):** When you need to ask for the user's salary, your question MUST specifically ask for **"รายได้ต่อเดือน" (monthly income)**. Do not ask for yearly income.
70
+ - **Example of a correct salary question:** "สุดท้ายนี้ ขออนุญาตสอบถามรายได้ต่อเดือนเพื่อประกอบการแนะนำได้ไหมคะ"
71
+
72
+ - **`recommend_for_existing_customer`:**
73
+ - **Trigger:** Use for a KNOWN, REMEMBERED customer asking for a recommendation.
74
+ - **Action:** If the customer specifies an interest (e.g., "add accident insurance", "what about investment plans?"), pass this interest into the `interest` parameter. Otherwise, you can call the tool without parameters.
75
+ """,
76
+ generation_config={"temperature": 0.0}
77
+ )
78
+ self.chat = self.model.start_chat(history=[]) # , metadata={"session_id": self.session_id}) # self.chat = self.model.start_chat()
79
+ print("✅ Agent is ready.")
80
+
81
+
82
+ @observe(name="customer_context")
83
+ def set_customer_context(self, customer_df: pd.DataFrame):
84
+ self.current_customer_context = customer_df
85
+ # if customer_df is not None and not customer_df.empty:
86
+ # customer_name = f"{customer_df.iloc[0].get('insured_firstname', '')} {customer_df.iloc[0].get('insured_lastname', '')}".strip()
87
+
88
+ @observe(name="get_customer_context")
89
+ def get_customer_context(self) -> pd.DataFrame | None:
90
+ return self.current_customer_context
91
+
92
+ @observe(name="chat")
93
+ def start_chat_session(self, user_input: str) -> str:
94
+ langfuse = get_client()
95
+ langfuse.update_current_trace(session_id=self.session_id)
96
+ if not user_input:
97
+ return "กรุณาพิมพ์ข้อความที่ต้องการสอบถามค่ะ"
98
+
99
+ try:
100
+ response = self.chat.send_message(user_input)
101
+ # print(f"==========")
102
+ # print(f"response: {response}")
103
+ # print(f"==========")
104
+
105
+ # --- Loop สำหรับจัดการ Tool Calling จะทำงานถ้า Gemini ตัดสินใจว่าต้องเรียกใช้เครื่องมือ
106
+ while response.candidates and response.candidates[0].content.parts[0].function_call:
107
+ function_call = response.candidates[0].content.parts[0].function_call
108
+ tool_name = function_call.name
109
+ tool_args = {key: value for key, value in function_call.args.items()}
110
+ # print(f"🔩 LLM wants to call Tool: {tool_name} with args: {tool_args}")
111
+
112
+ # หาฟังก์ชันของ tool จากชื่อ
113
+ tool_map = {t.__name__: t for t in self.tools}
114
+ tool_function = tool_map.get(tool_name)
115
+
116
+ if tool_function:
117
+ # ใส่ agent_instance เข้าไปใน arguments เพื่อให้ tool เข้าถึง context ได้
118
+ tool_args['agent_instance'] = self
119
+ # เรียกใช้ฟังก์ชัน tool และแปลงผลลัพธ์เป็น string
120
+ tool_response_content = str(tool_function(**tool_args))
121
+
122
+ # print(f"🔧 Tool Response: {tool_response_content[:200]}...")
123
+
124
+ # ส่งผลลัพธ์จาก tool กลับไปให้ Gemini เพื่อสรุปเป็นคำตอบ
125
+ response = self.chat.send_message(
126
+ [{"function_response": {
127
+ "name": tool_name,
128
+ "response": {"content": tool_response_content}
129
+ }}]
130
+ )
131
+ else:
132
+ # กรณีที่ LLM เรียก tool ที่ไม่มี
133
+ error_msg = f"ขออภัยค่ะ ไม่พบเครื่องมือ {tool_name}"
134
+ print(f"❌ Error: {error_msg}")
135
+ return error_msg
136
+
137
+ # --- final response ---
138
+ ai_response = response.text
139
+ ai_response = ai_response.replace("ดิฉัน", "เรา").replace("ฉัน", "เรา")
140
+ # print(f"🤖 AI: {ai_response}")
141
+ return ai_response
142
+
143
+ except StopCandidateException as e:
144
+ error_msg = f"‼️ API Error Detected: {e.finish_reason}. Responding gracefully."
145
+ print(error_msg) # หรือใช้ logging.error(error_msg)
146
+
147
+ # ตรวจสอบสาเหตุของ Error และ return คำตอบที่เหมาะสมออกไปเลย
148
+ if e.finish_reason == "MALFORMED_FUNCTION_CALL":
149
+ return "ขออภัยค่ะ ดูเหมือนจะมีปัญหาในการประมวลผลคำถาม รบกวนลองถามอีกครั้งด้วยประโยคที่สมบูรณ์ขึ้นได้ไหมคะ"
150
+ else:
151
+ # สำหรับ Error อื่นๆ เช่น SAFETY, RECITATION etc.
152
+ return "ขออภัยค่ะ เกิดข้อผิดพลาดในการสื่อสารกับระบบ โปรดลองอีกครั้งค่ะ"
153
+
154
+
155
+ # --- For checking chat history ---
156
+ def view_flow_history(self):
157
+ if not self.chat.history:
158
+ print("History is empty.")
159
+ else:
160
+ # [print(f"[{m.role.upper()}]") or [print(p) for p in m.parts] for m in self.chat.history]
161
+ return self.chat.history
162
+
163
+
164
+ # # ---
165
+ # agent = RabbitLifeAgent()
166
+
167
+
168
+ # async def chat_wrapper(user_input: str) -> str:
169
+ # return await agent.start_chat_session(user_input)
170
+
171
+ # if __name__ == '__main__':
172
+
173
+ # agent = RabbitLifeAgent()
174
+
175
+ # # --- เริ่ม Session การแชทใน Terminal ---
176
+ # print("-" * 50)
177
+ # print("🤖 สวัสดีค่ะ ให้ Rabbit Life ช่วยดูแลนะคะ (พิมพ์ 'exit' เพื่อจบการสนทนา)")
178
+ # print("-" * 50)
179
+
180
+ # while True:
181
+ # try:
182
+ # user_input = input("👤 คุณ: ")
183
+ # if user_input.lower() == 'exit':
184
+ # print("ขอบคุณที่ใช้บริการนะคะ สวัสดีค่ะ")
185
+ # break
186
+ # if not user_input:
187
+ # continue
188
+
189
+ # ai_response = agent.start_chat_session(user_input)
190
+ # # print(f"🤖 AI: {ai_response}")
191
+
192
+ # except (KeyboardInterrupt, EOFError): # ดัก Ctrl+C หรือ Ctrl+D
193
+ # print("\nขอบคุณที่ใช้บริการนะคะ สวัสดีค่ะ")
194
+ # break
195
+ # except Exception as e:
196
+ # print(f"เกิดข้อผิดพลาดร้ายแรง: {e}")
197
+ # import traceback
198
+ # traceback.print_exc()
199
+ # break
app_p/handler/customer_data_handler.py ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import json
3
+ import re
4
+ from pathlib import Path
5
+
6
+ # --- Data Loading ---
7
+ try:
8
+ print("Loading data for CustomerDataHandler module...")
9
+ PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent # หา Path ของ Root Directory
10
+ DATA_PATH = PROJECT_ROOT / "data"
11
+ CONFIG_PATH = PROJECT_ROOT / "config"
12
+
13
+ # customer df
14
+ CUSTOMER_DF = pd.read_csv(DATA_PATH / "mock_customer_data.csv")
15
+ COLUMN_MAP_DF = pd.read_csv(DATA_PATH / "column_mapping.csv")
16
+ COLUMN_MAP_DICT = pd.Series(COLUMN_MAP_DF.Description.values, index=COLUMN_MAP_DF.Field_name).to_dict() # dict mapping
17
+
18
+ # persona json
19
+ # ABSOLUTE_PATH_TO_CONFIG = '/Users/jts-ai-sumana/rabbitlife_gemini/config/personas.json'
20
+ # with open(ABSOLUTE_PATH_TO_CONFIG, "r", encoding="utf-8") as f:
21
+ with open(CONFIG_PATH / "personas.json", "r", encoding="utf-8") as f:
22
+ PERSONAS = json.load(f)
23
+ print("✅ Customer data, mapping, and personas loaded successfully.")
24
+
25
+ except Exception as e:
26
+ print(f"‼️ ERROR: Could not load data/config files for CustomerDataHandler: {e}")
27
+ CUSTOMER_DF = pd.DataFrame()
28
+ COLUMN_MAP_DICT = {}
29
+ PERSONAS = {}
30
+
31
+ # map ชื่อ: ประเภท
32
+ PLAN_NAME_TO_TYPE_MAP = {
33
+ "Smart Term Bronze 5": "ประกันคุ้มครองชีวิต", "Smart Term Bronze 10": "ประกันคุ้มครองชีวิต",
34
+ "Chai Leoy 99/20": "ประกันคุ้มครองชีวิต", "Chai Leoy 99/10": "ประกันคุ้มครองชีวิต",
35
+ "Chai Leoy 99/5": "ประกันคุ้มครองชีวิต", "High Protect 3/3": "ประกันคุ้มครองชีวิต",
36
+ "Smart Wellness 90/15": "ประกันคุ้มครองชีวิต", "Save 5 C": "ประกันคุ้มครองชีวิต",
37
+ "Sabai Jai 14/5": "ประกันเพื่อการลงทุน", "Jai Jai 25/9": "ประกันเพื่อการลงทุน",
38
+ "Protection Plus 18/9": "ประกันเพื่อการลงทุน", "Jai Jai 12/6": "ประกันเพื่อการลงทุน",
39
+ "Jai Jai 15/6": "ประกันเพื่อการลงทุน",
40
+ "Health Protect (สัญญาเพิ่มเติมสุขภาพค่ารักษาพยาบาล)": "ประกันสุขภาพ", "Health Smile": "ประกันสุขภาพ",
41
+ "Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง)": "ประกันสุขภาพ", "Worry Free 50 Critical Illness": "ประกันสุขภาพ",
42
+ "Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน)": "ประกันสุขภาพ",
43
+ "PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก)": "ประกันสุขภาพ", "PA Prompt (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก)": "ประกันสุขภาพ",
44
+ "สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย": "ประกันสุขภาพ", "OPD": "ประกันสุขภาพ", "Mental Health": "ประกันสุขภาพ",
45
+ "PA Max (อุบัติเหตุส่วนบุคคล)": "ประกันอุบัติเหตุ", "PA Prompt (อุบัติเหตุส่วนบุคคล)": "ประกันอุบัติเหตุ",
46
+ "Rider ADD (สัญญาเพิ่มเติมอุบัติเหตุ)": "ประกันอุบัติเหตุ", "Rider AI (สัญญาเพิ่มเติมอุบัติเหตุ)": "ประกันอุบัติเหตุ",
47
+ "Rider ADB (สัญญาเพิ่มเติมอุบัติเหตุ)": "ประกันอุบัติเหตุ",
48
+ "PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ)": "ประกันอุบัติเหตุ", "PA Prompt (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ)": "ประกันอุบัติเหตุ",
49
+ "Rider ADB and ADD(สัญญาเพิ่มเติมอุบัติเหตุ)": "ประกันอุบัติเหตุ"
50
+ }
51
+
52
+
53
+ # --- Utilize Fuctions ---
54
+
55
+ def clean_name(name):
56
+ if not isinstance(name, str): return ""
57
+ return re.sub(r'\s*\(.*\)\s*', '', name).strip()
58
+
59
+
60
+ def find_customer_data(identifier: str) -> pd.DataFrame | None:
61
+ """
62
+ return df
63
+ """
64
+ if CUSTOMER_DF.empty:
65
+ return None
66
+
67
+ identifier = str(identifier).strip()
68
+
69
+ # ลองค้นหาด้วยเลขบัตรประชาชนก่อน
70
+ numeric_identifier = re.sub(r'\D', '', identifier)
71
+ if len(numeric_identifier) == 13:
72
+ result_df = CUSTOMER_DF[CUSTOMER_DF['insured_id_number'] == int(numeric_identifier)]
73
+ if not result_df.empty:
74
+ return result_df
75
+
76
+ # ถ้าไม่เจอ ลองค้นหาด้วยชื่อ-นามสกุล
77
+ name_parts = identifier.split()
78
+ if len(name_parts) >= 2:
79
+ firstname, lastname = name_parts[0], " ".join(name_parts[1:])
80
+ result_df = CUSTOMER_DF[(CUSTOMER_DF['insured_firstname'] == firstname) & (CUSTOMER_DF['insured_lastname'] == lastname)]
81
+ if not result_df.empty:
82
+ return result_df
83
+
84
+ return None
85
+
86
+
87
+ def translate_and_format_data(customer_df: pd.DataFrame) -> str:
88
+ """
89
+ เลือกคอลัมน์ที่ต้องการ --> แปลชื่อคอลัมน์เป็นภาษาไทย --> และแปลงเป็น JSON string
90
+ """
91
+ columns_to_show = [
92
+ 'policy_no', 'policy_plan_name', 'plan_type', 'total_premium', 'policy_status',
93
+ 'policy_effective_date', 'premium_duedate', 'policy_maturity_date', 'sum_insured_first'
94
+ ]
95
+ existing_columns = [col for col in columns_to_show if col in customer_df.columns]
96
+ df_to_format = customer_df[existing_columns].copy()
97
+ df_to_format.rename(columns=COLUMN_MAP_DICT, inplace=True)
98
+ return df_to_format.to_json(orient='records', force_ascii=False, indent=2)
99
+
100
+
101
+ def find_recommendation_gaps(customer_df: pd.DataFrame) -> list:
102
+ """
103
+ วิเคราะห์ข้อมูลกรมธรรม์ของลูกค้าเพื่อหาผลิตภัณฑ์ที่น่าแนะนำเพิ่มเติม (Gap Analysis)
104
+ โดยพิจารณาจาก Age และ Salary
105
+ """
106
+ # print("[Gap Analysis] Starting analysis for existing customer...")
107
+ if customer_df.empty or not PERSONAS:
108
+ return []
109
+
110
+ try:
111
+ customer_info = customer_df.iloc[0]
112
+ age = customer_info.get('insured_age_latest')
113
+ gender = str(customer_info.get('insured_gender', '')).upper()
114
+ salary = customer_info.get('insured_salary', 0)
115
+
116
+ if age is None or not gender:
117
+ # print("[Gap Analysis] Missing age or gender. Cannot perform analysis.")
118
+ return []
119
+
120
+ # print(f"[Gap Analysis] Analyzing profile: Age={age}, Gender='{gender}', Salary={salary}")
121
+
122
+ # หา Persona
123
+ matched_persona = next((details for _, details in PERSONAS.items() if details.get("age_min", -1) <= age <= details.get("age_max", -1)), None)
124
+ if not matched_persona:
125
+ return []
126
+
127
+ # หา Tier จากเงินเดือน
128
+ products_from_tier = []
129
+ salary_tiers = matched_persona.get('recommendations_by_salary', [])
130
+ for tier in salary_tiers:
131
+ if tier.get("salary_min", 0) <= salary <= tier.get("salary_max", float('inf')):
132
+ products_from_tier = tier.get("products", [])
133
+ break
134
+
135
+ if not products_from_tier and salary_tiers:
136
+ products_from_tier = salary_tiers[0].get("products", [])
137
+
138
+ # ดึงลิสต์ผลิตภัณฑ์ที่ ideal จาก Tier และ เพศ
139
+ ideal_products = [p for p in products_from_tier if p.get('gender') == 'all' or p.get('gender') == gender]
140
+
141
+ # ดึงลิสต์ผลิตภัณฑ์ที่ "มีอยู่แล้ว" และทำความสะอาดชื่อ
142
+ existing_products_raw = set(customer_df['policy_plan_name'].unique())
143
+ existing_products_names = {clean_name(name) for name in existing_products_raw}
144
+
145
+ # หา Gaps
146
+ gaps = []
147
+ for ideal_product in ideal_products:
148
+ ideal_product_name_clean = clean_name(ideal_product.get('product_name', ''))
149
+ if ideal_product_name_clean not in existing_products_names:
150
+ gaps.append(ideal_product)
151
+
152
+ gaps.sort(key=lambda x: ('Rider' not in x.get('product_category', '')), reverse=False)
153
+
154
+ # print(f"[Gap Analysis] Found {len(gaps)} potential products to recommend.")
155
+ return gaps
156
+
157
+ except Exception as e:
158
+ print(f"‼️ ERROR during Gap Analysis: {e}")
159
+ import traceback
160
+ traceback.print_exc()
161
+ return []
162
+
163
+
164
+ def generate_upsell_text_from_gaps(gaps: list) -> str:
165
+ """สร้างประโยค Upsell สั้นๆ จาก Gap ที่หาเจอ"""
166
+ if gaps:
167
+ main_recommendation = gaps[0]
168
+ return (f"\n\nจากข้อมูลความคุ้มครองปัจจุบัน สังเกตว่า���ผนประกันของท่านจะครอบคลุมยิ่งขึ้น "
169
+ f"หากมีสัญญาเพิ่มเติม **{main_recommendation['product_name']}** "
170
+ f"ซึ่งจะช่วยดูแลในเรื่อง{main_recommendation.get('product_description', 'ความคุ้มครองเพิ่มเติม')}ค่ะ"
171
+ f"\n\nสนใจรับข้อมูลเพิ่มเติมเกี่ยวกับแผนนี้ไหมคะ")
172
+ return ""
app_p/handler/recommendation_handler.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from pathlib import Path
3
+ import os
4
+ from langchain_google_genai import ChatGoogleGenerativeAI
5
+
6
+ # --- Data Loading ---
7
+ try:
8
+ print("Loading personas for RecommendationHandler module...")
9
+ # ABSOLUTE_PATH_TO_CONFIG = '/Users/jts-ai-sumana/rabbitlife_gemini/config/personas.json'
10
+ # with open(ABSOLUTE_PATH_TO_CONFIG, "r", encoding="utf-8") as f:
11
+ PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
12
+ CONFIG_PATH = PROJECT_ROOT / "config" / "personas.json"
13
+ with open(CONFIG_PATH, "r", encoding="utf-8") as f:
14
+ PERSONAS = json.load(f)
15
+ print(f"✅ Personas config loaded successfully from: {CONFIG_PATH}")
16
+ except Exception as e:
17
+ PERSONAS = {}
18
+ print(f"‼️ ERROR: Could not load personas.json: {e}")
19
+
20
+ # --- LLM Initialization ---
21
+ try:
22
+ INTEREST_LLM = ChatGoogleGenerativeAI(
23
+ model="gemini-2.5-flash",
24
+ google_api_key=os.getenv("GOOGLE_API_KEY"),
25
+ temperature=0,
26
+ )
27
+ print("✅ LLM for interest classification initialized.")
28
+ except Exception as e:
29
+ INTEREST_LLM = None
30
+ print(f"‼️ ERROR initializing LLM for RecommendationHandler: {e}")
31
+
32
+
33
+ # RECOMMENDATION ###
34
+ def generate_recommendation_from_profile(
35
+ age: int,
36
+ gender: str, # M, F
37
+ salary: int,
38
+ original_interest: str
39
+ ) -> dict:
40
+ if not PERSONAS or not INTEREST_LLM:
41
+ return {"error": "Module not initialized correctly."}
42
+
43
+ # print(f"\n--- Generating Recommendation Profile ---")
44
+ # print(f"Input Data: Age={age}, Gender='{gender}', Salary={salary}, Interest='{original_interest}'")
45
+
46
+ # 1. หา Persona ที่ตรงกับอายุ
47
+ matched_persona = next((details for _, details in PERSONAS.items() if details.get("age_min", -1) <= age <= details.get("age_max", -1)), None)
48
+ if not matched_persona:
49
+ return {"error": f"No matching persona found for age {age}."}
50
+ # print(f"-> Matched Persona: '{matched_persona.get('persona_name', 'N/A')}'")
51
+
52
+ # 2. หา Tier ที่ตรงกับเงินเดือน
53
+ products_from_tier = []
54
+ salary_tiers = matched_persona.get('recommendations_by_salary', [])
55
+ for tier in salary_tiers:
56
+ if tier.get("salary_min", 0) <= salary <= tier.get("salary_max", float('inf')):
57
+ products_from_tier = tier.get("products", [])
58
+ # print(f"-> Matched Salary Tier: '{tier.get('tier_name')}'")
59
+ break
60
+ if not products_from_tier and salary_tiers:
61
+ products_from_tier = salary_tiers[0].get("products", [])
62
+
63
+ # 3. รวบรวม product จาก Tier และเพศ
64
+ all_tier_products = [p for p in products_from_tier if p.get('gender') == 'all' or p.get('gender') == gender]
65
+
66
+ # 4. กรองตาม Interest - LLM
67
+ interest_prompt = f"""Analyze the user's interest and classify it into ONE of these categories:
68
+ 'ประกันคุ้มครองชีวิต', 'ประกันเพื่อการลงทุน', 'ประกันสุขภาพ', 'ประกันอุบัติเหตุ', 'ทั่วไป'.
69
+ User Interest: "{original_interest}"
70
+ Category:"""
71
+
72
+ response = INTEREST_LLM.invoke(interest_prompt)
73
+ target_insurance_type = response.content.strip()
74
+ # print(f"-> LLM classified interest as: '{target_insurance_type}'")
75
+
76
+ products_to_recommend = all_tier_products
77
+ searched_outside_tier = False
78
+
79
+ valid_types = ['ประกันเพื่อการลงทุน', 'ประกันสุขภาพ', 'ประกันอุบัติเหตุ', 'ประกันคุ้มครองชีวิต']
80
+
81
+ if target_insurance_type in valid_types:
82
+ # print(f"-> Filtering for interest: '{target_insurance_type}' across all tiers...")
83
+
84
+ all_persona_products = []
85
+ for tier_fallback in matched_persona.get('recommendations_by_salary', []):
86
+ all_persona_products.extend(tier_fallback.get('products', []))
87
+
88
+ gender_filtered_products = [p for p in all_persona_products if p.get('gender') == 'all' or p.get('gender') == gender]
89
+ final_filtered_products = [p for p in gender_filtered_products if p.get('insurance_type') == target_insurance_type]
90
+
91
+ if final_filtered_products:
92
+ # print(f"-> Found {len(final_filtered_products)} matching products.")
93
+ products_to_recommend = final_filtered_products
94
+ else:
95
+ print(f"-> CRITICAL: No product of type '{target_insurance_type}' found anywhere in this persona.")
96
+ return {"error": f"ขออภัยค่ะ เราไม่พบผลิตภัณฑ์ประเภท '{target_insurance_type}' ที่เหมาะสมกับโปรไฟล์ของคุณในขณะนี้ค่ะ"}
97
+
98
+
99
+ # 5. ตรวจสอบและเพิ่มสัญญาหลักถ้าจำเป็น
100
+ has_basic_plan = any(p.get('plan_type') == 'Basic' for p in products_to_recommend)
101
+ auto_added_main_plan = False
102
+ if not has_basic_plan and any(p.get('plan_type') == 'Rider' for p in products_to_recommend):
103
+ # print("-> Filtered list only has Riders. Adding a default main plan.")
104
+ default_main_plans = [p for p in all_tier_products if p.get('plan_type') == 'Basic']
105
+ if default_main_plans:
106
+ products_to_recommend.insert(0, default_main_plans[0])
107
+ auto_added_main_plan = True
108
+
109
+
110
+ # 6. จัดกลุ่มและเตรียมข้อมูลสำหรับส่งคืน
111
+ main_plans = [p for p in products_to_recommend if p.get('plan_type') == 'Basic']
112
+ riders = [p for p in products_to_recommend if p.get('plan_type') == 'Rider']
113
+
114
+ main_plans_str = "ไม่มีแผนประกันหลักที่แนะนำ"
115
+ if main_plans:
116
+ main_plans_str = "\n".join([f"• **{p.get('product_name')}**: {p.get('product_description')}" for p in main_plans])
117
+ riders_str = "ไม่มีสัญญาเพิ่มเติมที่แนะนำ"
118
+ if riders:
119
+ riders_str = "\n".join([f"• **{p.get('product_name')}**: {p.get('product_description')}" for p in riders])
120
+
121
+ return {
122
+ "age": age, "gender": gender, "salary": f"{salary:,}",
123
+ "persona_name": matched_persona['persona_name'],
124
+ "persona_description": matched_persona['description'],
125
+ "original_interest": original_interest,
126
+ "main_plans_str": main_plans_str.strip(),
127
+ "riders_str": riders_str.strip(),
128
+ "auto_added_main_plan": auto_added_main_plan,
129
+ "searched_outside_tier": searched_outside_tier,
130
+ "interest_category": target_insurance_type if target_insurance_type != 'ทั่วไป' else 'ประกัน'
131
+ }
app_p/tools.py ADDED
@@ -0,0 +1,342 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ from typing import Annotated, Optional
4
+ import google.generativeai as genai
5
+ from langfuse import observe, get_client
6
+
7
+ from .utils.reranker import RerankRetriever
8
+ from .utils.prompts import CUSTOMER_DATA_SUMMARY_PROMPT, RECOMMENDATION_PROMPT
9
+ from .handler import customer_data_handler
10
+ from .handler import recommendation_handler
11
+
12
+
13
+ # --- Configurations & Initializations ---
14
+ try:
15
+ print("Initializing RerankRetriever for tools...")
16
+ rag_retriever = RerankRetriever()
17
+ print("✅ RerankRetriever initialized successfully.")
18
+ except Exception as e:
19
+ print(f"‼️ ERROR initializing RerankRetriever: {e}")
20
+ rag_retriever = None
21
+
22
+ GEMINI_API_KEY = os.getenv("GOOGLE_API_KEY")
23
+ if not GEMINI_API_KEY:
24
+ raise ValueError("GOOGLE_API_KEY not found in environment variables.")
25
+ genai.configure(api_key=GEMINI_API_KEY)
26
+
27
+ specialized_llm = genai.GenerativeModel(
28
+ 'gemini-2.5-flash',
29
+ system_instruction="""
30
+ You are an expert AI assistant for "Rabbit Life" insurance. Your persona is helpful, professional, and empathetic.
31
+ - **Language:** You MUST respond in Thai ONLY, using polite female particles like "ค่ะ" and "นะคะ".
32
+ - **Pronouns:** When referring to yourself, you MUST refer to yourself as "เรา" (we/us) or "ทางเรา" (on our part).
33
+ Your objective is to execute the given task (summarizing data, generating recommendations) based *only* on the provided information.
34
+ - **Strict Grounding:** Your answer must be derived exclusively from the provided data.
35
+ - **Do Not Translate Proper Nouns:** Keep product names and "Rabbit Life" in English.
36
+
37
+ //-- Formatting Rules (CRITICAL) --//
38
+ - **Use Bullet Points:** You MUST use Markdown bullet points (using `•` or `-`) to present lists of features, benefits, products, or any series of items. This is essential for readability.
39
+ - **Clarity & Tone:** Use clear headings (e.g., **หัวข้อความคุ้มครองหลัก:**) and a caring closing statement.
40
+ """,
41
+ generation_config={"temperature": 0.0}
42
+ )
43
+
44
+ # def run_async(coro):
45
+ # """A helper to run an async coroutine from a synchronous function."""
46
+ # try:
47
+ # loop = asyncio.get_running_loop()
48
+ # except RuntimeError:
49
+ # loop = asyncio.new_event_loop()
50
+ # asyncio.set_event_loop(loop)
51
+ # return loop.run_until_complete(coro)
52
+
53
+ KNOWN_PRODUCTS_SORTED = [
54
+ 'Health Protect (สัญญาเพิ่มเติมสุขภาพค่ารักษาพยาบาล)',
55
+ 'Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง)',
56
+ 'Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน)',
57
+ 'PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก)', # เพิ่มมาจาก MAP
58
+ 'PA Prompt (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก)', # เพิ่มมาจาก MAP
59
+ 'สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย', # เพิ่มมาจาก MAP
60
+ 'PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ)', # เพิ่มมาจาก MAP
61
+ 'PA Prompt (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ)',# เพิ่มมาจาก MAP
62
+ 'Rider ADB and ADD(สัญญาเพิ่มเติมอุบัติเหตุ)',
63
+ 'Rider ADB (สัญญาเพิ่มเติมอุบัติเหตุ)',
64
+ 'Rider ADD (สัญญาเพิ่มเติมอุบัติเหตุ)',
65
+ 'Rider AI (สัญญาเพิ่มเติมอุบัติเหตุ)',
66
+ 'PA Prompt (อุบัติเหตุส่วนบุคคล)',
67
+ 'Worry Free 50 Critical Illness',
68
+ 'PA Max (อุบัติเหตุส่วนบุคคล)',
69
+ 'Protection Plus 18/9',
70
+ 'Smart Term Bronze 10',
71
+ 'Smart Wellness 90/15',
72
+ 'Smart Term Bronze 5',
73
+ 'High Protect 3/3',
74
+ 'Chai Leoy 99/10',
75
+ 'Chai Leoy 99/20',
76
+ 'Chai Leoy 99/5',
77
+ 'Sabai Jai 14/5',
78
+ 'Mental Health',
79
+ 'Health Smile',
80
+ 'Jai Jai 15/6',
81
+ 'Jai Jai 12/6', # เพิ่มมาจาก MAP
82
+ 'Jai Jai 25/9',
83
+ 'OPD',
84
+ ]
85
+ KNOWN_PRODUCTS_SORTED = sorted(list(set(KNOWN_PRODUCTS_SORTED)), key=len, reverse=True)
86
+
87
+ # --- Tool 1: General Knowledge (RAG) ---
88
+ @observe(name="RAG_Flow")
89
+ def search_general_knowledge(
90
+ agent_instance,
91
+ query: Annotated[str, "The user's general question about an insurance product, its features, or related topics like claims or tax deductions."],
92
+ ) -> str:
93
+ """Use this tool to answer a user's general question about Rabbit Life insurance and their products.
94
+ This tool performs a semantic search (RAG) through the knowledge base of product documentation
95
+ to find the most relevant information to answer the query."""
96
+ # print(f"🛠️ Tool Called: search_general_knowledge(query='{query}')")
97
+
98
+ if not rag_retriever:
99
+ return "ขออภัยค่ะ ระบบสืบค้นข้อมูลขัดข้องชั่วคราว"
100
+
101
+ # --- 1. สกัดชื่อ Product ---
102
+ extracted_plan_name = None
103
+ lower_query = query.lower()
104
+
105
+ for product in KNOWN_PRODUCTS_SORTED:
106
+ # สร้าง keyword ตัดวงเล็บออก
107
+ simple_product_keyword = re.sub(r'\(.*\)', '', product).strip().lower()
108
+
109
+ # ตรวจสอบว่า keyword ที่สร้างขึ้น อยู่ในคำถามของผู้ใช้หรือไม่
110
+ if simple_product_keyword and simple_product_keyword in lower_query:
111
+ # ถ้าเจอ, ให้ใช้ "ชื่อเต็ม" ของผลิตภัณฑ์นั้นเป็นตัวกรอง
112
+ extracted_plan_name = product
113
+ break # เจออันที่ยาวที่สุดแล้ว หยุดทันที
114
+
115
+ # print(f"🕵️‍♂️ Extracted Plan Name for Filter: {extracted_plan_name}")
116
+
117
+ # --- 2. สร้าง Filter Dictionary & เรียก Retriever ---
118
+ retriever_kwargs = {}
119
+ if extracted_plan_name:
120
+ # print(f"✨ Applying metadata filter for: '{extracted_plan_name}'")
121
+ # สร้าง filter โดยใช้ Key ('vector_search_filter')
122
+ retriever_kwargs['vector_search_filter'] = {
123
+ "term": {
124
+ "query": extracted_plan_name,
125
+ "path": "policy_plan_name"
126
+ }
127
+ }
128
+ # print(f"🔍 Retrieving context for: '{query}' with filter: {retriever_kwargs}")
129
+
130
+ # ส่ง kwargs ที่มี filter ของเราเข้าไปใน retriever pipeline
131
+ compression_retriever = rag_retriever.get_compression_retriever(**retriever_kwargs)
132
+ context_docs = compression_retriever.invoke(query)
133
+
134
+ # print(f"Retrieved {len(context_docs)} documents")
135
+ # print(context_docs)
136
+
137
+ if not context_docs:
138
+ if extracted_plan_name:
139
+ return f"ขออภัยค่ะ เราพบข้อมูลเกี่ยวกับ '{extracted_plan_name}' แต่ไม่พบรายละเอียดที่ตรงกับคำถามของคุณค่ะ"
140
+ return "ขออภัยค่ะ เราไม่พบข้อมูลที่เกี่ยวข้องกับคำถามนี้"
141
+
142
+ # --- 3. Format Meta ---
143
+ # print(f"📄 Formatting {len(context_docs)} retrieved documents...")
144
+ formatted_docs = []
145
+ for i, doc in enumerate(context_docs):
146
+ insurance_type = doc.metadata.get('insurance_type', '-')
147
+ plan_name = doc.metadata.get('plan_name', '-')
148
+ header_1 = doc.metadata.get('Header 1', '-')
149
+ header_2 = doc.metadata.get('Header 2', '-')
150
+ header_3 = doc.metadata.get('Header 3', '-')
151
+ content = doc.page_content
152
+
153
+ formatted = (
154
+ f"<Doc_{i}>\n"
155
+ f"ชื่อประกัน: {plan_name}\n"
156
+ f"ประเภทประกัน: {insurance_type}\n"
157
+ f"หัวข้อใหญ่: {header_1}\n"
158
+ f"หัวข้อรอง: {header_2}\n"
159
+ f"หัวข้อย่อย: {header_3}\n\n"
160
+ f"{content}\n"
161
+ "----------"
162
+ )
163
+ formatted_docs.append(formatted)
164
+
165
+ context = "\n\n".join(formatted_docs)
166
+
167
+ final_prompt = f"""
168
+ <CONTEXT>
169
+ {context}
170
+ </CONTEXT>
171
+ User's Question: {query}
172
+ Based *only* on the context provided, answer the user's question in polite Thai.
173
+ """
174
+
175
+ # print("🧠 Generating response from context...")
176
+ try:
177
+ response = specialized_llm.generate_content(final_prompt)
178
+ ai_response_content = response.text or ""
179
+ clean_response = re.sub(r"<[^>]+>|#+", "", ai_response_content).strip()
180
+ # print(f"✅ RAG process completed.")
181
+ return clean_response
182
+ except Exception as e:
183
+ print(f"‼️ ERROR during RAG LLM generation: {e}")
184
+ return "ขออภัยค่ะ เกิดข้อผิดพลาดในการสร้างคำตอบ"
185
+
186
+
187
+ # --- Tool 2: Query Existing Customer Policy ---
188
+ @observe(name="Customer_Flow")
189
+ def query_customer_policy(
190
+ agent_instance,
191
+ customer_identifier: Annotated[str, "The customer's identification information, such as their full name ('Firstname Lastname') or their 13-digit National ID number, as provided by the user."],
192
+ question: Annotated[str, "The specific question the customer is asking about their policy. For example: 'When is my next payment due?', 'Summarize my coverage', or 'What is my policy status?'"]
193
+ ) -> str:
194
+ """Use this tool when an existing customer wants to 'check', 'review', or 'see' their personal policy information.
195
+ This tool retrieves the customer's policy data from the database using their identifier,
196
+ summarizes the relevant information based on their question, and also identifies potential upsell opportunities."""
197
+ # print(f"🛠️ Tool Called: query_customer_policy(identifier='{customer_identifier}')")
198
+
199
+ # find_customer_data
200
+ found_data_df = customer_data_handler.find_customer_data(customer_identifier) # return df
201
+ if found_data_df is None or found_data_df.empty:
202
+ return f"ขออภัยค่ะ ไม่พบข้อมูลของคุณ '{customer_identifier}' ในระบบ รบกวนตรวจสอบการสะกดอีกครั้งค่ะ"
203
+
204
+ agent_instance.set_customer_context(found_data_df)
205
+
206
+ # เตรียม Prompt
207
+ customer_name = f"{found_data_df.iloc[0].get('insured_firstname', '')} {found_data_df.iloc[0].get('insured_lastname', '')}".strip()
208
+ policy_data_json = customer_data_handler.translate_and_format_data(found_data_df)
209
+ prompt_string = CUSTOMER_DATA_SUMMARY_PROMPT.format(
210
+ customer_name=customer_name,
211
+ original_question=question,
212
+ policy_data_json=policy_data_json
213
+ )
214
+
215
+ # LLM Generate
216
+ try:
217
+ response = specialized_llm.generate_content(prompt_string)
218
+ summary = response.text
219
+
220
+ # 4. แปะ Upsell (ถ้ามี)
221
+ gaps = customer_data_handler.find_recommendation_gaps(found_data_df) # # วิเคราะห์ข้อมูลกรมธรรม์ของลูกค้าเพื่อหาผลิตภัณฑ์ที่น่าแนะนำเพิ่มเติม (Gap Analysis) โดยพิจารณาจาก Age และ Salary
222
+ upsell_text = customer_data_handler.generate_upsell_text_from_gaps(gaps)
223
+ return summary + upsell_text
224
+ except Exception as e:
225
+ print(f"‼️ ERROR during customer data summary generation: {e}")
226
+ return "ขออภัยค่ะ เกิดข้อผิดพลาดในการสรุปข้อมูลกรมธรรม์ของท่าน"
227
+
228
+
229
+ # --- Tool 3: New Customer Recommendation ---
230
+ @observe(name="Recommendation_Flow")
231
+ def get_new_customer_recommendation(
232
+ agent_instance,
233
+ age: Annotated[int, "อายุ"],
234
+ gender: Annotated[str, "เพศ"],
235
+ salary: Annotated[int, "รายได้"],
236
+ interest: Annotated[str, "ความสนใจ"] = "ประกันทั่วไป"
237
+ ) -> str:
238
+ # print(f"🛠️ Tool Called: get_new_customer_recommendation(...)")
239
+
240
+ gender_code = 'M' if any(g in gender for g in ['ชาย', 'male']) else 'F'
241
+
242
+ # --- [แก้ไข] เรียกใช้ฟังก์ชัน Sync ได้โดยตรง ---
243
+ recommendation_data = recommendation_handler.generate_recommendation_from_profile(
244
+ age=int(age), # แปลงเป็น int เพื่อความแน่นอน
245
+ gender=gender_code,
246
+ salary=int(salary), # แปลงเป็น int เพื่อความแน่นอน
247
+ original_interest=interest
248
+ )
249
+
250
+ if recommendation_data.get("error"):
251
+ return f"ขออภัยค่ะ ไม่สามารถสร้างคำแนะนำได้: {recommendation_data['error']}"
252
+
253
+ prompt_string = RECOMMENDATION_PROMPT.format(**recommendation_data)
254
+
255
+ try:
256
+ response = specialized_llm.generate_content(prompt_string)
257
+ return response.text
258
+ except Exception as e:
259
+ return f"ขออภัยค่ะ เกิดข้อผิดพลาดในการสร้างคำแนะนำ: {e}"
260
+
261
+
262
+ # --- Tool 4: Recommend for existing customers ---
263
+ @observe(name="Recommendation_existing_Flow")
264
+ def recommend_for_existing_customer(
265
+ agent_instance,
266
+ interest: Annotated[Optional[str], "An optional parameter for the customer's specific, newly-stated interest (e.g., 'accident insurance', 'investment plans'). Use this to filter the recommendation. If the user doesn't specify an interest, this can be omitted."] = None
267
+ ) -> str:
268
+ """
269
+ Use this tool to provide additional product recommendations to a KNOWN, IDENTIFIED customer whose data is already loaded in the agent's context.
270
+ This is the correct tool for an existing customer who asks 'what else should I get?', 'can you recommend something for accidents?', or 'I want to add investment coverage'.
271
+
272
+ CRITICAL: This tool should ONLY be used AFTER the customer's context has been successfully set (e.g., after a successful call to `query_customer_policy`). It relies on the agent's memory.
273
+ """
274
+ # print(f"🛠️ Tool Called: recommend_for_existing_customer(interest='{interest}')")
275
+
276
+ # 1) ดึงข้อมูลลูกค้าจากหน่วยความจำของ Agent
277
+ customer_df = agent_instance.get_customer_context()
278
+ if customer_df is None or customer_df.empty:
279
+ return "CONTEXT_NOT_FOUND_ASK_USER_TO_IDENTIFY"
280
+
281
+ # 2) Gap Analysis เพื่อหาผลิตภัณฑ์ทั้งหมดที่ลูกค้ายังขาด
282
+ all_gaps = customer_data_handler.find_recommendation_gaps(customer_df) # วิเคราะห์ข้อมูลกรมธรรม์ของลูกค้าเพื่อหาผลิตภัณฑ์ที่น่าแนะนำเพิ่มเติม (Gap Analysis) โดยพิจารณาจาก Age และ Salary
283
+
284
+ if not all_gaps: # ไม่มี
285
+ return "จากการตรวจสอบข้อมูล พบว่าท่านมีความคุ้มครองที่ครอบคลุมดีอยู่แล้วค่ะ หากมีคำถามอื่นๆ สอบถามได้เลยนะคะ"
286
+
287
+ products_to_recommend = all_gaps # เริ่มต้นด้วย gaps ทั้งหมด
288
+
289
+ # 3) กรอง Gaps ตาม Interest ที่ได้รับมา ---
290
+ if interest:
291
+ target_type = None
292
+ if "อุบัติเหตุ" in interest:
293
+ target_type = "ประกันอุบัติเหตุ"
294
+ elif "ลงทุน" in interest or "ออม" in interest:
295
+ target_type = "ประกันเพื่อการลงทุน"
296
+ elif "สุขภาพ" in interest:
297
+ target_type = "ประกันสุขภาพ"
298
+ elif "ชีวิต" in interest:
299
+ target_type = "ประกันคุ้มครองชีวิต"
300
+
301
+ if target_type:
302
+ filtered_gaps = [p for p in all_gaps if p.get('insurance_type') == target_type]
303
+ if filtered_gaps:
304
+ # print(f"-> Filtering gaps by interest: '{target_type}'.")
305
+ products_to_recommend = filtered_gaps
306
+ else:
307
+ # ถ้ากรองแล้วไม่เจอ Gap ที่ตรงกับความสนใจเลย
308
+ return f"จากการตรวจสอบข้อมูล พบว่าท่านมีความคุ้มครองที่ดีในด้าน '{target_type}' อยู่แล้ว หรือไม่มีผลิตภัณฑ์ประเภทนี้ที่แนะนำเพิ่มเติมสำหรับโปรไฟล์ของท่านในขณะนี้ค่ะ"
309
+
310
+ # ----------------------------------------------------
311
+
312
+ # 4) LLM สร้างคำแนะนำจาก `products_to_recommend`
313
+ customer_info = customer_df.iloc[0]
314
+ persona = next((p for p in customer_data_handler.PERSONAS.values() if p.get("age_min", -1) <= customer_info.get('insured_age_latest') <= p.get("age_max", -1)), {})
315
+ # [('young_adult', {...}), ('mid_career', {...}), ('pre_retirement', {...}), ...]
316
+
317
+ main_plans = [p for p in products_to_recommend if p.get('plan_type') == 'Basic']
318
+ riders = [p for p in products_to_recommend if p.get('plan_type') == 'Rider']
319
+
320
+ main_plans_str = "\n".join([f"• **{p['product_name']}**: {p['product_description']}" for p in main_plans]) if main_plans else "ไม่มีแผนประกันหลักแนะนำเพิ่มเติมในหมวดนี้"
321
+ riders_str = "\n".join([f"• **{p['product_name']}**: {p['product_description']}" for p in riders]) if riders else "ไม่มีสัญญาเพิ่มเติมแนะนำในหมวดนี้"
322
+
323
+ interest_category_for_prompt = interest if interest else "แผนประกันที่เหมาะสมเพิ่มเติม"
324
+
325
+ recommendation_data = {
326
+ "age": customer_info.get('insured_age_latest'),
327
+ "gender": customer_info.get('insured_gender'),
328
+ "salary": f"{customer_info.get('insured_salary'):,}",
329
+ "persona_name": persona.get('persona_name', 'ลูกค้าปัจจุบัน'),
330
+ "persona_description": f"ลูกค้าปัจจุบันที่ต้องการคำแนะนำเพิ่มเติมเกี่ยวกับ '{interest_category_for_prompt}'",
331
+ "original_interest": interest_category_for_prompt,
332
+ "main_plans_str": main_plans_str, "riders_str": riders_str,
333
+ "auto_added_main_plan": False, "searched_outside_tier": False,
334
+ "interest_category": interest_category_for_prompt
335
+ }
336
+
337
+ prompt_string = RECOMMENDATION_PROMPT.format(**recommendation_data)
338
+ try:
339
+ response = specialized_llm.generate_content(prompt_string)
340
+ return response.text
341
+ except Exception as e:
342
+ return f"ขออภัยค่ะ เกิดข้อผิดพลาดในการสร้างคำแนะนำ: {e}"
app_p/utils/prompts.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # --- Prompt สำหรับสรุปข้อมูลลูกค้า ---
2
+ CUSTOMER_DATA_SUMMARY_PROMPT = """
3
+ You are a helpful and factual AI assistant for Rabbit Life. Your primary task is to summarize the customer's full policy details in a clear, bulleted list based *only* on the provided data.
4
+
5
+ //-- Persona & Tone --//
6
+ - You are a professional and caring female Thai assistant.
7
+ - Use polite particles ("ค่ะ", "นะคะ").
8
+ - **Pronoun Control (CRITICAL RULE):** You MUST refer to yourself as "เรา" (we/us) or "ทางเรา" (on our part). You are STRICTLY FORBIDDEN from using "ดิฉัน" (I/me) under any circumstances. This is a non-negotiable rule. No exceptions.
9
+
10
+ //-- Data Dictionary (for interpreting codes) --//
11
+ Use this dictionary to explain the meaning of codes found in the policy data.
12
+ **policy_status (สถานะกรมธรรม์):**
13
+ - 'I' (Inforce): กรมธรรม์มีผลบังคับ
14
+ - 'L' (Lapse): กรมธรรม์ขาดผลบังคับ
15
+ - 'X' (Expired): กรมธรรม์หมดอายุ
16
+ - 'F' (Maturity): กรมธรรม์ครบกำหนดสัญญา
17
+
18
+ //-- Execution --//
19
+ 1. **Start with the Customer's Name:** Begin with "สำหรับข้อมูลกรมธรรม์ของคุณ {customer_name} มีรายละเอียดดังนี้ค่ะ:".
20
+ 2. **Summarize All Policies:** Present all policy information from the `Retrieved Customer Policy Data` in a well-structured list.
21
+ 3. **Provide a Concluding Summary (If Necessary):**
22
+ - After the list, re-read the `User's Original Question`.
23
+ - If the question asks for a **specific piece of information** (due date, status, etc.).
24
+ - After the bulleted list, if the original question was specific, add a "**สรุปสำหรับคำถามของท่าน:**" section.
25
+ - If the question is a general request (e.g., "ขอดูข้อมูล"), DO NOT add the concluding summary section.
26
+ 4. **Do Not Translate:** Keep product names in English.
27
+
28
+ ---
29
+ **Customer's Name:** {customer_name}
30
+ **User's Original Question:** "{original_question}"
31
+
32
+ **Retrieved Customer Policy Data (in JSON format):**
33
+ {policy_data_json}
34
+
35
+ ---
36
+ **Your Summary in Thai (following all instructions):**
37
+ """
38
+
39
+
40
+ # --- Prompt สำหรับแนะนำผลิตภัณฑ์ ---
41
+ RECOMMENDATION_PROMPT = """
42
+ You are an expert Rabbit Life insurance advisor. Your goal is to provide a personalized, friendly, and clear recommendation in Thai.
43
+
44
+ //-- Persona & Tone --//
45
+ - You are a professional and caring female Thai advisor.
46
+ - Use polite particles ("ค่ะ", "นะคะ").
47
+ - **Pronoun Control (CRITICAL RULE):** You MUST refer to yourself as "เรา" (we/us) or "ทางเรา" (on our part). You are STRICTLY FORBIDDEN from using "ดิฉัน" (I/me) under any circumstances. This is a non-negotiable rule. No exceptions.
48
+
49
+ //-- Instructions --//
50
+ 1. **Opening Statement:** Start by acknowledging the user's Persona and their Original Interest.
51
+ - **Correct Example:** "สำหรับกลุ่ม {persona_name} ที่กำลังมองหา{interest_category}โดยเฉพาะ ทางเราขอแนะนำแผนที่เหมาะสมดังนี้ค่ะ:"
52
+
53
+ 2. **Handle Special Cases (IMPORTANT):**
54
+ - **Case A (Searched Outside Tier):** If `searched_outside_tier` is `True`, you MUST add this exact Thai sentence:
55
+ - `"สำหรับความสนใจใน{interest_category}ของท่าน ถึงแม้ในกลุ่มโปรไฟล์ของท่านจะยังไม่มีแผนที่ตรงกันโดยเฉพาะ แต่ทางเราขอแนะนำแผนที่ใกล้เคียงและเป็นที่นิยมดังนี้ค่ะ:"`
56
+ - **Case B (Auto-Added Main Plan):** If `auto_added_main_plan` is `True`, you MUST add this exact Thai sentence:
57
+ - `"เพื่อให้ท่านได้รับความคุ้มครองที่ตรงใจที่สุดอย่างสัญญาเพิ่มเติมที่ท่านสนใจ ทางเราได้จับคู่กับแผนประกันหลักที่เป็นที่นิยมมาให้พิจารณาควบคู่กันค่ะ เนื่องจากสัญญาเพิ่มเติมจำเป็นต้องมีสัญญาหลักเป็นฐานความคุ้มครองนะคะ"`
58
+
59
+ 3. **Structure the Recommendation:**
60
+ - Present the **"แผนประกันหลัก (Main Plans)"** section.
61
+ - Then, present the **"สัญญาเพิ่มเติมแนะนำ (Recommended Riders)"** section.
62
+ - Use Markdown bullet points (`•`) and bolding.
63
+
64
+ 4. **Closing:** Conclude by inviting the user to ask for more details.
65
+
66
+ ---
67
+ **--- Input Data ---**
68
+ - User Profile: Age={age}, Gender={gender}, Salary={salary}
69
+ - Persona Name: {persona_name}
70
+ - Persona Description: {persona_description}
71
+ - Original Interest: "{original_interest}"
72
+ - Interest Category: "{interest_category}"
73
+ - Flags: auto_added_main_plan={auto_added_main_plan}, searched_outside_tier={searched_outside_tier}
74
+
75
+ **--- Recommended Products ---**
76
+ **แผนประกันหลักที่แนะนำ:**
77
+ {main_plans_str}
78
+ **สัญญาเพิ่มเติมที่แนะนำ:**
79
+ {riders_str}
80
+
81
+ ---
82
+ **Your Recommendation Response in Thai:**
83
+ """
app_p/utils/query_rewriter.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import google.generativeai as genai
3
+ import json
4
+
5
+ # --- สร้าง LLM สำหรับการ Rewrite โดยเฉพาะ ---
6
+ try:
7
+ genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
8
+ rewriter_model = genai.GenerativeModel('gemini-2.0-flash',
9
+ generation_config={"temperature": 0.0}
10
+ )
11
+ print("✅ Initialized Rewriter LLM.")
12
+ except Exception as e:
13
+ rewriter_model = None
14
+ print(f"‼️ ERROR initializing Rewriter LLM: {e}")
15
+
16
+
17
+ REWRITE_PROMPT_TEMPLATE = """
18
+ You are a highly precise query rewriting expert. Your one and only goal is to transform a follow-up or keyword-based question into a clear, standalone Thai question for a database search.
19
+
20
+ **Core Logic:**
21
+ 1. Analyze the `Chat History` to understand the context.
22
+ 2. Analyze the user's `Latest Input`.
23
+ 3. Combine the context and the latest input to construct a new, complete, and natural-sounding question in Thai.
24
+
25
+ **Crucial Rules:**
26
+ - The output MUST be a single, complete Thai question.
27
+ - Do not add explanations.
28
+ - If the `Latest Input` is already a complete question, just return it after minor corrections if needed.
29
+
30
+ **Example 1 (Keywords):**
31
+ - History: []
32
+ - Latest Input: "worry free cancer"
33
+ - Your Standalone Output: "ประกัน Worry Free Cancer คุ้มครองอะไรบ้าง"
34
+
35
+ **Example 2 (Follow-up):**
36
+ - History: [{"role": "user", "parts": [{"text":"Sabai Jai คืออะไร"}]}, {"role": "model", "parts": [{"text":"Sabai Jai เป็นประกัน..."}]}]
37
+ - Latest Input: "แล้วลดหย่อนภาษีได้ไหม"
38
+ - Your Standalone Output: "ประกัน Sabai Jai สามารถนำไปลดหย่อนภาษีได้หรือไม่"
39
+
40
+ ---
41
+ **Chat History:**
42
+ {chat_history}
43
+
44
+ **Latest Input:** "{question}"
45
+ **Your Standalone Output:**
46
+ """
47
+
48
+ def rewrite_query(question: str, chat_history: list) -> str:
49
+ """
50
+ Rewrites a user's query to be a standalone question using chat history.
51
+ """
52
+ if not rewriter_model:
53
+ print("-> Rewriter LLM not available. Returning original query.")
54
+ return question
55
+
56
+ print(f"🔄 Rewriting query: '{question}'")
57
+
58
+ prompt = REWRITE_PROMPT_TEMPLATE.format(
59
+ chat_history=json.dumps(chat_history[-4:]), # ใช้แค่ 2 รอบล่าสุด
60
+ question=question
61
+ )
62
+
63
+ try:
64
+ response = rewriter_model.generate_content(prompt)
65
+ rewritten = response.text.strip()
66
+ print(f"✅ Rewritten query: '{rewritten}'")
67
+ return rewritten
68
+ except Exception as e:
69
+ print(f"‼️ ERROR during query rewrite: {e}. Returning original query.")
70
+ return question
app_p/utils/reranker.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain.retrievers import ContextualCompressionRetriever
2
+ from langchain.retrievers.document_compressors import CrossEncoderReranker
3
+ from langchain_community.cross_encoders import HuggingFaceCrossEncoder
4
+ from .retriever import get_retriever
5
+
6
+ MODEL = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-base")
7
+ TOP_N = 15 # 7
8
+ COMPRESSOR = CrossEncoderReranker(model=MODEL, top_n=TOP_N)
9
+
10
+ class RerankRetriever:
11
+ def __init__(self):
12
+ pass
13
+
14
+ def get_base_retriever(self, **kwargs):
15
+ """
16
+ ส่ง kwargs ทั้งหมดไปให้ get_retriever โดยตรง
17
+ """
18
+ retriever = get_retriever(**kwargs)
19
+ return retriever
20
+
21
+ def get_compression_retriever(self, **kwargs):
22
+ """
23
+ รับ kwargs และส่งต่อไปยัง get_base_retriever
24
+ """
25
+ base_retriever_used = self.get_base_retriever(**kwargs)
26
+ compression_retriever = ContextualCompressionRetriever(
27
+ base_compressor=COMPRESSOR,
28
+ base_retriever=base_retriever_used,
29
+ )
30
+ return compression_retriever
31
+
32
+ def pretty_print_docs(self, docs):
33
+ return(f"\n{'-' * 100}\n".join([f"Document {i+1}:\n\n" + d.page_content for i, d in enumerate(docs)]))
34
+
35
+ # from langchain.retrievers import ContextualCompressionRetriever
36
+ # from langchain.retrievers.document_compressors import CrossEncoderReranker
37
+ # from langchain_community.cross_encoders import HuggingFaceCrossEncoder
38
+ # from .retriever import get_retriever
39
+
40
+ # # -- HuggingFaceCrossEncoder
41
+ # # https://python.langchain.com/docs/integrations/document_transformers/cross_encoder_reranker/
42
+
43
+
44
+ # # ---- Configurations for model ----
45
+ # MODEL = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-base")
46
+ # TOP_N = 15
47
+ # COMPRESSOR = CrossEncoderReranker(model=MODEL,
48
+ # top_n=TOP_N)
49
+
50
+
51
+ # # ---- Reranker Retriever ----
52
+ # class RerankRetriever:
53
+ # def __init__(self):
54
+ # pass
55
+
56
+ # def get_base_retriever(self, **kwargs):
57
+ # filters = {**kwargs}
58
+ # retriever = get_retriever(**filters)
59
+ # return retriever
60
+
61
+ # def get_compression_retriever(self, **kwargs):
62
+
63
+ # # ---- get_base_retriever ----
64
+ # base_retriever_used = self.get_base_retriever(**kwargs)
65
+
66
+ # # ---- Instantiate compression retriever ----
67
+ # compression_retriever = ContextualCompressionRetriever(
68
+ # base_compressor=COMPRESSOR,
69
+ # base_retriever=base_retriever_used,
70
+ # tags=["qa_retriever", "rerank"]
71
+ # )
72
+
73
+ # return compression_retriever
74
+
75
+ # def pretty_print_docs(self, docs):
76
+ # return(
77
+ # f"\n{'-' * 100}\n".join(
78
+ # [f"Document {i+1}:\n\n" + d.page_content for i, d in enumerate(docs)]
79
+ # )
80
+ # )
app_p/utils/retriever.py ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_huggingface import HuggingFaceEmbeddings
2
+ from langchain_mongodb.vectorstores import MongoDBAtlasVectorSearch
3
+ from langchain_mongodb.retrievers.hybrid_search import MongoDBAtlasHybridSearchRetriever
4
+ import os
5
+ from dotenv import load_dotenv
6
+
7
+ load_dotenv()
8
+
9
+ # ---- MongoDB credentials ----
10
+ # mongo_username = os.getenv('MONGO_USERNAME')
11
+ # mongo_password = os.getenv('MONGO_PASSWORD')
12
+ mongo_database = os.getenv('MONGO_DATABASE')
13
+ mongo_connection_str = os.getenv('MONGO_CONNECTION_STRING')
14
+ mongo_collection_name = os.getenv('MONGO_COLLECTION')
15
+
16
+ # ---- Common Configurations & Hybrid Retrieval Configuration ----
17
+ MODEL_KWARGS = {"device": "cpu"}
18
+ ENCODE_KWARGS = {"normalize_embeddings": True,
19
+ "batch_size": 32}
20
+ EMBEDDING_DIMENSIONS = 1024
21
+ MODEL_NAME = "BAAI/bge-m3"
22
+ FINAL_TOP_K = 50 # 30
23
+ HYBRID_FULLTEXT_PENALTY = 0 # 60
24
+ HYBRID_VECTOR_PENALTY = 0.8 # 60
25
+
26
+ # ---- Embedding model ----
27
+ embed_model = HuggingFaceEmbeddings(
28
+ model_name=MODEL_NAME,
29
+ model_kwargs=MODEL_KWARGS,
30
+ encode_kwargs=ENCODE_KWARGS
31
+ )
32
+
33
+ # ---- Vectore Search ----
34
+ num_vector_candidates = max(20, 2 * FINAL_TOP_K)
35
+ num_text_candidates = max(20, 2 * FINAL_TOP_K)
36
+ vector_k = num_vector_candidates
37
+ vector_num_candidates_for_operator = vector_k * 10
38
+
39
+ # ---- Vectore Store ----
40
+ vector_store = MongoDBAtlasVectorSearch.from_connection_string(
41
+ connection_string=mongo_connection_str,
42
+ namespace=f"{mongo_database}.{mongo_collection_name}",
43
+ embedding=embed_model,
44
+ index_name="search_index_v1",
45
+ )
46
+
47
+ # ---- Retriever (Hybrid) ----
48
+
49
+ def get_retriever(**kwargs):
50
+ """
51
+ สร้าง Retriever โดยสามารถรับ filter พิเศษสำหรับ Vector Search ได้
52
+ """
53
+ # ดึง vector_search_filter ออกมาจาก kwargs
54
+ vector_search_filter = kwargs.pop('vector_search_filter', None)
55
+
56
+ # kwargs ที่เหลือ (ถ้ามี) จะถูกใช้เป็น pre_filter
57
+ pre_filter = kwargs if kwargs else None
58
+
59
+ retriever = MongoDBAtlasHybridSearchRetriever(
60
+ vectorstore=vector_store,
61
+ search_index_name='search_index_v1',
62
+ embedding=embed_model,
63
+ text_key= 'text',
64
+ embedding_key='embedding',
65
+ top_k=FINAL_TOP_K,
66
+ vector_penalty=HYBRID_VECTOR_PENALTY,
67
+ fulltext_penalty=HYBRID_FULLTEXT_PENALTY,
68
+ vector_search_params={
69
+ "k": vector_k,
70
+ "numCandidates": vector_num_candidates_for_operator,
71
+ # --- ส่ง filter ที่ถูกต้องเข้าไปในตำแหน่งที่ถูกต้อง ---
72
+ "filter": vector_search_filter
73
+ },
74
+ text_search_params={
75
+ "limit": max(20, 2 * FINAL_TOP_K)
76
+ },
77
+ pre_filter=pre_filter
78
+ )
79
+ return retriever
80
+
81
+ # def get_retriever(**kwargs):
82
+ # retriever = MongoDBAtlasHybridSearchRetriever(
83
+ # vectorstore=vector_store,
84
+ # search_index_name='search_index_v1',
85
+ # embedding=embed_model,
86
+ # text_key= 'text', #'token',
87
+ # embedding_key='embedding',
88
+ # top_k=FINAL_TOP_K,
89
+ # vector_penalty=HYBRID_VECTOR_PENALTY,
90
+ # fulltext_penalty=HYBRID_FULLTEXT_PENALTY,
91
+ # vector_search_params={
92
+ # "k": vector_k,
93
+ # "numCandidates": vector_num_candidates_for_operator
94
+ # },
95
+ # text_search_params={
96
+ # "limit": num_text_candidates
97
+ # },
98
+ # pre_filter=kwargs
99
+ # )
100
+ # return retriever
101
+
102
+
103
+
104
+ # ---------- FILTER METAAAAA ----------
105
+ # ---------- FILTER METAAAAA ----------
106
+ # ---------- FILTER METAAAAA ----------
107
+ # ---------- FILTER METAAAAA ----------
108
+
109
+ # def get_retriever(**kwargs):
110
+ # # ดึง filter ที่เราจะส่งมาจาก tool ออกมาจาก kwargs
111
+ # # เราใช้ .pop() เพื่อเอามันออกมา จะได้ไม่ถูกส่งไปที่ pre_filter ซ้ำซ้อน
112
+ # search_filter = kwargs.pop('filter', None)
113
+
114
+ # retriever = MongoDBAtlasHybridSearchRetriever(
115
+ # vectorstore=vector_store,
116
+ # search_index_name='search_index_v1',
117
+ # embedding=embed_model,
118
+ # text_key= 'text',
119
+ # embedding_key='embedding',
120
+ # top_k=FINAL_TOP_K,
121
+ # vector_penalty=HYBRID_VECTOR_PENALTY,
122
+ # fulltext_penalty=HYBRID_FULLTEXT_PENALTY,
123
+ # vector_search_params={
124
+ # "k": vector_k,
125
+ # "numCandidates": vector_num_candidates_for_operator,
126
+ # "filter": search_filter
127
+ # },
128
+ # text_search_params={
129
+ # "limit": num_text_candidates
130
+ # },
131
+ # pre_filter=kwargs
132
+ # )
133
+ # return retriever
134
+
data/column_mapping.csv ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Field_name,Description
2
+ policy_no,หมายเลขกรมธรรม์
3
+ plan_type,ประเภทของแบบประกัน
4
+ policy_plan_code,รหัสแบบประกัน
5
+ policy_plan_name,ชื่อแบบประกัน
6
+ product_category,หมวดหมู่ของแบบประกัน
7
+ insured_id_number,เลขบัตรประชาชน
8
+ insured_title_name,คำนำหน้าชื่อของผู้เอาประกัน
9
+ insured_firstname,ชื่อของผู้เอาประกัน
10
+ insured_lastname,นามสกุลของผู้เอาประกัน
11
+ insured_gender,เพศของผู้เอาประกัน
12
+ insured_birthdate,วันเดือนปีเกิดของผู้เอาประกัน
13
+ insured_addr_province,จังหวัด
14
+ insured_zipcode,รหัสไปรษณีย์
15
+ insured_age_first,อายุของผู้เอาประกัน ณ วันออกเล่มกรมธรรม์
16
+ insured_age_latest,อายุของผู้เอาประกัน ณ วันที่ update ข้อมูล
17
+ insured_job_class,ชั้นอาชีพ(Occupation Class)
18
+ insured_salary,รายได้ / เงินเดือน
19
+ sale_channel,Sale Channel
20
+ policy_year,กรมธรรม์ ปีที่
21
+ policy_status,สถานะกรมธรรม์
22
+ coverage_term,จำนวนปีที่คุ้มครอง
23
+ payment_term,จำนวนปีที่ชำระเบี้ย
24
+ sum_insured_first,ทุนประกัน ณ วันเริ่มคุ้มครอง
25
+ payment_mode,ทุนประกันล่าสุดของกรมธรรม์
26
+ policy_effective_date,วันที่กรมธรรม์มีผลบังคับ
27
+ premium_duedate,วันที่ครบกำหนดการชำระเบี้ย ในงวดถัดไป
28
+ policy_expired_date,วันที่กรมธรรม์ขาดผลบังคับ
29
+ policy_maturity_date,วันที่ครบกำหนดสัญญา
30
+ total_premium,ค่าเบี้ยประกันทั้งหมดที่ลูกค้าต้องจ่าย
data/mock_customer_data.csv ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ policy_no,plan_type,policy_plan_code,policy_plan_name,product_category,insured_id_number,insured_title_name,insured_firstname,insured_lastname,insured_gender,insured_birthdate,insured_addr_province,insured_zipcode,insured_age_first,insured_age_latest,insured_job_class,insured_salary,sale_channel,policy_year,policy_status,coverage_term,payment_term,sum_insured_first,payment_mode,policy_effective_date,premium_duedate,policy_expired_date,policy_maturity_date,total_premium
2
+ 442191,Basic,QL311,Smart Term Bronze 5,High Protection,7016483658913,นาง,มณีรัตน์,ชัยอนันต์,F,1977-04-24,ภูเก็ต,83130,46,48,0,2000000,Agent,1,I,5,5,300000,A,2024-03-18,2026-03-18,,2029-03-18,2988
3
+ 442191,Rider,CD801,Health Protect (สัญญาเพิ่มเติมสุขภาพค่ารักษาพยาบาล),Rider Health,7016483658913,นาง,มณีรัตน์,ชัยอนันต์,F,1977-04-24,ภูเก็ต,83130,46,48,1,2000000,Agent,1,I,5,5,3000,A,2024-03-18,2026-03-18,,2029-03-18,13960
4
+ 442191,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,7016483658913,นาง,มณีรัตน์,ชัยอนันต์,F,1977-04-24,ภูเก็ต,83130,46,48,1,2000000,Agent,1,I,5,5,300000,A,2024-03-18,2026-03-18,,2029-03-18,0
5
+ 749864,Basic,WA681,Chai Leoy 99/20,High Protection,3643040985167,นาง,จิตร,จิตรภักดี,F,1990-02-11,อุบลราชธานี,34110,34,35,0,600000,Online,1,L,65,20,1000000,A,2024-03-16,2025-03-16,2025-03-16,2089-03-16,22000
6
+ 749864,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,3643040985167,นาง,จิตร,จิตรภักดี,F,1990-02-11,อุบลราชธานี,34110,34,35,2,600000,Online,1,L,36,36,400000,A,2024-03-16,2025-03-16,2025-03-16,2060-03-16,1260
7
+ 749864,Rider,RE191,Rider ADD (สัญญาเพิ่มเติมอุบัติเหตุ),Rider Accident,3643040985167,นาง,จิตร,จิตรภักดี,F,1990-02-11,อุบลราชธานี,34110,34,35,1,600000,Online,1,L,31,31,1000000,A,2024-03-16,2025-03-16,2025-03-16,2055-03-16,2000
8
+ 749864,Rider,SX571,Rider AI (สัญญาเพิ่มเติมอุบัติเหตุ),Rider Accident,3643040985167,นาง,จิตร,จิตรภักดี,F,1990-02-11,อุบลราชธานี,34110,34,35,2,600000,Online,1,L,31,31,500000,A,2024-03-16,2025-03-16,2025-03-16,2055-03-16,3000
9
+ 749864,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,3643040985167,นาง,จิตร,จิตรภักดี,F,1990-02-11,อุบลราชธานี,34110,34,35,1,600000,Online,1,L,20,20,1000000,A,2024-03-16,2025-03-16,2025-03-16,2044-03-16,0
10
+ 450045,Basic,AV311,PA Max (อุบัติเหตุส่วนบุคคล),Accident Protection,7610179173900,นาง,อรุณี,ปรีชาชาญ,F,1970-08-13,กระบี่,81000,53,55,2,400000,Agent,1,F,1,1,500000,A,2024-03-05,2025-03-05,2025-03-05,2025-03-05,650
11
+ 450045,Rider,SR951,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,7610179173900,นาง,อรุณี,ปรีชาชาญ,F,1970-08-13,กระบี่,81000,53,55,2,400000,Agent,1,X,1,1,1000,A,2024-03-05,2025-03-05,2025-03-05,2025-03-05,400
12
+ 450045,Rider,QV321,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ),Rider Accident,7610179173900,นาง,อรุณี,ปรีชาชาญ,F,1970-08-13,กระบี่,81000,53,55,2,400000,Agent,1,X,1,1,50000,A,2024-03-05,2025-03-05,2025-03-05,2025-03-05,2150
13
+ 670732,Basic,VR531,PA Prompt (อุบัติเหตุส่วนบุคคล),Accident Protection,3058139555839,นาง,กรกช,พงษ์พิทักษ์,F,1995-02-07,กระบี่,81130,29,30,2,350000,Online,1,F,1,1,500000,A,2024-03-02,2025-03-02,2025-03-02,2025-03-02,575
14
+ 670732,Rider,EL661,PA Prompt (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ),Rider Accident,3058139555839,นาง,กรกช,พงษ์พิทักษ์,F,1995-02-07,กระบี่,81130,29,30,2,350000,Online,1,X,1,1,50000,A,2024-03-02,2025-03-02,2025-03-02,2025-03-02,1825
15
+ 739608,Rider,CD801,Health Protect (สัญญาเพิ่มเติมสุขภาพค่ารักษาพยาบาล),Rider Health,2590058123425,เด็กชาย,ศรัญญู,ชัยอนันต์,M,2017-07-07,สิงห์บุรี,16150,6,8,1,0,Online,1,I,93,93,4000,A,2024-03-01,2026-03-01,,2117-03-01,16977
16
+ 739608,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,2590058123425,เด็กชาย,ศรัญญู,ชัยอนันต์,M,2017-07-07,สิงห์บุรี,16150,6,8,1,0,Online,1,I,64,64,1000,A,2024-03-01,2026-03-01,,2088-03-01,1230
17
+ 986261,Basic,WA681,Chai Leoy 99/20,High Protection,5692904038434,นาง,ปราณี,สมานมิตร,F,1980-01-22,ปทุมธานี,12120,44,45,0,240000,Agent,1,I,55,20,200000,S,2024-03-20,2025-09-20,,2079-03-20,2891
18
+ 423303,Basic,WA681,Chai Leoy 99/20,High Protection,5306862064774,นาง,ลลิตา,ประคอง,F,2000-03-22,กรุงเทพมหานคร,10120,23,25,0,240000,Online,1,L,76,20,500000,A,2024-03-13,2025-03-13,2025-03-13,2100-03-13,8700
19
+ 423303,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,5306862064774,นาง,ลลิตา,ประคอง,F,2000-03-22,กรุงเทพมหานคร,10120,23,25,1,240000,Online,1,L,20,20,500000,A,2024-03-13,2025-03-13,2025-03-13,2044-03-13,0
20
+ 260073,Basic,BY621,Sabai Jai 14/5,Protection + Saving,6205518668563,นาง,อาภรณ์,ภูมิใจดี,F,1998-02-13,กรุงเทพมหานคร,10230,26,27,0,192000,Telesale,1,L,14,5,30000,M,2024-03-20,2025-06-20,2025-06-20,2038-03-20,1345
21
+ 260073,Rider,CD801,Health Protect (สัญญาเพิ่มเติมสุขภาพค่ารักษาพยาบาล),Rider Health,6205518668563,นาง,อาภรณ์,ภูมิใจดี,F,1998-02-13,กรุงเทพมหานคร,10230,26,27,3,192000,Telesale,1,L,14,14,1000,M,2024-03-20,2025-06-20,2025-06-20,2038-03-20,543
22
+ 506065,Rider,CD801,Health Protect (สัญญาเพิ่มเติมสุขภาพค่ารักษาพยาบาล),Rider Health,7874254084263,เด็กชาย,ก้องเกียรติ,เกียรติก้อง,M,2015-04-30,สิงห์บุรี,16150,8,10,1,0,Telesale,1,I,91,91,4000,A,2024-03-01,2026-03-01,,2115-03-01,16977
23
+ 506065,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,7874254084263,เด็กชาย,ก้องเกียรติ,เกียรติก้อง,M,2015-04-30,สิงห์บุรี,16150,8,10,1,0,Telesale,1,I,62,62,1000,A,2024-03-01,2026-03-01,,2086-03-01,1230
24
+ 479540,Basic,WA681,Chai Leoy 99/20,High Protection,9512485369924,นาง,จารุวรรณ,ก้องเกียรติ,F,1956-11-28,กรุงเทพมหานคร,10210,67,69,0,120000,Agent,1,I,32,20,500000,A,2024-03-28,2026-03-28,,2056-03-28,36990
25
+ 150664,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,3611533423811,นาง,อารีย์,สมบูรณ์ทรัพย์,F,1999-04-12,นนทบุรี,11120,24,26,1,200000,Agent,1,I,5,5,200000,M,2024-03-05,2025-07-05,,2029-03-05,0
26
+ 937642,Basic,AV311,PA Max (อุบัติเหตุส่วนบุคคล),Accident Protection,3719182372672,นาง,วรางค์,อธิชาติ,F,2008-10-02,นนทบุรี,11000,15,17,1,0,Agent,1,F,1,1,500000,A,2024-03-07,2025-03-07,2025-03-07,2025-03-07,375
27
+ 937642,Rider,SR951,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,3719182372672,นาง,วรางค์,อธิชาติ,F,2008-10-02,นนทบุรี,11000,15,17,1,0,Agent,1,X,1,1,1000,A,2024-03-07,2025-03-07,2025-03-07,2025-03-07,275
28
+ 937642,Rider,QV321,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ),Rider Accident,3719182372672,นาง,วรางค์,อธิชาติ,F,2008-10-02,นนทบุรี,11000,15,17,1,0,Agent,1,X,1,1,50000,A,2024-03-07,2025-03-07,2025-03-07,2025-03-07,1750
29
+ 743158,Basic,HT861,High Protect 3/3,High Protection,2328730438207,นาง,ทิพย์,ทองพูล,F,1966-04-24,กรุงเทพมหานคร,10300,57,59,0,480000,Telesale,1,I,3,3,150000,A,2024-03-15,2026-03-15,,2027-03-15,8850
30
+ 743158,Rider,CD801,Health Protect (สัญญาเพิ่มเติมสุขภาพค่ารักษาพยาบาล),Rider Health,2328730438207,นาง,ทิพย์,ทองพูล,F,1966-04-24,กรุงเทพมหานคร,10300,57,59,2,480000,Telesale,1,I,3,3,800,A,2024-03-15,2026-03-15,,2027-03-15,7640
31
+ 866289,Basic,AV311,PA Max (อุบัติเหตุส่วนบุคคล),Accident Protection,6136952063580,นาง,ปาริชาติ,นพรัตน์,F,1998-03-11,นครราชสีมา,30000,26,27,1,110000,Online,1,F,1,1,500000,A,2024-03-19,2025-03-19,2025-03-19,2025-03-19,375
32
+ 866289,Rider,SR951,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,6136952063580,นาง,ปาริชาติ,นพรัตน์,F,1998-03-11,นครราชสีมา,30000,26,27,1,110000,Online,1,X,1,1,1000,A,2024-03-19,2025-03-19,2025-03-19,2025-03-19,275
33
+ 866289,Rider,QV321,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ),Rider Accident,6136952063580,นาง,ปาริชาติ,นพรัตน์,F,1998-03-11,นครราชสีมา,30000,26,27,1,110000,Online,1,X,1,1,50000,A,2024-03-19,2025-03-19,2025-03-19,2025-03-19,1750
34
+ 937197,Basic,FO311,Smart Wellness 90/15,High Protection,7415810859380,นาง,อาภรณ์,รุ่งเรือง,F,1992-10-02,นนทบุรี,11110,31,33,0,600000,Online,1,L,59,15,220000,A,2024-03-21,2025-03-21,2025-03-21,2083-03-21,40920
35
+ 937197,Rider,RE191,Rider ADD (สัญญาเพิ่มเติมอุบัติเหตุ),Rider Accident,7415810859380,นาง,อาภรณ์,รุ่งเรือง,F,1992-10-02,นนทบุรี,11110,31,33,1,600000,Online,1,L,34,34,200000,A,2024-03-21,2025-03-21,2025-03-21,2058-03-21,400
36
+ 134152,Basic,QL311,Smart Term Bronze 5,High Protection,6765695626370,นาง,ณปภัช,ธนกฤต,F,2001-08-01,เชียงใหม่,50100,22,24,0,60000,Online,1,L,5,5,900000,A,2024-03-11,2025-03-11,2025-03-11,2029-03-11,4500
37
+ 134152,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,6765695626370,นาง,ณปภัช,ธนกฤต,F,2001-08-01,เชียงใหม่,50100,22,24,1,60000,Online,1,L,5,5,900000,A,2024-03-11,2025-03-11,2025-03-11,2029-03-11,0
38
+ 617253,Rider,CD801,Health Protect (สัญญาเพิ่มเติมสุขภาพค่ารักษาพยาบาล),Rider Health,2212070725237,นาง,พิมพ์,รุ่งเรือง,F,1980-03-25,กรุงเทพมหานคร,10900,43,45,1,400000,Online,1,I,56,56,2000,A,2024-03-01,2026-03-01,,2080-03-01,11030
39
+ 617253,Rider,HE351,PA Prompt (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,2212070725237,นาง,พิมพ์,รุ่งเรือง,F,1980-03-25,กรุงเทพมหานคร,10900,43,45,1,400000,Online,1,I,56,56,1000,A,2024-03-01,2026-03-01,,2080-03-01,5090
40
+ 366337,Basic,WA681,Chai Leoy 99/20,High Protection,7731754084483,นาง,ทิพย์,ธนกฤต,F,1971-09-07,สุราษฎร์ธานี,84100,52,54,0,439800,Agent,1,L,47,20,200000,A,2024-03-20,2025-03-20,2025-03-20,2071-03-20,8140
41
+ 108024,Basic,UD681,Jai Jai 25/9,Protection + Saving,4731010977053,นาง,นพรัตน์,ประคอง,F,1992-12-01,สมุทรปราการ,10270,31,33,0,384000,Telesale,1,I,25,9,100000,A,2024-03-16,2026-03-16,,2049-03-16,21000
42
+ 204007,Basic,FO311,Smart Wellness 90/15,High Protection,7891069257371,นาง,ขวัญ,ศรีสวัสดิ์,F,1997-07-10,เชียงใหม่,50120,26,28,0,120000,Online,1,I,64,15,175000,A,2024-03-19,2025-03-19,2024-04-02,2088-03-19,32025
43
+ 675845,Basic,HT861,High Protect 3/3,High Protection,7378907523269,นาง,ประเสริฐสุข,รัตนรักษ์,F,1978-01-05,กาญจนบุรี,71000,46,47,0,144000,Agent,1,I,3,3,150000,M,2024-03-18,2025-06-18,,2027-03-18,743
44
+ 849424,Basic,BY621,Sabai Jai 14/5,Protection + Saving,9756718110383,นาง,กรกช,ลิขิตธรรม,F,1966-08-05,กรุงเทพมหานคร,10520,57,59,0,180000,Online,1,I,14,5,30000,M,2024-03-20,2025-06-20,,2038-03-20,1345
45
+ 666343,Basic,WA681,Chai Leoy 99/20,High Protection,7780218270149,นาง,ประเสริฐสุข,ธีรวุฒิ,F,1963-11-28,กรุงเทพมหานคร,10510,60,62,0,1200000,Online,1,I,39,20,2000000,A,2024-03-28,2026-03-28,,2063-03-28,99200
46
+ 666343,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,7780218270149,นาง,ประเสริฐสุข,ธีรวุฒิ,F,1963-11-28,กรุงเทพมหานคร,10510,60,62,1,1200000,Online,1,I,10,10,200000,A,2024-03-28,2026-03-28,,2034-03-28,7680
47
+ 724493,Basic,FO311,Smart Wellness 90/15,High Protection,5679953663419,นาง,ณปภัช,มณีรัตน์,F,1992-09-14,กรุงเทพมหานคร,10160,31,33,0,1000000,Telesale,1,I,59,15,270000,A,2024-03-21,2026-03-21,,2083-03-21,50220
48
+ 724493,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,5679953663419,นาง,ณปภัช,มณีรัตน์,F,1992-09-14,กรุงเทพมหานคร,10160,31,33,1,1000000,Telesale,1,I,15,15,270000,A,2024-03-21,2026-03-21,,2039-03-21,0
49
+ 844680,Basic,WA681,Chai Leoy 99/20,High Protection,4295456225055,นาง,ปวีณา,มงคลชัย,F,1991-02-20,สมุทรสาคร,74000,33,34,0,6000000,Agent,1,I,66,20,300000,A,2024-03-21,2026-03-21,,2090-03-21,6450
50
+ 453185,Basic,BY621,Sabai Jai 14/5,Protection + Saving,4801623234650,นาง,มยุรา,ภูมินทร์,F,1995-05-07,กรุงเทพมหานคร,10160,28,30,0,180000,Agent,1,I,14,5,40000,A,2024-03-20,2026-03-20,,2038-03-20,19920
51
+ 149741,Basic,FO311,Smart Wellness 90/15,High Protection,8719321585861,นาง,ฐาปนีย์,ภักดีพงษ์,F,1998-03-23,ลำปาง,52210,25,27,0,400000,Telesale,1,L,65,15,100000,M,2024-03-20,2025-02-20,2025-02-20,2089-03-20,1629
52
+ 149741,Rider,RE191,Rider ADD (สัญญาเพิ่มเติมอุบัติเหตุ),Rider Accident,8719321585861,นาง,ฐาปนีย์,ภักดีพงษ์,F,1998-03-23,ลำปาง,52210,25,27,1,400000,Telesale,1,L,40,40,300000,M,2024-03-20,2025-02-20,2025-02-20,2064-03-20,54
53
+ 149741,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,8719321585861,นาง,ฐาปนีย์,ภักดีพงษ์,F,1998-03-23,ลำปาง,52210,25,27,1,400000,Telesale,1,L,15,15,100000,M,2024-03-20,2025-02-20,2025-02-20,2039-03-20,0
54
+ 155118,Basic,AV311,PA Max (อุบัติเหตุส่วนบุคคล),Accident Protection,8484069723355,นาง,ฐาปนีย์,ประเสริฐสุข,F,1971-05-07,นนทบุรี,11000,52,54,1,400000,Telesale,1,F,1,1,500000,A,2024-03-07,2025-03-07,2025-03-07,2025-03-07,375
55
+ 155118,Rider,SR951,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,8484069723355,นาง,ฐาปนีย์,ประเสริฐสุข,F,1971-05-07,นนทบุรี,11000,52,54,1,400000,Telesale,1,X,1,1,1000,A,2024-03-07,2025-03-07,2025-03-07,2025-03-07,275
56
+ 155118,Rider,QV321,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ),Rider Accident,8484069723355,นาง,ฐาปนีย์,ประเสริฐสุข,F,1971-05-07,นนทบุรี,11000,52,54,1,400000,Telesale,1,X,1,1,50000,A,2024-03-07,2025-03-07,2025-03-07,2025-03-07,1750
57
+ 277149,Basic,WA681,Chai Leoy 99/20,High Protection,2952505425202,นาง,รัตนาภรณ์,อภิรักษ์,F,1995-08-27,กรุงเทพมหานคร,10250,28,30,0,3000000,Agent,1,L,71,20,500000,A,2024-03-21,2025-03-21,2025-03-21,2095-03-21,9650
58
+ 277149,Rider,RE191,Rider ADD (สัญญาเพิ่มเติมอุบัติเหตุ),Rider Accident,2952505425202,นาง,รัตนาภรณ์,อภิรักษ์,F,1995-08-27,กรุงเทพมหานคร,10250,28,30,1,3000000,Agent,1,L,37,37,200000,A,2024-03-21,2025-03-21,2025-03-21,2061-03-21,400
59
+ 277149,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,2952505425202,นาง,รัตนาภรณ์,อภิรักษ์,F,1995-08-27,กรุงเทพมหานคร,10250,28,30,1,3000000,Agent,1,L,20,20,500000,A,2024-03-21,2025-03-21,2025-03-21,2044-03-21,0
60
+ 131606,Basic,AV311,PA Max (อุบัติเหตุส่วนบุคคล),Accident Protection,9297615335947,นาง,ภารดี,ปัญญาวุฒิ,F,1981-08-12,กรุงเทพมหานคร,10700,42,44,1,800000,Telesale,1,F,1,1,1000000,A,2024-03-11,2025-03-11,2025-03-11,2025-03-11,750
61
+ 131606,Rider,SR951,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,9297615335947,นาง,ภารดี,ปัญญาวุฒิ,F,1981-08-12,กรุงเทพมหานคร,10700,42,44,1,800000,Telesale,1,X,1,1,1000,A,2024-03-11,2025-03-11,2025-03-11,2025-03-11,275
62
+ 973388,Basic,WA681,Chai Leoy 99/20,High Protection,9237419494236,นาง,วรางค์,มงคลชัย,F,1979-04-02,สมุทรปราการ,10130,44,46,0,360000,Telesale,1,L,55,20,200000,M,2024-03-20,2024-08-20,2024-08-20,2079-03-20,574
63
+ 702104,Basic,WA681,Chai Leoy 99/20,High Protection,8177665592728,นาง,ปรีชาชาญ,พรมพิทักษ์,F,2008-09-16,สุรินทร์,32150,15,17,0,120000,Online,1,L,84,20,200000,M,2024-03-18,2024-05-18,2024-05-18,2108-03-18,268
64
+ 702104,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,8177665592728,นาง,ปรีชาชาญ,พรมพิทักษ์,F,2008-09-16,สุรินทร์,32150,15,17,1,120000,Online,1,L,55,55,500,M,2024-03-18,2024-05-18,2024-05-18,2079-03-18,47
65
+ 913651,Basic,AV311,PA Max (อ��บัติเหตุส่วนบุคคล),Accident Protection,7962822848878,นาง,จิตร,พูนทรัพย์,F,1974-07-23,กรุงเทพมหานคร,10160,49,51,1,600000,Agent,1,F,1,1,1000000,A,2024-03-01,2025-03-01,2025-03-01,2025-03-01,750
66
+ 913651,Rider,SR951,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,7962822848878,นาง,จิตร,พูนทรัพย์,F,1974-07-23,กรุงเทพมหานคร,10160,49,51,1,600000,Agent,1,X,1,1,1000,A,2024-03-01,2025-03-01,2025-03-01,2025-03-01,275
67
+ 913651,Rider,QV321,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ),Rider Accident,7962822848878,นาง,จิตร,พูนทรัพย์,F,1974-07-23,กรุงเทพมหานคร,10160,49,51,1,600000,Agent,1,X,1,1,100000,A,2024-03-01,2025-03-01,2025-03-01,2025-03-01,3275
68
+ 882092,Basic,QL311,Smart Term Bronze 5,High Protection,4558787709044,นาง,วรางค์,อภิรักษ์,F,1994-06-09,กำแพงเพชร,62180,29,31,0,1200000,Agent,1,I,5,5,500000,A,2024-03-19,2026-03-19,,2029-03-19,2675
69
+ 882092,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,4558787709044,นาง,วรางค์,อภิรักษ์,F,1994-06-09,กำแพงเพชร,62180,29,31,2,1200000,Agent,1,I,5,5,3000,A,2024-03-19,2026-03-19,,2029-03-19,3810
70
+ 740268,Basic,QL311,Smart Term Bronze 5,High Protection,4558787709044,นาง,วรางค์,อภิรักษ์,F,1994-06-09,กำแพงเพชร,62180,29,31,0,1200000,Agent,1,I,5,5,800000,A,2024-03-19,2026-03-19,,2029-03-19,4280
71
+ 740268,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,4558787709044,นาง,วรางค์,อภิรักษ์,F,1994-06-09,กำแพงเพชร,62180,29,31,2,1200000,Agent,1,I,5,5,2000,A,2024-03-19,2026-03-19,,2029-03-19,2540
72
+ 730322,Basic,FO311,Smart Wellness 90/15,High Protection,4808016557272,นางสาว,พิมพ์,นาคะมโน,F,2002-01-14,ลำพูน,51000,22,23,0,144000,Agent,1,I,68,15,100000,A,2024-03-20,2026-03-20,,2092-03-20,17400
73
+ 730322,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,4808016557272,นางสาว,พิมพ์,นาคะมโน,F,2002-01-14,ลำพูน,51000,22,23,1,144000,Agent,1,I,15,15,100000,A,2024-03-20,2026-03-20,,2039-03-20,0
74
+ 387555,Basic,WA681,Chai Leoy 99/20,High Protection,2535256383550,นางสาว,ประเสริฐสุข,สมานมิตร,F,1987-10-24,เชียงใหม่,50100,36,38,0,180000,Agent,1,L,63,20,660000,A,2024-03-11,2025-03-11,2025-03-11,2087-03-11,15180
75
+ 387555,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,2535256383550,นางสาว,ประเสริฐสุข,สมานมิตร,F,1987-10-24,เชียงใหม่,50100,36,38,1,180000,Agent,1,L,20,20,660000,A,2024-03-11,2025-03-11,2025-03-11,2044-03-11,0
76
+ 686426,Basic,WA681,Chai Leoy 99/20,High Protection,4488600604074,นางสาว,ปรีชาชาญ,จรูญศักดิ์,F,1965-01-08,นนทบุรี,11140,59,60,0,180000,Online,1,I,40,20,200000,S,2024-03-21,2025-09-21,,2064-03-21,4669
77
+ 667102,Basic,WA681,Chai Leoy 99/20,High Protection,3761845834305,นางสาว,กรกช,อัครเศรษฐ์,F,2009-12-02,กรุงเทพมหานคร,10160,14,16,0,0,Agent,1,I,85,20,300000,M,2024-03-04,2025-07-04,,2109-03-04,394
78
+ 667102,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,3761845834305,นางสาว,กรกช,อัครเศรษฐ์,F,2009-12-02,กรุงเทพมหานคร,10160,14,16,1,0,Agent,1,I,56,56,1000,M,2024-03-04,2025-07-04,,2080-03-04,95
79
+ 366445,Basic,WA681,Chai Leoy 99/20,High Protection,1598722829350,เด็กหญิง,ลลิตา,นฤมล,F,2014-09-22,ขอนแก่น,40170,9,11,0,0,Telesale,1,L,90,20,300000,M,2024-03-20,2025-02-20,2025-02-20,2114-03-20,361
80
+ 366445,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,1598722829350,เด็กหญิง,ลลิตา,นฤมล,F,2014-09-22,ขอนแก่น,40170,9,11,2,0,Telesale,1,L,61,61,2000,M,2024-03-20,2025-02-20,2025-02-20,2085-03-20,180
81
+ 974291,Basic,NV911,Save 5 C,High Protection,5615219268935,นางสาว,กรกช,พูนทรัพย์,F,1972-03-06,สมุทรสาคร,74000,52,53,0,600000,Online,1,I,5,5,400000,A,2024-03-11,2026-03-11,,2029-03-11,18800
82
+ 567872,Basic,QL311,Smart Term Bronze 5,High Protection,5464504911764,นางสาว,ศิริพร,ทองพูล,F,1989-05-20,ชัยภูมิ,36000,34,36,0,600000,Telesale,1,L,5,5,500000,A,2024-03-28,2025-03-28,2025-03-28,2029-03-28,4320
83
+ 567872,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,5464504911764,นางสาว,ศิริพร,ทองพูล,F,1989-05-20,ชัยภูมิ,36000,34,36,3,600000,Telesale,1,L,5,5,100000,A,2024-03-28,2025-03-28,2025-03-28,2029-03-28,351
84
+ 548733,Basic,BY621,Sabai Jai 14/5,Protection + Saving,3334788906122,นางสาว,จารุวรรณ,รัตนวงศ์,F,1980-03-30,ปทุมธานี,12130,43,45,0,480000,Online,1,I,14,5,40000,A,2024-03-20,2026-03-20,,2038-03-20,19920
85
+ 654935,Basic,QL311,Smart Term Bronze 5,High Protection,5319583601217,นางสาว,ดวงใจ,ฐาปนีย์,F,1995-07-05,ชัยภูมิ,36000,28,30,0,180000,Agent,1,L,5,5,500000,A,2024-03-11,2025-03-11,2025-03-11,2029-03-11,1725
86
+ 654935,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,5319583601217,นางสาว,ดวงใจ,ฐาปนีย์,F,1995-07-05,ชัยภูมิ,36000,28,30,2,180000,Agent,1,L,5,5,100000,A,2024-03-11,2025-03-11,2025-03-11,2029-03-11,233
87
+ 854369,Basic,AV311,PA Max (อุบัติเหตุส่วนบุคคล),Accident Protection,9788498545698,นางสาว,ประเสริฐสุข,จิตรภักดี,F,1966-04-05,กรุงเทพมหานคร,10250,57,59,1,300000,Online,1,F,1,1,500000,A,2024-03-10,2025-03-10,2025-03-10,2025-03-10,375
88
+ 854369,Rider,SR951,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,9788498545698,นางสาว,ประเสริฐสุข,จิตรภักดี,F,1966-04-05,กรุงเทพมหานคร,10250,57,59,1,300000,Online,1,X,1,1,1000,A,2024-03-10,2025-03-10,2025-03-10,2025-03-10,275
89
+ 854369,Rider,QV321,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ),Rider Accident,9788498545698,นางสาว,ประเสริฐสุข,จิตรภักดี,F,1966-04-05,กรุงเทพมหานคร,10250,57,59,1,300000,Online,1,X,1,1,50000,A,2024-03-10,2025-03-10,2025-03-10,2025-03-10,1750
90
+ 574691,Basic,WA681,Chai Leoy 99/20,High Protection,5965105152147,นางสาว,จันทิมา,สถาพร,F,1967-05-21,ลพบุรี,15130,56,58,0,360000,Agent,1,I,43,20,1000000,S,2024-03-01,2025-09-01,,2067-03-01,23400
91
+ 945982,Basic,FO311,Smart Wellness 90/15,High Protection,9351982955376,นางสาว,ดวงใจ,ชาญชัย,F,2000-12-29,เชียงใหม่,50140,23,25,0,2016000,Online,1,L,67,15,100000,A,2024-03-20,2025-03-20,2025-03-20,2091-03-20,16900
92
+ 945982,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,9351982955376,นางสาว,ดวงใจ,ชาญชัย,F,2000-12-29,เชียงใหม่,50140,23,25,1,2016000,Online,1,L,15,15,100000,A,2024-03-20,2025-03-20,2025-03-20,2039-03-20,0
93
+ 238273,Basic,AV311,PA Max (อุบัติเหตุส่วนบุคคล),Accident Protection,3733707941707,นางสาว,มณีรัตน์,รัตนรักษ์,F,1981-08-20,กรุงเทพมหานคร,10160,42,44,1,300000,Agent,1,F,1,1,500000,A,2024-03-10,2025-03-10,2025-03-10,2025-03-10,375
94
+ 238273,Rider,SR951,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,3733707941707,นางสาว,มณีรัตน์,รัตนรักษ์,F,1981-08-20,กรุงเทพมหานคร,10160,42,44,1,300000,Agent,1,X,1,1,1000,A,2024-03-10,2025-03-10,2025-03-10,2025-03-10,275
95
+ 238273,Rider,QV321,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ),Rider Accident,3733707941707,นางสาว,มณีรัตน์,รัตนรักษ์,F,1981-08-20,กรุงเทพมหานคร,10160,42,44,1,300000,Agent,1,X,1,1,50000,A,2024-03-10,2025-03-10,2025-03-10,2025-03-10,1750
96
+ 193280,Basic,AV311,PA Max (อุบัติเหตุส่วนบุคคล),Accident Protection,5086432650279,นางสาว,อรุณี,สมบูรณ์ทรัพย์,F,1971-08-14,นนทบุรี,11000,52,54,1,500000,Telesale,1,F,1,1,500000,A,2024-03-07,2025-03-07,2025-03-07,2025-03-07,375
97
+ 193280,Rider,SR951,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู��ป่วยนอก),Rider Health,5086432650279,นางสาว,อรุณี,สมบูรณ์ทรัพย์,F,1971-08-14,นนทบุรี,11000,52,54,1,500000,Telesale,1,X,1,1,1000,A,2024-03-07,2025-03-07,2025-03-07,2025-03-07,275
98
+ 193280,Rider,QV321,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ),Rider Accident,5086432650279,นางสาว,อรุณี,สมบูรณ์ทรัพย์,F,1971-08-14,นนทบุรี,11000,52,54,1,500000,Telesale,1,X,1,1,50000,A,2024-03-07,2025-03-07,2025-03-07,2025-03-07,1750
99
+ 380623,Basic,WA681,Chai Leoy 99/20,High Protection,3865983434659,นางสาว,พิสมัย,ลิขิตธรรม,F,1990-01-15,กรุงเทพมหานคร,10250,34,35,0,240000,Online,1,I,65,20,500000,A,2024-03-21,2026-03-21,,2089-03-21,11000
100
+ 380623,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,3865983434659,นางสาว,พิสมัย,ลิขิตธรรม,F,1990-01-15,กรุงเทพมหานคร,10250,34,35,2,240000,Online,1,I,20,20,500000,A,2024-03-21,2026-03-21,,2044-03-21,41
101
+ 415529,Basic,WA681,Chai Leoy 99/20,High Protection,9394733238013,นางสาว,ประเสริฐสุข,ภูมินทร์,F,1974-03-28,นนทบุรี,11130,49,51,0,2400000,Telesale,1,I,50,20,300000,A,2024-03-21,2026-03-21,,2074-03-21,9450
102
+ 415529,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,9394733238013,นางสาว,ประเสริฐสุข,ภูมินทร์,F,1974-03-28,นนทบุรี,11130,49,51,1,2400000,Telesale,1,I,21,21,2000,A,2024-03-21,2026-03-21,,2045-03-21,4200
103
+ 415529,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,9394733238013,นางสาว,ประเสริฐสุข,ภูมินทร์,F,1974-03-28,นนทบุรี,11130,49,51,1,2400000,Telesale,1,I,16,16,300000,A,2024-03-21,2026-03-21,,2040-03-21,0
104
+ 415529,Rider,HE351,PA Prompt (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,9394733238013,นางสาว,ประเสริฐสุข,ภูมินทร์,F,1974-03-28,นนทบุรี,11130,49,51,1,2400000,Telesale,1,I,50,50,2000,A,2024-03-21,2026-03-21,,2074-03-21,11680
105
+ 537813,Basic,BY621,Sabai Jai 14/5,Protection + Saving,9389951502923,นางสาว,ปวีณา,จรูญศักดิ์,F,1975-09-17,กรุงเทพมหานคร,10240,48,50,0,720000,Telesale,1,I,14,5,30000,A,2024-03-11,2026-03-11,,2038-03-11,14940
106
+ 588796,Basic,BY621,Sabai Jai 14/5,Protection + Saving,5763833667989,นางสาว,ณปภัช,อนันต์พร,F,1966-06-22,เชียงใหม่,50150,57,59,0,840000,Telesale,1,I,14,5,40000,A,2024-03-08,2026-03-08,,2038-03-08,19920
107
+ 720619,Basic,WA681,Chai Leoy 99/20,High Protection,2597290678329,นางสาว,บุญสม,ภูมิใจดี,F,1997-05-10,กรุงเทพมหานคร,10160,26,28,0,300000,Telesale,1,L,73,20,1100000,A,2024-03-18,2025-03-18,2025-03-18,2097-03-18,23540
108
+ 720619,Rider,CD801,Health Protect (สัญญาเพิ่มเติมสุขภาพค่ารักษาพยาบาล),Rider Health,2597290678329,นางสาว,บุญสม,ภูมิใจดี,F,1997-05-10,กรุงเทพมหานคร,10160,26,28,2,300000,Telesale,1,L,73,73,4000,A,2024-03-18,2025-03-18,2025-03-18,2097-03-18,10330
109
+ 720619,Rider,SX571,Rider AI (สัญญาเพิ่มเติมอุบัติเหตุ),Rider Accident,2597290678329,นางสาว,บุญสม,ภูมิใจดี,F,1997-05-10,กรุงเทพมหานคร,10160,26,28,2,300000,Telesale,1,L,39,39,500000,A,2024-03-18,2025-03-18,2025-03-18,2063-03-18,3000
110
+ 720619,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,2597290678329,นางสาว,บุญสม,ภูมิใจดี,F,1997-05-10,กรุงเทพมหานคร,10160,26,28,1,300000,Telesale,1,L,20,20,1100000,A,2024-03-18,2025-03-18,2025-03-18,2044-03-18,0
111
+ 592384,Basic,QL311,Smart Term Bronze 5,High Protection,1777999334017,นางสาว,รัตนาภรณ์,ชัยอนันต์,F,1985-05-13,ตรัง,92000,38,40,0,600000,Telesale,1,L,5,5,500000,A,2024-03-20,2025-03-20,2025-03-20,2029-03-20,3455
112
+ 996688,Basic,QL311,Smart Term Bronze 5,High Protection,1788514145849,นางสาว,มณีรัตน์,ก้องเกียรติ,F,1982-09-05,กรุงเทพมหานคร,10260,41,43,0,480000,Telesale,1,F,5,5,500000,M,2024-03-18,2025-02-18,2025-01-08,2029-03-18,351
113
+ 996688,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,1788514145849,นางสาว,มณีรัตน์,ก้องเกียรติ,F,1982-09-05,กรุงเทพมหานคร,10260,41,43,1,480000,Telesale,1,F,5,5,3500,M,2024-03-18,2025-02-18,2025-01-08,2029-03-18,463
114
+ 932395,Basic,HT861,High Protect 3/3,High Protection,8759775732909,นางสาว,ดวงใจ,อธิชาติ,F,1985-03-13,ปทุมธานี,12120,39,40,0,420000,Online,1,I,3,3,150000,M,2024-03-20,2025-07-20,,2027-03-20,729
115
+ 932395,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,8759775732909,นางสาว,ดวงใจ,อธิชาติ,F,1985-03-13,ปทุมธานี,12120,39,40,1,420000,Online,1,I,3,3,1000,M,2024-03-20,2025-07-20,,2027-03-20,144
116
+ 633853,Basic,FO311,Smart Wellness 90/15,High Protection,8486452339858,นางสาว,จิตร,นฤมล,F,2001-03-23,ลำปาง,52100,22,24,0,300000,Telesale,1,L,68,15,100000,A,2024-03-08,2025-03-08,2025-03-08,2092-03-08,17400
117
+ 633853,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,8486452339858,นางสาว,จิตร,นฤมล,F,2001-03-23,ลำปาง,52100,22,24,1,300000,Telesale,1,L,48,48,100000,A,2024-03-08,2025-03-08,2025-03-08,2072-03-08,150
118
+ 633853,Rider,KM381,Rider ADB (สัญญาเพิ่มเติมอุบัติเหตุ),Rider Accident,8486452339858,นางสาว,จิตร,นฤมล,F,2001-03-23,ลำปาง,52100,22,24,1,300000,Telesale,1,L,43,43,100000,A,2024-03-08,2025-03-08,2025-03-08,2067-03-08,125
119
+ 633853,Rider,RE191,Rider ADD (สัญญาเพิ่มเติมอุบัติเหตุ),Rider Accident,8486452339858,นางสาว,จิตร,นฤมล,F,2001-03-23,ลำปาง,52100,22,24,1,300000,Telesale,1,L,43,43,100000,A,2024-03-08,2025-03-08,2025-03-08,2067-03-08,200
120
+ 633853,Rider,SX571,Rider AI (สัญญาเพิ่มเติมอุบัติเหตุ),Rider Accident,8486452339858,นางสาว,จิตร,นฤมล,F,2001-03-23,ลำปาง,52100,22,24,1,300000,Telesale,1,L,43,43,100000,A,2024-03-08,2025-03-08,2025-03-08,2067-03-08,500
121
+ 633853,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,8486452339858,นางสาว,จิตร,นฤมล,F,2001-03-23,ลำปาง,52100,22,24,1,300000,Telesale,1,L,15,15,100000,A,2024-03-08,2025-03-08,2025-03-08,2039-03-08,0
122
+ 603792,Basic,BY621,Sabai Jai 14/5,Protection + Saving,9359001590307,นางสาว,ปาริชาติ,ปรีชาชาญ,F,1969-07-16,สิงห์บุรี,16120,54,56,0,420000,Telesale,1,I,14,5,30000,M,2024-03-22,2025-06-22,,2038-03-22,1345
123
+ 449629,Basic,WA681,Chai Leoy 99/20,High Protection,1386145300997,นางสาว,อาภรณ์,สถาพร,F,1961-12-02,สมุทรสาคร,74110,62,64,0,480000,Agent,1,I,37,20,300000,A,2024-03-20,2026-03-20,,2061-03-20,17100
124
+ 449629,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,1386145300997,นางสาว,อาภรณ์,สถาพร,F,1961-12-02,สมุทรสาคร,74110,62,64,2,480000,Agent,1,I,8,8,500000,A,2024-03-20,2026-03-20,,2032-03-20,21800
125
+ 754780,Basic,QL311,Smart Term Bronze 5,High Protection,5912685469517,นางสาว,ปรีชาชาญ,ศรีสวัสดิ์,F,1993-12-25,ร้อยเอ็ด,45120,30,32,0,360000,Telesale,1,I,5,5,500000,S,2024-03-20,2025-09-20,,2029-03-20,913
126
+ 754780,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,5912685469517,นางสาว,ปรีชาชาญ,ศรีสวัสดิ์,F,1993-12-25,ร้อยเอ็ด,45120,30,32,2,360000,Telesale,1,I,5,5,100000,S,2024-03-20,2025-09-20,,2029-03-20,127
127
+ 754780,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,5912685469517,นางสาว,ปรีชาชาญ,ศรีสวัสดิ์,F,1993-12-25,ร้อยเอ็ด,45120,30,32,2,360000,Telesale,1,I,5,5,1000,S,2024-03-20,2025-09-20,,2029-03-20,764
128
+ 655461,Basic,FO311,Smart Wellness 90/15,High Protection,8836700265592,นางสาว,ขวัญ,อนันต์พร,F,1997-01-20,เชียงใหม่,50100,27,28,0,480000,Online,1,L,63,15,190000,A,2024-03-11,2025-03-11,2025-03-11,2087-03-11,35150
129
+ 655461,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,8836700265592,นางสาว,ขวัญ,อนันต์พร,F,1997-01-20,���ชียงใหม่,50100,27,28,1,480000,Online,1,L,15,15,190000,A,2024-03-11,2025-03-11,2025-03-11,2039-03-11,0
130
+ 376759,Basic,QL311,Smart Term Bronze 5,High Protection,8836700265592,นางสาว,ขวัญ,อนันต์พร,F,1997-01-20,เชียงใหม่,50100,27,28,0,480000,Online,1,L,5,5,800000,A,2024-03-11,2025-03-11,2025-03-11,2029-03-11,2736
131
+ 376759,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,8836700265592,นางสาว,ขวัญ,อนันต์พร,F,1997-01-20,เชียงใหม่,50100,27,28,1,480000,Online,1,L,5,5,800000,A,2024-03-11,2025-03-11,2025-03-11,2029-03-11,0
132
+ 635727,Basic,FO311,Smart Wellness 90/15,High Protection,9036592471044,นางสาว,รัตนาภรณ์,ชัยอนันต์,F,1995-03-12,เชียงใหม่,50140,28,30,0,2160000,Agent,1,I,62,15,100000,A,2024-03-11,2026-03-11,,2086-03-11,18800
133
+ 635727,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,9036592471044,นางสาว,รัตนาภรณ์,ชัยอนันต์,F,1995-03-12,เชียงใหม่,50140,28,30,1,2160000,Agent,1,I,15,15,100000,A,2024-03-11,2026-03-11,,2039-03-11,0
134
+ 307574,Basic,QL311,Smart Term Bronze 5,High Protection,5018367196609,นางสาว,มณีรัตน์,จรูญศักดิ์,F,1985-08-30,มหาสารคาม,44000,38,40,0,187680,Agent,1,L,5,5,500000,M,2024-03-20,2025-04-20,2025-04-20,2029-03-20,186
135
+ 307574,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,5018367196609,นางสาว,มณีรัตน์,จรูญศักดิ์,F,1985-08-30,มหาสารคาม,44000,38,40,1,187680,Agent,1,L,5,5,200000,M,2024-03-20,2025-04-20,2025-04-20,2029-03-20,83
136
+ 307574,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,5018367196609,นางสาว,มณีรัตน์,จรูญศักดิ์,F,1985-08-30,มหาสารคาม,44000,38,40,1,187680,Agent,1,L,5,5,500,M,2024-03-20,2025-04-20,2025-04-20,2029-03-20,68
137
+ 757893,Basic,WA681,Chai Leoy 99/20,High Protection,9487967209724,เด็กหญิง,ปาริชาติ,ภักดีพงษ์,F,2011-04-08,กรุงเทพมหานคร,10120,12,14,0,0,Online,1,L,87,20,500000,A,2024-03-13,2025-03-13,2025-03-13,2111-03-13,7050
138
+ 905675,Rider,HE351,PA Prompt (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,9253084655511,เด็กชาย,กานต์,ชาญชัย,M,2014-04-19,นนทบุรี,11000,9,11,1,0,Agent,1,I,90,90,2000,A,2024-03-11,2026-03-11,,2114-03-11,14430
139
+ 600583,Basic,BY621,Sabai Jai 14/5,Protection + Saving,9613923575374,นางสาว,จิตร,แก้วกาญจน์,F,1984-08-20,ระยอง,21000,39,41,0,600000,Telesale,1,I,14,5,30000,A,2024-03-22,2026-03-22,,2038-03-22,14940
140
+ 625826,Basic,WA681,Chai Leoy 99/20,High Protection,8026618605856,นาย,ฐิติ,ธีรวุฒิ,M,1962-06-06,กรุงเทพมหานคร,10600,61,63,0,380000,Telesale,1,L,38,20,417000,A,2024-03-19,2025-03-19,2025-03-19,2062-03-19,19599
141
+ 142102,Basic,WA681,Chai Leoy 99/20,High Protection,4164187334603,นาย,ธีรภัทร,แก้วกาญจน์,M,1982-06-18,เชียงราย,57120,41,43,0,600000,Agent,1,L,58,20,1000000,A,2024-03-15,2025-03-15,2025-03-15,2082-03-15,25900
142
+ 142102,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,4164187334603,นาย,ธีรภัทร,แก้วกาญจน์,M,1982-06-18,เชียงราย,57120,41,43,2,600000,Agent,1,L,29,29,1000000,A,2024-03-15,2025-03-15,2025-03-15,2053-03-15,5320
143
+ 142102,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,4164187334603,นาย,ธีรภัทร,แก้วกาญจน์,M,1982-06-18,เชียงราย,57120,41,43,1,600000,Agent,1,L,20,20,1000000,A,2024-03-15,2025-03-15,2025-03-15,2044-03-15,0
144
+ 632469,Basic,AV311,PA Max (อุบัติเหตุส่วนบุคคล),Accident Protection,6695510789794,นาย,ฐิติ,อภิรักษ์,M,1967-05-16,แพร่,54110,56,58,2,140000,Telesale,1,F,1,1,200000,A,2024-03-15,2025-03-15,2025-03-15,2025-03-15,260
145
+ 632469,Rider,SR951,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,6695510789794,นาย,ฐิติ,อภิรักษ์,M,1967-05-16,แพร่,54110,56,58,2,140000,Telesale,1,X,1,1,1000,A,2024-03-15,2025-03-15,2025-03-15,2025-03-15,400
146
+ 632469,Rider,QV321,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ),Rider Accident,6695510789794,นาย,ฐิติ,อภิรักษ์,M,1967-05-16,แพร่,54110,56,58,2,140000,Telesale,1,X,1,1,20000,A,2024-03-15,2025-03-15,2025-03-15,2025-03-15,1040
147
+ 194347,Basic,UL421,Protection Plus 18/9,Protection + Saving,1491319051870,นาย,เกรียงไกร,นพรัตน์,M,1978-03-09,กรุงเทพมหานคร,10220,46,47,0,228000,Online,1,I,18,9,30000,A,2024-03-22,2025-03-22,2024-04-22,2042-03-22,12600
148
+ 789223,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,6626844341132,นาย,ก้องเกียรติ,นาคะมโน,M,1994-09-15,ร้อยเอ็ด,45000,29,31,1,650000,Online,1,L,41,41,500,A,2024-03-05,2025-03-05,2025-03-05,2065-03-05,735
149
+ 594944,Basic,LP481,Jai Jai 12/6,Protection + Saving,9485771945648,นาย,ภูมินทร์,ฐาปนีย์,M,1991-11-27,บุรีรัมย์,31110,32,34,0,720000,Online,1,I,12,6,30000,A,2024-03-16,2026-03-16,,2036-03-16,30000
150
+ 798982,Basic,BY621,Sabai Jai 14/5,Protection + Saving,2845976265025,นาย,ภูวดล,โชติวัฒน์,M,1972-12-09,กรุงเทพมหานคร,10150,51,53,0,840000,Online,1,I,14,5,40000,A,2024-03-12,2026-03-12,,2038-03-12,19920
151
+ 914187,Basic,HT861,High Protect 3/3,High Protection,3106150923730,นาย,วรพงษ์,บุญเลิศ,M,1973-08-17,ฉะเชิงเทรา,24000,50,52,0,336000,Agent,1,I,3,3,150000,S,2024-03-10,2025-09-10,,2027-03-10,4368
152
+ 914187,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,3106150923730,นาย,วรพงษ์,บุญเลิศ,M,1973-08-17,ฉะเชิงเทรา,24000,50,52,2,336000,Agent,1,I,3,3,150000,S,2024-03-10,2025-09-10,,2027-03-10,1069
153
+ 121779,Basic,UD681,Jai Jai 25/9,Protection + Saving,6970266349268,นาย,นรุตม์,อัครเศรษฐ์,M,1970-11-11,ปทุมธานี,12150,53,55,0,960000,Telesale,1,I,25,9,300000,A,2024-03-08,2026-03-08,,2049-03-08,63000
154
+ 968914,Basic,BY621,Sabai Jai 14/5,Protection + Saving,4094675912273,นาย,นรุตม์,ชัยอนันต์,M,1969-07-26,กรุงเทพมหานคร,10210,54,56,0,720000,Online,1,F,14,5,30000,A,2024-03-08,2025-03-08,2024-10-22,2038-03-08,14940
155
+ 771211,Basic,WA681,Chai Leoy 99/20,High Protection,8822645023872,นาย,พงษ์พิทักษ์,มณีโชติ,M,1970-09-26,กรุงเทพมหานคร,10900,53,55,0,2400000,Agent,1,I,46,20,200000,M,2024-03-22,2025-07-22,,2070-03-22,750
156
+ 414537,Basic,WA681,Chai Leoy 99/20,High Protection,8400336985402,นาย,ฐิติ,นฤมล,M,1964-03-18,กรุงเทพมหานคร,10700,59,61,0,144000,Agent,1,I,40,20,300000,A,2024-03-14,2026-03-14,,2064-03-14,13470
157
+ 414537,Rider,SX571,Rider AI (สัญญาเพิ่มเติมอุบัติเหตุ),Rider Accident,8400336985402,นาย,ฐิติ,นฤมล,M,1964-03-18,กรุงเทพมหานคร,10700,59,61,3,144000,Agent,1,I,6,6,100000,A,2024-03-14,2026-03-14,,2030-03-14,700
158
+ 414537,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,8400336985402,นาย,ฐิติ,นฤมล,M,1964-03-18,กรุงเทพมหานคร,10700,59,61,1,144000,Agent,1,I,6,6,300000,A,2024-03-14,2026-03-14,2024-03-14,2030-03-14,0
159
+ 274104,Basic,FO311,Smart Wellness 90/15,High Protection,9538408226840,นาย,ภานุ,มณีโชติ,M,2000-05-11,ลำพูน,51110,23,25,0,816000,Agent,1,L,67,15,210000,A,2024-03-21,2025-03-21,2025-03-21,2091-03-21,35490
160
+ 274104,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,9538408226840,นาย,ภานุ,มณีโชติ,M,2000-05-11,ลำพูน,51110,23,25,1,816000,Agent,1,L,15,15,210000,A,2024-03-21,2025-03-21,2025-03-21,2039-03-21,0
161
+ 250263,Basic,HT861,High Protect 3/3,High Protection,6017001287022,นาย,ก้องเกียรติ,ฐาปนีย์,M,1968-03-06,แพร่,54000,56,57,0,240000,Telesale,1,I,3,3,150000,A,2024-03-28,2026-03-28,,2027-03-28,9900
162
+ 250263,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,6017001287022,นาย,ก้องเกียรติ,ฐาปนีย์,M,1968-03-06,แพร่,54000,56,57,2,240000,Telesale,1,I,3,3,1000,A,2024-03-28,2026-03-28,,2027-03-28,2500
163
+ 553915,Basic,UL421,Protection Plus 18/9,Protection + Saving,8887750575151,นาย,พนม,เกียรติก้อง,M,1990-11-01,กรุงเทพมหานคร,10310,33,35,0,600000,Telesale,1,L,18,9,30000,M,2024-03-21,2024-05-21,2024-05-21,2042-03-21,1161
164
+ 248414,Basic,WA681,Chai Leoy 99/20,High Protection,3193806471949,นาย,ภูวดล,รัตนรักษ์,M,1960-10-21,สมุทรปราการ,10540,63,65,0,120000,Telesale,1,I,36,20,500000,A,2024-03-10,2026-03-10,,2060-03-10,30000
165
+ 485385,Basic,WA681,Chai Leoy 99/20,High Protection,9474324886918,นาย,ทศพล,จิตรภักดี,M,1998-07-08,นครราชสีมา,30000,25,27,0,350000,Telesale,1,I,74,20,200000,M,2024-03-16,2025-06-16,,2098-03-16,327
166
+ 485385,Rider,CD801,Health Protect (สัญญาเพิ่มเติมสุขภาพค่ารักษาพยาบาล),Rider Health,9474324886918,นาย,ทศพล,จิตรภักดี,M,1998-07-08,นครราชสีมา,30000,25,27,2,350000,Telesale,1,I,74,74,4000,M,2024-03-16,2025-06-16,,2098-03-16,1027
167
+ 485385,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,9474324886918,นาย,ทศพล,จิตรภักดี,M,1998-07-08,นครราชสีมา,30000,25,27,2,350000,Telesale,1,I,45,45,1000,M,2024-03-16,2025-06-16,,2069-03-16,132
168
+ 485385,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,9474324886918,นาย,ทศพล,จิตรภักดี,M,1998-07-08,นครราชสีมา,30000,25,27,1,350000,Telesale,1,I,20,20,200000,M,2024-03-16,2025-06-16,,2044-03-16,0
169
+ 214206,Basic,HT861,High Protect 3/3,High Protection,7055037920528,นาย,ยุทธนา,ธีรวุฒิ,M,1976-05-09,กรุงเทพมหานคร,10240,47,49,0,2400000,Telesale,1,I,3,3,150000,A,2024-03-05,2026-03-05,,2027-03-05,8250
170
+ 214206,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,7055037920528,นาย,ยุทธนา,ธีรวุฒิ,M,1976-05-09,กรุงเทพมหานคร,10240,47,49,1,2400000,Telesale,1,I,3,3,450000,A,2024-03-05,2026-03-05,,2027-03-05,5310
171
+ 889551,Basic,WA681,Chai Leoy 99/20,High Protection,9563325704297,นาย,ธนพล,ลิขิตธรรม,M,1986-10-02,กระบี่,81000,37,39,0,800000,Online,1,L,62,20,200000,A,2024-03-16,2025-03-16,2025-03-16,2086-03-16,4720
172
+ 889551,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,9563325704297,นาย,ธนพล,ลิขิตธรรม,M,1986-10-02,กระบี่,81000,37,39,1,800000,Online,1,L,33,33,1000,A,2024-03-16,2025-03-16,2025-03-16,2057-03-16,1500
173
+ 889551,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,9563325704297,นาย,ธนพล,ลิขิตธรรม,M,1986-10-02,กระบี่,81000,37,39,1,800000,Online,1,L,20,20,200000,A,2024-03-16,2025-03-16,2025-03-16,2044-03-16,0
174
+ 209506,Basic,FO311,Smart Wellness 90/15,High Protection,2519665803840,นาย,ณัฐ,วัฒนกุล,M,2000-11-04,น่าน,55140,23,25,0,240000,Agent,1,L,67,15,180000,A,2024-03-07,2025-03-07,2025-03-07,2091-03-07,30420
175
+ 209506,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,2519665803840,นาย,ณัฐ,วัฒนกุล,M,2000-11-04,น่าน,55140,23,25,1,240000,Agent,1,L,47,47,270000,A,2024-03-07,2025-03-07,2025-03-07,2071-03-07,297
176
+ 209506,Rider,RE191,Rider ADD (สัญญาเพิ่มเติมอุบัติเหตุ),Rider Accident,2519665803840,นาย,ณัฐ,วัฒนกุล,M,2000-11-04,น่าน,55140,23,25,1,240000,Agent,1,L,42,42,500000,A,2024-03-07,2025-03-07,2025-03-07,2066-03-07,1000
177
+ 209506,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,2519665803840,นาย,ณัฐ,วัฒนกุล,M,2000-11-04,น่าน,55140,23,25,1,240000,Agent,1,L,15,15,180000,A,2024-03-07,2025-03-07,2025-03-07,2039-03-07,0
178
+ 486993,Basic,HT861,High Protect 3/3,High Protection,7677815325872,นาย,ฐิติ,วรสิทธิ์,M,1965-05-19,ชลบุรี,20230,58,60,0,180000,Online,1,I,3,3,150000,M,2024-03-21,2025-07-21,,2027-03-21,810
179
+ 173537,Basic,HT861,High Protect 3/3,High Protection,5071198130711,นาย,ธีรภัทร,มณีโชติ,M,1974-11-14,สมุทรปราการ,10130,49,51,0,564000,Online,1,I,3,3,200000,A,2024-03-15,2026-03-15,,2027-03-15,12000
180
+ 104198,Basic,AV311,PA Max (อุบัติเหตุส่วนบุคคล),Accident Protection,2595332428470,นาย,สุนทร,สุนทรสิงห์,M,1993-08-17,กรุงเทพมหานคร,10310,30,32,1,600000,Online,1,F,1,1,200000,A,2024-03-21,2025-03-21,2025-03-21,2025-03-21,150
181
+ 104198,Rider,SR951,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,2595332428470,นาย,สุนทร,สุนทรสิงห์,M,1993-08-17,กรุงเทพมหานคร,10310,30,32,1,600000,Online,1,X,1,1,1000,A,2024-03-21,2025-03-21,2025-03-21,2025-03-21,275
182
+ 104198,Rider,QV321,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ),Rider Accident,2595332428470,นาย,สุนทร,สุนทรสิงห์,M,1993-08-17,กรุงเทพมหานคร,10310,30,32,1,600000,Online,1,X,1,1,20000,A,2024-03-21,2025-03-21,2025-03-21,2025-03-21,875
183
+ 231979,Basic,NV911,Save 5 C,High Protection,8141903034772,นาย,ฉัตรชัย,วัฒนกุล,M,1972-05-04,กรุงเทพมหานคร,10150,51,53,0,600000,Agent,1,I,5,5,300000,A,2024-03-20,2026-03-20,,2029-03-20,13800
184
+ 794474,Basic,BY621,Sabai Jai 14/5,Protection + Saving,5297526293006,นาย,นรินทร์,มณีรัตน์,M,1976-06-26,ยะลา,95000,47,49,0,1200000,Agent,1,I,14,5,30000,A,2024-03-21,2026-03-21,,2038-03-21,14940
185
+ 919351,Basic,AV311,PA Max (อุบัติเหตุส่วนบุคคล),Accident Protection,5947579547829,นาย,อภิชาติ,วรสิทธิ์,M,1994-08-07,เชียงใหม่,50140,29,31,3,132000,Agent,1,F,1,1,200000,A,2024-03-01,2025-03-01,2025-03-01,2025-03-01,370
186
+ 919351,Rider,SR951,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาผู้ป่วยนอก),Rider Health,5947579547829,นาย,อภิชาติ,วรสิทธิ์,M,1994-08-07,เชียงใหม่,50140,29,31,3,132000,Agent,1,X,1,1,1000,A,2024-03-01,2025-03-01,2025-03-01,2025-03-01,525
187
+ 919351,Rider,QV321,PA Max (สัญญาเพิ่มเติมสุขภาพค่ารักษาเนื่องจากอุบัติเหตุ),Rider Accident,5947579547829,นาย,อภิชาติ,วรสิทธิ์,M,1994-08-07,เชียงใหม่,50140,29,31,3,132000,Agent,1,X,1,1,20000,A,2024-03-01,2025-03-01,2025-03-01,2025-03-01,1205
188
+ 229240,Basic,WA681,Chai Leoy 99/20,High Protection,1284151650384,นาย,นรินทร์,มณีโชติ,M,1980-06-15,กรุงเทพมหานคร,10330,43,45,0,700000,Agent,1,L,56,20,200000,M,2024-03-25,2024-09-25,2024-09-25,2080-03-25,559
189
+ 229240,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,1284151650384,นาย,นรินทร์,มณีโชติ,M,1980-06-15,กรุงเทพมหานคร,10330,43,45,4,700000,Agent,1,L,27,27,150000,M,2024-03-25,2024-09-25,2024-09-25,2051-03-25,124
190
+ 229240,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,1284151650384,นาย,นรินทร์,มณีโชติ,M,1980-06-15,กรุงเทพมหานคร,10330,43,45,4,700000,Agent,1,L,27,27,1000,M,2024-03-25,2024-09-25,2024-09-25,2051-03-25,192
191
+ 157562,Basic,WA681,Chai Leoy 99/20,High Protection,4006356581092,นาย,สุนทร,ภูมิใจดี,M,1988-11-15,สิงห์บุรี,16110,35,37,0,300000,Agent,1,I,64,20,200000,A,2024-03-21,2026-03-21,,2088-03-21,4500
192
+ 113217,Basic,QL311,Smart Term Bronze 5,High Protection,4169298567308,นาย,อภิชาติ,ลิขิตธรรม,M,1971-08-24,แพร่,54000,52,54,0,540000,Agent,1,L,5,5,500000,M,2024-03-20,2025-02-20,2025-02-20,2029-03-20,347
193
+ 113217,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,4169298567308,นาย,อภิชาติ,ลิขิตธรรม,M,1971-08-24,แพร่,54000,52,54,2,540000,Agent,1,L,5,5,500,M,2024-03-20,2025-02-20,2025-02-20,2029-03-20,95
194
+ 839072,Basic,HT861,High Protect 3/3,High Protection,6864834140949,นาย,นรินทร์,วรสิทธิ์,M,1973-09-25,กรุงเทพมหานคร,10150,50,52,0,360000,Online,1,I,3,3,150000,M,2024-03-08,2025-07-08,,2027-03-08,824
195
+ 839072,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,6864834140949,นาย,นรินทร์,วรสิทธิ์,M,1973-09-25,กรุงเทพมหานคร,10150,50,52,2,360000,Online,1,I,3,3,500,M,2024-03-08,2025-07-08,,2027-03-08,95
196
+ 765067,Basic,UL421,Protection Plus 18/9,Protection + Saving,7241549493452,นาย,ชัยอนันต์,ทรัพย์เจริญ,M,1991-04-02,กรุงเทพมหานคร,10240,32,34,0,1080000,Telesale,1,L,18,9,100000,A,2024-03-11,2025-03-11,2025-02-13,2042-03-11,43000
197
+ 765067,Rider,BJ751,Worry Free Cancer (สัญญาเพิ่มเติมคุ้มครองโรคมะเร็ง),Rider Critical Illness,7241549493452,นาย,ชัยอนันต์,ทรัพย์เจริญ,M,1991-04-02,กรุงเทพมหานคร,10240,32,34,1,1080000,Telesale,1,I,18,18,300000,A,2024-03-11,2025-03-11,2025-02-13,2042-03-11,630
198
+ 593988,Basic,WA681,Chai Leoy 99/20,High Protection,8380449522682,นาย,มงคล,สมบูรณ์ทรัพย์,M,1965-09-12,สุราษฎร์ธานี,84000,58,60,0,600000,Telesale,1,I,41,20,200000,A,2024-03-21,2026-03-21,,2065-03-21,8700
199
+ 593988,Rider,CD801,Health Protect (สัญญาเพิ่มเติมสุขภาพค่ารักษาพยาบาล),Rider Health,8380449522682,นาย,มงคล,สมบูรณ์ทรัพย์,M,1965-09-12,สุราษฎร์ธานี,84000,58,60,1,600000,Telesale,1,I,41,41,3000,A,2024-03-21,2026-03-21,,2065-03-21,20880
200
+ 593988,Rider,ZB661,Rider HIB 365 (สัญญาเพิ่มเติมสุขภาพค่าชดเชยรายวัน),Rider Health,8380449522682,นาย,มงคล,สมบูรณ์ทรัพย์,M,1965-09-12,สุราษฎร์ธานี,84000,58,60,1,600000,Telesale,1,I,12,12,1000,A,2024-03-21,2026-03-21,,2036-03-21,2500
201
+ 593988,Rider,TL851,สัญญาเพิ่มเติมยกเว้นเบี้ยประกันภัย,Rider Health,8380449522682,นาย,มงคล,สมบูรณ์ทรัพย์,M,1965-09-12,สุราษฎร์ธานี,84000,58,60,1,600000,Telesale,1,I,20,20,200000,A,2024-03-21,2026-03-21,,2044-03-21,0
requirements.txt ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ langchain
2
+ langchain-google-genai
3
+ langchain-community
4
+ langchain-huggingface
5
+ langchain-mongodb
6
+ google-generativeai
7
+ sentence-transformers
8
+ torch
9
+ pandas
10
+ gradio
11
+ langfuse
12
+ python-dotenv