Spaces:
Sleeping
Sleeping
File size: 12,004 Bytes
6f8d9d0 325b400 |
1 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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
from langchain_community.utilities.sql_database import SQLDatabase
from langchain_experimental.sql import SQLDatabaseChain
import os, sys
import os
from dotenv import load_dotenv
# Load biến môi trường từ file .env
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../")) # hoặc ".." tùy vị trí
dotenv_path = os.path.join(BASE_DIR, ".env")
import os
from dotenv import load_dotenv
# # Gán đường dẫn tuyệt đối đến file .env
# dotenv_path = r"d:\HmDrinks_Chat\V2\chatbot - 19_5\.env"
from dotenv import load_dotenv, find_dotenv
# Tự động tìm file .env gần nhất trong cây thư mục cha
load_dotenv(find_dotenv(), override=True)
# Debug kiểm tra
# print(">> DEBUG: dotenv_path =", dotenv_path)
# print(">> DEBUG: DB_HOST =", os.getenv("DB_HOST"))
# print(">> DEBUG: DB_USER =", os.getenv("DB_USER"))
# print(">> DEBUG: DB_PASSWORD =", os.getenv("DB_PASSWORD"))
# print(">> DEBUG: DB_NAME =", os.getenv("DB_NAME"))
# print(">> DEBUG: DB_PORT =", os.getenv("DB_PORT"))
DB_HOST = os.getenv("DB_HOST")
DB_USER = os.getenv("DB_USER")
DB_PASSWORD = os.getenv("DB_PASSWORD")
DB_NAME = os.getenv("DB_NAME")
DB_PORT = os.getenv("DB_PORT")
import os
from urllib.parse import quote
password = os.getenv("DB_PASSWORD")
DB_PASSWORD = quote(password)
# Tạo connection string
connection_uri = (
f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
"?ssl_verify_cert=false&ssl_verify_identity=false"
)
print(">> DEBUG connection_uri:", connection_uri)
current_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.abspath(os.path.join(current_dir, '..', '..')) # Lên 2 cấp
sys.path.append(project_root)
from support import get_key
api_key = get_key.get_random_api_key()
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
os.environ["GOOGLE_API_KEY"] = "AIzaSyCO-RlqYewC4e9BEPoC8m-AxHUY7J3_o2E"
import prompt.prompt_main as prompt
from langchain_google_genai import GoogleGenerativeAIEmbeddings, ChatGoogleGenerativeAI
llm1 = ChatGoogleGenerativeAI(model='gemini-2.0-flash-thinking-exp-01-21',temperature=0.6,api_key=api_key)
db = SQLDatabase.from_uri(connection_uri)
db.get_table_info_no_throw()
import re
db_chain = SQLDatabaseChain.from_llm(llm=llm1,db=db,prompt= prompt.PROMPT)
import prompt.prompt_table as prompt_table
import prompt.prompt_create_table as prompt_create
import json
# import google.generativeai as genai
# genai.configure(api_key=api_key)
# async def response_general(input:str)->list:
# api_key = get_key.get_random_api_key()
# genai.configure(api_key=api_key)
# generation_config = {
# "temperature": 1,
# "top_p": 0.95,
# "top_k": 40,
# "max_output_tokens": 8192,
# "response_mime_type": "text/plain",
# }
# model = genai.GenerativeModel(
# model_name="gemini-2.5-flash-preview-04-17",
# generation_config=generation_config,
# )
# chat_session = model.start_chat(
# history=[
# {
# "role": "user",
# "parts": [
# 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}.
# 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.
# 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.
# Hãy phân biệt rõ giữa đơn hàng bình thường(orders) và đơn hàng nhóm(group_orders).
# ** Cách trả lời:
# - 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"].
# - Luôn bao gồm bảng user trong mọi trường hợp câu hỏi.
# - 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.
# - Không được phép dùng bảng "Token, user_chat, notification"
# - Nếu trong list có bảng cart thì phải kèm theo cart_item
# - Nếu trong list có bảng cart_group thì phải kèm theo cart_item_group
# - Nếu trong bảng có 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
# - 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
# - Nếu trong list có bảng group_orders thì phải kèm theo group_order_members.
# - Nếu trong list có bảng group_order_members thì phải kèm theo cart_group.
# - Nếu trong list trả về có các bảng như product, post, hay category phải kèm theo bảng translation liên kết với nó.
# - 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.
# - 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ụ.
# - 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.
# - Luôn luôn trả về đúng list []. Cấm trả sai định dạng mà mình đã cung cấp""",
# ],
# }
# ]
# )
# 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.")
# data = response.text
# if data.strip(): # Kiểm tra dữ liệu không rỗng
# try:
# # Cố gắng parse JSON
# data_list = json.loads(data)
# return data_list
# except json.JSONDecodeError:
# # Nếu không phải JSON, thử tìm danh sách bảng trong chuỗi văn bản
# match = re.search(r'\[(.*?)\]', data)
# if match:
# # Lấy phần trong dấu [ ], tách thành list
# items_str = match.group(1)
# items = [item.strip().strip('"').strip("'") for item in items_str.split(',')]
# print("Danh sách bảng đã trích xuất:", items)
# return items
# else:
# print("Không tìm thấy danh sách bảng trong dữ liệu văn bản!")
# else:
# print("Dữ liệu đầu vào rỗng!")
import asyncio
import json
import re
from support import get_key
import google.generativeai as genai
async def response_general(input: str) -> list:
async def call_model_once() -> list:
# Lấy API key và cấu hình
api_key = get_key.get_random_api_key()
genai.configure(api_key=api_key)
generation_config = {
"temperature": 1,
"top_p": 0.95,
"top_k": 40,
"max_output_tokens": 8192,
"response_mime_type": "text/plain",
}
model = genai.GenerativeModel(
model_name="gemini-2.5-flash-preview-04-17",
generation_config=generation_config,
)
chat_session = model.start_chat(
history=[
{
"role": "user",
"parts": [
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}.
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.
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.
Hãy phân biệt rõ giữa đơn hàng bình thường(orders) và đơn hàng nhóm(group_orders).
** Cách trả lời:
- 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"].
- Luôn bao gồm bảng user trong mọi trường hợp câu hỏi.
- 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.
- Không được phép dùng bảng "Token, user_chat, notification"
- Nếu trong list có bảng cart thì phải kèm theo cart_item
- Nếu trong list có bảng cart_group thì phải kèm theo cart_item_group
- Nếu trong bảng có 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
- 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
- Nếu trong list có bảng group_orders thì phải kèm theo group_order_members.
- Nếu trong list có bảng group_order_members thì phải kèm theo cart_group.
- Nếu trong list trả về có các bảng như product, post, hay category phải kèm theo bảng translation liên kết với nó.
- 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.
- 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ụ.
- 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.
- Luôn luôn trả về đúng list []. Cấm trả sai định dạng mà mình đã cung cấp""",
],
}
]
)
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.")
data = response.text
if data.strip():
try:
return json.loads(data)
except json.JSONDecodeError:
match = re.search(r'\[(.*?)\]', data)
if match:
items_str = match.group(1)
items = [item.strip().strip('"').strip("'") for item in items_str.split(',')]
print("✅ Danh sách bảng đã trích xuất:", items)
return items
else:
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.")
else:
raise ValueError("Dữ liệu phản hồi trống.")
# Gọi lần đầu
try:
return await call_model_once()
except Exception as e:
print(f"⚠️ Lỗi lần đầu: {e} — thử lại sau 2 giây...")
await asyncio.sleep(2)
try:
return await call_model_once()
except Exception as retry_error:
print(f"❌ Lỗi lần 2: {retry_error}")
raise Exception("Gọi mô hình thất bại sau khi thử lại.")
# if __name__ == "__main__":
# import asyncio
# asyncio.run(response_general("Danh sách bài đăng mới nhất")) |