diff --git a/.env b/.env index 277e49e..438f2b3 100644 --- a/.env +++ b/.env @@ -12,4 +12,10 @@ EMBED_DIM=768 QDRANT_URL=http://localhost:6333 QDRANT_COLLECTION=text_chunks GEMINI_API_KEY = "AIzaSyDWqNUBKhaZjbFI8CW52_hKr46JtWABkGU" -GEMINI_MODEL = "models/gemini-2.0-flash-001" \ No newline at end of file +GEMINI_MODEL = "models/gemini-2.0-flash-001" +SERPER_API_KEY = "14ea1e5de7b68084d3e41a4efe204108a8fa76c6fab062b00fa1912a97d3c28b" +GOOGLE_API_KEY=AIzaSyCOtXgt7M6qKlj5srF8hF_7iyvZbBrVnhA +GOOGLE_CX=9379e94eed0f145b4 +TRUSTED_DOMAINS = "wikipedia.org,chinhphu.vn,vnexpress.net,bbc.com,nhandan.vn,tuoitre.vn,thanhnien.vn,zingnews.vn,vov.vn,vietnamnet.vn" +ALLOW_WEB_SEARCH=true +SECOND_PASS=true diff --git a/__pycache__/main.cpython-313.pyc b/__pycache__/main.cpython-313.pyc index c461d4d..1f02bce 100644 Binary files a/__pycache__/main.cpython-313.pyc and b/__pycache__/main.cpython-313.pyc differ diff --git a/image-1.png b/image-1.png new file mode 100644 index 0000000..ed3ced8 Binary files /dev/null and b/image-1.png differ diff --git a/logs/api_2025-10-12.log b/logs/api_2025-10-12.log new file mode 100644 index 0000000..7578992 --- /dev/null +++ b/logs/api_2025-10-12.log @@ -0,0 +1,257 @@ +2025-10-12 18:14:03,660 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-12 18:15:29,187 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK" +2025-10-12 18:15:29,199 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK" +2025-10-12 18:15:29,211 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base +2025-10-12 18:15:43,063 [INFO] src.chatbot.llm_client - 🔮 LLMClient khởi tạo với model: models/gemini-2.0-flash-001 +2025-10-12 18:15:43,063 [INFO] function_router - 🔧 Đã đăng ký tool: create_txt +2025-10-12 18:15:43,064 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công. +2025-10-12 18:15:46,719 [INFO] rag_api - 📥 Câu hỏi: Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nhân viên? +2025-10-12 18:16:03,855 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-12 18:19:21,649 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-12 18:19:27,724 [INFO] src.chatbot.llm_client - 💬 Gemini output: Đại học Hanover có 9 khoa. Đội ngũ cán bộ của trường bao gồm 1.120 nhân viên, trong đó có 340 giáo sư và 1.560 nhân viên... +2025-10-12 18:19:40,751 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống: +Bạn là trợ lý AI chuyên nghiệp, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn có thể vừa trả lời, vừa thực hiện hành động theo yêu cầu người dùng. Nếu người dùng chỉ đặt câu hỏi, hãy trả lời tự nhiên. Nếu người dùng yêu cầu hành động, hãy trả về **đúng JSON hợp lệ**. + +### Dữ liệu ngữ cảnh: +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.886) +Đại học Hanover + +Đại học Hanover, chính thức là Gottfried Wilhelm Leibniz Universität Hannover hoặc Luh, là một trường đại học nằm ở Hanover, Đức. Trường được thành lập vào năm 1831 và là tổ chức đào tạo đại học lớn thứ hai ở Niedersachsen. Đại học Leibniz Hannover là một thành viên của TU9, một hiệp hội của chín Viện Công nghệ hàng đầu tại Đức. +Lịch sử. +Trường đại học này được thành lập vào năm 1831 là một trường cao đẳng thương mại. Trường đã bắt đầu nghiên cứu toán học, kiến trúc, kỹ thuật, lịch sử tự nhiên, vật lý, hóa học, vẽ, công nghệ, nghiên cứu và kế toán. Năm 1879 trường đã được nâng cấp thành Trường Cao đẳng Công nghệ Hoàng gia, năm 1898 nó đã được trao quyền đào tạo tiến sĩ. +Lĩnh vực của trường đại học này, từ đầu của nó, tập trung vào khoa học và công nghệ. Trong thế kỷ 20, các ngành nghệ thuật và nhân văn đã được bổ sung, và trường đã được sáp nhập thêm Trường Cao đẳng Sư phạm trước đó là một trường độc lập. +Khoa. +Trường có 9 khoa với hơn 150 cấp độ độ đầu tiên toàn thời gian và các khóa học trình độ bán thời gian, khiến cho trường này là trường đại học lớn thứ hai của giáo dục đại học tổ chức ở Lower Saxony. Đội ngũ cán bộ trường đại học này bao gồm 1.120 nhân viên, bao gồm 340 giáo sư, 1.560 nhân viên trong các chức năng hành chính, và có thêm 900 người được tài trợ của bên thứ ba. + +(Đoạn 2 - score=0.630) +Viện Thiên văn học của Đại học Hawaii + +Viện Thiên văn học của Đại học Hawaii (, viết tắt: IfA) là một đơn vị nghiên cứu trong hệ thống Đại học Hawaii, do Günther Hasinger làm giám đốc. Trụ sở chính của IfA đặt tại 2680 Woodlawn Drive ở Honolulu, Hawaii, , trong khuôn viên Đại học Hawaii tại Mānoa. Các cơ sở khác đặt tại Pukalani, Maui và Hilo trên đảo Hawaiʻi (Đảo Lớn). IfA tuyển dụng hơn 150 nhà thiên văn học và tình nguyện viên. Các nhà thiên văn IfA thực hiện nghiên cứu vật thể, sao, thiên hà và Hệ Mặt Trời. +Viện Thiên văn học được thành lập năm 1967 để nghiên cứu và quản lý các khu phức hợp quan sát tại Haleakalā, Maui và Đài Quan sát Mauna Kea trên đỉnh Mauna Kea. Nó có khoảng 55 giảng viên và hơn 300 nhân viên. + +(Đoạn 3 - score=0.607) +Đại học Khoa học Đời sống Warszawa + +Đại học Khoa học Đời sống Warszawa (, SGGW) là trường đại học nông nghiệp lớn nhất Ba Lan, được thành lập năm 1816 tại Warszawa. Trường có hơn 2.600 nhân viên bao gồm hơn 1.200 nhà giáo dục học thuật. Từ năm 2005, trường đại học này là một thành viên của tổ chức Euroleague cho Khoa học sự sống (ELLS) được thành lập năm 2001. SGGW cung cấp khoảng 37 lĩnh vực nghiên cứu khác nhau, 13 khoa Khoa học Nông nghiệp, Khoa học Kinh tế, Nhân văn, Kỹ thuật cũng như Khoa học Đời sống. +Khuôn viên. +Khuôn viên trường nằm ở quận cực nam của Warszawa, Ursynów. Khuôn viên có một phần lịch sử, với một cung điện từ thế kỷ 18, và một phần hiện đại nơi có hầu hết các tòa nhà văn phòng khoa và ký túc xá. Trên khuôn viên chính rộng 70 ha, có 12 ký túc xá, thư viện hiện đại, trung tâm thể thao (có sân tennis, phòng thể thao và hồ bơi) một trung tâm ngôn ngữ, phòng khám thú y. + +(Đoạn 4 - score=0.591) +Hán học + +Hán học (chữ Hán: 漢學) hay Trung Quốc học (chữ Hán: 中國學) là ngành khoa học chuyên nghiên cứu về Trung Quốc, bao gồm lịch sử, chính trị, xã hội, triết học, kinh tế, thậm chí nghiên cứu cả về cộng đồng người Hoa ở nước ngoài. Đây là khái niệm do người nước ngoài đặt ra, tiếng Anh gọi môn khoa học này là Sinology hay Chinese Studies, còn người Trung Quốc gọi khoa học nghiên cứu về Trung Quốc là Quốc học 國學. +Lịch sử. +Ban đầu Hán học chỉ nghiên cứu về văn hoá cổ đại Trung Quốc, chủ yếu nghiên cứu cổ văn, triết học, văn học, hầu như không bao quát hết xã hội Trung Quốc hiện đại. Sau Chiến tranh thế giới thứ hai, Hán học mới bắt đầu nghiên cứu đến Trung Quốc hiện đại. +Hán học thường được chia làm hai thời kỳ là "Hán học cổ đại" và "Hán học hiện đại" … + +### Công cụ có thể sử dụng: + +Hiện bạn có thể sử dụng công cụ sau: +1. create_txt(text: str) — Tạo file .txt chứa nội dung văn bản. + +Nếu người dùng yêu cầu hành động (như tạo, lưu, ghi vào file), +hãy trả về đúng JSON theo mẫu sau: +{"action": "create_txt", "params": {"text": ""}} + +Nếu người dùng chỉ hỏi thông tin, hãy trả lời văn bản tự nhiên, không JSON. + + +### Câu hỏi của người dùng: +Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nhân viên? + +### Hướng dẫn cho AI: +- Nếu người dùng chỉ hỏi → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu người dùng yêu cầu lưu/tạo file → hãy dùng create_txt. +- Khi trả về JSON, không thêm giải thích, chỉ trả JSON hợp lệ duy nhất. +- Nếu không đủ dữ liệu, hãy nói rõ ràng rằng bạn chưa có thông tin chính xác. +- Không bịa thêm, không suy diễn. + +### Trả lời: +... +2025-10-12 18:19:45,211 [INFO] rag_api - ✅ Đã trả lời: Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nh... +2025-10-12 18:20:13,978 [INFO] rag_api - 📥 Câu hỏi: Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nhân viên? Lưu thông tin vào file txt +2025-10-12 18:20:16,935 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-12 18:21:46,603 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-12 18:22:08,879 [INFO] src.chatbot.llm_client - 💬 Gemini output: Đại học Hanover có 9 khoa. Số lượng nhân viên là 1.120, bao gồm 340 giáo sư, 1.560 nhân viên hành chính, và 900 người đư... +2025-10-12 18:22:21,101 [INFO] src.chatbot.llm_client - 🤖 Function call JSON: {'action': 'create_txt', 'params': {'text': 'Đại học Hanover có 9 khoa. Số lượng nhân viên là 1.120, bao gồm 340 giáo sư, 1.560 nhân viên hành chính, và 900 người được tài trợ.'}} +2025-10-12 18:22:34,885 [WARNING] function_executor - Không thể parse JSON từ LLM output: 'dict' object has no attribute 'find' +2025-10-12 18:22:47,884 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống: +Bạn là trợ lý AI chuyên nghiệp, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn có thể vừa trả lời, vừa thực hiện hành động theo yêu cầu người dùng. Nếu người dùng chỉ đặt câu hỏi, hãy trả lời tự nhiên. Nếu người dùng yêu cầu hành động, hãy trả về **đúng JSON hợp lệ**. + +### Dữ liệu ngữ cảnh: +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.818) +Đại học Hanover + +Đại học Hanover, chính thức là Gottfried Wilhelm Leibniz Universität Hannover hoặc Luh, là một trường đại học nằm ở Hanover, Đức. Trường được thành lập vào năm 1831 và là tổ chức đào tạo đại học lớn thứ hai ở Niedersachsen. Đại học Leibniz Hannover là một thành viên của TU9, một hiệp hội của chín Viện Công nghệ hàng đầu tại Đức. +Lịch sử. +Trường đại học này được thành lập vào năm 1831 là một trường cao đẳng thương mại. Trường đã bắt đầu nghiên cứu toán học, kiến trúc, kỹ thuật, lịch sử tự nhiên, vật lý, hóa học, vẽ, công nghệ, nghiên cứu và kế toán. Năm 1879 trường đã được nâng cấp thành Trường Cao đẳng Công nghệ Hoàng gia, năm 1898 nó đã được trao quyền đào tạo tiến sĩ. +Lĩnh vực của trường đại học này, từ đầu của nó, tập trung vào khoa học và công nghệ. Trong thế kỷ 20, các ngành nghệ thuật và nhân văn đã được bổ sung, và trường đã được sáp nhập thêm Trường Cao đẳng Sư phạm trước đó là một trường độc lập. +Khoa. +Trường có 9 khoa với hơn 150 cấp độ độ đầu tiên toàn thời gian và các khóa học trình độ bán thời gian, khiến cho trường này là trường đại học lớn thứ hai của giáo dục đại học tổ chức ở Lower Saxony. Đội ngũ cán bộ trường đại học này bao gồm 1.120 nhân viên, bao gồm 340 giáo sư, 1.560 nhân viên trong các chức năng hành chính, và có thêm 900 người được tài trợ của bên thứ ba. + +(Đoạn 2 - score=0.584) +Viện Thiên văn học của Đại học Hawaii + +Viện Thiên văn học của Đại học Hawaii (, viết tắt: IfA) là một đơn vị nghiên cứu trong hệ thống Đại học Hawaii, do Günther Hasinger làm giám đốc. Trụ sở chính của IfA đặt tại 2680 Woodlawn Drive ở Honolulu, Hawaii, , trong khuôn viên Đại học Hawaii tại Mānoa. Các cơ sở khác đặt tại Pukalani, Maui và Hilo trên đảo Hawaiʻi (Đảo Lớn). IfA tuyển dụng hơn 150 nhà thiên văn học và tình nguyện viên. Các nhà thiên văn IfA thực hiện nghiên cứu vật thể, sao, thiên hà và Hệ Mặt Trời. +Viện Thiên văn học được thành lập năm 1967 để nghiên cứu và quản lý các khu phức hợp quan sát tại Haleakalā, Maui và Đài Quan sát Mauna Kea trên đỉnh Mauna Kea. Nó có khoảng 55 giảng viên và hơn 300 nhân viên. + +(Đoạn 3 - score=0.573) +Đại học Khoa học Đời sống Warszawa + +Đại học Khoa học Đời sống Warszawa (, SGGW) là trường đại học nông nghiệp lớn nhất Ba Lan, được thành lập năm 1816 tại Warszawa. Trường có hơn 2.600 nhân viên bao gồm hơn 1.200 nhà giáo dục học thuật. Từ năm 2005, trường đại học này là một thành viên của tổ chức Euroleague cho Khoa học sự sống (ELLS) được thành lập năm 2001. SGGW cung cấp khoảng 37 lĩnh vực nghiên cứu khác nhau, 13 khoa Khoa học Nông nghiệp, Khoa học Kinh tế, Nhân văn, Kỹ thuật cũng như Khoa học Đời sống. +Khuôn viên. +Khuôn viên trường nằm ở quận cực nam của Warszawa, Ursynów. Khuôn viên có một phần lịch sử, với một cung điện từ thế kỷ 18, và một phần hiện đại nơi có hầu hết các tòa nhà văn phòng khoa và ký túc xá. Trên khuôn viên chính rộng 70 ha, có 12 ký túc xá, thư viện hiện đại, trung tâm thể thao (có sân tennis, phòng thể thao và hồ bơi) một trung tâm ngôn ngữ, phòng khám thú y. + +(Đoạn 4 - score=0.545) +Đại học Eötvös Loránd + +Đại học Eötvös Loránd (phiên âm: Ết-vêx Lô-ran), thành lập năm 1635, là trường đại học lớn nhất ở Hungary. Trường tọa lạc tại Thủ đô Budapest. +Lịch sử. +Trường được Đức Tổng Giám mục và nhà thần học Péter Pázmány thành lập năm 1635 tại Nagyszombat (Trnava, Slovakia hiện nay). Các tu sĩ Dòng Tên đã nắm quyền lãnh đạo trường. Ban đầu, trường chỉ có hai trường thành viên (Trường Nghệ thuật và Trường Thần học). Đại học Luật đã được bổ sung năm 1667 và Đại học Y khoa đã được bắt đầu năm 1769. Sau đợt giải thể của trật tự dòng Tên, trường đại học đã được chuyển đến Buda (ngày nay là một phần của Budapest) vào năm 1777 phù hợp với ý định của người sáng lập. Trường đã được di chuyển đến vị trí cuối cùng của nó trong Pest (cũng là một phần của Budapest) năm 1784 … + +### Công cụ có thể sử dụng: + +Hiện bạn có thể sử dụng công cụ sau: +1. create_txt(text: str) — Tạo file .txt chứa nội dung văn bản. + +Nếu người dùng yêu cầu hành động (như tạo, lưu, ghi vào file), +hãy trả về đúng JSON theo mẫu sau: +{"action": "create_txt", "params": {"text": ""}} + +Nếu người dùng chỉ hỏi thông tin, hãy trả lời văn bản tự nhiên, không JSON. + + +### Câu hỏi của người dùng: +Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nhân viên? Lưu thông tin vào file txt + +### Hướng dẫn cho AI: +- Nếu người dùng chỉ hỏi → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu người dùng yêu cầu lưu/tạo file → hãy dùng create_txt. +- Khi trả về JSON, không thêm giải thích, chỉ trả JSON hợp lệ duy nhất. +- Nếu không đủ dữ liệu, hãy nói rõ ràng rằng bạn chưa có thông tin chính xác. +- Không bịa thêm, không suy diễn. + +### Trả lời: +... +2025-10-12 18:22:50,804 [INFO] rag_api - ✅ Đã trả lời: Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nh... +2025-10-12 18:23:12,573 [INFO] rag_api - 📥 Câu hỏi: Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nhân viên? Lưu thông tin vào file txt +2025-10-12 18:23:14,740 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-12 18:23:26,449 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-12 18:23:35,323 [INFO] src.chatbot.llm_client - 💬 Gemini output: Đại học Hanover có 9 khoa. Đội ngũ cán bộ của trường bao gồm 1.120 nhân viên, bao gồm 340 giáo sư, 1.560 nhân viên trong... +2025-10-12 18:23:56,910 [INFO] src.chatbot.llm_client - 🤖 Function call JSON: {'action': 'create_txt', 'params': {'text': 'Đại học Hanover có 9 khoa. Đội ngũ cán bộ của trường bao gồm 1.120 nhân viên, bao gồm 340 giáo sư, 1.560 nhân viên trong các chức năng hành chính, và có thêm 900 người được tài trợ của bên thứ ba.'}} +2025-10-12 18:27:48,814 [WARNING] function_executor - Không thể parse JSON từ LLM output: 'dict' object has no attribute 'find' +2025-10-12 18:29:06,767 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-12 18:29:38,852 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-12 18:29:56,031 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK" +2025-10-12 18:29:56,039 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK" +2025-10-12 18:29:56,050 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base +2025-10-12 18:30:02,939 [INFO] src.chatbot.llm_client - 🔮 LLMClient khởi tạo với model: models/gemini-2.0-flash-001 +2025-10-12 18:30:02,939 [INFO] function_router - 🔧 Đã đăng ký tool: create_txt +2025-10-12 18:30:02,939 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công. +2025-10-12 18:30:05,771 [INFO] rag_api - 📥 Câu hỏi: Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nhân viên? Lưu thông tin vào file txt +2025-10-12 18:30:10,939 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-12 18:30:27,710 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-12 18:30:32,763 [INFO] src.chatbot.llm_client - 💬 Gemini output: Đại học Hanover có 9 khoa. Đội ngũ cán bộ của trường bao gồm 1.120 nhân viên, bao gồm 340 giáo sư, 1.560 nhân viên trong... +2025-10-12 18:30:37,214 [INFO] src.chatbot.llm_client - 🤖 Function call JSON: {'action': 'create_txt', 'params': {'text': 'Đại học Hanover có 9 khoa. Đội ngũ cán bộ của trường bao gồm 1.120 nhân viên, trong đó có 340 giáo sư, 1.560 nhân viên hành chính và 900 nhân viên được tài trợ.'}} +2025-10-12 18:30:54,917 [INFO] function_router - ⚙️ Gọi tool 'create_txt' với params={'text': 'Đại học Hanover có 9 khoa. Đội ngũ cán bộ của trường bao gồm 1.120 nhân viên, trong đó có 340 giáo sư, 1.560 nhân viên hành chính và 900 nhân viên được tài trợ.'} +2025-10-12 18:30:54,920 [INFO] function_router - ✅ Tool 'create_txt' thực thi thành công +2025-10-12 18:31:01,729 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống: +Bạn là trợ lý AI chuyên nghiệp, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn có thể vừa trả lời, vừa thực hiện hành động theo yêu cầu người dùng. Nếu người dùng chỉ đặt câu hỏi, hãy trả lời tự nhiên. Nếu người dùng yêu cầu hành động, hãy trả về **đúng JSON hợp lệ**. + +### Dữ liệu ngữ cảnh: +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.818) +Đại học Hanover + +Đại học Hanover, chính thức là Gottfried Wilhelm Leibniz Universität Hannover hoặc Luh, là một trường đại học nằm ở Hanover, Đức. Trường được thành lập vào năm 1831 và là tổ chức đào tạo đại học lớn thứ hai ở Niedersachsen. Đại học Leibniz Hannover là một thành viên của TU9, một hiệp hội của chín Viện Công nghệ hàng đầu tại Đức. +Lịch sử. +Trường đại học này được thành lập vào năm 1831 là một trường cao đẳng thương mại. Trường đã bắt đầu nghiên cứu toán học, kiến trúc, kỹ thuật, lịch sử tự nhiên, vật lý, hóa học, vẽ, công nghệ, nghiên cứu và kế toán. Năm 1879 trường đã được nâng cấp thành Trường Cao đẳng Công nghệ Hoàng gia, năm 1898 nó đã được trao quyền đào tạo tiến sĩ. +Lĩnh vực của trường đại học này, từ đầu của nó, tập trung vào khoa học và công nghệ. Trong thế kỷ 20, các ngành nghệ thuật và nhân văn đã được bổ sung, và trường đã được sáp nhập thêm Trường Cao đẳng Sư phạm trước đó là một trường độc lập. +Khoa. +Trường có 9 khoa với hơn 150 cấp độ độ đầu tiên toàn thời gian và các khóa học trình độ bán thời gian, khiến cho trường này là trường đại học lớn thứ hai của giáo dục đại học tổ chức ở Lower Saxony. Đội ngũ cán bộ trường đại học này bao gồm 1.120 nhân viên, bao gồm 340 giáo sư, 1.560 nhân viên trong các chức năng hành chính, và có thêm 900 người được tài trợ của bên thứ ba. + +### Công cụ có thể sử dụng: + +Hiện bạn có thể sử dụng công cụ sau: +1. create_txt(text: str) — Tạo file .txt chứa nội dung văn bản. + +Nếu người dùng yêu cầu hành động (như tạo, lưu, ghi vào file), +hãy trả về đúng JSON theo mẫu sau: +{"action": "create_txt", "params": {"text": ""}} + +Nếu người dùng chỉ hỏi thông tin, hãy trả lời văn bản tự nhiên, không JSON. + + +### Câu hỏi của người dùng: +Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nhân viên? Lưu thông tin vào file txt + +### Hướng dẫn cho AI: +- Nếu người dùng chỉ hỏi → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu người dùng yêu cầu lưu/tạo file → hãy dùng create_txt. +- Khi trả về JSON, không thêm giải thích, chỉ trả JSON hợp lệ duy nhất. +- Nếu không đủ dữ liệu, hãy nói rõ ràng rằng bạn chưa có thông tin chính xác. +- Không bịa thêm, không suy diễn. + +### Trả lời: +... +2025-10-12 18:31:04,946 [INFO] rag_api - ✅ Đã trả lời: Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nh... +2025-10-12 18:36:06,726 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-12 18:36:09,883 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK" +2025-10-12 18:36:09,916 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK" +2025-10-12 18:36:09,923 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base +2025-10-12 18:36:16,771 [INFO] src.chatbot.llm_client - 🔮 LLMClient khởi tạo với model: models/gemini-2.0-flash-001 +2025-10-12 18:36:16,771 [INFO] function_router - 🔧 Đã đăng ký tool: create_txt +2025-10-12 18:36:16,771 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công. +2025-10-12 18:36:25,890 [INFO] rag_api - 📥 Câu hỏi: Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nhân viên? Lưu thông tin vào file txt +2025-10-12 18:36:26,245 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-12 18:36:26,250 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-12 18:36:27,947 [INFO] src.chatbot.llm_client - 💬 Gemini output: Đại học Hanover có 9 khoa. Đội ngũ cán bộ của trường bao gồm 1.120 nhân viên, trong đó có 340 giáo sư, 1.560 nhân viên h... +2025-10-12 18:36:27,948 [INFO] src.chatbot.llm_client - 🤖 Function call JSON: {'action': 'create_txt', 'params': {'text': 'Đại học Hanover có 9 khoa. Đội ngũ cán bộ của trường bao gồm 1.120 nhân viên, trong đó có 340 giáo sư, 1.560 nhân viên hành chính và 900 người được tài trợ từ bên thứ ba.'}} +2025-10-12 18:36:27,949 [INFO] function_router - ⚙️ Gọi tool 'create_txt' với params={'text': 'Đại học Hanover có 9 khoa. Đội ngũ cán bộ của trường bao gồm 1.120 nhân viên, trong đó có 340 giáo sư, 1.560 nhân viên hành chính và 900 người được tài trợ từ bên thứ ba.'} +2025-10-12 18:36:27,952 [INFO] function_router - ✅ Tool 'create_txt' thực thi thành công +2025-10-12 18:36:27,952 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống: +Bạn là trợ lý AI chuyên nghiệp, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn có thể vừa trả lời, vừa thực hiện hành động theo yêu cầu người dùng. Nếu người dùng chỉ đặt câu hỏi, hãy trả lời tự nhiên. Nếu người dùng yêu cầu hành động, hãy trả về **đúng JSON hợp lệ**. + +### Dữ liệu ngữ cảnh: +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.818) +Đại học Hanover + +Đại học Hanover, chính thức là Gottfried Wilhelm Leibniz Universität Hannover hoặc Luh, là một trường đại học nằm ở Hanover, Đức. Trường được thành lập vào năm 1831 và là tổ chức đào tạo đại học lớn thứ hai ở Niedersachsen. Đại học Leibniz Hannover là một thành viên của TU9, một hiệp hội của chín Viện Công nghệ hàng đầu tại Đức. +Lịch sử. +Trường đại học này được thành lập vào năm 1831 là một trường cao đẳng thương mại. Trường đã bắt đầu nghiên cứu toán học, kiến trúc, kỹ thuật, lịch sử tự nhiên, vật lý, hóa học, vẽ, công nghệ, nghiên cứu và kế toán. Năm 1879 trường đã được nâng cấp thành Trường Cao đẳng Công nghệ Hoàng gia, năm 1898 nó đã được trao quyền đào tạo tiến sĩ. +Lĩnh vực của trường đại học này, từ đầu của nó, tập trung vào khoa học và công nghệ. Trong thế kỷ 20, các ngành nghệ thuật và nhân văn đã được bổ sung, và trường đã được sáp nhập thêm Trường Cao đẳng Sư phạm trước đó là một trường độc lập. +Khoa. +Trường có 9 khoa với hơn 150 cấp độ độ đầu tiên toàn thời gian và các khóa học trình độ bán thời gian, khiến cho trường này là trường đại học lớn thứ hai của giáo dục đại học tổ chức ở Lower Saxony. Đội ngũ cán bộ trường đại học này bao gồm 1.120 nhân viên, bao gồm 340 giáo sư, 1.560 nhân viên trong các chức năng hành chính, và có thêm 900 người được tài trợ của bên thứ ba. + +### Công cụ có thể sử dụng: + +Hiện bạn có thể sử dụng công cụ sau: +1. create_txt(text: str) — Tạo file .txt chứa nội dung văn bản. + +Nếu người dùng yêu cầu hành động (như tạo, lưu, ghi vào file), +hãy trả về đúng JSON theo mẫu sau: +{"action": "create_txt", "params": {"text": ""}} + +Nếu người dùng chỉ hỏi thông tin, hãy trả lời văn bản tự nhiên, không JSON. + + +### Câu hỏi của người dùng: +Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nhân viên? Lưu thông tin vào file txt + +### Hướng dẫn cho AI: +- Nếu người dùng chỉ hỏi → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu người dùng yêu cầu lưu/tạo file → hãy dùng create_txt. +- Khi trả về JSON, không thêm giải thích, chỉ trả JSON hợp lệ duy nhất. +- Nếu không đủ dữ liệu, hãy nói rõ ràng rằng bạn chưa có thông tin chính xác. +- Không bịa thêm, không suy diễn. + +### Trả lời: +... +2025-10-12 18:36:27,952 [INFO] rag_api - ✅ Đã trả lời: Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nh... diff --git a/logs/api_2025-10-13.log b/logs/api_2025-10-13.log new file mode 100644 index 0000000..17a6e5f --- /dev/null +++ b/logs/api_2025-10-13.log @@ -0,0 +1,1053 @@ +2025-10-13 00:25:41,494 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-13 00:26:13,383 [ERROR] rag_api - ❌ Lỗi khi khởi tạo RAGPipeline +Traceback (most recent call last): + File "C:\Users\SLG PC\Documents\rag_app_2\src\api\chat_api.py", line 58, in startup_event + from src.chatbot.rag_pipeline import RAGPipeline + File "C:\Users\SLG PC\Documents\rag_app_2\src\chatbot\rag_pipeline.py", line 11, in + from src.core.config import ALLOW_WEB_SEARCH, SECOND_PASS +ImportError: cannot import name 'ALLOW_WEB_SEARCH' from 'src.core.config' (C:\Users\SLG PC\Documents\rag_app_2\src\core\config.py) +2025-10-13 00:27:27,530 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-13 00:27:44,775 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK" +2025-10-13 00:27:44,786 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK" +2025-10-13 00:27:44,948 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base +2025-10-13 00:27:51,759 [INFO] src.chatbot.llm_client - 🔮 LLMClient khởi tạo với model: models/gemini-2.0-flash-001 +2025-10-13 00:27:51,760 [INFO] function_router - 🔧 Đã đăng ký tool: create_txt +2025-10-13 00:27:51,760 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công. +2025-10-13 00:28:23,823 [INFO] rag_api - 📥 Câu hỏi: nhóm nhạc stray kids có bao nhiêu thành viên? +2025-10-13 00:28:30,180 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 00:29:28,993 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 00:29:51,355 [INFO] src.chatbot.llm_client - 💬 Gemini output: Tôi không có thông tin về số lượng thành viên của nhóm nhạc Stray Kids. Bạn có muốn tôi tìm kiếm trên Google không?... +2025-10-13 00:30:50,288 [INFO] function_executor - ⚠️ Không có action → fallback Google Search +2025-10-13 00:31:23,120 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 00:31:27,574 [INFO] src.chatbot.llm_client - 💬 Gemini output: Stray Kids là một nhóm nhạc nam Hàn Quốc được thành lập bởi JYP Entertainment thông qua chương trình truyền hình thực tế... +2025-10-13 00:31:37,895 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống: +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. Nếu người dùng chỉ hỏi, hãy trả lời tự nhiên. Nếu người dùng yêu cầu hành động hoặc thông tin ngoài ngữ cảnh, hãy dùng công cụ phù hợp. + +### Dữ liệu ngữ cảnh (retrieved from database): +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.654) +Thời Đại Thiếu Niên Đoàn + +Thời Đại Thiếu Niên Đoàn (, , tên thường gọi: TNT) là nhóm nhạc nam Trung Quốc gồm 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn. Bảy thành viên trước khi ra mắt đều là thực tập sinh thế hệ thứ hai trực thuộc TF Entertainment, sau thành công của thế hệ thứ nhất là TFBoys. Nhóm được thành lập chính thức từ chương trình thực tế sống còn "Đài Phong Lột Xác Chiến" do TF Entertainment cải tổ lại. Chương trình kết thúc và nhóm chính thức được thành lập vào ngày 25 tháng 8 năm 2019. +Ngày 23 tháng 11 năm 2019 nhóm tổ chức buổi ra mắt và ra mắt với bài hát mới "Thông Báo Toàn Trường". +Fandom chính thức "Bạo Mễ Hoa" (tiếng Trung: 爆米花). Màu tiếp ứng là: Vàng, Đen. Khẩu hiệu tiếp ứng: Phá Thiên Hạ, Định Phong Vân, Thời Đại Thiếu Niên Tinh Kiên Hành.(tiếng Trung:破天下,定风云,时代少年并肩行). +Thành viên. +Tất cả các thành viên của Thời Đại Thiếu Niên Đoàn đều là mang quốc tịch Trung Quốc. Mã Gia Kỳ, người giành được hạng 1 trong chương trình thực tế ra mắt của cả nhóm, vừa là trưởng nhóm vừa đảm nhiệm vai trò vị trí trung tâm. +Lưu ý. + Các nội dung sau đây mang tính tham khảo, không tự ý sửa đổi, nếu sửa đổi sẽ được cho là phá hoại. Mong không sửa đổi dưới mọi hình thức, chỉ bổ sung khi thiếu, hoàn thành lại khi sai. Vì một số sửa đổi của một số bạn nên chúng tôi có thể không hoàn thiện nó như lúc đầu, vì vậy sửa đổi không cần thiết chính là phá hoại trang. + +(Đoạn 2 - score=0.611) +Boney M. + +Boney M. là một nhóm nhạc được thành lập vào năm 1976 bởi nhà sản xuất âm nhạc người Tây Đức Frank Farian. Bốn thành viên gốc của ban nhạc là Liz Mitchell và Marcia Barrett (Jamaica), Maizie Williams (Montserrat) và Bobby Farrell (Aruba). Boney M. thành công vào cuối thập niên 1970, đứng đầu nhiều bảng xếp hạng với số lượng đĩa bán lớn với những ca khúc nổi tiếng như Daddy Cool, Sunny, Rasputin... Kể từ thập niên 1980, ban nhạc thay đổi thành viên thường xuyên. Thành viên nam duy nhất Bobby Farrell qua đời vào cuối năm 2010 ở Saint Petersburg vì trụy tim. +Bảng xếp hạng. +Đĩa đơn. +"-" nghĩa là không có thông tin hoặc không được xếp hạng + +### Công cụ có thể sử dụng: + +Hiện bạn có thể sử dụng các công cụ sau: +1. search_google(query: str, max_results: int = 5) + → Tìm kiếm thông tin mới nhất trên Internet (dành cho các câu hỏi không có trong ngữ cảnh). +2. create_txt(text: str) + → Tạo file .txt chứa nội dung văn bản (nếu người dùng yêu cầu lưu lại kết quả). + +Nếu người dùng yêu cầu hành động, hãy trả về đúng JSON hợp lệ: +{"action": "", "params": {"query" hoặc "text": ""}} + +Nếu người dùng chỉ hỏi thông tin, hãy trả lời văn bản tự nhiên, không JSON. + + +### Câu hỏi của người dùng: +nhóm nhạc stray kids có bao nhiêu thành viên? + +### Hướng dẫn cho AI: +- Nếu thông tin trong ngữ cảnh đủ → trả lời bình thường, ngắn gọn, tự nhiên. +- Nếu ngữ cảnh không đủ → gọi công cụ search_google với câu hỏi gốc. +- Nếu người dùng yêu cầu hành động (như tạo/lưu file) → dùng create_txt. +- Khi trả về JSON, không thêm giải thích hay văn bản nào khác. +- Trả duy nhất một JSON hợp lệ khi gọi công cụ. +- Không bịa thêm hoặc suy diễn nếu thông tin không có. + +### Trả lời: +... +2025-10-13 00:31:42,136 [INFO] rag_api - ✅ Đã trả lời: nhóm nhạc stray kids có bao nhiêu thành viên?... +2025-10-13 00:34:20,287 [INFO] rag_api - 📥 Câu hỏi: nhóm nhạc stray kids có bao nhiêu thành viên? +2025-10-13 00:34:24,356 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 00:34:50,766 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 00:34:55,409 [INFO] src.chatbot.llm_client - 💬 Gemini output: Tôi không có thông tin về số lượng thành viên của nhóm nhạc Stray Kids. Bạn có muốn tôi tìm kiếm trên Google không?... +2025-10-13 00:41:46,324 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-13 00:42:03,781 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK" +2025-10-13 00:42:03,810 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK" +2025-10-13 00:42:03,977 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base +2025-10-13 00:42:11,346 [INFO] src.chatbot.llm_client - 🔮 LLMClient khởi tạo với model: models/gemini-2.0-flash-001 +2025-10-13 00:42:11,346 [INFO] function_router - 🔧 Đã đăng ký tool: create_txt +2025-10-13 00:42:11,346 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công. +2025-10-13 00:54:18,166 [INFO] rag_api - 📥 Câu hỏi: nhóm nhạc stray kids có bao nhiêu thành viên? +2025-10-13 00:54:22,660 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 00:54:45,794 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 00:55:05,481 [INFO] src.chatbot.llm_client - 💬 Gemini output: Tôi không có thông tin về số lượng thành viên của nhóm nhạc Stray Kids.... +2025-10-13 00:56:10,159 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-13 00:56:28,160 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK" +2025-10-13 00:56:28,167 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK" +2025-10-13 00:56:28,179 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base +2025-10-13 00:56:35,841 [INFO] src.chatbot.llm_client - 🔮 LLMClient khởi tạo với model: models/gemini-2.0-flash-001 +2025-10-13 00:56:35,841 [INFO] function_router - 🔧 Đã đăng ký tool: create_txt +2025-10-13 00:56:35,842 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công. +2025-10-13 00:56:43,560 [INFO] rag_api - 📥 Câu hỏi: nhóm nhạc stray kids có bao nhiêu thành viên? +2025-10-13 00:56:47,602 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 00:58:25,888 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 00:58:43,454 [INFO] src.chatbot.llm_client - 💬 Gemini output: Tôi không có thông tin về số lượng thành viên của nhóm nhạc Stray Kids.... +2025-10-13 01:02:59,777 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-13 01:03:17,011 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK" +2025-10-13 01:03:17,019 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK" +2025-10-13 01:03:17,187 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base +2025-10-13 01:03:25,027 [INFO] src.chatbot.llm_client - 🔮 LLMClient khởi tạo với model: models/gemini-2.0-flash-001 +2025-10-13 01:03:25,027 [INFO] function_router - 🔧 Đã đăng ký tool: create_txt +2025-10-13 01:03:25,027 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công. +2025-10-13 01:03:29,615 [INFO] rag_api - 📥 Câu hỏi: nhóm nhạc stray kids có bao nhiêu thành viên? +2025-10-13 01:03:36,705 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:03:38,581 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:03:51,722 [INFO] src.chatbot.llm_client - 💬 Gemini output: {"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}}... +2025-10-13 01:03:55,916 [INFO] src.chatbot.llm_client - 🤖 Function call JSON: {'action': 'search_google', 'params': {'query': 'Stray Kids có bao nhiêu thành viên?'}} +2025-10-13 01:04:37,209 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. + +### Ngữ cảnh (retrieved from database) +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.654) +Thời Đại Thiếu Niên Đoàn + +Thời Đại Thiếu Niên Đoàn (, , tên thường gọi: TNT) là nhóm nhạc nam Trung Quốc gồm 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn. Bảy thành viên trước khi ra mắt đều là thực tập sinh thế hệ thứ hai trực thuộc TF Entertainment, sau thành công của thế hệ thứ nhất là TFBoys. Nhóm được thành lập chính thức từ chương trình thực tế sống còn "Đài Phong Lột Xác Chiến" do TF Entertainment cải tổ lại. Chương trình kết thúc và nhóm chính thức được thành lập vào ngày 25 tháng 8 năm 2019. +Ngày 23 tháng 11 năm 2019 nhóm tổ chức buổi ra mắt và ra mắt với bài hát mới "Thông Báo Toàn Trường". +Fandom chính thức "Bạo Mễ Hoa" (tiếng Trung: 爆米花). Màu tiếp ứng là: Vàng, Đen. Khẩu hiệu tiếp ứng: Phá Thiên Hạ, Định Phong Vân, Thời Đại Thiếu Niên Tinh Kiên Hành.(tiếng Trung:破天下,定风云,时代少年并肩行). +Thành viên. +Tất cả các thành viên của Thời Đại Thiếu Niên Đoàn đều là mang quốc tịch Trung Quốc. Mã Gia Kỳ, người giành được hạng 1 trong chương trình thực tế ra mắt của cả nhóm, vừa là trưởng nhóm vừa đảm nhiệm vai trò vị trí trung tâm. +Lưu ý. + Các nội dung sau đây mang tính tham khảo, không tự ý sửa đổi, nếu sửa đổi sẽ được cho là phá hoại. Mong không sửa đổi dưới mọi hình thức, chỉ bổ sung khi thiếu, hoàn thành lại khi sai. Vì một số sửa đổi của một số bạn nên chúng tôi có thể không hoàn thiện nó như lúc đầu, vì vậy sửa đổi không cần thiết chính là phá hoại trang. + +(Đoạn 2 - score=0.611) +Boney M. + +Boney M. là một nhóm nhạc được thành lập vào năm 1976 bởi nhà sản xuất âm nhạc người Tây Đức Frank Farian. Bốn thành viên gốc của ban nhạc là Liz Mitchell và Marcia Barrett (Jamaica), Maizie Williams (Montserrat) và Bobby Farrell (Aruba). Boney M. thành công vào cuối thập niên 1970, đứng đầu nhiều bảng xếp hạng với số lượng đĩa bán lớn với những ca khúc nổi tiếng như Daddy Cool, Sunny, Rasputin... Kể từ thập niên 1980, ban nhạc thay đổi thành viên thường xuyên. Thành viên nam duy nhất Bobby Farrell qua đời vào cuối năm 2010 ở Saint Petersburg vì trụy tim. +Bảng xếp hạng. +Đĩa đơn. +"-" nghĩa là không có thông tin hoặc không được xếp hạng + +### Công cụ có thể sử dụng + +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. + + +### Câu hỏi người dùng +nhóm nhạc stray kids có bao nhiêu thành viên? + +### Hướng dẫn cho AI + +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. + + +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời +... +2025-10-13 01:04:40,222 [INFO] rag_api - ✅ Đã trả lời: nhóm nhạc stray kids có bao nhiêu thành viên?... +2025-10-13 01:08:53,091 [INFO] rag_api - 📥 Câu hỏi: nhóm nhạc stray kids có bao nhiêu thành viên? +2025-10-13 01:08:55,089 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:09:00,657 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:09:05,722 [INFO] src.chatbot.llm_client - 💬 Gemini output: {"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}}... +2025-10-13 01:09:07,758 [INFO] src.chatbot.llm_client - 🤖 Function call JSON: {'action': 'search_google', 'params': {'query': 'Stray Kids có bao nhiêu thành viên?'}} +2025-10-13 01:09:53,333 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. + +### Ngữ cảnh (retrieved from database) +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.654) +Thời Đại Thiếu Niên Đoàn + +Thời Đại Thiếu Niên Đoàn (, , tên thường gọi: TNT) là nhóm nhạc nam Trung Quốc gồm 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn. Bảy thành viên trước khi ra mắt đều là thực tập sinh thế hệ thứ hai trực thuộc TF Entertainment, sau thành công của thế hệ thứ nhất là TFBoys. Nhóm được thành lập chính thức từ chương trình thực tế sống còn "Đài Phong Lột Xác Chiến" do TF Entertainment cải tổ lại. Chương trình kết thúc và nhóm chính thức được thành lập vào ngày 25 tháng 8 năm 2019. +Ngày 23 tháng 11 năm 2019 nhóm tổ chức buổi ra mắt và ra mắt với bài hát mới "Thông Báo Toàn Trường". +Fandom chính thức "Bạo Mễ Hoa" (tiếng Trung: 爆米花). Màu tiếp ứng là: Vàng, Đen. Khẩu hiệu tiếp ứng: Phá Thiên Hạ, Định Phong Vân, Thời Đại Thiếu Niên Tinh Kiên Hành.(tiếng Trung:破天下,定风云,时代少年并肩行). +Thành viên. +Tất cả các thành viên của Thời Đại Thiếu Niên Đoàn đều là mang quốc tịch Trung Quốc. Mã Gia Kỳ, người giành được hạng 1 trong chương trình thực tế ra mắt của cả nhóm, vừa là trưởng nhóm vừa đảm nhiệm vai trò vị trí trung tâm. +Lưu ý. + Các nội dung sau đây mang tính tham khảo, không tự ý sửa đổi, nếu sửa đổi sẽ được cho là phá hoại. Mong không sửa đổi dưới mọi hình thức, chỉ bổ sung khi thiếu, hoàn thành lại khi sai. Vì một số sửa đổi của một số bạn nên chúng tôi có thể không hoàn thiện nó như lúc đầu, vì vậy sửa đổi không cần thiết chính là phá hoại trang. + +(Đoạn 2 - score=0.611) +Boney M. + +Boney M. là một nhóm nhạc được thành lập vào năm 1976 bởi nhà sản xuất âm nhạc người Tây Đức Frank Farian. Bốn thành viên gốc của ban nhạc là Liz Mitchell và Marcia Barrett (Jamaica), Maizie Williams (Montserrat) và Bobby Farrell (Aruba). Boney M. thành công vào cuối thập niên 1970, đứng đầu nhiều bảng xếp hạng với số lượng đĩa bán lớn với những ca khúc nổi tiếng như Daddy Cool, Sunny, Rasputin... Kể từ thập niên 1980, ban nhạc thay đổi thành viên thường xuyên. Thành viên nam duy nhất Bobby Farrell qua đời vào cuối năm 2010 ở Saint Petersburg vì trụy tim. +Bảng xếp hạng. +Đĩa đơn. +"-" nghĩa là không có thông tin hoặc không được xếp hạng + +### Công cụ có thể sử dụng + +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. + + +### Câu hỏi người dùng +nhóm nhạc stray kids có bao nhiêu thành viên? + +### Hướng dẫn cho AI + +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. + + +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời +... +2025-10-13 01:09:57,125 [INFO] rag_api - ✅ Đã trả lời: nhóm nhạc stray kids có bao nhiêu thành viên?... +2025-10-13 01:10:29,207 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-13 01:10:46,580 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK" +2025-10-13 01:10:46,586 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK" +2025-10-13 01:10:46,774 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base +2025-10-13 01:10:53,326 [INFO] src.chatbot.llm_client - 🔮 LLMClient khởi tạo với model: models/gemini-2.0-flash-001 +2025-10-13 01:11:01,495 [INFO] function_router - 🔧 Đã đăng ký tool: create_txt — Tạo file TXT. Tham số: {text: str, filename?: str} +2025-10-13 01:11:01,496 [INFO] function_router - 🔧 Đã đăng ký tool: search_google — Tìm thông tin mới nhất trên Internet bằng Google Custom Search API. +2025-10-13 01:11:01,496 [INFO] function_router - ✅ FunctionRouter khởi tạo, có 2 công cụ sẵn sàng. +2025-10-13 01:11:01,496 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công. +2025-10-13 01:11:05,835 [INFO] rag_api - 📥 Câu hỏi: nhóm nhạc stray kids có bao nhiêu thành viên? +2025-10-13 01:11:10,310 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:11:12,316 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:11:22,121 [INFO] src.chatbot.llm_client - 💬 Gemini output: {"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}}... +2025-10-13 01:11:24,072 [INFO] src.chatbot.llm_client - 🤖 Function call JSON: {'action': 'search_google', 'params': {'query': 'Stray Kids có bao nhiêu thành viên?'}} +2025-10-13 01:11:59,380 [INFO] function_router - ⚙️ Thực thi tool 'search_google' với params={'query': 'Stray Kids có bao nhiêu thành viên?'} +2025-10-13 01:12:09,600 [INFO] function_router - ✅ Tool 'search_google' thực thi thành công. +2025-10-13 01:12:51,036 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. + +### Ngữ cảnh (retrieved from database) +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.654) +Thời Đại Thiếu Niên Đoàn + +Thời Đại Thiếu Niên Đoàn (, , tên thường gọi: TNT) là nhóm nhạc nam Trung Quốc gồm 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn. Bảy thành viên trước khi ra mắt đều là thực tập sinh thế hệ thứ hai trực thuộc TF Entertainment, sau thành công của thế hệ thứ nhất là TFBoys. Nhóm được thành lập chính thức từ chương trình thực tế sống còn "Đài Phong Lột Xác Chiến" do TF Entertainment cải tổ lại. Chương trình kết thúc và nhóm chính thức được thành lập vào ngày 25 tháng 8 năm 2019. +Ngày 23 tháng 11 năm 2019 nhóm tổ chức buổi ra mắt và ra mắt với bài hát mới "Thông Báo Toàn Trường". +Fandom chính thức "Bạo Mễ Hoa" (tiếng Trung: 爆米花). Màu tiếp ứng là: Vàng, Đen. Khẩu hiệu tiếp ứng: Phá Thiên Hạ, Định Phong Vân, Thời Đại Thiếu Niên Tinh Kiên Hành.(tiếng Trung:破天下,定风云,时代少年并肩行). +Thành viên. +Tất cả các thành viên của Thời Đại Thiếu Niên Đoàn đều là mang quốc tịch Trung Quốc. Mã Gia Kỳ, người giành được hạng 1 trong chương trình thực tế ra mắt của cả nhóm, vừa là trưởng nhóm vừa đảm nhiệm vai trò vị trí trung tâm. +Lưu ý. + Các nội dung sau đây mang tính tham khảo, không tự ý sửa đổi, nếu sửa đổi sẽ được cho là phá hoại. Mong không sửa đổi dưới mọi hình thức, chỉ bổ sung khi thiếu, hoàn thành lại khi sai. Vì một số sửa đổi của một số bạn nên chúng tôi có thể không hoàn thiện nó như lúc đầu, vì vậy sửa đổi không cần thiết chính là phá hoại trang. + +(Đoạn 2 - score=0.611) +Boney M. + +Boney M. là một nhóm nhạc được thành lập vào năm 1976 bởi nhà sản xuất âm nhạc người Tây Đức Frank Farian. Bốn thành viên gốc của ban nhạc là Liz Mitchell và Marcia Barrett (Jamaica), Maizie Williams (Montserrat) và Bobby Farrell (Aruba). Boney M. thành công vào cuối thập niên 1970, đứng đầu nhiều bảng xếp hạng với số lượng đĩa bán lớn với những ca khúc nổi tiếng như Daddy Cool, Sunny, Rasputin... Kể từ thập niên 1980, ban nhạc thay đổi thành viên thường xuyên. Thành viên nam duy nhất Bobby Farrell qua đời vào cuối năm 2010 ở Saint Petersburg vì trụy tim. +Bảng xếp hạng. +Đĩa đơn. +"-" nghĩa là không có thông tin hoặc không được xếp hạng + +### Công cụ có thể sử dụng + +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. + + +### Câu hỏi người dùng +nhóm nhạc stray kids có bao nhiêu thành viên? + +### Hướng dẫn cho AI + +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. + + +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời +... +2025-10-13 01:12:54,158 [INFO] rag_api - ✅ Đã trả lời: nhóm nhạc stray kids có bao nhiêu thành viên?... +2025-10-13 01:16:26,490 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-13 01:16:29,505 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK" +2025-10-13 01:16:29,509 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK" +2025-10-13 01:16:29,517 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base +2025-10-13 01:17:13,121 [INFO] src.chatbot.llm_client - 🔮 LLMClient khởi tạo với model: models/gemini-2.0-flash-001 +2025-10-13 01:17:13,121 [INFO] function_router - 🔧 Đã đăng ký tool: create_txt — Tạo file TXT. Tham số: {text: str, filename?: str} +2025-10-13 01:17:13,121 [INFO] function_router - 🔧 Đã đăng ký tool: search_google — Tìm thông tin mới nhất trên Internet bằng Google Custom Search API. +2025-10-13 01:17:13,122 [INFO] function_router - ✅ FunctionRouter khởi tạo, có 2 công cụ sẵn sàng. +2025-10-13 01:17:13,122 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công. +2025-10-13 01:17:51,802 [INFO] rag_api - 📥 Câu hỏi: nhóm nhạc stray kids có bao nhiêu thành viên? +2025-10-13 01:17:52,167 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:17:52,170 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:17:53,204 [INFO] src.chatbot.llm_client - 💬 Gemini output: {"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}}... +2025-10-13 01:17:53,205 [INFO] src.chatbot.llm_client - 🤖 Function call JSON: {'action': 'search_google', 'params': {'query': 'Stray Kids có bao nhiêu thành viên?'}} +2025-10-13 01:17:53,205 [INFO] function_executor - 🔧 LLM yêu cầu thực thi tool: search_google({'query': 'Stray Kids có bao nhiêu thành viên?'}) +2025-10-13 01:17:53,205 [INFO] function_router - ⚙️ Thực thi tool 'search_google' với params={'query': 'Stray Kids có bao nhiêu thành viên?'} +2025-10-13 01:17:54,620 [INFO] function_router - ✅ Tool 'search_google' thực thi thành công. +2025-10-13 01:17:54,621 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:17:55,895 [INFO] src.chatbot.llm_client - 💬 Gemini output: Stray Kids là nhóm nhạc nam Hàn Quốc được thành lập bởi JYP Entertainment thông qua chương trình truyền hình thực tế cùn... +2025-10-13 01:17:55,896 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. + +### Ngữ cảnh (retrieved from database) +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.654) +Thời Đại Thiếu Niên Đoàn + +Thời Đại Thiếu Niên Đoàn (, , tên thường gọi: TNT) là nhóm nhạc nam Trung Quốc gồm 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn. Bảy thành viên trước khi ra mắt đều là thực tập sinh thế hệ thứ hai trực thuộc TF Entertainment, sau thành công của thế hệ thứ nhất là TFBoys. Nhóm được thành lập chính thức từ chương trình thực tế sống còn "Đài Phong Lột Xác Chiến" do TF Entertainment cải tổ lại. Chương trình kết thúc và nhóm chính thức được thành lập vào ngày 25 tháng 8 năm 2019. +Ngày 23 tháng 11 năm 2019 nhóm tổ chức buổi ra mắt và ra mắt với bài hát mới "Thông Báo Toàn Trường". +Fandom chính thức "Bạo Mễ Hoa" (tiếng Trung: 爆米花). Màu tiếp ứng là: Vàng, Đen. Khẩu hiệu tiếp ứng: Phá Thiên Hạ, Định Phong Vân, Thời Đại Thiếu Niên Tinh Kiên Hành.(tiếng Trung:破天下,定风云,时代少年并肩行). +Thành viên. +Tất cả các thành viên của Thời Đại Thiếu Niên Đoàn đều là mang quốc tịch Trung Quốc. Mã Gia Kỳ, người giành được hạng 1 trong chương trình thực tế ra mắt của cả nhóm, vừa là trưởng nhóm vừa đảm nhiệm vai trò vị trí trung tâm. +Lưu ý. + Các nội dung sau đây mang tính tham khảo, không tự ý sửa đổi, nếu sửa đổi sẽ được cho là phá hoại. Mong không sửa đổi dưới mọi hình thức, chỉ bổ sung khi thiếu, hoàn thành lại khi sai. Vì một số sửa đổi của một số bạn nên chúng tôi có thể không hoàn thiện nó như lúc đầu, vì vậy sửa đổi không cần thiết chính là phá hoại trang. + +(Đoạn 2 - score=0.611) +Boney M. + +Boney M. là một nhóm nhạc được thành lập vào năm 1976 bởi nhà sản xuất âm nhạc người Tây Đức Frank Farian. Bốn thành viên gốc của ban nhạc là Liz Mitchell và Marcia Barrett (Jamaica), Maizie Williams (Montserrat) và Bobby Farrell (Aruba). Boney M. thành công vào cuối thập niên 1970, đứng đầu nhiều bảng xếp hạng với số lượng đĩa bán lớn với những ca khúc nổi tiếng như Daddy Cool, Sunny, Rasputin... Kể từ thập niên 1980, ban nhạc thay đổi thành viên thường xuyên. Thành viên nam duy nhất Bobby Farrell qua đời vào cuối năm 2010 ở Saint Petersburg vì trụy tim. +Bảng xếp hạng. +Đĩa đơn. +"-" nghĩa là không có thông tin hoặc không được xếp hạng + +### Công cụ có thể sử dụng + +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. + + +### Câu hỏi người dùng +nhóm nhạc stray kids có bao nhiêu thành viên? + +### Hướng dẫn cho AI + +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. + + +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời +... +2025-10-13 01:17:55,897 [INFO] rag_api - ✅ Đã trả lời: nhóm nhạc stray kids có bao nhiêu thành viên?... +2025-10-13 01:18:20,842 [INFO] rag_api - 📥 Câu hỏi: Thời Đại Thiếu Niên Đoàn có mấy thành viên? +2025-10-13 01:18:21,040 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:18:21,042 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:18:21,937 [INFO] src.chatbot.llm_client - 💬 Gemini output: Thời Đại Thiếu Niên Đoàn có 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiê... +2025-10-13 01:18:21,938 [INFO] function_executor - ⚠️ Không có action → fallback Google Search +2025-10-13 01:18:23,297 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:18:24,857 [INFO] src.chatbot.llm_client - 💬 Gemini output: Thời Đại Thiếu Niên Đoàn (TNT) là nhóm nhạc nam Trung Quốc gồm 7 thành viên: Mã Gia Kỳ, Đinh Trình Hâm, Tống Á Hiên, Lưu... +2025-10-13 01:18:24,857 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. + +### Ngữ cảnh (retrieved from database) +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.929) +Thời Đại Thiếu Niên Đoàn + +Thời Đại Thiếu Niên Đoàn (, , tên thường gọi: TNT) là nhóm nhạc nam Trung Quốc gồm 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn. Bảy thành viên trước khi ra mắt đều là thực tập sinh thế hệ thứ hai trực thuộc TF Entertainment, sau thành công của thế hệ thứ nhất là TFBoys. Nhóm được thành lập chính thức từ chương trình thực tế sống còn "Đài Phong Lột Xác Chiến" do TF Entertainment cải tổ lại. Chương trình kết thúc và nhóm chính thức được thành lập vào ngày 25 tháng 8 năm 2019. +Ngày 23 tháng 11 năm 2019 nhóm tổ chức buổi ra mắt và ra mắt với bài hát mới "Thông Báo Toàn Trường". +Fandom chính thức "Bạo Mễ Hoa" (tiếng Trung: 爆米花). Màu tiếp ứng là: Vàng, Đen. Khẩu hiệu tiếp ứng: Phá Thiên Hạ, Định Phong Vân, Thời Đại Thiếu Niên Tinh Kiên Hành.(tiếng Trung:破天下,定风云,时代少年并肩行). +Thành viên. +Tất cả các thành viên của Thời Đại Thiếu Niên Đoàn đều là mang quốc tịch Trung Quốc. Mã Gia Kỳ, người giành được hạng 1 trong chương trình thực tế ra mắt của cả nhóm, vừa là trưởng nhóm vừa đảm nhiệm vai trò vị trí trung tâm. +Lưu ý. + Các nội dung sau đây mang tính tham khảo, không tự ý sửa đổi, nếu sửa đổi sẽ được cho là phá hoại. Mong không sửa đổi dưới mọi hình thức, chỉ bổ sung khi thiếu, hoàn thành lại khi sai. Vì một số sửa đổi của một số bạn nên chúng tôi có thể không hoàn thiện nó như lúc đầu, vì vậy sửa đổi không cần thiết chính là phá hoại trang. + +(Đoạn 2 - score=0.666) +Tiểu Thời Đại + +Tiểu Thời Đại hay Tiểu Thời Đại 1.0 (小时代) là phim điện ảnh của đạo diễn kiêm biên kịch Quách Kính Minh dựa trên tiểu thuyết cùng tên của chính anh. +Bộ phim thành công về mặt thương mại và nhận được những phản ứng tích cực từ giới chuyên môn. Phần hai có tựa đề "Tiểu Thời Đại 2" được quay song song cùng phần một của bộ phim và dựa trên phần hai của bộ tiểu thuyết đã ra mắt vào ngày 8 tháng 8 năm 2013. "Tiểu Thời Đại 3" cũng đã nhanh chóng khởi quay và ra mắt công chúng vào ngày 17 tháng 7 năm 2014. +Nội dung. +Bộ phim dựa trên bộ truyện có tên là "Tiểu Thời Đại "với 3 phần" 1.0, 2.0, 3.0" xoay quanh tình bạn của bốn cô gái gồm Lâm Tiêu, Cố Lý, Nam Tương và Đường Uyển Như sống giữa thành phố Thượng Hải phồn hoa nhưng đầy rẫy tham vọng, toan tính, khát khao của tuổi trẻ. +Bốn cô gái là bạn cùng lớp thời trung học và bạn cùng phòng khi lên đại học. Trong trường, họ phải đối mặt với áp lực nặng nề, làm quen với cuộc sống sinh viên nội trú, gặp rắc rối với những chuyện tình cảm xảy ra liên tục. Sau khi tốt nghiệp, họ dần thay đổi và vướng vào những mối quan hệ phức tạp khác trong cuộc sống và dần trở nên nghi kị và hiểu lầm lẫn nhau. +Ra mắt và phản hồi. +Doanh thu phòng vé. +Dù kinh phí sản xuất của bộ phim chưa đến 50 triệu nhân dân tệ, được chia làm 2 phần, mỗi phần vỏn vẹn 25 triệu, nhưng ngay ngày đầu tiên công chiếu, "Tiểu Thời Đại" đã đạt doanh thu hơn 73 triệu Nhân dân tệ +Bộ phim đã thu về US$79.7 triệu tại các phòng vé ở Trung Quốc. +Sau ngày ra mắt, doanh thu phòng vé của Tiểu Thời Đại 3 đạt 150 triệu tệ (~ 525 tỷ đồng), lập kỷ lục phim điện ảnh 2D nội địa ăn khách nhất Trung Quốc. + +### Công cụ có thể sử dụng + +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. + + +### Câu hỏi người dùng +Thời Đại Thiếu Niên Đoàn có mấy thành viên? + +### Hướng dẫn cho AI + +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. + + +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời +... +2025-10-13 01:18:24,858 [INFO] rag_api - ✅ Đã trả lời: Thời Đại Thiếu Niên Đoàn có mấy thành viên?... +2025-10-13 01:19:03,866 [INFO] rag_api - 📥 Câu hỏi: Thời Đại Thiếu Niên Đoàn có mấy thành viên? bạn viết ra file txt +2025-10-13 01:19:04,099 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:19:04,100 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:19:05,452 [INFO] src.chatbot.llm_client - 💬 Gemini output: Thời Đại Thiếu Niên Đoàn có 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiê... +2025-10-13 01:19:05,452 [INFO] src.chatbot.llm_client - 🤖 Function call JSON: {'action': 'create_txt', 'params': {'text': 'Thời Đại Thiếu Niên Đoàn có 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn.'}} +2025-10-13 01:19:05,452 [INFO] function_executor - 🔧 LLM yêu cầu thực thi tool: create_txt({'text': 'Thời Đại Thiếu Niên Đoàn có 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn.'}) +2025-10-13 01:19:05,453 [INFO] function_router - ⚙️ Thực thi tool 'create_txt' với params={'text': 'Thời Đại Thiếu Niên Đoàn có 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn.'} +2025-10-13 01:19:05,454 [INFO] function_router - ✅ Tool 'create_txt' thực thi thành công. +2025-10-13 01:19:05,454 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. + +### Ngữ cảnh (retrieved from database) +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.829) +Thời Đại Thiếu Niên Đoàn + +Thời Đại Thiếu Niên Đoàn (, , tên thường gọi: TNT) là nhóm nhạc nam Trung Quốc gồm 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn. Bảy thành viên trước khi ra mắt đều là thực tập sinh thế hệ thứ hai trực thuộc TF Entertainment, sau thành công của thế hệ thứ nhất là TFBoys. Nhóm được thành lập chính thức từ chương trình thực tế sống còn "Đài Phong Lột Xác Chiến" do TF Entertainment cải tổ lại. Chương trình kết thúc và nhóm chính thức được thành lập vào ngày 25 tháng 8 năm 2019. +Ngày 23 tháng 11 năm 2019 nhóm tổ chức buổi ra mắt và ra mắt với bài hát mới "Thông Báo Toàn Trường". +Fandom chính thức "Bạo Mễ Hoa" (tiếng Trung: 爆米花). Màu tiếp ứng là: Vàng, Đen. Khẩu hiệu tiếp ứng: Phá Thiên Hạ, Định Phong Vân, Thời Đại Thiếu Niên Tinh Kiên Hành.(tiếng Trung:破天下,定风云,时代少年并肩行). +Thành viên. +Tất cả các thành viên của Thời Đại Thiếu Niên Đoàn đều là mang quốc tịch Trung Quốc. Mã Gia Kỳ, người giành được hạng 1 trong chương trình thực tế ra mắt của cả nhóm, vừa là trưởng nhóm vừa đảm nhiệm vai trò vị trí trung tâm. +Lưu ý. + Các nội dung sau đây mang tính tham khảo, không tự ý sửa đổi, nếu sửa đổi sẽ được cho là phá hoại. Mong không sửa đổi dưới mọi hình thức, chỉ bổ sung khi thiếu, hoàn thành lại khi sai. Vì một số sửa đổi của một số bạn nên chúng tôi có thể không hoàn thiện nó như lúc đầu, vì vậy sửa đổi không cần thiết chính là phá hoại trang. + +(Đoạn 2 - score=0.678) +Tiểu Thời Đại + +Tiểu Thời Đại hay Tiểu Thời Đại 1.0 (小时代) là phim điện ảnh của đạo diễn kiêm biên kịch Quách Kính Minh dựa trên tiểu thuyết cùng tên của chính anh. +Bộ phim thành công về mặt thương mại và nhận được những phản ứng tích cực từ giới chuyên môn. Phần hai có tựa đề "Tiểu Thời Đại 2" được quay song song cùng phần một của bộ phim và dựa trên phần hai của bộ tiểu thuyết đã ra mắt vào ngày 8 tháng 8 năm 2013. "Tiểu Thời Đại 3" cũng đã nhanh chóng khởi quay và ra mắt công chúng vào ngày 17 tháng 7 năm 2014. +Nội dung. +Bộ phim dựa trên bộ truyện có tên là "Tiểu Thời Đại "với 3 phần" 1.0, 2.0, 3.0" xoay quanh tình bạn của bốn cô gái gồm Lâm Tiêu, Cố Lý, Nam Tương và Đường Uyển Như sống giữa thành phố Thượng Hải phồn hoa nhưng đầy rẫy tham vọng, toan tính, khát khao của tuổi trẻ. +Bốn cô gái là bạn cùng lớp thời trung học và bạn cùng phòng khi lên đại học. Trong trường, họ phải đối mặt với áp lực nặng nề, làm quen với cuộc sống sinh viên nội trú, gặp rắc rối với những chuyện tình cảm xảy ra liên tục. Sau khi tốt nghiệp, họ dần thay đổi và vướng vào những mối quan hệ phức tạp khác trong cuộc sống và dần trở nên nghi kị và hiểu lầm lẫn nhau. +Ra mắt và phản hồi. +Doanh thu phòng vé. +Dù kinh phí sản xuất của bộ phim chưa đến 50 triệu nhân dân tệ, được chia làm 2 phần, mỗi phần vỏn vẹn 25 triệu, nhưng ngay ngày đầu tiên công chiếu, "Tiểu Thời Đại" đã đạt doanh thu hơn 73 triệu Nhân dân tệ +Bộ phim đã thu về US$79.7 triệu tại các phòng vé ở Trung Quốc. +Sau ngày ra mắt, doanh thu phòng vé của Tiểu Thời Đại 3 đạt 150 triệu tệ (~ 525 tỷ đồng), lập kỷ lục phim điện ảnh 2D nội địa ăn khách nhất Trung Quốc. + +### Công cụ có thể sử dụng + +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. + + +### Câu hỏi người dùng +Thời Đại Thiếu Niên Đoàn có mấy thành viên? bạn viết ra file txt + +### Hướng dẫn cho AI + +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. + + +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời +... +2025-10-13 01:19:05,454 [INFO] rag_api - ✅ Đã trả lời: Thời Đại Thiếu Niên Đoàn có mấy thành viên? bạn vi... +2025-10-13 01:19:25,271 [INFO] rag_api - 📥 Câu hỏi: Thời Đại Thiếu Niên Đoàn có mấy thành viên? +2025-10-13 01:19:25,426 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:19:25,428 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:19:26,166 [INFO] src.chatbot.llm_client - 💬 Gemini output: Thời Đại Thiếu Niên Đoàn có 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiê... +2025-10-13 01:19:26,166 [INFO] function_executor - ⚠️ Không có action → fallback Google Search +2025-10-13 01:19:27,499 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:19:29,078 [INFO] src.chatbot.llm_client - 💬 Gemini output: Thời Đại Thiếu Niên Đoàn (TNT) là nhóm nhạc nam Trung Quốc gồm 7 thành viên: Mã Gia Kỳ, Đinh Trình Hâm, Tống Á Hiên, Lưu... +2025-10-13 01:19:29,078 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. + +### Ngữ cảnh (retrieved from database) +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.929) +Thời Đại Thiếu Niên Đoàn + +Thời Đại Thiếu Niên Đoàn (, , tên thường gọi: TNT) là nhóm nhạc nam Trung Quốc gồm 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn. Bảy thành viên trước khi ra mắt đều là thực tập sinh thế hệ thứ hai trực thuộc TF Entertainment, sau thành công của thế hệ thứ nhất là TFBoys. Nhóm được thành lập chính thức từ chương trình thực tế sống còn "Đài Phong Lột Xác Chiến" do TF Entertainment cải tổ lại. Chương trình kết thúc và nhóm chính thức được thành lập vào ngày 25 tháng 8 năm 2019. +Ngày 23 tháng 11 năm 2019 nhóm tổ chức buổi ra mắt và ra mắt với bài hát mới "Thông Báo Toàn Trường". +Fandom chính thức "Bạo Mễ Hoa" (tiếng Trung: 爆米花). Màu tiếp ứng là: Vàng, Đen. Khẩu hiệu tiếp ứng: Phá Thiên Hạ, Định Phong Vân, Thời Đại Thiếu Niên Tinh Kiên Hành.(tiếng Trung:破天下,定风云,时代少年并肩行). +Thành viên. +Tất cả các thành viên của Thời Đại Thiếu Niên Đoàn đều là mang quốc tịch Trung Quốc. Mã Gia Kỳ, người giành được hạng 1 trong chương trình thực tế ra mắt của cả nhóm, vừa là trưởng nhóm vừa đảm nhiệm vai trò vị trí trung tâm. +Lưu ý. + Các nội dung sau đây mang tính tham khảo, không tự ý sửa đổi, nếu sửa đổi sẽ được cho là phá hoại. Mong không sửa đổi dưới mọi hình thức, chỉ bổ sung khi thiếu, hoàn thành lại khi sai. Vì một số sửa đổi của một số bạn nên chúng tôi có thể không hoàn thiện nó như lúc đầu, vì vậy sửa đổi không cần thiết chính là phá hoại trang. + +(Đoạn 2 - score=0.666) +Tiểu Thời Đại + +Tiểu Thời Đại hay Tiểu Thời Đại 1.0 (小时代) là phim điện ảnh của đạo diễn kiêm biên kịch Quách Kính Minh dựa trên tiểu thuyết cùng tên của chính anh. +Bộ phim thành công về mặt thương mại và nhận được những phản ứng tích cực từ giới chuyên môn. Phần hai có tựa đề "Tiểu Thời Đại 2" được quay song song cùng phần một của bộ phim và dựa trên phần hai của bộ tiểu thuyết đã ra mắt vào ngày 8 tháng 8 năm 2013. "Tiểu Thời Đại 3" cũng đã nhanh chóng khởi quay và ra mắt công chúng vào ngày 17 tháng 7 năm 2014. +Nội dung. +Bộ phim dựa trên bộ truyện có tên là "Tiểu Thời Đại "với 3 phần" 1.0, 2.0, 3.0" xoay quanh tình bạn của bốn cô gái gồm Lâm Tiêu, Cố Lý, Nam Tương và Đường Uyển Như sống giữa thành phố Thượng Hải phồn hoa nhưng đầy rẫy tham vọng, toan tính, khát khao của tuổi trẻ. +Bốn cô gái là bạn cùng lớp thời trung học và bạn cùng phòng khi lên đại học. Trong trường, họ phải đối mặt với áp lực nặng nề, làm quen với cuộc sống sinh viên nội trú, gặp rắc rối với những chuyện tình cảm xảy ra liên tục. Sau khi tốt nghiệp, họ dần thay đổi và vướng vào những mối quan hệ phức tạp khác trong cuộc sống và dần trở nên nghi kị và hiểu lầm lẫn nhau. +Ra mắt và phản hồi. +Doanh thu phòng vé. +Dù kinh phí sản xuất của bộ phim chưa đến 50 triệu nhân dân tệ, được chia làm 2 phần, mỗi phần vỏn vẹn 25 triệu, nhưng ngay ngày đầu tiên công chiếu, "Tiểu Thời Đại" đã đạt doanh thu hơn 73 triệu Nhân dân tệ +Bộ phim đã thu về US$79.7 triệu tại các phòng vé ở Trung Quốc. +Sau ngày ra mắt, doanh thu phòng vé của Tiểu Thời Đại 3 đạt 150 triệu tệ (~ 525 tỷ đồng), lập kỷ lục phim điện ảnh 2D nội địa ăn khách nhất Trung Quốc. + +### Công cụ có thể sử dụng + +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. + + +### Câu hỏi người dùng +Thời Đại Thiếu Niên Đoàn có mấy thành viên? + +### Hướng dẫn cho AI + +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. + + +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời +... +2025-10-13 01:19:29,079 [INFO] rag_api - ✅ Đã trả lời: Thời Đại Thiếu Niên Đoàn có mấy thành viên? ... +2025-10-13 01:20:01,389 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-13 01:20:19,002 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK" +2025-10-13 01:20:19,007 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK" +2025-10-13 01:20:19,170 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base +2025-10-13 01:20:25,807 [INFO] src.chatbot.llm_client - 🔮 LLMClient khởi tạo với model: models/gemini-2.0-flash-001 +2025-10-13 01:20:25,807 [INFO] function_router - 🔧 Đã đăng ký tool: create_txt — Tạo file TXT. Tham số: {text: str, filename?: str} +2025-10-13 01:20:25,808 [INFO] function_router - 🔧 Đã đăng ký tool: search_google — Tìm thông tin mới nhất trên Internet bằng Google Custom Search API. +2025-10-13 01:20:25,808 [INFO] function_router - ✅ FunctionRouter khởi tạo, có 2 công cụ sẵn sàng. +2025-10-13 01:20:25,808 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công. +2025-10-13 01:20:33,300 [INFO] rag_api - 📥 Câu hỏi: Thời Đại Thiếu Niên Đoàn có mấy thành viên? +2025-10-13 01:20:37,732 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:20:40,358 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:20:57,112 [INFO] src.chatbot.llm_client - 💬 Gemini output: Thời Đại Thiếu Niên Đoàn có 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiê... +2025-10-13 01:21:18,879 [INFO] function_executor - ⚠️ Không có action → fallback Google Search +2025-10-13 01:25:19,920 [INFO] numexpr.utils - NumExpr defaulting to 12 threads. +2025-10-13 01:25:23,027 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK" +2025-10-13 01:25:23,031 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK" +2025-10-13 01:25:23,038 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base +2025-10-13 01:25:29,724 [INFO] src.chatbot.llm_client - 🔮 LLMClient khởi tạo với model: models/gemini-2.0-flash-001 +2025-10-13 01:25:29,724 [INFO] function_router - 🔧 Đã đăng ký tool: create_txt — Tạo file TXT. Tham số: {text: str, filename?: str} +2025-10-13 01:25:29,725 [INFO] function_router - 🔧 Đã đăng ký tool: search_google — Tìm thông tin mới nhất trên Internet bằng Google Custom Search API. +2025-10-13 01:25:29,725 [INFO] function_router - ✅ FunctionRouter khởi tạo, có 2 công cụ sẵn sàng. +2025-10-13 01:25:29,725 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công. +2025-10-13 01:25:35,666 [INFO] rag_api - 📥 Câu hỏi: Thời Đại Thiếu Niên Đoàn có mấy thành viên? +2025-10-13 01:25:35,852 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:25:35,855 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:25:37,093 [INFO] src.chatbot.llm_client - 💬 Gemini output: Thời Đại Thiếu Niên Đoàn có 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiê... +2025-10-13 01:25:37,093 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. + +### Ngữ cảnh (retrieved from database) +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.929) +Thời Đại Thiếu Niên Đoàn + +Thời Đại Thiếu Niên Đoàn (, , tên thường gọi: TNT) là nhóm nhạc nam Trung Quốc gồm 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn. Bảy thành viên trước khi ra mắt đều là thực tập sinh thế hệ thứ hai trực thuộc TF Entertainment, sau thành công của thế hệ thứ nhất là TFBoys. Nhóm được thành lập chính thức từ chương trình thực tế sống còn "Đài Phong Lột Xác Chiến" do TF Entertainment cải tổ lại. Chương trình kết thúc và nhóm chính thức được thành lập vào ngày 25 tháng 8 năm 2019. +Ngày 23 tháng 11 năm 2019 nhóm tổ chức buổi ra mắt và ra mắt với bài hát mới "Thông Báo Toàn Trường". +Fandom chính thức "Bạo Mễ Hoa" (tiếng Trung: 爆米花). Màu tiếp ứng là: Vàng, Đen. Khẩu hiệu tiếp ứng: Phá Thiên Hạ, Định Phong Vân, Thời Đại Thiếu Niên Tinh Kiên Hành.(tiếng Trung:破天下,定风云,时代少年并肩行). +Thành viên. +Tất cả các thành viên của Thời Đại Thiếu Niên Đoàn đều là mang quốc tịch Trung Quốc. Mã Gia Kỳ, người giành được hạng 1 trong chương trình thực tế ra mắt của cả nhóm, vừa là trưởng nhóm vừa đảm nhiệm vai trò vị trí trung tâm. +Lưu ý. + Các nội dung sau đây mang tính tham khảo, không tự ý sửa đổi, nếu sửa đổi sẽ được cho là phá hoại. Mong không sửa đổi dưới mọi hình thức, chỉ bổ sung khi thiếu, hoàn thành lại khi sai. Vì một số sửa đổi của một số bạn nên chúng tôi có thể không hoàn thiện nó như lúc đầu, vì vậy sửa đổi không cần thiết chính là phá hoại trang. + +(Đoạn 2 - score=0.666) +Tiểu Thời Đại + +Tiểu Thời Đại hay Tiểu Thời Đại 1.0 (小时代) là phim điện ảnh của đạo diễn kiêm biên kịch Quách Kính Minh dựa trên tiểu thuyết cùng tên của chính anh. +Bộ phim thành công về mặt thương mại và nhận được những phản ứng tích cực từ giới chuyên môn. Phần hai có tựa đề "Tiểu Thời Đại 2" được quay song song cùng phần một của bộ phim và dựa trên phần hai của bộ tiểu thuyết đã ra mắt vào ngày 8 tháng 8 năm 2013. "Tiểu Thời Đại 3" cũng đã nhanh chóng khởi quay và ra mắt công chúng vào ngày 17 tháng 7 năm 2014. +Nội dung. +Bộ phim dựa trên bộ truyện có tên là "Tiểu Thời Đại "với 3 phần" 1.0, 2.0, 3.0" xoay quanh tình bạn của bốn cô gái gồm Lâm Tiêu, Cố Lý, Nam Tương và Đường Uyển Như sống giữa thành phố Thượng Hải phồn hoa nhưng đầy rẫy tham vọng, toan tính, khát khao của tuổi trẻ. +Bốn cô gái là bạn cùng lớp thời trung học và bạn cùng phòng khi lên đại học. Trong trường, họ phải đối mặt với áp lực nặng nề, làm quen với cuộc sống sinh viên nội trú, gặp rắc rối với những chuyện tình cảm xảy ra liên tục. Sau khi tốt nghiệp, họ dần thay đổi và vướng vào những mối quan hệ phức tạp khác trong cuộc sống và dần trở nên nghi kị và hiểu lầm lẫn nhau. +Ra mắt và phản hồi. +Doanh thu phòng vé. +Dù kinh phí sản xuất của bộ phim chưa đến 50 triệu nhân dân tệ, được chia làm 2 phần, mỗi phần vỏn vẹn 25 triệu, nhưng ngay ngày đầu tiên công chiếu, "Tiểu Thời Đại" đã đạt doanh thu hơn 73 triệu Nhân dân tệ +Bộ phim đã thu về US$79.7 triệu tại các phòng vé ở Trung Quốc. +Sau ngày ra mắt, doanh thu phòng vé của Tiểu Thời Đại 3 đạt 150 triệu tệ (~ 525 tỷ đồng), lập kỷ lục phim điện ảnh 2D nội địa ăn khách nhất Trung Quốc. + +### Công cụ có thể sử dụng + +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. + + +### Câu hỏi người dùng +Thời Đại Thiếu Niên Đoàn có mấy thành viên? + +### Hướng dẫn cho AI + +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. + + +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời +... +2025-10-13 01:25:37,094 [INFO] rag_api - ✅ Đã trả lời: Thời Đại Thiếu Niên Đoàn có mấy thành viên? ... +2025-10-13 01:25:42,772 [INFO] rag_api - 📥 Câu hỏi: Thời Đại Thiếu Niên Đoàn có mấy thành viên? +2025-10-13 01:25:42,954 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:25:42,955 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:25:43,924 [INFO] src.chatbot.llm_client - 💬 Gemini output: Thời Đại Thiếu Niên Đoàn có 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiê... +2025-10-13 01:25:43,924 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. + +### Ngữ cảnh (retrieved from database) +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.929) +Thời Đại Thiếu Niên Đoàn + +Thời Đại Thiếu Niên Đoàn (, , tên thường gọi: TNT) là nhóm nhạc nam Trung Quốc gồm 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn. Bảy thành viên trước khi ra mắt đều là thực tập sinh thế hệ thứ hai trực thuộc TF Entertainment, sau thành công của thế hệ thứ nhất là TFBoys. Nhóm được thành lập chính thức từ chương trình thực tế sống còn "Đài Phong Lột Xác Chiến" do TF Entertainment cải tổ lại. Chương trình kết thúc và nhóm chính thức được thành lập vào ngày 25 tháng 8 năm 2019. +Ngày 23 tháng 11 năm 2019 nhóm tổ chức buổi ra mắt và ra mắt với bài hát mới "Thông Báo Toàn Trường". +Fandom chính thức "Bạo Mễ Hoa" (tiếng Trung: 爆米花). Màu tiếp ứng là: Vàng, Đen. Khẩu hiệu tiếp ứng: Phá Thiên Hạ, Định Phong Vân, Thời Đại Thiếu Niên Tinh Kiên Hành.(tiếng Trung:破天下,定风云,时代少年并肩行). +Thành viên. +Tất cả các thành viên của Thời Đại Thiếu Niên Đoàn đều là mang quốc tịch Trung Quốc. Mã Gia Kỳ, người giành được hạng 1 trong chương trình thực tế ra mắt của cả nhóm, vừa là trưởng nhóm vừa đảm nhiệm vai trò vị trí trung tâm. +Lưu ý. + Các nội dung sau đây mang tính tham khảo, không tự ý sửa đổi, nếu sửa đổi sẽ được cho là phá hoại. Mong không sửa đổi dưới mọi hình thức, chỉ bổ sung khi thiếu, hoàn thành lại khi sai. Vì một số sửa đổi của một số bạn nên chúng tôi có thể không hoàn thiện nó như lúc đầu, vì vậy sửa đổi không cần thiết chính là phá hoại trang. + +(Đoạn 2 - score=0.666) +Tiểu Thời Đại + +Tiểu Thời Đại hay Tiểu Thời Đại 1.0 (小时代) là phim điện ảnh của đạo diễn kiêm biên kịch Quách Kính Minh dựa trên tiểu thuyết cùng tên của chính anh. +Bộ phim thành công về mặt thương mại và nhận được những phản ứng tích cực từ giới chuyên môn. Phần hai có tựa đề "Tiểu Thời Đại 2" được quay song song cùng phần một của bộ phim và dựa trên phần hai của bộ tiểu thuyết đã ra mắt vào ngày 8 tháng 8 năm 2013. "Tiểu Thời Đại 3" cũng đã nhanh chóng khởi quay và ra mắt công chúng vào ngày 17 tháng 7 năm 2014. +Nội dung. +Bộ phim dựa trên bộ truyện có tên là "Tiểu Thời Đại "với 3 phần" 1.0, 2.0, 3.0" xoay quanh tình bạn của bốn cô gái gồm Lâm Tiêu, Cố Lý, Nam Tương và Đường Uyển Như sống giữa thành phố Thượng Hải phồn hoa nhưng đầy rẫy tham vọng, toan tính, khát khao của tuổi trẻ. +Bốn cô gái là bạn cùng lớp thời trung học và bạn cùng phòng khi lên đại học. Trong trường, họ phải đối mặt với áp lực nặng nề, làm quen với cuộc sống sinh viên nội trú, gặp rắc rối với những chuyện tình cảm xảy ra liên tục. Sau khi tốt nghiệp, họ dần thay đổi và vướng vào những mối quan hệ phức tạp khác trong cuộc sống và dần trở nên nghi kị và hiểu lầm lẫn nhau. +Ra mắt và phản hồi. +Doanh thu phòng vé. +Dù kinh phí sản xuất của bộ phim chưa đến 50 triệu nhân dân tệ, được chia làm 2 phần, mỗi phần vỏn vẹn 25 triệu, nhưng ngay ngày đầu tiên công chiếu, "Tiểu Thời Đại" đã đạt doanh thu hơn 73 triệu Nhân dân tệ +Bộ phim đã thu về US$79.7 triệu tại các phòng vé ở Trung Quốc. +Sau ngày ra mắt, doanh thu phòng vé của Tiểu Thời Đại 3 đạt 150 triệu tệ (~ 525 tỷ đồng), lập kỷ lục phim điện ảnh 2D nội địa ăn khách nhất Trung Quốc. + +### Công cụ có thể sử dụng + +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. + + +### Câu hỏi người dùng +Thời Đại Thiếu Niên Đoàn có mấy thành viên? + +### Hướng dẫn cho AI + +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. + + +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời +... +2025-10-13 01:25:43,925 [INFO] rag_api - ✅ Đã trả lời: Thời Đại Thiếu Niên Đoàn có mấy thành viên? ... +2025-10-13 01:26:06,376 [INFO] rag_api - 📥 Câu hỏi: Tân binh toàn năng là chương trình gì? +2025-10-13 01:26:06,549 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:26:06,550 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:26:07,216 [INFO] src.chatbot.llm_client - 💬 Gemini output: {"action": "search_google", "params": {"query": "Tân binh toàn năng là chương trình gì?"}}... +2025-10-13 01:26:07,216 [INFO] src.chatbot.llm_client - 🤖 Function call JSON: {'action': 'search_google', 'params': {'query': 'Tân binh toàn năng là chương trình gì?'}} +2025-10-13 01:26:07,216 [INFO] function_executor - 🔧 LLM yêu cầu thực thi tool: search_google({'query': 'Tân binh toàn năng là chương trình gì?'}) +2025-10-13 01:26:07,217 [INFO] function_router - ⚙️ Thực thi tool 'search_google' với params={'query': 'Tân binh toàn năng là chương trình gì?'} +2025-10-13 01:26:09,723 [INFO] function_router - ✅ Tool 'search_google' thực thi thành công. +2025-10-13 01:26:09,724 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:26:11,886 [INFO] src.chatbot.llm_client - 💬 Gemini output: "Tân binh toàn năng" là một chương trình truyền hình thực tế theo format "sống còn" nhằm tìm kiếm và đào tạo nhóm nhạc n... +2025-10-13 01:26:11,886 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. + +### Ngữ cảnh (retrieved from database) +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.597) +Tổng động viên + +Tổng động viên là một khái niệm quân sự chỉ một hành động vừa mang tính kêu gọi vừa mang tính mệnh lệnh trong tình hình quốc gia đó chuyển sang tình trạng chiến tranh. Đối tượng của lệnh Tổng động viên bao gồm tất cả những thanh niên có độ tuổi từ 18 đến 30 tuổi. Tại một số quốc gia đối tượng của Tổng động viên chỉ gói gọn trong những binh sĩ, hạ sĩ quan, sĩ quan dự bị đã giải ngũ. Về sau có thể do yêu cầu của tình hình đất nước đối tượng của Tổng động viên được mở rộng đến cả những thanh niên chưa từng qua huấn luyện quân sự như học sinh sinh viên, công nhân, công chức, nông dân... +Người có quyền ra quyết định Tổng động viên thường là Tổng tư lệnh quân đội. Tại nhiều nước người ra quyết định Tổng động viên là Tổng thống đối với những quốc gia theo chế độ Tư bản chủ nghĩa và Chủ tịch nước hoặc Chủ tịch Hội đồng Nhà nước đối với những quốc gia theo chế độ Xã hội Chủ nghĩa do Đảng Cộng sản đứng đầu. + +(Đoạn 2 - score=0.594) +Chương trình Ranger + +Chương trình Ranger là một loạt các phi vụ không gian không người lái của Hoa Kỳ trong những năm 1960 mà mục tiêu là để có được những hình ảnh cận cảnh đầu tiên về bề mặt của Mặt Trăng. Phi thuyền Ranger được thiết kế để có hình ảnh của bề mặt mặt trăng, truyền những hình ảnh về Trái đất cho đến khi tàu vũ trụ đã bị phá hủy khi tác động. Một loạt các rủi ro, tuy nhiên, đã dẫn đến sự thất bại của sáu chuyến bay đầu tiên. Tại một thời điểm, chương trình được gọi là "phóng đi và hy vọng". Quốc hội Hoa Kỳ đã phát động một cuộc điều tra vào "vấn đề của quản lý" tại trụ sở NASA và Phòng thí nghiệm Sức đẩy phản lực. Sau hai tái tổ chức của các cơ quan, Ranger 7 trở thành hình ảnh trong tháng 7 năm 1964, tiếp theo là hai nhiệm vụ thành công hơn. +Ranger được thiết kế ban đầu, bắt đầu từ năm 1959, trong ba giai đoạn riêng biệt, được gọi là "khối". Mỗi khối có mục tiêu nhiệm vụ khác nhau và thiết kế hệ thống dần dần nâng cao hơn. Các nhà thiết kế phi vụ JPL lên kế hoạch ra mắt nhiều trong mỗi khối, để tối đa hóa các kinh nghiệm kỹ thuật và giá trị khoa học của nhiệm vụ này và để đảm bảo ít nhất một chuyến bay thành công. Tổng số nghiên cứu, phát triển, ra mắt, và hỗ trợ chi phí cho các dòng Ranger của tàu vũ trụ (Ranger 1 đến 9) là khoảng 170 triệu đô la Mỹ. + +### Công cụ có thể sử dụng + +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. + + +### Câu hỏi người dùng +Tân binh toàn năng là chương trình gì? + +### Hướng dẫn cho AI + +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. + + +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời +... +2025-10-13 01:26:11,886 [INFO] rag_api - ✅ Đã trả lời: Tân binh toàn năng là chương trình gì? ... +2025-10-13 01:28:39,563 [INFO] rag_api - 📥 Câu hỏi: Ca sĩ Mahola là ai? +2025-10-13 01:28:39,736 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:28:39,737 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:28:40,838 [INFO] src.chatbot.llm_client - 💬 Gemini output: Zolani Mahola là một ca sĩ, diễn viên người Nam Phi, ca sĩ chính của nhóm nhạc Freshlyground. Cô sinh ngày 19 tháng 7 nă... +2025-10-13 01:28:40,838 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. + +### Ngữ cảnh (retrieved from database) +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.811) +Zolani Mahola + +Zolani Mahola (sinh ngày 19 tháng 7 năm 1981) là một ca sĩ, diễn viên, người Nam Phi, ca sĩ chính của nhóm nhạc Nam Phi Freshlyground. +Tiểu sử. +Mahola được sinh ra tại thành phố Port Elizabeth, thủ phủ của tỉnh Eastern Cape, Nam Phi. Cô lớn lên gần phía Đông London ở Bhisho, và theo học trường trung học Trinity (sau này đã sáp nhập vào trường St Priic's Priory). +Cô làm nhân viên tiếp tân tại Makro vào cuối tuần và ngày nghỉ học. Cô ở lại với cha và em gái của mình từ năm 1999 đến năm 2001. Năm 2011, Zolani và Freshlyground đã có một buổi hòa nhạc miễn phí trên phố Ntshekisa như một phần trong chuyến lưu diễn kỷ niệm 10 năm hoạt động của họ. +Sau khi học kịch tại Đại học Cape Town, cô được chọn đóng vai chính trong bộ phim truyền hình Tsha-Tsha, phát sóng trên SABC 1. Mahola lồng tiếng cho nhân vật Zoë trong bộ phim hoạt hình Zambezia (2012), và đã thu âm bài hát "Get Up" cho bản nhạc nền của phim hoạt hình này. +Vào tháng 3 năm 2013, Mahola đã công bố lần mang thai đầu tiên của mình. Vào ngày 8 tháng 8 năm 2013, Mahola sinh một đứa con trai tên là Zazi Bastion Mahola-Klemp với Nicholas. +Sự nghiệp âm nhạc. +Mahola và sáu nhạc sĩ khác đã thành lập Freshlyground ở Cape Town vào năm 2002. +Sau khi Freshlyground xuất bản album thứ hai của họ, Nomvula, vào năm 2004, The Sunday Times mô tả Mahola là một trong những ca sĩ trẻ tốt nhất và đầy cảm hứng nhất của Nam Phi. +Cô đến Cape Town, Durban và Pretoria với ca sĩ nhạc pop người Anh Robbie Williams vào năm 2006, Freshlyground biểu diễn như một vai diễn hỗ trợ của Williams. +Cô hát trong album phòng thu thứ ba của The Parlotones, Stardust Galaxies (2009). +Tại World Cup 2010, Mahola, với Freshlyground và Shakira, biểu diễn "Waka Waka (This Time for Africa)" trong lễ khai mạc và bế mạc. "Waka Waka (This Time for Africa)" là bài hát chính thức của FIFA World Cup năm 2010. +Tại Lễ trao giải Phụ nữ của năm 2011, được tổ chức vào ngày 25 tháng 7 tại Johannesburg, Mahola là một trong tám người phụ nữ được vinh danh bởi hạng mục người phụ nữ quyến rũ Nam Phi. + +(Đoạn 2 - score=0.631) +LMFAO + +LMFAO là một bộ đôi song ca electro hop người Mỹ thành lập vào năm 2006 tại Los Angeles, California, bao gồm rapper đồng thời là DJs Redfoo (tên thật là Stefan Kendal Gordy, sinh 3 tháng 9 năm 1975) và SkyBlu (tên thật là Skyler Husten Gordy, sinh 23 tháng 8 năm 1986). Họ là con trai và cháu trai của nhà sáng lập hãng đĩa thu âm Motown Berry Gordy, và hai người có mối quan hệ cháu và chú. Âm nhạc của họ thống nhất 2 chủ đề chính là tiệc tùng và rượu chè, và nhóm thường tự cho phong cách âm nhạc của mình là "party rock". Cái tên LMFAO là một chữ viết tắt từ "Laughing My Fucking Ass Out" và được phát âm từng chữ một. Nhóm hiện đã tan rã. +Giải thưởng và đề cử. +Hip-Hop Nation Awards +Grammy Award + +### Công cụ có thể sử dụng + +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. + + +### Câu hỏi người dùng +Ca sĩ Mahola là ai? + +### Hướng dẫn cho AI + +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. + + +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời +... +2025-10-13 01:28:40,839 [INFO] rag_api - ✅ Đã trả lời: Ca sĩ Mahola là ai? ... +2025-10-13 01:30:04,067 [INFO] rag_api - 📥 Câu hỏi: Bóng đá Malaysia sắp nhận án phạt nào ? +2025-10-13 01:30:04,243 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK" +2025-10-13 01:30:04,244 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:30:05,060 [INFO] src.chatbot.llm_client - 💬 Gemini output: {"action": "search_google", "params": {"query": "bóng đá Malaysia nhận án phạt"}}... +2025-10-13 01:30:05,060 [INFO] src.chatbot.llm_client - 🤖 Function call JSON: {'action': 'search_google', 'params': {'query': 'bóng đá Malaysia nhận án phạt'}} +2025-10-13 01:30:05,060 [INFO] function_executor - 🔧 LLM yêu cầu thực thi tool: search_google({'query': 'bóng đá Malaysia nhận án phạt'}) +2025-10-13 01:30:05,061 [INFO] function_router - ⚙️ Thực thi tool 'search_google' với params={'query': 'bóng đá Malaysia nhận án phạt'} +2025-10-13 01:30:08,333 [INFO] function_router - ✅ Tool 'search_google' thực thi thành công. +2025-10-13 01:30:08,333 [INFO] src.chatbot.llm_client - 🧠 Gửi prompt tới Gemini... +2025-10-13 01:30:11,917 [INFO] src.chatbot.llm_client - 💬 Gemini output: Bóng đá Malaysia đang đối mặt với án phạt nặng từ FIFA và AFC do gian dối trong quá trình nhập tịch cầu thủ. Cụ thể, Liê... +2025-10-13 01:30:11,917 [INFO] root - 📤 Gửi prompt tới LLM: ### Vai trò hệ thống +Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm hoặc thực hiện hành động nếu cần. + +### Ngữ cảnh (retrieved from database) +Dưới đây là các thông tin có liên quan: + +(Đoạn 1 - score=0.682) +Đại dịch COVID-19 tại Malaysia + +Đại dịch COVID-19 đã được xác nhận đã lan sang Malaysia vào ngày 25 tháng 1 năm 2020. Tính đến ngày 31 tháng 7 năm 2023, Malaysia có 5,120,581 ca nhiễm COVID-19 và 37,164 ca tử vong được xác nhận. Sau sự gia tăng của các ca nhiễm vào tháng 3 năm 2020, Vua Yang di-Pertuan Agong đã bày tỏ mối quan tâm lớn nhất của mình đối với bước nhảy vọt số lượng các ca nhiễm bệnh. Các biện pháp tiếp theo sau đó đã được Thủ tướng Malaysia công bố để chống lại sự lây lan của virus trong nước thông qua một chương trình truyền hình trực tiếp trên toàn quốc vào ngày 13 tháng 3 năm 2020. +Với sự lây lan của virus vào tất cả các bang và lãnh thổ liên bang của Malaysia vào ngày 16 tháng 3 năm 2020, chính phủ Malaysia tuyên bố rằng họ đã quyết định thực hiện khóa cửa một phần trên toàn quốc (được gọi là Lệnh Kiểm soát Di chuyển) từ ngày 18 tháng 3 đến ngày 31 tháng 3 năm 2020 để hạn chế sự bùng phát số ca dương tính với virus này trong nước. +Đặt tên. +Bộ Y tế gọi căn bệnh này là "coronavirus mới 2019". Một số phương tiện truyền thông gọi căn bệnh này là "coronavirus Vũ Hán". Vào thời điểm dịch bệnh bùng phát, truyền thông Malaysia gọi nó là "radang paru-paru Wuhan" trong tiếng Mã Lai. Sau đó, một số phương tiện truyền thông đã đổi tên thành "radang paru-paru koronavirus baru" trong tiếng Malay. + +(Đoạn 2 - score=0.647) +Sân vận động Sultan Ibrahim + +Sân vận động Sultan Ibrahim () là một sân vận động bóng đá ở Iskandar Puteri, Johor, Malaysia. Sân được đặt tên để vinh danh người đứng đầu hiện tại của bang, Sultan Ibrahim ibni Almarhum Sultan Iskandar. +Kể từ năm 2020, đây là sân nhà của Johor Darul Ta'zim thuộc Malaysia Super League. Sân vận động này đã thay thế Sân vận động Larkin, nơi đã từng là sân nhà của Johor Darul Ta'zim và tất cả các đội bóng ở Johor trước đây kể từ năm 1964. Tổng chi phí xây dựng ước tính khoảng 200 triệu MYR. Sân vận động có sức chứa 40.000 khán giả và được khánh thành vào ngày 22 tháng 2 năm 2020. +Thiết kế. +Lấy cảm hứng từ lá chuối, ý tưởng và thiết kế cuối cùng đã được Tunku Ismail trình làng trong một buổi lễ được tổ chức tại Iskandar Puteri, Johor. Sân vận động được xây dựng trên khu đất rộng 140.000 mét vuông với tổng diện tích xây dựng là 70.000 mét vuông và có sức chứa 40.000 người. Đèn LED màu đỏ, xanh lam và trắng (màu của hiệu kỳ Johor) được lắp đặt bên ngoài sân vận động để chiếu sáng vào ban đêm. Sân cũng là nơi đặt trụ sở của câu lạc bộ, và có trung tâm tập luyện và một cửa hàng lưu niệm. +Một thử nghiệm đường hầm gió tích hợp cho thiết kế của sân vận động đã được thực hiện bởi Guangdong Provincial Academy of Building Research Group, một công ty con của Guangdong Construction Engineering Group Co Ltd. +Xây dựng. +Với chi phí xây dựng sân vận động mới ước tính khoảng 200 triệu RM, Sultan của Johor đã cấp kinh phí cần thiết cho công việc xây dựng. +Country Garden Pacificview Sdn Bhd đã được giao trách nhiệm xây dựng sân vận động. +Vào tháng 1 năm 2017, câu lạc bộ cho biết công việc xây dựng sân vận động đã bị trì hoãn trong vài tháng và sẽ được hoàn thành từ tháng 7 đến cuối năm 2018 sau những điều chỉnh, thay đổi về vị trí, kỹ thuật và thiết kế của sân vận động do Tunku Ismail thực hiện. + +### Công cụ có thể sử dụng + +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. + + +### Câu hỏi người dùng + Bóng đá Malaysia sắp nhận án phạt nào ? + +### Hướng dẫn cho AI + +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. + + +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời +... +2025-10-13 01:30:11,918 [INFO] rag_api - ✅ Đã trả lời: Bóng đá Malaysia sắp nhận án phạt nào ? ... diff --git a/outputs/file_20251012_183627.txt b/outputs/file_20251012_183627.txt new file mode 100644 index 0000000..2bbeb78 --- /dev/null +++ b/outputs/file_20251012_183627.txt @@ -0,0 +1 @@ +Đại học Hanover có 9 khoa. Đội ngũ cán bộ của trường bao gồm 1.120 nhân viên, trong đó có 340 giáo sư, 1.560 nhân viên hành chính và 900 người được tài trợ từ bên thứ ba. \ No newline at end of file diff --git a/outputs/file_20251013_011905.txt b/outputs/file_20251013_011905.txt new file mode 100644 index 0000000..e2c26df --- /dev/null +++ b/outputs/file_20251013_011905.txt @@ -0,0 +1 @@ +Thời Đại Thiếu Niên Đoàn có 7 thành viên: Đinh Trình Hâm, Mã Gia Kỳ, Trương Chân Nguyên, Tống Á Hiên, Hạ Tuấn Lâm, Nghiêm Hạo Tường, Lưu Diệu Văn. \ No newline at end of file diff --git a/src/api/__pycache__/chat_api.cpython-313.pyc b/src/api/__pycache__/chat_api.cpython-313.pyc index cc4538c..2d46938 100644 Binary files a/src/api/__pycache__/chat_api.cpython-313.pyc and b/src/api/__pycache__/chat_api.cpython-313.pyc differ diff --git a/src/api/chat_api.py b/src/api/chat_api.py index 062e288..979d4d7 100644 --- a/src/api/chat_api.py +++ b/src/api/chat_api.py @@ -86,11 +86,14 @@ async def chat_endpoint(req: ChatRequest): try: result = rag_pipeline.run(req.query, top_k=req.top_k) logging.info(f"📤 Gửi prompt tới LLM: {result['prompt']}...") + response = { "query": req.query, "answer": result["answer"], "context_count": len(result.get("context_used", [])), "context_used": result.get("context_used", []), + "sources": result.get("sources", []), # ✅ mới + "used_web": result.get("used_web", False), # ✅ mới } logger.info(f"✅ Đã trả lời: {req.query[:50]}...") diff --git a/src/chatbot/__pycache__/llm_client.cpython-313.pyc b/src/chatbot/__pycache__/llm_client.cpython-313.pyc index 49f8b3e..aebc561 100644 Binary files a/src/chatbot/__pycache__/llm_client.cpython-313.pyc and b/src/chatbot/__pycache__/llm_client.cpython-313.pyc differ diff --git a/src/chatbot/__pycache__/prompt_builder.cpython-313.pyc b/src/chatbot/__pycache__/prompt_builder.cpython-313.pyc index 9b8127a..0b7f3e8 100644 Binary files a/src/chatbot/__pycache__/prompt_builder.cpython-313.pyc and b/src/chatbot/__pycache__/prompt_builder.cpython-313.pyc differ diff --git a/src/chatbot/__pycache__/rag_pipeline.cpython-313.pyc b/src/chatbot/__pycache__/rag_pipeline.cpython-313.pyc index 532bbda..6ddc345 100644 Binary files a/src/chatbot/__pycache__/rag_pipeline.cpython-313.pyc and b/src/chatbot/__pycache__/rag_pipeline.cpython-313.pyc differ diff --git a/src/chatbot/__pycache__/retriever.cpython-313.pyc b/src/chatbot/__pycache__/retriever.cpython-313.pyc index 015c3c4..7746f76 100644 Binary files a/src/chatbot/__pycache__/retriever.cpython-313.pyc and b/src/chatbot/__pycache__/retriever.cpython-313.pyc differ diff --git a/src/chatbot/function_tools/__init__.py b/src/chatbot/function_tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/chatbot/function_tools/__pycache__/__init__.cpython-313.pyc b/src/chatbot/function_tools/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..dab2fc7 Binary files /dev/null and b/src/chatbot/function_tools/__pycache__/__init__.cpython-313.pyc differ diff --git a/src/chatbot/function_tools/__pycache__/base_tool.cpython-313.pyc b/src/chatbot/function_tools/__pycache__/base_tool.cpython-313.pyc new file mode 100644 index 0000000..cd4c5c7 Binary files /dev/null and b/src/chatbot/function_tools/__pycache__/base_tool.cpython-313.pyc differ diff --git a/src/chatbot/function_tools/__pycache__/function_executor.cpython-313.pyc b/src/chatbot/function_tools/__pycache__/function_executor.cpython-313.pyc new file mode 100644 index 0000000..7fe9585 Binary files /dev/null and b/src/chatbot/function_tools/__pycache__/function_executor.cpython-313.pyc differ diff --git a/src/chatbot/function_tools/__pycache__/google_tool.cpython-313.pyc b/src/chatbot/function_tools/__pycache__/google_tool.cpython-313.pyc new file mode 100644 index 0000000..a8643a1 Binary files /dev/null and b/src/chatbot/function_tools/__pycache__/google_tool.cpython-313.pyc differ diff --git a/src/chatbot/function_tools/__pycache__/router.cpython-313.pyc b/src/chatbot/function_tools/__pycache__/router.cpython-313.pyc new file mode 100644 index 0000000..deb97cf Binary files /dev/null and b/src/chatbot/function_tools/__pycache__/router.cpython-313.pyc differ diff --git a/src/chatbot/function_tools/__pycache__/txt_tool.cpython-313.pyc b/src/chatbot/function_tools/__pycache__/txt_tool.cpython-313.pyc new file mode 100644 index 0000000..2053fbf Binary files /dev/null and b/src/chatbot/function_tools/__pycache__/txt_tool.cpython-313.pyc differ diff --git a/src/chatbot/function_tools/base_tool.py b/src/chatbot/function_tools/base_tool.py new file mode 100644 index 0000000..3522ef0 --- /dev/null +++ b/src/chatbot/function_tools/base_tool.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +from abc import ABC, abstractmethod + +class BaseTool(ABC): + """ + Interface (chuẩn chung) cho mọi công cụ (tool). + Mọi tool con đều phải kế thừa và implement hàm execute(). + """ + + # Tên duy nhất của tool (LLM và router sẽ dùng để gọi) + name: str = "base_tool" + + # Mô tả ngắn, để LLM biết công cụ này làm gì (sẽ hiển thị trong prompt) + description: str = "No description." + + @abstractmethod + def execute(self, **kwargs) -> str: + """ + Phương thức bắt buộc. + - Nhận tham số (kwargs) từ hệ thống hoặc LLM + - Trả về kết quả sau khi thực thi công cụ + """ + ... diff --git a/src/chatbot/function_tools/function_executor.py b/src/chatbot/function_tools/function_executor.py new file mode 100644 index 0000000..b1097bd --- /dev/null +++ b/src/chatbot/function_tools/function_executor.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +""" +FunctionExecutor — giải mã output LLM & kích hoạt tool nếu cần. +""" +import json +import logging +from typing import Any, Dict, Optional + +from .router import FunctionRouter +from src.chatbot.function_tools.google_tool import GoogleSearchTool + +logger = logging.getLogger("function_executor") + + +def _strip_code_fences(s: str) -> str: + if not isinstance(s, str): + return s + s = s.strip() + if s.startswith("```"): + s = s.strip("`") + # nếu có ```json ... ``` thì bỏ dòng đầu/cuối + if s.startswith("json"): + s = s[4:] + return s.strip() + + +class FunctionExecutor: + def __init__(self): + self.router = FunctionRouter() + self.google_tool = GoogleSearchTool() + + def parse_action(self, text: Any) -> Optional[Dict[str, Any]]: + """Parse JSON action từ LLM output (hỗ trợ string/dict, có code-fence).""" + if not text: + return None + + if isinstance(text, dict): + return text if "action" in text else None + + if isinstance(text, str): + try: + s = _strip_code_fences(text) + start = s.find("{") + end = s.rfind("}") + 1 + if start == -1 or end == 0: + return None + data = json.loads(s[start:end]) + return data if isinstance(data, dict) and "action" in data else None + except Exception as e: + logger.warning(f"Không thể parse JSON từ LLM output: {e}") + return None + + return None + + def execute_if_needed(self, llm_output: Any, original_query: str = "", allow_web_search: bool = True) -> Dict: + """ + Trả về dict chuẩn cho pipeline: + { + "text": "", + "action_result": "", + "web": {"summary_text":..., "items":[...]} | None + } + """ + result: Dict[str, Any] = {"text": "", "action_result": None, "web": None} + + # Base text + result["text"] = llm_output if isinstance(llm_output, str) else json.dumps(llm_output, ensure_ascii=False) + + # 1️⃣ Nếu LLM yêu cầu action → parse JSON + data = self.parse_action(llm_output) + if data: + action = data.get("action") + params = data.get("params", {}) + try: + logger.info(f"🔧 LLM yêu cầu thực thi tool: {action}({params})") + exec_out = self.router.execute_tool(action, **params) + + # 🧠 Nếu tool là search_google → gán vào result["web"] + if action == "search_google" and isinstance(exec_out, dict): + result["web"] = exec_out + result["action_result"] = f"✅ Đã tìm kiếm Google với truy vấn: {params.get('query', '')}" + else: + result["action_result"] = exec_out + + return result + + except Exception as e: + msg = f"⚠️ Tool '{action}' lỗi: {e}" + logger.exception(msg) + result["action_result"] = msg + return result + + # 2️⃣ Nếu không có action → fallback Google (nếu bật cờ và có query) + # if allow_web_search and original_query: + # logger.info("⚠️ Không có action → fallback Google Search") + # web = self.google_tool.execute(original_query, max_results=3, fetch_pages=True) + # result["web"] = web + # return result + + # 3️⃣ Nếu không có gì cả + return result diff --git a/src/chatbot/function_tools/google_tool.py b/src/chatbot/function_tools/google_tool.py new file mode 100644 index 0000000..baefd93 --- /dev/null +++ b/src/chatbot/function_tools/google_tool.py @@ -0,0 +1,149 @@ +# -*- coding: utf-8 -*- +""" +GoogleSearchTool (Custom Search API + Smart Filter + Page fetch) +---------------------------------------------------------------- +- Tìm bằng Google CSE +- Lọc domain uy tín + khử trùng lặp theo domain +- Tải nội dung trang (HTML) và rút trích đoạn

+- Chuẩn hóa output: trả về cả summary_text và items (để two-pass và sources) +""" + +import logging +from typing import List, Dict +from urllib.parse import urlparse + +import requests +from bs4 import BeautifulSoup + +from src.chatbot.function_tools.base_tool import BaseTool +from src.core.config import GOOGLE_API_KEY, GOOGLE_CX, TRUSTED_DOMAINS + +logger = logging.getLogger("google_search_tool") + + +class GoogleSearchTool(BaseTool): + name = "search_google" + description = "Tìm thông tin mới nhất trên Internet bằng Google Custom Search API." + + def __init__(self): + if not GOOGLE_API_KEY or not GOOGLE_CX: + raise ValueError("❌ Thiếu GOOGLE_API_KEY hoặc GOOGLE_CX trong config.") + self.api_key = GOOGLE_API_KEY + self.cx = GOOGLE_CX + self.trusted_domains = set(TRUSTED_DOMAINS) + + # ----------------- helpers ----------------- + def _domain(self, url: str) -> str: + return urlparse(url).netloc.lower() + + def _is_trusted(self, url: str) -> bool: + dom = self._domain(url) + return any(trust in dom for trust in self.trusted_domains) + + def _summarize(self, text: str, limit: int = 280) -> str: + if not text: + return "" + text = " ".join(text.split()) + if len(text) <= limit: + return text + cut = text.rfind(".", 0, limit) + if cut < int(limit * 0.6): + cut = limit + return text[:cut].rstrip() + " …" + + def _fetch_page_text(self, url: str, limit_chars: int = 1800) -> str: + try: + headers = {"User-Agent": "Mozilla/5.0 (RAGBot)"} + r = requests.get(url, headers=headers, timeout=10) + if r.status_code != 200 or not r.text: + return "" + soup = BeautifulSoup(r.text, "html.parser") + paragraphs = [p.get_text(" ", strip=True) for p in soup.find_all("p")] + text = " ".join(paragraphs) + text = " ".join(text.split()) + if len(text) > limit_chars: + text = text[:limit_chars] + " …" + return text + except Exception as e: + logger.warning(f"Fetch page failed {url}: {e}") + return "" + + # ----------------- main ----------------- + def execute(self, query: str, max_results: int = 5, fetch_pages: bool = True) -> Dict: + """ + Return: + { + "summary_text": "", + "items": [ + {"title":..., "snippet":..., "link":..., "domain":..., "page_text":...}, + ... + ] + } + """ + try: + url = "https://www.googleapis.com/customsearch/v1" + params = { + "key": self.api_key, + "cx": self.cx, + "q": query, + "num": max_results * 2, # xin nhiều hơn chút để lọc + "hl": "vi", + } + resp = requests.get(url, params=params, timeout=10) + if resp.status_code != 200: + return { + "summary_text": f"⚠️ Google API lỗi {resp.status_code}: {resp.text}", + "items": [] + } + + data = resp.json() + raw_items = data.get("items", []) + + # Lọc domain uy tín + khử trùng lặp theo domain + picked: List[Dict] = [] + seen_domains = set() + for it in raw_items: + link = it.get("link") or "" + if not link: + continue + dom = self._domain(link) + if not self._is_trusted(link): + continue + if dom in seen_domains: + continue + seen_domains.add(dom) + + item = { + "title": (it.get("title") or "").strip(), + "snippet": self._summarize(it.get("snippet") or ""), + "link": link, + "domain": dom, + "page_text": "" + } + + if fetch_pages: + item["page_text"] = self._fetch_page_text(link) + + picked.append(item) + if len(picked) >= max_results: + break + + if not picked: + return { + "summary_text": f"❌ Không tìm thấy nguồn uy tín cho truy vấn: '{query}'", + "items": [] + } + + # Gộp summary_text để hiển thị/nhét prompt dễ + blocks = [] + for i, it in enumerate(picked, 1): + page_part = f"\n📄 {self._summarize(it['page_text'], 700)}" if it["page_text"] else "" + blocks.append( + f"{i}. {it['title']}\n{it['snippet']}{page_part}\n🔗 {it['link']}" + ) + summary_text = f"🔍 Kết quả Google (đã lọc nguồn) cho: '{query}'\n\n" + "\n\n".join(blocks) + + return {"summary_text": summary_text, "items": picked} + + except Exception as e: + return {"summary_text": f"⚠️ Lỗi khi tìm kiếm Google: {e}", "items": []} diff --git a/src/chatbot/function_tools/router.py b/src/chatbot/function_tools/router.py new file mode 100644 index 0000000..0ecee9c --- /dev/null +++ b/src/chatbot/function_tools/router.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +""" +FunctionRouter — Bộ điều phối công cụ (function tools) +------------------------------------------------------ +- Quản lý và điều hướng các công cụ mà LLM có thể gọi. +- Khi LLM trả JSON {"action": "", "params": {...}}, + router sẽ xác định đúng tool và gọi thực thi tương ứng. +""" + +import logging +from typing import Dict +from .base_tool import BaseTool +from .txt_tool import TxtTool +from .google_tool import GoogleSearchTool # ✅ Thêm import Google search + +logger = logging.getLogger("function_router") + + +class FunctionRouter: + """ + Router trung tâm, chịu trách nhiệm: + - Đăng ký tool vào registry (theo tên) + - Điều phối thực thi tool + """ + + def __init__(self): + # Danh mục các tool khả dụng (tên -> instance) + self.tools: Dict[str, BaseTool] = {} + + # 🔧 Đăng ký các tool mặc định + self.register_tool(TxtTool()) + self.register_tool(GoogleSearchTool()) + + logger.info(f"✅ FunctionRouter khởi tạo, có {len(self.tools)} công cụ sẵn sàng.") + + # ------------------------------------------------------------ + # Đăng ký tool mới + # ------------------------------------------------------------ + def register_tool(self, tool: BaseTool): + """Đăng ký 1 tool mới vào router""" + if not isinstance(tool, BaseTool): + raise TypeError("Tool phải kế thừa BaseTool.") + if not hasattr(tool, "name"): + raise ValueError("Tool phải có thuộc tính name.") + if not callable(getattr(tool, "execute", None)): + raise ValueError("Tool phải có hàm execute().") + + # Ghi đè nếu trùng tên + if tool.name in self.tools: + logger.warning(f"⚠️ Tool '{tool.name}' đã tồn tại, ghi đè instance mới.") + self.tools[tool.name] = tool + logger.info(f"🔧 Đã đăng ký tool: {tool.name} — {tool.description}") + + # ------------------------------------------------------------ + # Lấy danh sách tool (cho debug / hiển thị) + # ------------------------------------------------------------ + def list_tools(self) -> Dict[str, str]: + """Trả về danh sách tên và mô tả của tất cả công cụ""" + return {name: t.description for name, t in self.tools.items()} + + # ------------------------------------------------------------ + # Thực thi tool dựa trên action + # ------------------------------------------------------------ + def execute_tool(self, action: str, **params) -> str: + """ + Gọi tool theo tên hành động (action). + Ví dụ: + router.execute_tool("create_txt", text="Xin chào!") + router.execute_tool("search_google", query="tin tức hôm nay") + + Trả về: Chuỗi kết quả hoặc message lỗi. + """ + tool = self.tools.get(action) + if not tool: + msg = f"❌ Không tìm thấy tool '{action}' trong router." + logger.error(msg) + return msg + + try: + logger.info(f"⚙️ Thực thi tool '{action}' với params={params}") + result = tool.execute(**params) + logger.info(f"✅ Tool '{action}' thực thi thành công.") + return result + except Exception as e: + msg = f"❌ Lỗi khi thực thi tool '{action}': {e}" + logger.exception(msg) + return msg diff --git a/src/chatbot/function_tools/txt_tool.py b/src/chatbot/function_tools/txt_tool.py new file mode 100644 index 0000000..83ef405 --- /dev/null +++ b/src/chatbot/function_tools/txt_tool.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +""" +TxtTool — công cụ tạo file văn bản .txt +""" +import os +import re +from datetime import datetime +from .base_tool import BaseTool + + +def _slugify(s: str) -> str: + """Chuẩn hóa tên file an toàn (không dấu, không ký tự lạ).""" + s = (s or "").lower().strip() + s = re.sub(r"[^a-z0-9._-]+", "-", s) + s = re.sub(r"-{2,}", "-", s).strip("-") + return s or "output" + + +class TxtTool(BaseTool): + """Tool tạo file TXT từ nội dung văn bản.""" + + # Định danh của tool (LLM sẽ dùng để gọi) + name = "create_txt" + + # Mô tả — dùng cho LLM biết công cụ này làm gì + description = "Tạo file TXT. Tham số: {text: str, filename?: str}" + + def execute(self, text: str, filename: str | None = None) -> str: + """ + Tạo file txt chứa nội dung được truyền vào. + Trả về thông báo thành công (và đường dẫn file). + """ + # 1️⃣ Đảm bảo thư mục outputs tồn tại + os.makedirs("outputs", exist_ok=True) + + # 2️⃣ Nếu không chỉ định tên, tạo theo timestamp + if not filename: + filename = f"file_{datetime.now():%Y%m%d_%H%M%S}.txt" + + # 3️⃣ Chuẩn hóa tên file (loại bỏ ký tự lạ) + filename = _slugify(filename) + if not filename.endswith(".txt"): + filename += ".txt" + + path = os.path.join("outputs", filename) + + # 4️⃣ Ghi nội dung vào file + try: + with open(path, "w", encoding="utf-8") as f: + f.write((text or "")[:20000]) # giới hạn 20k ký tự cho an toàn + except Exception as e: + return f"❌ Lỗi khi ghi file: {e}" + + # 5️⃣ Trả kết quả + return f"✅ File TXT đã được tạo: {path}" diff --git a/src/chatbot/llm_client.py b/src/chatbot/llm_client.py index e6c1909..3c8e180 100644 --- a/src/chatbot/llm_client.py +++ b/src/chatbot/llm_client.py @@ -1,24 +1,78 @@ +# -*- coding: utf-8 -*- +""" +LLMClient +--------- +Tầng giao tiếp với mô hình ngôn ngữ Gemini (Google Generative AI). +Hỗ trợ cả phản hồi văn bản tự nhiên và function calling (JSON). +""" + import os +import json +import re import google.generativeai as genai +import logging +from typing import Any, Optional from src.core.config import GEMINI_API_KEY, GEMINI_MODEL +logger = logging.getLogger(__name__) + class LLMClient: def __init__(self, api_key: str = GEMINI_API_KEY, model: str = GEMINI_MODEL): if not api_key: - raise ValueError("Thiếu GEMINI_API_KEY trong config hoặc .env") + raise ValueError("❌ Thiếu GEMINI_API_KEY trong config hoặc .env") genai.configure(api_key=api_key) self.model = genai.GenerativeModel(model) + logger.info(f"🔮 LLMClient khởi tạo với model: {model}") - def generate(self, prompt: str) -> str: + # ---------------------------------------------------------- + def _try_extract_json(self, text: str) -> Optional[dict]: """ - Gửi prompt vào Gemini và trả về nội dung text. + Cố gắng trích JSON từ đầu ra LLM. + - Loại bỏ text thừa, chỉ giữ đoạn {...} đầu tiên. + - Nếu JSON chứa 'action', coi là function call hợp lệ. """ try: - response = self.model.generate_content(prompt) - return response.text.strip() if response.text else "" + match = re.search(r"\{.*\}", text, re.DOTALL) + if not match: + return None + + json_str = match.group(0).strip() + parsed = json.loads(json_str) + + if isinstance(parsed, dict) and "action" in parsed: + return parsed + + return None except Exception as e: - print(f"[GeminiLLMClient] Lỗi khi gọi Gemini API: {e}") - return "" + logger.warning(f"⚠️ Không thể parse JSON: {e}") + return None + + # ---------------------------------------------------------- + def generate(self, prompt: str) -> Any: + """ + Gửi prompt vào Gemini và trả về: + - dict (nếu là function call) + - str (nếu là câu trả lời tự nhiên) + """ + try: + logger.info("🧠 Gửi prompt tới Gemini...") + response = self.model.generate_content(prompt) + + text = response.text.strip() if response.text else "" + logger.info(f"💬 Gemini output: {text[:120]}...") + + # ✅ Cố gắng parse JSON (function call) + parsed = self._try_extract_json(text) + if parsed: + logger.info(f"🤖 Function call JSON: {parsed}") + return parsed + + # 🔤 Nếu không phải JSON → trả lời tự nhiên + return text + + except Exception as e: + logger.exception(f"❌ Lỗi khi gọi Gemini API: {e}") + return f"Lỗi LLM: {str(e)}" diff --git a/src/chatbot/prompt_builder.py b/src/chatbot/prompt_builder.py index d88a58f..9305ca2 100644 --- a/src/chatbot/prompt_builder.py +++ b/src/chatbot/prompt_builder.py @@ -18,43 +18,33 @@ class PromptBuilder: context_label: str = "Dưới đây là các thông tin có liên quan:" ): self.system_prompt = system_prompt or ( - "Bạn là trợ lý AI chuyên nghiệp, hiểu tiếng Việt, " - "có khả năng trả lời tự nhiên, chính xác và ngắn gọn. " - "Chỉ sử dụng thông tin trong phần ngữ cảnh để trả lời. " - "Nếu không đủ dữ liệu, hãy nói 'Tôi chưa có thông tin để trả lời chính xác' " - "và không phỏng đoán hoặc suy luận thêm." + "Bạn là trợ lý AI thông minh, hiểu tiếng Việt, có khả năng trả lời tự nhiên, " + "chính xác và ngắn gọn. Bạn được phép sử dụng các công cụ có sẵn để tìm kiếm " + "hoặc thực hiện hành động nếu cần." ) self.max_context_len = max_context_len self.context_label = context_label + # ----------------------------------------------------- def _smart_truncate(self, text: str, limit: int) -> str: """Cắt ngắn văn bản theo giới hạn ký tự, ưu tiên dừng ở dấu câu.""" text = text.strip() if len(text) <= limit: return text - cut = text.rfind(".", 0, limit) - if cut < int(limit * 0.6): # không tìm thấy dấu chấm hợp lý + if cut < int(limit * 0.6): cut = limit - return text[:cut].rstrip() + " …" - # ----------------------------------------------------- # ----------------------------------------------------- def build_context_block(self, retrieved_docs: List[Dict]) -> str: - """ - Ghép các đoạn văn bản được truy xuất từ Qdrant thành block context. - - Luôn đảm bảo có ít nhất một đoạn context. - - Cắt ngắn tự động để không vượt quá giới hạn max_context_len. - """ + """Ghép các đoạn văn bản được truy xuất từ Qdrant thành block context.""" if not retrieved_docs: return "(Không có dữ liệu ngữ cảnh)" sorted_docs = sorted(retrieved_docs, key=lambda x: x.get("score", 0), reverse=True) - - context_blocks = [] - total_len = 0 - budget = self.max_context_len - len(self.context_label) - 50 # trừ phần tiêu đề + context_blocks, total_len = [], 0 + budget = self.max_context_len - len(self.context_label) - 50 for i, doc in enumerate(sorted_docs, start=1): text = (doc.get("text") or "").strip() @@ -76,7 +66,6 @@ class PromptBuilder: if total_len >= budget: break - # Nếu vì lý do nào đó chưa có đoạn nào, lấy đoạn đầu tiên if not context_blocks: first = sorted_docs[0] header = f"(Đoạn 1 - score={first.get('score', 0):.3f})\n" @@ -85,30 +74,59 @@ class PromptBuilder: return f"{self.context_label}\n\n" + "\n\n".join(context_blocks) - # ----------------------------------------------------- - # Xây prompt hoàn chỉnh # ----------------------------------------------------- def build_prompt(self, user_query: str, retrieved_docs: List[Dict]) -> str: - """ - Tạo prompt hoàn chỉnh cho LLM. - """ + """Tạo prompt hoàn chỉnh cho LLM, ép trả JSON nếu thiếu dữ liệu.""" context_block = self.build_context_block(retrieved_docs) - prompt = f"""### Vai trò hệ thống: + tools_description = """ +Bạn có thể sử dụng các công cụ sau: + +1) search_google(query: str, max_results: int = 5) + → Dùng khi ngữ cảnh không đủ hoặc không có thông tin để trả lời chính xác. + +2) create_txt(text: str) + → Dùng khi người dùng yêu cầu lưu hoặc tạo file văn bản. + +Khi cần dùng công cụ, bạn PHẢI trả về **JSON hợp lệ duy nhất** theo mẫu: +{"action": "", "params": {...}} + +Ví dụ: +{"action": "search_google", "params": {"query": "Stray Kids có bao nhiêu thành viên?"}} +{"action": "create_txt", "params": {"text": "Nội dung cần lưu"}} + +Không bao giờ thêm chữ, ký tự hay lời giải thích nào ngoài JSON. +""" + + rules = """ +Quy tắc ra quyết định: +1️⃣ Nếu dữ liệu trong ngữ cảnh (context) chứa đủ chi tiết để trả lời chính xác → Trả lời văn bản tự nhiên, KHÔNG JSON. +2️⃣ Nếu ngữ cảnh thiếu, mơ hồ, hoặc không có dữ liệu liên quan → TRẢ VỀ JSON: + {"action": "search_google", "params": {"query": ""}} +3️⃣ Nếu người dùng yêu cầu lưu/tạo file → TRẢ VỀ JSON: + {"action": "create_txt", "params": {"text": ""}} +4️⃣ Nếu bạn không chắc chắn, cũng hãy gọi search_google thay vì suy đoán. +""" + + prompt = f"""### Vai trò hệ thống {self.system_prompt} -### Dữ liệu ngữ cảnh: +### Ngữ cảnh (retrieved from database) {context_block} -### Câu hỏi của người dùng: +### Công cụ có thể sử dụng +{tools_description} + +### Câu hỏi người dùng {user_query} -### Hướng dẫn cho AI: -- Trả lời ngắn gọn, rõ ràng, đúng trọng tâm. -- Dựa hoàn toàn vào thông tin trong ngữ cảnh. -- Nếu thông tin không có trong ngữ cảnh, hãy nói rõ ràng rằng bạn chưa có dữ liệu để trả lời chính xác. -- Không bịa thêm, không suy diễn. +### Hướng dẫn cho AI +{rules} -### Trả lời: +### Định dạng đầu ra +- Nếu đủ thông tin → trả lời tự nhiên, ngắn gọn, chính xác. +- Nếu thiếu thông tin → trả về JSON như hướng dẫn trên, KHÔNG văn bản khác. + +### Trả lời """ return prompt diff --git a/src/chatbot/rag_pipeline.py b/src/chatbot/rag_pipeline.py index 81ba8a2..65a5a1d 100644 --- a/src/chatbot/rag_pipeline.py +++ b/src/chatbot/rag_pipeline.py @@ -1,39 +1,90 @@ # -*- coding: utf-8 -*- """ -RAGPipeline ------------ -Kết nối các module: - - Retriever (Qdrant) - - PromptBuilder - - LLMClient -Đầu vào: user_query (string) -Đầu ra: câu trả lời (string) +RAGPipeline — RAG + Function Calling + Google fallback + Two-pass refine """ +from typing import Dict, Any, List -from typing import List, Dict, Any from src.chatbot.llm_client import LLMClient from src.chatbot.retriever import Retriever from src.chatbot.prompt_builder import PromptBuilder +from src.chatbot.function_tools.function_executor import FunctionExecutor +from src.core.config import ALLOW_WEB_SEARCH, SECOND_PASS + class RAGPipeline: def __init__(self): self.retriever = Retriever() self.prompt_builder = PromptBuilder() - self.llm = LLMClient() + self.llm = LLMClient() + self.function_executor = FunctionExecutor() - def run(self, user_query: str, top_k: int = 5) -> Dict[str, Any]: - """Trả về cả câu trả lời và context dùng""" + def _build_refine_prompt(self, user_query: str, web_summary: str, items: List[Dict]) -> str: + # Tạo block nguồn gọn để LLM trích dẫn + links = [it.get("link", "") for it in items if it.get("link")] + sources_text = "\n".join([f"- {url}" for url in links]) + + return f"""### Dữ liệu web (đã thu thập): +{web_summary} + +### Nguồn: +{sources_text} + +### Câu hỏi gốc: +{user_query} + +### Yêu cầu: +- Tóm tắt chính xác và súc tích (3–6 câu), ngắn gọn, dễ hiểu. +- Không bịa đặt. Nếu thông tin không chắc chắn, nêu rõ mức độ chắc chắn. +- Trích dẫn 1–3 nguồn ở cuối, dạng: "Nguồn: , " +""" + + def run(self, user_query: str, top_k: int = 5, allow_web_search: bool = ALLOW_WEB_SEARCH, second_pass: bool = SECOND_PASS) -> Dict[str, Any]: + # 1) RAG retrieve docs = self.retriever.search(user_query, top_k=top_k) + + # 2) Build prompt từ context prompt = self.prompt_builder.build_prompt(user_query, docs) - answer = self.llm.generate(prompt) + + # 3) Gọi LLM (pass 1) + llm_answer = self.llm.generate(prompt) + + # 4) Thực thi tool nếu có / fallback Google + exec_result = self.function_executor.execute_if_needed( + llm_output=llm_answer, + original_query=user_query, + allow_web_search=allow_web_search + ) + + # Chuẩn bị output mặc định + final_answer = exec_result.get("text") or "" + sources = [] + + # Nếu có web result → two-pass refine (nếu bật) + web = exec_result.get("web") + if web and isinstance(web, dict) and web.get("items"): + sources = [it.get("link") for it in web["items"] if it.get("link")] + if second_pass: + refine_prompt = self._build_refine_prompt(user_query, web.get("summary_text", ""), web["items"]) + final_answer = self.llm.generate(refine_prompt) + + # Nếu có action_result (VD: create_txt), nối thêm thông báo ngắn + action_result = exec_result.get("action_result") + if action_result: + final_answer = f"{final_answer}\n\n🛠️ Tool: {action_result}" + + # 5) Trả đầy đủ cho API return { - "answer": answer, + "answer": final_answer.strip(), "context_used": docs, "prompt": prompt, + "sources": sources, # ✅ link nguồn (nếu có) + "used_web": bool(web), # ✅ có dùng web hay không } + + if __name__ == "__main__": pipeline = RAGPipeline() - query = "Bạn biết Mahola là ai không?" - response = pipeline.run(query) - print("Câu hỏi:", query) - print("Trả lời:", response) \ No newline at end of file + q = "Acid propionic là gì? Hôm nay có cập nhật gì mới không?" + out = pipeline.run(q) + print("Answer:\n", out["answer"]) + print("Sources:", out["sources"]) diff --git a/src/core/__pycache__/config.cpython-313.pyc b/src/core/__pycache__/config.cpython-313.pyc index 9b01531..ac1a5e2 100644 Binary files a/src/core/__pycache__/config.cpython-313.pyc and b/src/core/__pycache__/config.cpython-313.pyc differ diff --git a/src/core/config.py b/src/core/config.py index d9105d7..e053ecf 100644 --- a/src/core/config.py +++ b/src/core/config.py @@ -48,12 +48,22 @@ load_dotenv() DATA_RAW = Path(os.getenv("DATA_RAW", "./data/data_raw10k")).resolve() GEMINI_API_KEY = os.getenv("GEMINI_API_KEY", "") GEMINI_MODEL = os.getenv("GEMINI_MODEL", "models/gemini-2.0-flash-001") +SERPER_API_KEY = os.getenv("SERPER_API_KEY", "14ea1e5de7b68084d3e41a4efe204108a8fa76c6fab062b00fa1912a97d3c28b") +GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY", "AIzaSyCOtXgt7M6qKlj5srF8hF_7iyvZbBrVnhA") +GOOGLE_CX = os.getenv("GOOGLE_CX", "9379e94eed0f145b4") # ==== Embedding model (SentenceTransformers) ==== EMBED_MODEL = os.getenv("EMBED_MODEL", "Alibaba-NLP/gte-multilingual-base") EMBED_DIM = int(os.getenv("EMBED_DIM", "768")) EMBED_DEVICE = os.getenv("EMBED_DEVICE", "cuda") # "cuda" | "cpu" | "auto" EMBED_BATCH_SIZE = int(os.getenv("EMBED_BATCH_SIZE", "64")) +_TRUSTED = os.getenv( + "TRUSTED_DOMAINS", + "wikipedia.org,chinhphu.vn,vnexpress.net,bbc.com,nhandan.vn,tuoitre.vn,thanhnien.vn,zingnews.vn,vov.vn,vietnamnet.vn" +) +TRUSTED_DOMAINS = [d.strip().lower() for d in _TRUSTED.split(",") if d.strip()] +ALLOW_WEB_SEARCH = os.getenv("ALLOW_WEB_SEARCH", "true").lower() == "true" +SECOND_PASS = os.getenv("SECOND_PASS", "true").lower() == "true" # ==== Semantic chunking ==== # Ngưỡng cosine similarity để tách chủ đề (thấp hơn ngưỡng => tách chunk) diff --git a/utils/__pycache__/test_searchgg.cpython-313.pyc b/utils/__pycache__/test_searchgg.cpython-313.pyc new file mode 100644 index 0000000..c83e215 Binary files /dev/null and b/utils/__pycache__/test_searchgg.cpython-313.pyc differ diff --git a/utils/test_searchgg.py b/utils/test_searchgg.py new file mode 100644 index 0000000..75cb109 --- /dev/null +++ b/utils/test_searchgg.py @@ -0,0 +1,4 @@ +from src.chatbot.function_tools.google_tool import GoogleSearchTool + +tool = GoogleSearchTool() +print(tool.execute("Messi là ai?", max_results=2))