strakid
This commit is contained in:
parent
3fd5370049
commit
feee56dc56
|
|
@ -1,16 +1,20 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug rag_pipeline (as module)",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "src.chatbot.rag_pipeline", // chạy theo module
|
||||
"cwd": "${workspaceFolder}", // thư mục gốc project
|
||||
"envFile": "${workspaceFolder}/.env", // load biến môi trường
|
||||
"env": { "PYTHONPATH": "${workspaceFolder}" }, // đảm bảo 'src' là package gốc
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": true
|
||||
}
|
||||
]
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "Python Debugger: FastAPI",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "uvicorn",
|
||||
"args": [
|
||||
"main:app",
|
||||
"--port", "8386",
|
||||
],
|
||||
"jinja": true
|
||||
}
|
||||
]
|
||||
}
|
||||
21
README.md
21
README.md
|
|
@ -0,0 +1,21 @@
|
|||
How to debug :
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug rag_pipeline (as module)",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "src.chatbot.rag_pipeline",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"envFile": "${workspaceFolder}/.env",
|
||||
"env": { "PYTHONPATH": "${workspaceFolder}" },
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": true
|
||||
}
|
||||
]
|
||||
}
|
||||
(launch.json)
|
||||
|
||||
uvicorn main:app --port 8386 (--host 0.0.0.0)
|
||||

|
||||
Binary file not shown.
|
|
@ -0,0 +1,248 @@
|
|||
2025-10-08 23:26:27,626 [INFO] numexpr.utils - NumExpr defaulting to 12 threads.
|
||||
2025-10-08 23:26:30,539 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK"
|
||||
2025-10-08 23:26:30,544 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK"
|
||||
2025-10-08 23:26:30,552 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base
|
||||
2025-10-08 23:26:36,963 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công.
|
||||
2025-10-08 23:26:40,982 [INFO] rag_api - 📥 Câu hỏi: Kể tên phần mềm miễn phí trên hệ điều hành Linux?
|
||||
2025-10-08 23:26:41,196 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK"
|
||||
2025-10-08 23:26:42,517 [INFO] rag_api - ✅ Đã trả lời: Kể tên phần mềm miễn phí trên hệ điều hành Linux? ...
|
||||
2025-10-08 23:28:23,168 [INFO] numexpr.utils - NumExpr defaulting to 12 threads.
|
||||
2025-10-08 23:28:26,142 [INFO] httpx - HTTP Request: GET http://localhost:6333 "HTTP/1.1 200 OK"
|
||||
2025-10-08 23:28:26,146 [INFO] httpx - HTTP Request: GET http://localhost:6333/collections/text_chunks "HTTP/1.1 200 OK"
|
||||
2025-10-08 23:28:26,153 [INFO] sentence_transformers.SentenceTransformer - Load pretrained SentenceTransformer: Alibaba-NLP/gte-multilingual-base
|
||||
2025-10-08 23:28:32,452 [INFO] rag_api - ✅ RAGPipeline đã khởi tạo thành công.
|
||||
2025-10-08 23:28:35,794 [INFO] rag_api - 📥 Câu hỏi: Kể tên phần mềm miễn phí trên hệ điều hành Linux?
|
||||
2025-10-08 23:28:36,017 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK"
|
||||
2025-10-08 23:28:36,936 [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. 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.
|
||||
|
||||
### Dữ liệu ngữ cảnh:
|
||||
Dưới đây là các thông tin có liên quan:
|
||||
|
||||
(Đoạn 1 - score=0.670)
|
||||
OpenMosix
|
||||
|
||||
openMosix là một hệ thống quản lý các nhóm máy vi tính (tiếng Anh: "cluster") tự do và miễn phí theo giấy phép mã nguồn mở GPL. Hệ thống này cho phép các quá trình vi tính di chuyển từ một máy này đến một máy khác trong nhóm máy của hệ thống nếu như quá trình đó có thể được thi hành nhanh chóng hơn. Hệ thống openMosix hữu ích trong các ứng dụng thường hay truy cập đến phần cứng như các thao tác đọc và ghi trên đĩa cứng. openMosix được phát hành dưới dạng phần mềm vá ("patch") cho hạt nhân Linux. Ngoài ra hệ thống openMosix còn được phát hành theo một số đĩa LiveCD chuyên môn và dưới dạng sẵn sàng để dùng trong hệ điều hành Gentoo Linux.
|
||||
Hiện tại phiên bản openMosix ổn định chạy trên hệ điều hành Linux nhân 2.4 với cấu trúc máy kiểu Intel x86. Hỗ trợ cho các cấu trúc AMD 64-bit chỉ có trong phiên bản đang được phát triển cho hạt nhân Linux phiên bản 2.6. Phiên bản openMosix dành cho hạt nhân Linux 2.6 đang còn được thử nghiệm. Ngoài ra, các chương trình hỗ trợ người dùng còn chưa có trong phiên bản này.
|
||||
Hệ thống openMosix được ông Moshe Bar đưa lên mạng vào ngày 10 tháng 2 năm 2002 khi hệ thống Mosix mà ông tham gia phát triển trước đó trở thành phần mềm tư hữu.
|
||||
Các LiveCD.
|
||||
GNU/Linux LiveCD có openMosix:
|
||||
|
||||
(Đoạn 2 - score=0.660)
|
||||
GNU
|
||||
|
||||
GNU là một hệ điều hành và bộ sưu tập phần mềm máy tính phong phú. GNU bao gồm toàn bộ phần mềm tự do, hầu hết được cấp phép theo General Public License (GPL) của GNU Project.
|
||||
"GNU" là một kiểu viết tắt đệ quy của "GNU's Not Unix!", nó được chọn bởi thiết kế của GNU là tương tự Unix, nhưng khác với Unix vì nó là phần mềm miễn phí và không có mã Unix. Dự án GNU bao gồm nhân hệ điều hành, GNU Hurd, vốn là trọng tâm ban đầu của Free Software Foundation (FSF). Tuy nhiên với trạng thái của hạt nhân Hurd là chưa sẵn sàng ra mắt, các hạt nhân phi GNU, phổ biến nhất là nhân Linux, cũng có thể được sử dụng với phần mềm GNU. Sự kết hợp giữa GNU và Linux đã trở nên phổ biến đến mức bộ đôi này thường được gọi tắt là "Linux", hoặc ít thường xuyên hơn, "GNU/Linux". (xem Tranh cãi về đặt tên GNU/Linux)
|
||||
Richard Stallman, người sáng lập dự án, xem GNU như một "phương tiện kỹ thuật để kết thúc xã hội". Liên quan đến Lawrence Lessig trong phần giới thiệu về ấn bản thứ hai của cuốn sách "Free Software, Free Society" của mình Stallman đã viết về "các khía cạnh xã hội của phần mềm và cách Phần mềm tự do có thể tạo ra công bằng và xã hội".
|
||||
Lịch sử.
|
||||
Việc phát triển hệ điều hành GNU được Richard Stallman khởi xướng khi ông làm việc tại Phòng thí nghiệm trí tuệ nhân tạo MIT. Nó được gọi là Dự án GNU, và được công bố công khai vào ngày 27 tháng 9 năm 1983, trên các nhóm tin net.unix-wizards và net.usoft bởi Stallman. Việc phát triển phần mềm bắt đầu vào ngày 5 tháng 1 năm 1984, khi Stallman nghỉ việc tại Phòng thí nghiệm để họ không thể đòi quyền sở hữu hoặc can thiệp vào việc phân phối các thành phần GNU dưới dạng phần mềm tự do. Richard Stallman đã chọn tên bằng cách sử dụng nhiều cách chơi chữ khác nhau, bao gồm cả bài hát "The Gnu".
|
||||
Mục tiêu là ra mắt một hệ điều hành phần mềm hoàn toàn tự do. Stallman muốn người dùng máy tính được tự do nghiên cứu mã nguồn của phần mềm họ sử dụng, chia sẻ phần mềm với người khác, sửa đổi hành vi của phần mềm và xuất bản các phiên bản phần mềm được sửa đổi của riêng họ. Triết lý này sau đó đã được xuất bản thành Tuyên ngôn GNU vào tháng 3 năm 1985.
|
||||
Kinh nghiệm của Richard Stallman với Incompatible Timesharing System (ITS), một hệ điều hành ban đầu được viết bằng hợp ngữ đã trở nên lỗi thời do PDP-10 bị ngừng phát triển, kiến trúc máy tính mà ITS đã viết, dẫn đến một quyết định rằng hệ thống di động là cần thiết. Do đó ông đã quyết định rằng sự phát triển sẽ được bắt đầu bằng C và Lisp làm ngôn ngữ lập trình hệ thống, và GNU sẽ tương thích với Unix. Vào thời điểm đó, Unix đã là một hệ điều hành độc quyền phổ biến …
|
||||
|
||||
(Đoạn 3 - score=0.658)
|
||||
OpenSUSE Project
|
||||
|
||||
openSUSE Proje …
|
||||
|
||||
### Câu hỏi của người dùng:
|
||||
Kể tên phần mềm miễn phí trên hệ điều hành Linux?
|
||||
|
||||
### 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.
|
||||
|
||||
### Trả lời:
|
||||
...
|
||||
2025-10-08 23:28:36,937 [INFO] rag_api - ✅ Đã trả lời: Kể tên phần mềm miễn phí trên hệ điều hành Linux? ...
|
||||
2025-10-08 23:29:36,817 [INFO] rag_api - 📥 Câu hỏi: Radio Free Asia là tên viết tắt của đài nào?
|
||||
2025-10-08 23:29:37,013 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK"
|
||||
2025-10-08 23:29:37,927 [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. 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.
|
||||
|
||||
### Dữ liệu ngữ cảnh:
|
||||
Dưới đây là các thông tin có liên quan:
|
||||
|
||||
(Đoạn 1 - score=0.759)
|
||||
Đài Á Châu Tự Do
|
||||
|
||||
Đài Á Châu Tự Do (tên khác: RFA Tiếng Việt, Đài Châu Á Tự Do; tên tiếng Anh: Radio Free Asia, viết tắt là RFA) là một đài phát thanh tư nhân phi lợi nhuận có trụ sở chính tại Hoa Kỳ và được chính phủ Hoa Kỳ tài trợ nhằm phát sóng các chương trình phát thanh; cung cấp thông tin, tin tức và bình luận trực tuyến cho khán giả tại châu Á. Hoạt động với mục đích giúp những người theo dõi có thể tiếp cận các tin tức độc lập, không bị kiểm duyệt cho một số quốc gia ở châu Á có môi trường truyền thông, tự do báo chí và tự do ngôn luận kém. RFA được tài trợ và hoạt động dưới sự giám sát bởi —USAGM (tên trước đây là Hội đồng Quản trị Phát thanh và Truyền hình Hoa Kỳ—BBG), một cơ quan độc lập của chính phủ Hoa Kỳ nhưng họ phủ nhận rằng bản thân không chịu sự quản lý của chính phủ Hoa Kỳ và các thành viên của họ không có quan hệ mật thiết nào với chính phủ nước này.
|
||||
Đài Á Châu Tự Do được thành lập dựa trên các nguyên tắc của Đạo luật Phát thanh Quốc tế năm 1994 với mục đích đã nêu là "thúc đẩy các giá trị dân chủ và nhân quyền", mục tiêu ban đầu của RFA nhằm đối địch với các nỗ lực tuyên truyền của Đảng Cộng sản Trung Quốc, cũng như cung cấp các thông tin truyền thông về chính phủ Bắc Triều Tiên. Chương trình đầu tiên của Đài Á Châu Tự Do được phát sóng bằng tiếng Quan Thoại ngày nay đã được mở rộng với 9 thứ tiếng ở châu Á.
|
||||
Lịch sử.
|
||||
Giai đoạn đầu.
|
||||
Đầu thập niên 1950, với những căng thẳng đang gia tăng của cuộc Chiến tranh Lạnh, chính phủ Hoa Kỳ cần một cơ quan vận động chính trị nhằm đối chọi lại Chủ nghĩa cộng sản ở châu Á. Do đó vào năm 1951, Cơ quan Tình báo Trung ương (CIA) quyết định cho thành lập thành lập "Ủy ban Châu Á Tự do" (Committee for Free Asia), có trụ sở chính tại San Francisco, Hoa Kỳ và đồng thời cho phát sóng các chương trình của "Đài phát thanh châu Á tự do" (tiền thân của Đài Á Châu Tự Do- RFA sau này) trên khắp Trung Quốc đại lục và Đông Nam Á thông qua các trạm phát sóng ở Manila, Dhaka, Pakistan (ngày nay là Bangladesh) và Karachi, với văn phòng chính tại Tokyo, Nhật Bản. Sau khi phát sóng, CIA nhận thấy rằng Trung Quốc đại lục có rất ít máy radio thu vô tuyến cá nhân, vì vậy họ đã thiển khai kế hoạch ứng phó đó là sử dụng những quả khinh khí cầu bay từ đảo Đài Loan mang theo những chiếc đài thu thanh nhỏ được điều chỉnh để người dân người dân Trung Quốc có thể sử dụng. Nhưng kế hoạch này đã bị hủy bỏ vì những quả khinh khí cầu này thường bị gió thổi trở lại Đài Loan và không thể tới nơi. Cuối cùng các chương trình phát sóng bị dừng hẳn vào năm 1955 sau khoảng thời gian hoạt động kém hiệu quả.
|
||||
Tái thành lập và đổi mới.
|
||||
Mãi cho đến đầu thập niên 90, ở Trung Quốc đại lục ngày càng gia tăng các cuộc đàn áp dân chủ nhất là sau Sự kiện Thiên An Môn vào năm 1989. Thấy được sự cấp bách của vấn đề này dân biểu của Hạ viện Hoa Kỳ đã đề xuất ý tưởng hình thành đạo luật về phát thanh nhằm tìm cách tạo ra một tổ chức để thúc đẩy các giá trị dân chủ và nhân quyền ở châu Á hoạt động theo mô hình của Đài Âu Châu Tự Do. Vào tháng 10 năm 1991, Ủy ban Đối ngoại Thượng viện Hoa Kỳ lần đầu tiên đề xuất và thông qua đề xuất "thành lập một đài phát thanh dành riêng cho Trung Quốc đại lục", đồng thời quyết định lập một ủy ban đặc biệt để nghiên cứu tính khả thi của đề xuất này. Tháng 8 năm 1992, ủy ban đã đệ trình lên Quốc hội Hoa Kỳ và Tổng thống một báo cáo khả thi về việc thành lập "Đài Trung Quốc Tự do", và đã được thông qua. Nhưng sau đó, chính phủ Hoa Kỳ đã không sử dụng cái tên "Đài Trung Quốc Tự do" vì ngoài việc chủ yếu nhắm vào Trung Quốc đại lục, đài còn bao gồm một số quốc gia khác ở Đông Bắc Á và Đông Nam Á..
|
||||
Được tái lập lại như một tổ chức tư nhân vào tháng 3 năm 1996, Đài Á Châu Tự Do đã bắt đầu phát thanh trở lại từ tháng 9 năm 1996. Cần chú ý, tổ chức mới này không có liên quan gì đến tổ chức RFA cũ từ những năm thập niên 50 …
|
||||
|
||||
(Đoạn 2 - score=0.662)
|
||||
Asia Times
|
||||
|
||||
Asia Times (, tiếng Việt: "Thời …
|
||||
|
||||
### Câu hỏi của người dùng:
|
||||
Radio Free Asia là tên viết tắt của đài nào?
|
||||
|
||||
### 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.
|
||||
|
||||
### Trả lời:
|
||||
...
|
||||
2025-10-08 23:29:37,928 [INFO] rag_api - ✅ Đã trả lời: Radio Free Asia là tên viết tắt của đài nào? ...
|
||||
2025-10-08 23:30:29,152 [INFO] rag_api - 📥 Câu hỏi: Đại học Hanover có bao nhiêu khoa?
|
||||
2025-10-08 23:30:29,334 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK"
|
||||
2025-10-08 23:30:30,054 [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. 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.
|
||||
|
||||
### Dữ liệu ngữ cảnh:
|
||||
Dưới đây là các thông tin có liên quan:
|
||||
|
||||
(Đoạn 1 - score=0.894)
|
||||
Đạ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)
|
||||
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". Thời gian phân chia hai thời kỳ này không thống nhất, có ý kiến lấy năm 1850 (thời kỳ Trung Quốc suy yếu) hoặc năm 1911 (Cách mạng Tân Hợi) hoặc năm 1949 (Cộng hoà nhân dân Trung Hoa thành lập) từ về trước là Hán học cổ đại, các nghiên cứu sau này thuộc về Hán học hiện đại.
|
||||
Hán học, Hoa học và Sinology.
|
||||
Theo nhận định của học giả Trung Quốc Trương Kỳ Quân, thì danh từ Sinology mà người phương Tây thường dùng là chỉ Hoa học chứ không phải Hán học. Nhiều học giả phương Tây còn đề xướng Tạng học (nghiên cứu về Tây Tạng), Mãn học (nghiên cứu về Mãn Châu), theo quan điểm của các học giả Đại lục là phá hoại sự thống nhất của Trung Quốc. Theo đó thì Hoa học không phải là nghiên cứu về Trung Quốc mà chủ yếu nghiên cứu về các dân tộc thiểu số Trung Quốc.
|
||||
|
||||
(Đoạn 3 - score=0.627)
|
||||
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 4 - score=0.623)
|
||||
Đạ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 …
|
||||
|
||||
### Câu hỏi của người dùng:
|
||||
Đại học Hanover có bao nhiêu khoa?
|
||||
|
||||
### 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.
|
||||
|
||||
### Trả lời:
|
||||
...
|
||||
2025-10-08 23:30:30,055 [INFO] rag_api - ✅ Đã trả lời: Đại học Hanover có bao nhiêu khoa?...
|
||||
2025-10-08 23:30:52,036 [INFO] rag_api - 📥 Câu hỏi: Đại học Hanover có bao nhiêu khoa? Gồm các khoa nào?
|
||||
2025-10-08 23:30:52,244 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK"
|
||||
2025-10-08 23:30:53,129 [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. 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.
|
||||
|
||||
### Dữ liệu ngữ cảnh:
|
||||
Dưới đây là các thông tin có liên quan:
|
||||
|
||||
(Đoạn 1 - score=0.901)
|
||||
Đạ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.620)
|
||||
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". Thời gian phân chia hai thời kỳ này không thống nhất, có ý kiến lấy năm 1850 (thời kỳ Trung Quốc suy yếu) hoặc năm 1911 (Cách mạng Tân Hợi) hoặc năm 1949 (Cộng hoà nhân dân Trung Hoa thành lập) từ về trước là Hán học cổ đại, các nghiên cứu sau này thuộc về Hán học hiện đại.
|
||||
Hán học, Hoa học và Sinology.
|
||||
Theo nhận định của học giả Trung Quốc Trương Kỳ Quân, thì danh từ Sinology mà người phương Tây thường dùng là chỉ Hoa học chứ không phải Hán học. Nhiều học giả phương Tây còn đề xướng Tạng học (nghiên cứu về Tây Tạng), Mãn học (nghiên cứu về Mãn Châu), theo quan điểm của các học giả Đại lục là phá hoại sự thống nhất của Trung Quốc. Theo đó thì Hoa học không phải là nghiên cứu về Trung Quốc mà chủ yếu nghiên cứu về các dân tộc thiểu số Trung Quốc.
|
||||
|
||||
(Đoạn 3 - score=0.616)
|
||||
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 4 - score=0.611)
|
||||
Đạ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 …
|
||||
|
||||
### Câu hỏi của người dùng:
|
||||
Đại học Hanover có bao nhiêu khoa? Gồm các khoa nào?
|
||||
|
||||
### 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.
|
||||
|
||||
### Trả lời:
|
||||
...
|
||||
2025-10-08 23:30:53,130 [INFO] rag_api - ✅ Đã trả lời: Đại học Hanover có bao nhiêu khoa? Gồm các khoa nà...
|
||||
2025-10-08 23:31:11,108 [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-08 23:31:11,185 [INFO] httpx - HTTP Request: POST http://localhost:6333/collections/text_chunks/points/search "HTTP/1.1 200 OK"
|
||||
2025-10-08 23:31:12,190 [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. 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.
|
||||
|
||||
### 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â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:
|
||||
- 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.
|
||||
|
||||
### Trả lời:
|
||||
...
|
||||
2025-10-08 23:31:12,190 [INFO] rag_api - ✅ Đã trả lời: Đại học Hanover có bao nhiêu khoa? Có bao nhiêu nh...
|
||||
Binary file not shown.
|
|
@ -6,37 +6,108 @@ FastAPI cho chatbot RAG.
|
|||
Nhận câu hỏi từ người dùng, trả lời bằng RAGPipeline.
|
||||
"""
|
||||
|
||||
import os
|
||||
import logging
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from src.chatbot.rag_pipeline import RAGPipeline
|
||||
from datetime import datetime
|
||||
|
||||
app = FastAPI(title="RAG Chatbot API", version="1.0")
|
||||
# ------------------------------------------------------------
|
||||
# 🧩 Cấu hình logging (ghi cả ra console và file)
|
||||
# ------------------------------------------------------------
|
||||
|
||||
rag_pipeline = RAGPipeline() # khởi tạo pipeline dùng chung
|
||||
# Tạo thư mục logs nếu chưa tồn tại
|
||||
LOG_DIR = "logs"
|
||||
os.makedirs(LOG_DIR, exist_ok=True)
|
||||
|
||||
# Tên file log có dạng: logs/api_2025-10-08.log
|
||||
LOG_FILE = os.path.join(LOG_DIR, f"api_{datetime.now().strftime('%Y-%m-%d')}.log")
|
||||
|
||||
# Định dạng log
|
||||
log_format = "%(asctime)s [%(levelname)s] %(name)s - %(message)s"
|
||||
|
||||
# Cấu hình handler ghi ra file
|
||||
file_handler = logging.FileHandler(LOG_FILE, encoding="utf-8")
|
||||
file_handler.setFormatter(logging.Formatter(log_format))
|
||||
|
||||
# Cấu hình handler ghi ra console
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setFormatter(logging.Formatter(log_format))
|
||||
|
||||
# Gắn cả hai handler vào root logger
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
handlers=[file_handler, console_handler],
|
||||
)
|
||||
|
||||
logger = logging.getLogger("rag_api")
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 🚀 Khởi tạo FastAPI
|
||||
# ------------------------------------------------------------
|
||||
app = FastAPI(title="RAG Chatbot API", version="1.3")
|
||||
|
||||
rag_pipeline = None # Pipeline toàn cục
|
||||
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup_event():
|
||||
"""Tải RAGPipeline khi FastAPI khởi động"""
|
||||
global rag_pipeline
|
||||
try:
|
||||
from src.chatbot.rag_pipeline import RAGPipeline
|
||||
rag_pipeline = RAGPipeline()
|
||||
logger.info("✅ RAGPipeline đã khởi tạo thành công.")
|
||||
except Exception as e:
|
||||
logger.exception("❌ Lỗi khi khởi tạo RAGPipeline")
|
||||
raise RuntimeError("Không thể khởi tạo RAGPipeline.")
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 📩 API Models
|
||||
# ------------------------------------------------------------
|
||||
class ChatRequest(BaseModel):
|
||||
query: str
|
||||
top_k: int = 5
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 💬 Endpoint: /chat
|
||||
# ------------------------------------------------------------
|
||||
@app.post("/chat")
|
||||
async def chat_endpoint(req: ChatRequest):
|
||||
"""
|
||||
Nhận câu hỏi người dùng -> gọi RAGPipeline -> trả lời
|
||||
"""
|
||||
"""Nhận câu hỏi người dùng -> gọi RAGPipeline -> trả lời"""
|
||||
global rag_pipeline
|
||||
if rag_pipeline is None:
|
||||
raise HTTPException(status_code=503, detail="RAGPipeline chưa sẵn sàng.")
|
||||
|
||||
logger.info(f"📥 Câu hỏi: {req.query}")
|
||||
|
||||
try:
|
||||
result = rag_pipeline.query(req.query, top_k=req.top_k)
|
||||
return {
|
||||
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", []),
|
||||
}
|
||||
|
||||
logger.info(f"✅ Đã trả lời: {req.query[:50]}...")
|
||||
return response
|
||||
|
||||
except ConnectionError as ce:
|
||||
logger.error(f"⚠️ Không thể kết nối tới Qdrant: {ce}")
|
||||
raise HTTPException(status_code=503, detail="Không thể kết nối tới Qdrant.")
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
logger.exception(f"❌ Lỗi xử lý truy vấn: {e}")
|
||||
raise HTTPException(status_code=500, detail=f"Lỗi nội bộ: {e}")
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 🩺 Endpoint: / (root)
|
||||
# ------------------------------------------------------------
|
||||
@app.get("/")
|
||||
async def root():
|
||||
"""Kiểm tra tình trạng API"""
|
||||
return {"message": "RAG Chatbot API is running 🚀"}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
PromptBuilder: tạo prompt hoàn chỉnh để gửi đến LLM (RAG).
|
||||
PromptBuilder: Tạo prompt hoàn chỉnh để gửi đến LLM trong mô hình RAG.
|
||||
"""
|
||||
|
||||
from typing import List, Dict
|
||||
|
|
@ -8,66 +8,107 @@ from typing import List, Dict
|
|||
|
||||
class PromptBuilder:
|
||||
"""
|
||||
Tạo prompt kết hợp giữa context (retrieved documents) và query người dùng.
|
||||
Xây dựng prompt kết hợp giữa context (retrieved docs) và câu hỏi người dùng.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
system_prompt: str | None = None,
|
||||
max_context_len: int = 3000,
|
||||
context_label: str = "Dưới đây là các thông tin có liên quan:",
|
||||
max_context_len: int = 4000,
|
||||
context_label: str = "Dưới đây là các thông tin có liên quan:"
|
||||
):
|
||||
# Prompt hệ thống có thể chỉnh để điều khiển phong cách trả lời
|
||||
self.system_prompt = system_prompt or (
|
||||
"Bạn là trợ lý AI hiểu tiếng Việt, có khả năng trả lời tự nhiên, chính xác, "
|
||||
"và súc tích. Khi có thông tin trong ngữ cảnh, hãy dựa vào đó để trả lời. "
|
||||
"Nếu không có thông tin, hãy nói 'Tôi chưa có dữ liệu để trả lời chính xác.'"
|
||||
"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."
|
||||
)
|
||||
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ý
|
||||
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.
|
||||
Giới hạn độ dài để tránh vượt quá token LLM.
|
||||
- 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.
|
||||
"""
|
||||
if not retrieved_docs:
|
||||
return ""
|
||||
return "(Không có dữ liệu ngữ cảnh)"
|
||||
|
||||
# Ghép các đoạn text lại theo độ quan trọng (score cao trước)
|
||||
sorted_docs = sorted(retrieved_docs, key=lambda x: x["score"], reverse=True)
|
||||
context_texts = []
|
||||
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 đề
|
||||
|
||||
for doc in sorted_docs:
|
||||
chunk = f"[{doc.get('file_name', 'unknown')}] {doc.get('text', '').strip()}"
|
||||
chunk_len = len(chunk)
|
||||
if total_len + chunk_len > self.max_context_len:
|
||||
for i, doc in enumerate(sorted_docs, start=1):
|
||||
text = (doc.get("text") or "").strip()
|
||||
if not text:
|
||||
continue
|
||||
|
||||
header = f"(Đoạn {i} - score={doc.get('score', 0):.3f})\n"
|
||||
chunk_len = len(header) + len(text)
|
||||
|
||||
if total_len + chunk_len > budget:
|
||||
remaining = budget - total_len - len(header)
|
||||
if remaining <= 0:
|
||||
break
|
||||
text = self._smart_truncate(text, remaining)
|
||||
|
||||
context_blocks.append(header + text)
|
||||
total_len += len(header) + len(text)
|
||||
|
||||
if total_len >= budget:
|
||||
break
|
||||
context_texts.append(chunk)
|
||||
total_len += chunk_len
|
||||
|
||||
joined_context = "\n\n".join(context_texts)
|
||||
return f"{self.context_label}\n{joined_context}"
|
||||
# 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"
|
||||
text = self._smart_truncate(first.get("text", ""), budget - len(header))
|
||||
context_blocks.append(header + text)
|
||||
|
||||
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 đưa cho LLM.
|
||||
Tạo prompt hoàn chỉnh cho LLM.
|
||||
"""
|
||||
context_block = self.build_context_block(retrieved_docs)
|
||||
|
||||
prompt = f"""### Hệ thống:
|
||||
prompt = f"""### Vai trò hệ thống:
|
||||
{self.system_prompt}
|
||||
|
||||
### Ngữ cảnh:
|
||||
{context_block or "(Không có dữ liệu ngữ cảnh)"}
|
||||
### Dữ liệu ngữ cảnh:
|
||||
{context_block}
|
||||
|
||||
### Câu hỏi của 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.
|
||||
|
||||
### Trả lời:
|
||||
"""
|
||||
return prompt
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,11 +21,16 @@ class RAGPipeline:
|
|||
self.prompt_builder = PromptBuilder()
|
||||
self.llm = LLMClient()
|
||||
|
||||
def run(self, user_query: str) -> str:
|
||||
docs = self.retriever.search(user_query)
|
||||
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"""
|
||||
docs = self.retriever.search(user_query, top_k=top_k)
|
||||
prompt = self.prompt_builder.build_prompt(user_query, docs)
|
||||
answer = self.llm.generate(prompt)
|
||||
return answer
|
||||
return {
|
||||
"answer": answer,
|
||||
"context_used": docs,
|
||||
"prompt": prompt,
|
||||
}
|
||||
if __name__ == "__main__":
|
||||
pipeline = RAGPipeline()
|
||||
query = "Bạn biết Mahola là ai không?"
|
||||
|
|
|
|||
|
|
@ -25,11 +25,13 @@ class Retriever:
|
|||
qdrant_url: str = QDRANT_URL,
|
||||
qdrant_api_key: str = QDRANT_API_KEY,
|
||||
collection: str = QDRANT_COLLECTION,
|
||||
top_k: int = 5,
|
||||
# top_k: int = 5,
|
||||
):
|
||||
self.collection = collection
|
||||
self.top_k = top_k
|
||||
# self.top_k = top_k
|
||||
self.client = QdrantClient(url=qdrant_url, api_key=qdrant_api_key)
|
||||
info = self.client.get_collection(QDRANT_COLLECTION)
|
||||
print(info.config)
|
||||
|
||||
# Model để encode query
|
||||
self.model = SentenceTransformer(model_name, device=device, trust_remote_code=True)
|
||||
|
|
@ -39,13 +41,15 @@ class Retriever:
|
|||
vec = self.model.encode([query], normalize_embeddings=True)
|
||||
return vec[0].tolist()
|
||||
|
||||
def search(self, query: str) -> List[Dict[str, Any]]:
|
||||
def search(self, query: str, top_k: int) -> List[Dict[str, Any]]:
|
||||
"""Truy vấn các đoạn văn bản tương tự trong Qdrant"""
|
||||
query_vec = self.encode_query(query)
|
||||
print("Vector length:", len(query_vec))
|
||||
|
||||
results: List[ScoredPoint] = self.client.search(
|
||||
collection_name=self.collection,
|
||||
query_vector=query_vec,
|
||||
limit=self.top_k,
|
||||
limit=top_k,
|
||||
)
|
||||
|
||||
formatted = []
|
||||
|
|
@ -62,9 +66,9 @@ class Retriever:
|
|||
|
||||
if __name__ == "__main__":
|
||||
# Test nhanh
|
||||
retriever = Retriever(top_k=3)
|
||||
retriever = Retriever()
|
||||
query = "Mahola la ai"
|
||||
results = retriever.search(query)
|
||||
results = retriever.search(query, top_k=3)
|
||||
for i, r in enumerate(results, 1):
|
||||
print(f"\n[{i}] Score={r['score']:.4f}")
|
||||
print(f"File: {r['file_name']}")
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue