Spaces:
Sleeping
Sleeping
SUMANA SUMANAKUL (ING)
commited on
Commit
·
30adccc
1
Parent(s):
8e85b71
first commit
Browse files- .gitignore +23 -0
- app.py +105 -69
- app_p/gemini_agent.py +199 -0
- app_p/handler/customer_data_handler.py +172 -0
- app_p/handler/recommendation_handler.py +131 -0
- app_p/tools.py +342 -0
- app_p/utils/prompts.py +83 -0
- app_p/utils/query_rewriter.py +70 -0
- app_p/utils/reranker.py +80 -0
- app_p/utils/retriever.py +134 -0
- data/column_mapping.csv +30 -0
- data/mock_customer_data.csv +201 -0
- requirements.txt +12 -0
.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 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
):
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
""
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|