Spaces:
Sleeping
Sleeping
File size: 8,345 Bytes
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 |
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
import os
import os,sys
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../"))
sys.path.insert(0, BASE_DIR)
import function.gemini_response.filter_query_internal as filter_query
#Test OpenAI
os.environ["OPENAI_API_KEY"] = "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"
llm = ChatOpenAI(model="gpt-4.1")
#Test google
os.environ["GOOGLE_API_KEY"] = "AIzaSyB_7ahCuAOZU0UKcON_A00ya5breHTEgQM"
from langchain_google_genai import GoogleGenerativeAIEmbeddings, ChatGoogleGenerativeAI
llm1 = ChatGoogleGenerativeAI(model='gemini-2.5-flash-preview-05-20',temperature=0.6)
from langchain_core.messages import HumanMessage, ToolMessage
@tool
def question_information(query: str) -> str:
"""
Trả lời các câu hỏi về thông tin liên hệ của cửa hàng, thông tin về sinh viên, tên đề tài các nội dung liên quan mà không phải sql
Hàm này chỉ phục vụ mục đích cung cấp thông tin liên lạc của cửa hàng, bao gồm:
- Số điện thoại liên hệ.
- Địa chỉ cửa hàng.
- Giờ làm việc.
- Email hỗ trợ.
- Các kênh liên hệ khác như Facebook, Zalo, v.v.
⚠️ Lưu ý:
- Hàm này KHÔNG trả lời các câu hỏi khác như: gợi ý món ăn, tư vấn sản phẩm, giá cả, chương trình khuyến mãi, cách pha chế đồ uống, v.v.
- Nếu truy vấn không liên quan đến thông tin cửa hàng, hàm sẽ từ chối trả lời.
Args:
query (str): Câu hỏi của người dùng liên quan đến thông tin liên hệ của cửa hàng. bao gồm:
- Số điện thoại liên hệ.
- Địa chỉ cửa hàng.
- Giờ làm việc.
- Email hỗ trợ.
- Các kênh liên hệ khác như Facebook, Zalo, v.v.
Returns:
str: Thông tin liên hệ của cửa hàng hoặc thông báo từ chối nếu câu hỏi không phù hợp. Xác định rõ câu hỏi không viết gọn
"""
return query
@tool(description="Vui lòng giữ đúng truy vấn người dùng không tạo ra câu truy vấn khác ý nghĩa câu hỏi người dùng định hỏi, (**yêu cầu phải bám sát không được tự sinh câu hỏi)")
def question_sql(query: str)->str:
"""
Hỗ trợ truy xuất schema của database để giúp tạo truy vấn SQL cho các bảng sau:
- **Giỏ hàng (cart, cart_item)**
- **Danh mục sản phẩm(tên sản phẩm) (category, category_translation)**
- **Liên hệ và yêu thích (contact, favourite, favourite_item)**
- **Thông báo (notification)**
- **Đơn hàng (orders, order_item, shipment)**
- **Thanh toán (otp, payments)**
- **Bài viết & tin tức (post, post_translation)**
- **Lịch sử giá (price_history)**
- **Sản phẩm (product, product_translation, product_variants)**
- **Đánh giá sản phẩm (review)**
- **Người dùng (user, user_coin, token)**
- **Mã giảm giá & phiếu giảm giá (voucher, user_voucher)**
- **Xác nhận về mua/xem, xóa giỏ hàng, đơn hàng**(Hãy lưu ý những câu hỏi về này)
⚠ **Lưu ý**:
- Chỉ hỗ trợ truy vấn liên quan đến các bảng trong database.
- Không trả lời các câu hỏi về thông tin cửa hàng như số điện thoại, email, giờ làm việc.
Args:
query (str): Câu hỏi liên quan đến việc truy vấn dữ liệu từ database.
Returns:
str: Mô tả bảng tương ứng hoặc thông báo từ chối nếu câu hỏi không phù hợp.
"""
return query
@tool
def question_general(query: str) -> str:
"""
Xử lý các câu hỏi không liên quan đến các công cụ có sẵn.
Hàm này nhận vào một câu hỏi dưới dạng chuỗi và trả về câu hỏi đó
mà không thực hiện bất kỳ xử lý nào khác. Nó có thể được sử dụng như
một phương án dự phòng khi không có tool nào phù hợp để xử lý câu hỏi.
Args:
query (str): Câu hỏi đầu vào từ người dùng.
Returns:
str: Trả về chính câu hỏi mà không thay đổi.
"""
return query
@tool(description="""ác định xem truy vấn có phải là câu chào hỏi hay không.
Câu chào hỏi bao gồm các từ hoặc cụm từ thể hiện sự chào đón, bắt đầu cuộc trò chuyện, chẳng hạn như:
- "Xin chào", "Chào bạn", "Hello", "Hi", "Hey", "Good morning", "Good evening", ...
- Cụm từ mang ý nghĩa xã giao: "Rất vui được gặp bạn", "Hôm nay bạn thế nào?", "Chúc một ngày tốt lành", ...
Lưu ý:
- Chỉ xử lý các câu hỏi thuộc nhóm chào hỏi.
- Không liên quan đến **question_sql** hoặc các câu hỏi về dữ liệu.
Args:
query (str): Câu hỏi đầu vào của người dùng.
Returns:
str: Trả về câu hỏi nếu nó thuộc nhóm chào hỏi, ngược lại có thể xử lý theo yêu cầu cụ thể.""")
def question_hello(query: str)->str:
"""
Xác định xem truy vấn có phải là câu chào hỏi hay không.
Câu chào hỏi bao gồm các từ hoặc cụm từ thể hiện sự chào đón, bắt đầu cuộc trò chuyện, chẳng hạn như:
- "Xin chào", "Chào bạn", "Hello", "Hi", "Hey", "Good morning", "Good evening", ...
- Cụm từ mang ý nghĩa xã giao: "Rất vui được gặp bạn", "Hôm nay bạn thế nào?", "Chúc một ngày tốt lành", ...
Lưu ý:
- Chỉ xử lý các câu hỏi thuộc nhóm chào hỏi.
- Không liên quan đến **question_sql** hoặc các câu hỏi về dữ liệu.
Args:
query (str): Câu hỏi đầu vào của người dùng.
Returns:
str: Trả về câu hỏi nếu nó thuộc nhóm chào hỏi, ngược lại có thể xử lý theo yêu cầu cụ thể.
"""
return query
import asyncio
import importlib
import function.chat as chat_module
async def update_tool_calls(tool_calls, chat_id,user_id,user_input):
updated_calls = []
for tool in tool_calls:
query = tool['args']['query']
list_history = await chat_module.get_chat_details_text(chat_id, user_id)
new_question = await filter_query.response_rename_question(user_input, list_history, query)
tool['args']['query'] = new_question
new_name = await filter_query.response_general(new_question, list_history)
if new_name is not None and new_name == "question_sql":
tool['name'] = new_name.strip()
updated_calls.append(tool)
if new_name == "question_general":
tool['name'] = new_name.strip()
updated_calls.append(tool)
return updated_calls
else:
return tool_calls
return updated_calls
async def process_user_query(user_input, user_id, role, language,chat_id):
always_call_tool_llm = llm.bind_tools([question_information, question_sql, question_hello], tool_choice=True,strict=True)
tool_calls = always_call_tool_llm.invoke(f"{user_input}").tool_calls
for tc in tool_calls:
tc["user_id"] = user_id
tc["role"] = role
tc["language"] = language
print("Tool gốc:",tool_calls)
data = await update_tool_calls(tool_calls,chat_id,user_id,user_input)
for item in data:
item['chat_id'] = chat_id
print("Tool update: ", data)
return data
# import asyncio
async def main():
await process_user_query("Tôi muốn thêm trà chanh size L vào giỏ hàng", 4, "CUSTOMER", "VN", "67d2fc6607b51a01e3beb501")
if __name__ == "__main__":
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(main())
loop.close() |