kltn21110 commited on
Commit
6f8d9d0
·
verified ·
1 Parent(s): 1dcc2bf

Update function/gemini_response/get_table.py

Browse files
Files changed (1) hide show
  1. function/gemini_response/get_table.py +234 -231
function/gemini_response/get_table.py CHANGED
@@ -1,232 +1,235 @@
1
- from langchain_community.utilities.sql_database import SQLDatabase
2
- from langchain_experimental.sql import SQLDatabaseChain
3
- import os, sys
4
- import os
5
- from dotenv import load_dotenv
6
-
7
- # Load biến môi trường từ file .env
8
- BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../")) # hoặc ".." tùy vị trí
9
- dotenv_path = os.path.join(BASE_DIR, ".env")
10
- import os
11
- from dotenv import load_dotenv
12
-
13
- # # Gán đường dẫn tuyệt đối đến file .env
14
- # dotenv_path = r"d:\HmDrinks_Chat\V2\chatbot - 19_5\.env"
15
-
16
- from dotenv import load_dotenv, find_dotenv
17
-
18
- # Tự động tìm file .env gần nhất trong cây thư mục cha
19
- load_dotenv(find_dotenv(), override=True)
20
-
21
- # Debug kiểm tra
22
- # print(">> DEBUG: dotenv_path =", dotenv_path)
23
- # print(">> DEBUG: DB_HOST =", os.getenv("DB_HOST"))
24
- # print(">> DEBUG: DB_USER =", os.getenv("DB_USER"))
25
- # print(">> DEBUG: DB_PASSWORD =", os.getenv("DB_PASSWORD"))
26
- # print(">> DEBUG: DB_NAME =", os.getenv("DB_NAME"))
27
- # print(">> DEBUG: DB_PORT =", os.getenv("DB_PORT"))
28
-
29
-
30
-
31
-
32
- DB_HOST = os.getenv("DB_HOST")
33
- DB_USER = os.getenv("DB_USER")
34
- DB_PASSWORD = os.getenv("DB_PASSWORD")
35
- DB_NAME = os.getenv("DB_NAME")
36
- DB_PORT = os.getenv("DB_PORT")
37
- import os
38
- from urllib.parse import quote
39
-
40
- password = os.getenv("DB_PASSWORD")
41
- DB_PASSWORD = quote(password)
42
- # Tạo connection string
43
- connection_uri = f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
44
- print(">> DEBUG connection_uri:", connection_uri)
45
- current_dir = os.path.dirname(os.path.abspath(__file__))
46
- project_root = os.path.abspath(os.path.join(current_dir, '..', '..')) # Lên 2 cấp
47
- sys.path.append(project_root)
48
-
49
-
50
-
51
- from support import get_key
52
-
53
- api_key = get_key.get_random_api_key()
54
- sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
55
-
56
- os.environ["GOOGLE_API_KEY"] = "AIzaSyCO-RlqYewC4e9BEPoC8m-AxHUY7J3_o2E"
57
- import prompt.prompt_main as prompt
58
- from langchain_google_genai import GoogleGenerativeAIEmbeddings, ChatGoogleGenerativeAI
59
- llm1 = ChatGoogleGenerativeAI(model='gemini-2.0-flash-thinking-exp-01-21',temperature=0.6,api_key=api_key)
60
-
61
-
62
-
63
- db = SQLDatabase.from_uri(connection_uri)
64
- db.get_table_info_no_throw()
65
- import re
66
- db_chain = SQLDatabaseChain.from_llm(llm=llm1,db=db,prompt= prompt.PROMPT)
67
- import prompt.prompt_table as prompt_table
68
- import prompt.prompt_create_table as prompt_create
69
- import json
70
-
71
- # import google.generativeai as genai
72
- # genai.configure(api_key=api_key)
73
-
74
- # async def response_general(input:str)->list:
75
- # api_key = get_key.get_random_api_key()
76
- # genai.configure(api_key=api_key)
77
- # generation_config = {
78
- # "temperature": 1,
79
- # "top_p": 0.95,
80
- # "top_k": 40,
81
- # "max_output_tokens": 8192,
82
- # "response_mime_type": "text/plain",
83
- # }
84
-
85
-
86
- # model = genai.GenerativeModel(
87
- # model_name="gemini-2.5-flash-preview-04-17",
88
- # generation_config=generation_config,
89
- # )
90
-
91
- # chat_session = model.start_chat(
92
- # history=[
93
- # {
94
- # "role": "user",
95
- # "parts": [
96
- # f"""Hãy vui lòng đọc kỹ các bảng sau đây gồm có các thuộc tÍNH, khóa ngoại của các bảng sau khi tạo bảng trong MySQL. {prompt_create.PROMPT_TABLE}.
97
- # Mình có định nghĩa các thuộc tính tham số, mối quan hệ các bảng sau đây: {prompt_table}. Luôn đọc kĩ càng các thông tin mô tả này. Hãy xác định kĩ càng các bước, mô tả của mình để lấy các bảng cần dùng chính xác nhất.
98
- # Hãy cân nhắc cho câu hỏi sau đây: {input}. Phân tích câu hỏi và chọn các bảng cần thiết để có thể trả lời câu hỏi.
99
- # Hãy phân biệt giữa đơn hàng bình thường(orders) đơn hàng nhóm(group_orders).
100
- # ** Cách trả lời:
101
- # - Bạn vui lòng trả lại danh sách các table liên quan. Vui lòng ghép chúng vào trong list nối với nhau bằng , dụ ["cart","user"].
102
- # - Luôn bao gồm bảng user trong mọi trường hợp câu hỏi.
103
- # - Chỉ lấy tên các bảng mà mình đã cung cấp, không được tự ý sinh thêm bảng. Điều này là cấm.
104
- # - Không được phép dùng bảng "Token, user_chat, notification"
105
- # - Nếu trong list bảng cart thì phải kèm theo cart_item
106
- # - Nếu trong list bảng cart_group thì phải kèm theo cart_item_group
107
- # - Nếu trong bảng chứa các bảng như cart_item, cart_item_group thì vui lòng kèm theo các bảng liên quan về sản phẩm như product_translation và product_variants, product
108
- # - Nếu trong list có bảng category thì phải kèm theo category_translation, product phải kèm theo product_translation và product_variant
109
- # - Nếu trong list có bảng group_orders thì phải kèm theo group_order_members.
110
- # - Nếu trong listb���ng group_order_members thì phải kèm theo cart_group.
111
- # - Nếu trong list trả về các bảng như product, post, hay category phải kèm theo bảng translation liên kết với nó.
112
- # - Khi trong list có liên quan product hãy luôn cung cấp product_variants để có thể cung cấp thêm giá tùy trương hợp.
113
- # - Không yêu cầu giải thích thêm chỉ cần trả về list theo mình mô tả ví dụ.
114
- # - Luôn đảm bảo Xác định chính xác bảng cần dùng cho câu hỏi, không thừa bảng, không bỏ sót bảng cần thiết.
115
- # - Luôn luôn trả về đúng list []. Cấm trả sai định dạng mình đã cung cấp""",
116
- # ],
117
- # }
118
- # ]
119
- # )
120
-
121
- # response = chat_session.send_message("Hãy luôn đảm bảo rằng bạn tuân thủ những gì mình đưa ra, không được phép làm khác đi.")
122
- # data = response.text
123
- # if data.strip(): # Kiểm tra dữ liệu không rỗng
124
- # try:
125
- # # Cố gắng parse JSON
126
- # data_list = json.loads(data)
127
- # return data_list
128
- # except json.JSONDecodeError:
129
- # # Nếu không phải JSON, thử tìm danh sách bảng trong chuỗi văn bản
130
- # match = re.search(r'\[(.*?)\]', data)
131
- # if match:
132
- # # Lấy phần trong dấu [ ], tách thành list
133
- # items_str = match.group(1)
134
- # items = [item.strip().strip('"').strip("'") for item in items_str.split(',')]
135
- # print("Danh sách bảng đã trích xuất:", items)
136
- # return items
137
- # else:
138
- # print("Không tìm thấy danh sách bảng trong dữ liệu văn bản!")
139
- # else:
140
- # print("Dữ liệu đầu vào rỗng!")
141
-
142
-
143
- import asyncio
144
- import json
145
- import re
146
- from support import get_key
147
- import google.generativeai as genai
148
-
149
- async def response_general(input: str) -> list:
150
- async def call_model_once() -> list:
151
- # Lấy API key và cấu hình
152
- api_key = get_key.get_random_api_key()
153
- genai.configure(api_key=api_key)
154
-
155
- generation_config = {
156
- "temperature": 1,
157
- "top_p": 0.95,
158
- "top_k": 40,
159
- "max_output_tokens": 8192,
160
- "response_mime_type": "text/plain",
161
- }
162
-
163
- model = genai.GenerativeModel(
164
- model_name="gemini-2.5-flash-preview-04-17",
165
- generation_config=generation_config,
166
- )
167
-
168
- chat_session = model.start_chat(
169
- history=[
170
- {
171
- "role": "user",
172
- "parts": [
173
- f"""Hãy vui lòng đọc kỹ các bảng sau đây gồm có các thuộc tÍNH, khóa ngoại của các bảng sau khi tạo bảng trong MySQL. {prompt_create.PROMPT_TABLE}.
174
- Mình có định nghĩa các thuộc tính tham số, mối quan hệ các bảng sau đây: {prompt_table}. Luôn đọc kĩ càng các thông tin mô tả này. Hãy xác định kĩ càng các bước, mô tả của mình để lấy các bảng cần dùng chính xác nhất.
175
- Hãy cân nhắc cho câu hỏi sau đây: {input}. Phân tích câu hỏi và chọn các bảng cần thiết để có thể trả lời câu hỏi.
176
- Hãy phân biệt giữa đơn hàng bình thường(orders) đơn hàng nhóm(group_orders).
177
- ** Cách trả lời:
178
- - Bạn vui lòng trả lại danh sách các table liên quan. Vui lòng ghép chúng vào trong list nối với nhau bằng , dụ ["cart","user"].
179
- - Luôn bao gồm bảng user trong mọi trường hợp câu hỏi.
180
- - Chỉ lấy tên các bảng mà mình đã cung cấp, không được tự ý sinh thêm bảng. Điều này là cấm.
181
- - Không được phép dùng bảng "Token, user_chat, notification"
182
- - Nếu trong list bảng cart thì phải kèm theo cart_item
183
- - Nếu trong list bảng cart_group thì phải kèm theo cart_item_group
184
- - Nếu trong bảng chứa các bảng như cart_item, cart_item_group thì vui lòng kèm theo các bảng liên quan về sản phẩm như product_translation và product_variants, product
185
- - Nếu trong list có bảng category thì phải kèm theo category_translation, product phải kèm theo product_translation và product_variant
186
- - Nếu trong list có bảng group_orders thì phải kèm theo group_order_members.
187
- - Nếu trong list có bảng group_order_members thì phải kèm theo cart_group.
188
- - Nếu trong list trả về các bảng như product, post, hay category phải kèm theo bảng translation liên kết với nó.
189
- - Khi trong list có liên quan product hãy luôn cung cấp product_variants để có thể cung cấp thêm giá tùy trương hợp.
190
- - Không yêu cầu giải thích thêm chỉ cần trả về list theo mình mô tả ví dụ.
191
- - Luôn đảm bảo Xác định chính xác bảng cần dùng cho câu hỏi, không thừa bảng, không bỏ sót bảng cần thiết.
192
- - Luôn luôn trả về đúng list []. Cấm trả sai định dạng mình đã cung cấp""",
193
- ],
194
- }
195
- ]
196
- )
197
-
198
- response = await chat_session.send_message_async("Hãy luôn đảm bảo rằng bạn tuân thủ những gì mình đưa ra, không được phép làm khác đi.")
199
- data = response.text
200
-
201
- if data.strip():
202
- try:
203
- return json.loads(data)
204
- except json.JSONDecodeError:
205
- match = re.search(r'\[(.*?)\]', data)
206
- if match:
207
- items_str = match.group(1)
208
- items = [item.strip().strip('"').strip("'") for item in items_str.split(',')]
209
- print("✅ Danh sách bảng đã trích xuất:", items)
210
- return items
211
- else:
212
- raise ValueError("Không tìm thấy danh sách bảng hợp lệ trong phản hồi văn bản.")
213
- else:
214
- raise ValueError("Dữ liệu phản hồi trống.")
215
-
216
- # Gọi lần đầu
217
- try:
218
- return await call_model_once()
219
- except Exception as e:
220
- print(f"⚠️ Lỗi lần đầu: {e} — thử lại sau 2 giây...")
221
- await asyncio.sleep(2)
222
-
223
- try:
224
- return await call_model_once()
225
- except Exception as retry_error:
226
- print(f"❌ Lỗi lần 2: {retry_error}")
227
- raise Exception("Gọi mô hình thất bại sau khi thử lại.")
228
-
229
-
230
- # if __name__ == "__main__":
231
- # import asyncio
 
 
 
232
  # asyncio.run(response_general("Danh sách bài đăng mới nhất"))
 
1
+ from langchain_community.utilities.sql_database import SQLDatabase
2
+ from langchain_experimental.sql import SQLDatabaseChain
3
+ import os, sys
4
+ import os
5
+ from dotenv import load_dotenv
6
+
7
+ # Load biến môi trường từ file .env
8
+ BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../")) # hoặc ".." tùy vị trí
9
+ dotenv_path = os.path.join(BASE_DIR, ".env")
10
+ import os
11
+ from dotenv import load_dotenv
12
+
13
+ # # Gán đường dẫn tuyệt đối đến file .env
14
+ # dotenv_path = r"d:\HmDrinks_Chat\V2\chatbot - 19_5\.env"
15
+
16
+ from dotenv import load_dotenv, find_dotenv
17
+
18
+ # Tự động tìm file .env gần nhất trong cây thư mục cha
19
+ load_dotenv(find_dotenv(), override=True)
20
+
21
+ # Debug kiểm tra
22
+ # print(">> DEBUG: dotenv_path =", dotenv_path)
23
+ # print(">> DEBUG: DB_HOST =", os.getenv("DB_HOST"))
24
+ # print(">> DEBUG: DB_USER =", os.getenv("DB_USER"))
25
+ # print(">> DEBUG: DB_PASSWORD =", os.getenv("DB_PASSWORD"))
26
+ # print(">> DEBUG: DB_NAME =", os.getenv("DB_NAME"))
27
+ # print(">> DEBUG: DB_PORT =", os.getenv("DB_PORT"))
28
+
29
+
30
+
31
+
32
+ DB_HOST = os.getenv("DB_HOST")
33
+ DB_USER = os.getenv("DB_USER")
34
+ DB_PASSWORD = os.getenv("DB_PASSWORD")
35
+ DB_NAME = os.getenv("DB_NAME")
36
+ DB_PORT = os.getenv("DB_PORT")
37
+ import os
38
+ from urllib.parse import quote
39
+
40
+ password = os.getenv("DB_PASSWORD")
41
+ DB_PASSWORD = quote(password)
42
+ # Tạo connection string
43
+ connection_uri = (
44
+ f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
45
+ "?ssl_verify_cert=false&ssl_verify_identity=false"
46
+ )
47
+ print(">> DEBUG connection_uri:", connection_uri)
48
+ current_dir = os.path.dirname(os.path.abspath(__file__))
49
+ project_root = os.path.abspath(os.path.join(current_dir, '..', '..')) # Lên 2 cấp
50
+ sys.path.append(project_root)
51
+
52
+
53
+
54
+ from support import get_key
55
+
56
+ api_key = get_key.get_random_api_key()
57
+ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
58
+
59
+ os.environ["GOOGLE_API_KEY"] = "AIzaSyCO-RlqYewC4e9BEPoC8m-AxHUY7J3_o2E"
60
+ import prompt.prompt_main as prompt
61
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings, ChatGoogleGenerativeAI
62
+ llm1 = ChatGoogleGenerativeAI(model='gemini-2.0-flash-thinking-exp-01-21',temperature=0.6,api_key=api_key)
63
+
64
+
65
+
66
+ db = SQLDatabase.from_uri(connection_uri)
67
+ db.get_table_info_no_throw()
68
+ import re
69
+ db_chain = SQLDatabaseChain.from_llm(llm=llm1,db=db,prompt= prompt.PROMPT)
70
+ import prompt.prompt_table as prompt_table
71
+ import prompt.prompt_create_table as prompt_create
72
+ import json
73
+
74
+ # import google.generativeai as genai
75
+ # genai.configure(api_key=api_key)
76
+
77
+ # async def response_general(input:str)->list:
78
+ # api_key = get_key.get_random_api_key()
79
+ # genai.configure(api_key=api_key)
80
+ # generation_config = {
81
+ # "temperature": 1,
82
+ # "top_p": 0.95,
83
+ # "top_k": 40,
84
+ # "max_output_tokens": 8192,
85
+ # "response_mime_type": "text/plain",
86
+ # }
87
+
88
+
89
+ # model = genai.GenerativeModel(
90
+ # model_name="gemini-2.5-flash-preview-04-17",
91
+ # generation_config=generation_config,
92
+ # )
93
+
94
+ # chat_session = model.start_chat(
95
+ # history=[
96
+ # {
97
+ # "role": "user",
98
+ # "parts": [
99
+ # f"""Hãy vui lòng đọc kỹ các bảng sau đây gồm các thuộc tÍNH, khóa ngoại của các bảng sau khi tạo bảng trong MySQL. {prompt_create.PROMPT_TABLE}.
100
+ # Mình định nghĩa các thuộc tính tham số, mối quan hệ các bảng sau đây: {prompt_table}. Luôn đọc kĩ càng các thông tin mô tả này. Hãy xác định kĩ càng các bước, mô tả của mình để lấy các bảng cần dùng chính xác nhất.
101
+ # Hãy cân nhắc cho câu hỏi sau đây: {input}. Phân tích câu hỏi chọn các bảng cần thiết để thể trả lời câu hỏi.
102
+ # Hãy phân biệt giữa đơn hàng bình thường(orders) đơn hàng nhóm(group_orders).
103
+ # ** Cách trả lời:
104
+ # - Bạn vui lòng trả lại danh sách các table liên quan. Vui lòng ghép chúng vào trong list và nối với nhau bằng , ví dụ ["cart","user"].
105
+ # - Luôn bao gồm bảng user trong mọi trường hợp câu hỏi.
106
+ # - Chỉ lấy tên các bảng mình đã cung cấp, không được tự ý sinh thêm bảng. Điều này là cấm.
107
+ # - Không được phép dùng bảng "Token, user_chat, notification"
108
+ # - Nếu trong list có bảng cart thì phải kèm theo cart_item
109
+ # - Nếu trong list có bảng cart_group thì phải kèm theo cart_item_group
110
+ # - Nếu trong bảngchứa các bảng như cart_item, cart_item_group thì vui lòng kèm theo các bảng liên quan về sản phẩm như product_translation và product_variants, product
111
+ # - Nếu trong list bảng category thì phải kèm theo category_translation, product phải kèm theo product_translation product_variant
112
+ # - Nếu trong list có bảng group_orders thì phải kèm theo group_order_members.
113
+ # - Nếu trong list bảng group_order_members thì phải kèm theo cart_group.
114
+ # - Nếu trong list trả về các bảng như product, post, hay category phải kèm theo bảng translation liên kết với .
115
+ # - Khi trong list liên quan product hãy luôn cung cấp product_variants để thể cung cấp thêm giá tùy trương hợp.
116
+ # - Không yêu cầu giải thích gì thêm chỉ cần trả về list theo mình mô tả ví dụ.
117
+ # - Luôn đảm bảo Xác định chính xác bảng cần dùng cho câu hỏi, không dư thừa bảng, không bỏ sót bảng cần thiết.
118
+ # - Luôn luôn trả về đúng list []. Cấm trả sai định dạng mà mình đã cung cấp""",
119
+ # ],
120
+ # }
121
+ # ]
122
+ # )
123
+
124
+ # response = chat_session.send_message("Hãy luôn đảm bảo rằng bạn tuân thủ những gì mình đưa ra, không được phép làm khác đi.")
125
+ # data = response.text
126
+ # if data.strip(): # Kiểm tra dữ liệu không rỗng
127
+ # try:
128
+ # # Cố gắng parse JSON
129
+ # data_list = json.loads(data)
130
+ # return data_list
131
+ # except json.JSONDecodeError:
132
+ # # Nếu không phải JSON, thử tìm danh sách bảng trong chuỗi văn bản
133
+ # match = re.search(r'\[(.*?)\]', data)
134
+ # if match:
135
+ # # Lấy phần trong dấu [ ], tách thành list
136
+ # items_str = match.group(1)
137
+ # items = [item.strip().strip('"').strip("'") for item in items_str.split(',')]
138
+ # print("Danh sách bảng đã trích xuất:", items)
139
+ # return items
140
+ # else:
141
+ # print("Không tìm thấy danh sách bảng trong dữ liệu văn bản!")
142
+ # else:
143
+ # print("Dữ liệu đầu vào rỗng!")
144
+
145
+
146
+ import asyncio
147
+ import json
148
+ import re
149
+ from support import get_key
150
+ import google.generativeai as genai
151
+
152
+ async def response_general(input: str) -> list:
153
+ async def call_model_once() -> list:
154
+ # Lấy API key và cấu hình
155
+ api_key = get_key.get_random_api_key()
156
+ genai.configure(api_key=api_key)
157
+
158
+ generation_config = {
159
+ "temperature": 1,
160
+ "top_p": 0.95,
161
+ "top_k": 40,
162
+ "max_output_tokens": 8192,
163
+ "response_mime_type": "text/plain",
164
+ }
165
+
166
+ model = genai.GenerativeModel(
167
+ model_name="gemini-2.5-flash-preview-04-17",
168
+ generation_config=generation_config,
169
+ )
170
+
171
+ chat_session = model.start_chat(
172
+ history=[
173
+ {
174
+ "role": "user",
175
+ "parts": [
176
+ f"""Hãy vui lòng đọc kỹ các bảng sau đây gồm các thuộc tÍNH, khóa ngoại của các bảng sau khi tạo bảng trong MySQL. {prompt_create.PROMPT_TABLE}.
177
+ Mình định nghĩa các thuộc tính tham số, mối quan hệ các bảng sau đây: {prompt_table}. Luôn đọc kĩ càng các thông tin mô tả này. Hãy xác định kĩ càng các bước, mô tả của mình để lấy các bảng cần dùng chính xác nhất.
178
+ Hãy cân nhắc cho câu hỏi sau đây: {input}. Phân tích câu hỏi chọn các bảng cần thiết để thể trả lời câu hỏi.
179
+ Hãy phân biệt giữa đơn hàng bình thường(orders) đơn hàng nhóm(group_orders).
180
+ ** Cách trả lời:
181
+ - Bạn vui lòng trả lại danh sách các table liên quan. Vui lòng ghép chúng vào trong list và nối với nhau bằng , ví dụ ["cart","user"].
182
+ - Luôn bao gồm bảng user trong mọi trường hợp câu hỏi.
183
+ - Chỉ lấy tên các bảng mình đã cung cấp, không được tự ý sinh thêm bảng. Điều này là cấm.
184
+ - Không được phép dùng bảng "Token, user_chat, notification"
185
+ - Nếu trong list có bảng cart thì phải kèm theo cart_item
186
+ - Nếu trong list có bảng cart_group thì phải kèm theo cart_item_group
187
+ - Nếu trong bảngchứa các bảng như cart_item, cart_item_group thì vui lòng kèm theo các bảng liên quan về sản phẩm như product_translation và product_variants, product
188
+ - Nếu trong list bảng category thì phải kèm theo category_translation, product phải kèm theo product_translation product_variant
189
+ - Nếu trong list có bảng group_orders thì phải kèm theo group_order_members.
190
+ - Nếu trong list bảng group_order_members thì phải kèm theo cart_group.
191
+ - Nếu trong list trả về các bảng như product, post, hay category phải kèm theo bảng translation liên kết với .
192
+ - Khi trong list liên quan product hãy luôn cung cấp product_variants để thể cung cấp thêm giá tùy trương hợp.
193
+ - Không yêu cầu giải thích gì thêm chỉ cần trả về list theo mình mô tả ví dụ.
194
+ - Luôn đảm bảo Xác định chính xác bảng cần dùng cho câu hỏi, không dư thừa bảng, không bỏ sót bảng cần thiết.
195
+ - Luôn luôn trả về đúng list []. Cấm trả sai định dạng mà mình đã cung cấp""",
196
+ ],
197
+ }
198
+ ]
199
+ )
200
+
201
+ response = await chat_session.send_message_async("Hãy luôn đảm bảo rằng bạn tuân thủ những gì mình đưa ra, không được phép làm khác đi.")
202
+ data = response.text
203
+
204
+ if data.strip():
205
+ try:
206
+ return json.loads(data)
207
+ except json.JSONDecodeError:
208
+ match = re.search(r'\[(.*?)\]', data)
209
+ if match:
210
+ items_str = match.group(1)
211
+ items = [item.strip().strip('"').strip("'") for item in items_str.split(',')]
212
+ print(" Danh sách bảng đã trích xuất:", items)
213
+ return items
214
+ else:
215
+ raise ValueError("Không tìm thấy danh sách bảng hợp lệ trong phản hồi văn bản.")
216
+ else:
217
+ raise ValueError("Dữ liệu phản hồi trống.")
218
+
219
+ # Gọi lần đầu
220
+ try:
221
+ return await call_model_once()
222
+ except Exception as e:
223
+ print(f"⚠️ Lỗi lần đầu: {e} — thử lại sau 2 giây...")
224
+ await asyncio.sleep(2)
225
+
226
+ try:
227
+ return await call_model_once()
228
+ except Exception as retry_error:
229
+ print(f"❌ Lỗi lần 2: {retry_error}")
230
+ raise Exception("Gọi hình thất bại sau khi thử lại.")
231
+
232
+
233
+ # if __name__ == "__main__":
234
+ # import asyncio
235
  # asyncio.run(response_general("Danh sách bài đăng mới nhất"))