Spaces:
Sleeping
Sleeping
| 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")) |