- RAG dùng trong AI dựa trên tri thức nghiệp vụ có thể bỏ lỡ thông tin liên quan vì mất ngữ cảnh như tên công ty hoặc thời điểm trong quá trình chia tài liệu thành các chunk nhỏ
- Contextual Retrieval của Anthropic là phương pháp thêm một mô tả ngắn dựa trên toàn bộ tài liệu vào trước mỗi chunk, sau đó tạo embedding và chỉ mục BM25 để giảm tỷ lệ truy xuất thất bại
- Trong thử nghiệm, Contextual Embeddings đã giảm tỷ lệ thất bại khi truy xuất top-20 chunk từ 5,7% xuống 3,7%, tức 35%, còn kết hợp Contextual Embeddings với Contextual BM25 giảm xuống 2,9%, tức 49%
- Khi thêm reranking (tái xếp hạng), hệ thống chấm điểm lại top-150 ứng viên và chỉ chuyển top-20 cho mô hình, giúp tỷ lệ truy xuất thất bại giảm từ 5,7% xuống 1,9%, tức 67%
- Nếu cơ sở tri thức có từ 200.000 token trở xuống, cũng có thể đưa toàn bộ vào prompt; nhưng với cơ sở tri thức lớn hơn, cần đánh giá kết hợp Contextual Retrieval và reranking theo từng use case
Ngữ cảnh tài liệu bị RAG làm mất
- Để mô hình AI hữu ích trong một nghiệp vụ cụ thể, nó cần truy cập được tri thức nền
- Chatbot hỗ trợ khách hàng cần tri thức về doanh nghiệp đó
- Bot phân tích pháp lý cần tri thức về các án lệ trước đây
- Các nhà phát triển thường bổ sung tri thức cho mô hình bằng Retrieval-Augmented Generation(RAG)
- Truy xuất thông tin liên quan từ cơ sở tri thức
- Gắn thông tin đã truy xuất vào prompt của người dùng để cải thiện câu trả lời của mô hình
- RAG truyền thống có thể loại bỏ ngữ cảnh trong quá trình chia tài liệu thành chunk, khiến không tìm được thông tin liên quan
- Contextual Retrieval là một cách cải thiện bước truy xuất của RAG, và có thể dùng đồng thời hai kỹ thuật con
- Contextual Embeddings: tạo embedding từ các chunk đã được gắn ngữ cảnh
- Contextual BM25: tạo chỉ mục BM25 từ các chunk đã được gắn ngữ cảnh
- Sự kết hợp này giảm số lần truy xuất thất bại 49%, và khi kết hợp với reranking có thể giảm tới 67%
- Có cung cấp cookbook để triển khai Contextual Retrieval với Claude
Với cơ sở tri thức nhỏ, cũng có thể dùng prompt dài
- Nếu cơ sở tri thức có từ 200.000 token trở xuống, nhỏ hơn khoảng 500 trang, có thể đưa toàn bộ cơ sở tri thức vào prompt mà không cần RAG
- Prompt caching của Claude giúp cách tiếp cận này nhanh hơn và tiết kiệm chi phí hơn
- Có thể cache các prompt thường dùng giữa các lần gọi API
- Có thể giảm độ trễ hơn 2 lần
- Có thể giảm chi phí tới 90%
- Có thể xem cách hoạt động trong prompt caching cookbook
- Khi cơ sở tri thức lớn hơn, cần một phương thức truy xuất có khả năng mở rộng hơn, và Contextual Retrieval được dùng trong trường hợp này
Vai trò của RAG thông thường và BM25
- Khi cơ sở tri thức lớn không vừa trong context window, giải pháp phổ biến là RAG
- Luồng tiền xử lý của RAG như sau
- Chia corpus tài liệu thành các chunk văn bản nhỏ, thường chỉ vài trăm token trở xuống
- Chuyển đổi chunk thành vector embedding chứa ngữ nghĩa bằng mô hình embedding
- Lưu embedding vào cơ sở dữ liệu vector hỗ trợ tìm kiếm tương đồng ngữ nghĩa
- Tại thời điểm chạy, hệ thống tìm trong cơ sở dữ liệu vector các chunk có ngữ nghĩa tương đồng nhất với truy vấn của người dùng, rồi thêm các chunk liên quan vào prompt của mô hình sinh
- Mô hình embedding nắm bắt tốt quan hệ ngữ nghĩa nhưng có thể bỏ lỡ khớp chuỗi chính xác
- BM25(Best Matching 25) là hàm xếp hạng dùng đối sánh từ vựng, đặc biệt hiệu quả với truy vấn chứa mã định danh riêng hoặc thuật ngữ kỹ thuật
- BM25 dựa trên khái niệm TF-IDF
- TF-IDF đo mức độ quan trọng của một từ cụ thể trong một tài liệu thuộc một tập tài liệu
- BM25 xét đến độ dài tài liệu và áp dụng hàm bão hòa cho term frequency để các từ phổ biến không chi phối kết quả
- Ví dụ, khi tìm kiếm
"Error code TS-999" trong cơ sở dữ liệu hỗ trợ kỹ thuật, mô hình embedding có thể tìm được tài liệu về mã lỗi nói chung nhưng bỏ lỡ khớp chính xác "TS-999"
- BM25 trực tiếp tìm chuỗi đó để xác định tài liệu liên quan
RAG dùng kết hợp embedding và BM25
- RAG có thể kết hợp embedding và BM25 để truy xuất chunk chính xác hơn
- Chia cơ sở tri thức thành các chunk nhỏ
- Tạo mã hóa TF-IDF và embedding ngữ nghĩa cho từng chunk
- Dùng BM25 để tìm các chunk hàng đầu dựa trên khớp chính xác
- Dùng embedding để tìm các chunk hàng đầu dựa trên tương đồng ngữ nghĩa
- Kết hợp kết quả bằng kỹ thuật rank fusion và loại bỏ trùng lặp
- Đưa top K chunk vào prompt để tạo câu trả lời
- Cách này cân bằng giữa khớp thuật ngữ chính xác và hiểu ngữ nghĩa rộng hơn
- Có thể mở rộng hiệu quả về chi phí tới các cơ sở tri thức khổng lồ không thể chứa trong một prompt đơn lẻ
- Tuy nhiên, hệ thống RAG truyền thống có hạn chế là phá vỡ ngữ cảnh khi chia tài liệu thành chunk
- Tình huống tiêu biểu là khi hỏi
"What was the revenue growth for ACME Corp in Q2 2023?" trên cơ sở tri thức dựa trên hồ sơ SEC
- Chunk liên quan có thể chỉ chứa
"The company's revenue grew by 3% over the previous quarter."
- Chỉ với chunk này, không thể biết đó là công ty nào và giai đoạn nào
- Vì vậy khó tận dụng đúng thông tin ở cả bước truy xuất lẫn bước sử dụng
Cách hoạt động của Contextual Retrieval
- Contextual Retrieval thêm ngữ cảnh mô tả theo từng chunk vào trước mỗi chunk trước khi embedding và tạo chỉ mục BM25
- Khi áp dụng cho embedding là Contextual Embeddings
- Khi áp dụng cho chỉ mục BM25 là Contextual BM25
- Trong ví dụ về hồ sơ SEC, chunk ban đầu như sau
The company's revenue grew by 3% over the previous quarter.
- Chunk đã được ngữ cảnh hóa sẽ đổi thành như sau
This chunk is from an SEC filing on ACME corp's performance in Q2 2023; the previous quarter's revenue was $314 million. The company's revenue grew by 3% over the previous quarter.
- Trước đây cũng đã có các phương pháp tận dụng ngữ cảnh để cải thiện truy xuất
- Các phương pháp này khác với cách Contextual Retrieval thêm ngữ cảnh theo từng chunk
Tạo ngữ cảnh cho chunk bằng Claude
- Việc con người trực tiếp chú thích hàng nghìn hoặc hàng triệu chunk là không thực tế
- Anthropic viết prompt để Claude tạo ngữ cảnh ngắn, theo từng chunk, mô tả mỗi chunk dựa trên ngữ cảnh của toàn bộ tài liệu
- Prompt dùng cho Claude 3 Haiku như sau
<document>
{{WHOLE_DOCUMENT}}
</document>
Here is the chunk we want to situate within the whole document
<chunk>
{{CHUNK_CONTENT}}
</chunk>
Please give a short succinct context to situate this chunk within the overall document for the purposes of improving search retrieval of the chunk. Answer only with the succinct context and nothing else.
- Văn bản ngữ cảnh được tạo thường dài 50~100 token, được gắn vào trước chunk rồi dùng để tạo embedding và chỉ mục BM25
- Khi dùng prompt caching, không cần gửi lại tài liệu tham chiếu cho từng chunk
- Đưa tài liệu vào cache một lần và tham chiếu nội dung đã được cache trước đó
- Giả sử chunk 800 token, tài liệu 8k token, chỉ thị ngữ cảnh 50 token và ngữ cảnh 100 token cho mỗi chunk, chi phí một lần để tạo chunk đã ngữ cảnh hóa là 1,02 USD cho mỗi 1 triệu token tài liệu
Phương pháp thử nghiệm và hiệu năng truy xuất
- Thử nghiệm được thực hiện trên nhiều lĩnh vực tri thức, mô hình embedding, chiến lược truy xuất và chỉ số đánh giá
- Codebase
- Tiểu thuyết
- Bài báo ArXiv
- Bài báo khoa học
- Ví dụ câu hỏi và câu trả lời của từng lĩnh vực có trong Appendix II
- Biểu đồ cho thấy hiệu năng trung bình trên tất cả lĩnh vực tri thức, sử dụng cấu hình embedding hàng đầu là Gemini Text 004 và truy xuất top-20 chunk
- Chỉ số đánh giá là 1 - recall@20
- Đo tỷ lệ không truy xuất được tài liệu liên quan trong 20 chunk đứng đầu
- Trong toàn bộ kết quả, mọi kết hợp embedding-source được đánh giá đều cải thiện hiệu năng khi áp dụng ngữ cảnh hóa
- Kết quả cải thiện hiệu năng như sau
- Contextual Embeddings: giảm tỷ lệ thất bại khi truy xuất top-20 chunk từ 5,7% → 3,7%, tức 35%
- Contextual Embeddings + Contextual BM25: giảm tỷ lệ truy xuất thất bại từ 5,7% → 2,9%, tức 49%
Những điểm cần cân nhắc khi triển khai
- Ranh giới chunk có thể ảnh hưởng đến hiệu năng truy xuất
- Kích thước chunk
- Ranh giới chunk
- Phần chồng lấn giữa các chunk
- Contextual Retrieval cải thiện hiệu năng trên tất cả mô hình embedding đã kiểm thử, nhưng mức cải thiện có thể khác nhau theo từng mô hình
- Prompt chung được cung cấp hoạt động tốt, nhưng có thể đạt kết quả tốt hơn với prompt contextualizer tùy chỉnh phù hợp với domain hoặc use case
- Ví dụ: bao gồm glossary của các thuật ngữ then chốt chỉ được định nghĩa trong các tài liệu khác của cơ sở tri thức
- Đưa nhiều chunk hơn vào context window làm tăng khả năng chứa thông tin liên quan
- Tuy nhiên, càng nhiều thông tin thì mô hình càng dễ bị phân tán, nên có giới hạn
- Khi thử truyền 5, 10 và 20 chunk, 20 chunk cho hiệu năng tốt nhất
- Trong use case thực tế, cần thử nghiệm
- Khi tạo câu trả lời, việc truyền các chunk đã ngữ cảnh hóa và phân biệt đâu là ngữ cảnh, đâu là chunk gốc có thể giúp cải thiện kết quả
- Luôn phải chạy đánh giá
Cải thiện thêm bằng reranking
- Reranking là kỹ thuật lọc trong cơ sở tri thức lớn, chỉ chuyển cho mô hình những chunk liên quan nhất trong số các chunk ứng viên được truy xuất ban đầu
- Bước này giảm lượng thông tin mô hình phải xử lý, có thể ảnh hưởng đến chất lượng câu trả lời, chi phí và độ trễ
- Quy trình như sau
- Lấy các chunk hàng đầu có khả năng liên quan bằng truy xuất ban đầu
- Trong thử nghiệm dùng top 150
- Chuyển top N chunk và truy vấn người dùng cho mô hình reranking
- Mô hình reranking gán điểm liên quan và mức độ quan trọng cho từng chunk
- Chọn top K chunk
- Trong thử nghiệm dùng top 20
- Đưa các chunk đã chọn vào context của mô hình để tạo kết quả cuối cùng
- Thử nghiệm được thực hiện với Cohere reranker
- Cũng có Voyage reranker, nhưng không có thời gian kiểm thử
- Việc thêm bước reranking trên nhiều domain giúp tối ưu hóa truy xuất hơn nữa
- Reranked Contextual Embedding + Contextual BM25 giảm tỷ lệ thất bại khi truy xuất top-20 chunk từ 5,7% → 1,9%, tức 67%
Cân bằng giữa chi phí và độ trễ
- Reranking chắc chắn thêm một độ trễ nhỏ vì đưa thêm bước vào runtime
- Dù mô hình reranking chấm điểm tất cả chunk song song, vẫn cần cân nhắc tác động đến độ trễ và chi phí
- Rerank nhiều chunk hơn có thể cải thiện hiệu năng nhưng làm tăng chi phí và độ trễ
- Rerank ít chunk hơn giúp giảm chi phí và độ trễ nhưng mức cải thiện hiệu năng có thể giảm
- Cần tìm sự cân bằng phù hợp bằng cách thử nghiệm nhiều cấu hình trong use case cụ thể
Kết quả khi kết hợp
- So sánh các tổ hợp mô hình embedding, việc dùng BM25 hay không, dùng Contextual Retrieval hay không, dùng reranking hay không, và số lượng truy xuất top-K trên nhiều loại dataset
- Tóm tắt kết quả như sau
- Embeddings + BM25 tốt hơn chỉ dùng embedding
- Trong các embedding đã kiểm thử, Voyage và Gemini là tốt nhất
- Chuyển top-20 chunk cho mô hình hiệu quả hơn top-10 hoặc top-5
- Thêm ngữ cảnh vào chunk cải thiện đáng kể độ chính xác truy xuất
- Reranking tốt hơn so với không dùng reranking
- Để tối đa hóa cải thiện hiệu năng, có thể kết hợp Contextual Embeddings dựa trên Voyage hoặc Gemini, Contextual BM25, bước reranking và thêm 20 chunk vào prompt
- Nhà phát triển có thể thử nghiệm cách tiếp cận này bằng Contextual Retrieval cookbook
1 bình luận
Các ý kiến trên Hacker News
Đang xây dựng RAG doanh nghiệp cho cơ quan chính phủ. Khi thử A/B thử nghiệm bằng các chỉ số RAGAS, dựa trên các câu hỏi đánh giá tổng hợp thì việc thêm tái xếp hạng dựa trên LLM sau tìm kiếm lai (tìm kiếm ngữ nghĩa + vector) không tạo ra thay đổi lớn, còn HyDE làm giảm đáng kể chất lượng câu trả lời và chất lượng tìm kiếm
Vẫn cần đánh giá RAGAS thêm bằng câu hỏi của chuyên gia và câu hỏi thực tế của người dùng
Vì vậy, trong RAG vận hành/doanh nghiệp, việc tìm kiếm lai thường tốt không phải là chuyện mới, nhưng không có phương pháp nào luôn thắng. Trong trường hợp của chúng tôi, chỉ riêng tìm kiếm ngữ nghĩa của Azure AI Search làm phương pháp thứ hai bên cạnh độ tương đồng vector là đã đủ. Ở nơi khác, BM25 hoặc một mô hình ngôn ngữ nhỏ tinh chỉnh để hậu xử lý truy vấn có thể tốt hơn, nên cuối cùng vẫn phải liên tục kiểm thử theo từng trường hợp sử dụng
Tiếp theo dự định thử RAPTOR, SelfRAG, RAG dạng tác nhân, cải thiện truy vấn (mở rộng và truy vấn con), GraphRAG
Bài học đến nay là cần có baseline và nhóm thử nghiệm rồi cố gắng bác bỏ giả thuyết không bằng các chỉ số như RAGAS; câu hỏi/câu trả lời đánh giá nên dùng ba loại: Q&A do chuyên gia viết, câu hỏi người dùng thực tế lấy từ log, và Q&A tổng hợp tạo từ tài liệu gốc
Điều tôi thích nhất ở cách này là tận dụng tốt prompt caching
Prompt được cache thường chỉ tốn khoảng 1/10 chi phí, nên mẹo kiểu chạy mọi chunk cùng với toàn bộ tài liệu gốc trước đây không hợp lý về chi phí, nhưng giờ thì khả thi
Nhờ giảm chi phí bằng caching, có vẻ sẽ mở ra thêm nhiều kỹ thuật hay kiểu này
Ghi chú về tìm kiếm theo ngữ cảnh: https://simonwillison.net/2024/Sep/20/introducing-contextual... và ghi chú về prompt caching: https://simonwillison.net/2024/Aug/14/prompt-caching-with-cl...
Đây có vẻ là bối cảnh hữu ích để hình dung cần chi bao nhiêu nếu muốn theo kịp các mô hình và tính năng mới nhất
Nhìn từ nền tảng tìm kiếm truyền thống, việc giới hạn RAG vào mô hình embedding có sẵn và tìm kiếm vector là một chiến lược khá ngây thơ. Bản thân tìm kiếm vector không tốt đến vậy, và để cải thiện ngữ cảnh cung cấp cho LLM thì cần thêm các chiến lược truy xuất thông tin. Những gì đang làm ở đây thực chất cũng là việc đó
Trước đây Microsoft đã công bố bài báo Graph RAG, kết hợp RAG và tìm kiếm vector dựa trên đồ thị khái niệm được tạo bằng trích xuất thực thể từ dữ liệu chỉ mục. Cách này có thể kéo lên thông tin liên quan về mặt ngữ cảnh cho các chunk được khớp
Tôi có cảm giác là có thể đi khá xa ngay cả khi không có tìm kiếm vector. Chi phí cũng rẻ hơn nhiều. Chỉ cần dùng công cụ tìm kiếm truyền thống và truy vấn được điều chỉnh tốt. Tất nhiên, điểm mấu chốt là tinh chỉnh truy vấn, và có thể không hợp với trường hợp tổng quát, nhưng có thể hiệu quả với các trường hợp chuyên biệt hơn
Bổ sung ngữ cảnh thì cách tiếp cận này không mới đến vậy. Một trong những cách phổ biến để cải thiện kết quả RAG là dùng LLM “mở rộng” các chunk nền tảng để tăng diện tích bề mặt ngữ nghĩa có thể được khớp
Chạy mở rộng truy vấn bằng HyDE[1] có thể cải thiện hơn nữa, nhưng không phải lúc nào cũng tốt hơn nên tôi dùng nó như một đường thay thế
Tôi không rõ Anthropic đã đưa ra điều gì mới ở đây. Nhìn vào code cookbook thì cũng chỉ cho thấy quy trình tạo ngữ cảnh đó, chứ API thực tế không thay đổi gì đối với “tìm kiếm theo ngữ cảnh”
Điều khác biệt là prompt caching được giới thiệu một tháng trước, cho phép cung cấp toàn bộ tài liệu dài làm ngữ cảnh để gắn ngữ cảnh tốt hơn vào từng chunk với chi phí rất rẻ. Caching là một tính năng tuyệt vời để mở cho developer và tôi công nhận giá trị của nó
Nhưng ngoài ra thì có vẻ chỉ là một cookbook trình bày một workflow RAG cụ thể
Nói thêm, Cohere là một trong những API tôi thích nhất trong số các API đã dùng. Tôi không liên quan gì đến họ, và Cohere RAG API rất tốt so với các nhà cung cấp khác. Rất khuyến nghị
1: https://arxiv.org/abs/2212.10496
Nếu dữ liệu có hàng chục nghìn chunk thì phải làm tất cả việc này, nên chi phí rất cao. Cache tài liệu có thể giảm chi phí đó
Nó không hợp lắm với yêu cầu RAG của tôi, và có lẽ với đa số cũng vậy. Vì truy vấn có thể được chạy vào tháng sau hoặc 1 năm sau. Có vẻ chính sách đó cũng chưa thay đổi, nên việc nói về Prompt Caching liên quan đến RAG làm tôi hơi ngạc nhiên
Chúng tôi cũng đang làm một thứ tương tự. Trước hết, chúng tôi chia tài liệu thành các chunk dựa trên tiêu đề h1, h2, h3, rồi gắn header vào phần đầu chunk làm ngữ cảnh
Ví dụ giả định: nếu chunk gốc là “liều dùng thông thường cho người lớn là 1–2 viên nén hoặc viên nang 200mg, ngày 3 lần”, thì giờ sẽ có
# Fever,## Treatment, rồi sau đường phân cách là cùng nội dung đóCó vẻ hoạt động khá tốt, và khi lập chỉ mục tài liệu cũng không cần LLM
Đây cũng có thể là nguồn gốc của cuộc tranh luận “ChatGPT chậm đi vào tháng 12”. Tức là metadata “ngày tháng” đó có thể đã báo cho ChatGPT rằng nó kém hữu ích hơn
Trước tiên, tôi tóm tắt từng trang, đặt tiêu đề và trích xuất danh sách các tiểu mục. Sau đó, tôi gộp tất cả bản tóm tắt lại và yêu cầu mô hình tạo một chỉ mục phân cấp. Mô hình sắp xếp toàn bộ tập thành một cây, và tại thời điểm truy vấn, đường dẫn trong cây được kết hợp làm ngữ cảnh bổ sung
Tôi không thích kỹ thuật này lắm. Tôi đồng ý rằng kịch bản được nêu là một vấn đề phổ biến, nhưng giải pháp đề xuất thì có cảm giác gượng gạo
Vector embedding có tính chất giống như nén bag-of-words, và có thể bị lập chỉ mục quá mức theo khối văn bản ở dòng đầu tiên. Kết quả là một số chỉ mục cụ thể trong vector sẽ gần 0 hơn nhiều so với ban đầu. Sau khi lượng tử hóa, cuối cùng chúng có thể thành 0, làm mất rất nhiều độ chính xác của vector dày đặc. Tìm kiếm IDF có bù đắp phần nào nhưng không đủ
Nếu “boost về mặt ngữ nghĩa” embedding để nó dịch chuyển gần hơn tới tiêu đề, tóm tắt, abstract của tài liệu, ta có thể nhận được lợi ích về recall của tiền tố “ngữ cảnh” này mà không làm nhiễm vector nền. Về triển khai thì đó là tổng có trọng số. Ở bước tăng cường, khi đưa vào cửa sổ ngữ cảnh, nếu tài liệu khớp thì cũng có thể tiêm kèm chunk tóm tắt. Cá nhân tôi thấy đây là giải pháp gọn gàng hơn nhiều
Mô tả “semantic boost” của Trieve API[1]:
semantic_boost: hữu ích để dịch chuyển vector embedding của chunk theo hướng cụm từ khoảng cách. Ví dụ, với một chunk cóchunk_htmllàiphone, có thể dùngflagshiplàmdistance_phrasevà0.25làmdistance_factorđể đẩy nó gần hơn 25% tới thuật ngữ “flagship”. Về mặt khái niệm, đó là vẽ một đường khoảng cách Euclid/L2 giữa vectorinnerTextcủachunk_htmlvà vector củadistance_phrase, rồi dọc theo đường đó dịch chuyển vectorchunk_htmllại gần hơn hoặc ra xa hơn một lượngdistance_factorL2Distance[1]:https://docs.trieve.ai/api-reference/chunk/create-or-upsert-...
Nếu vậy, chẳng phải vector DB sẽ bị buộc vào một LLM duy nhất, thậm chí một phiên bản duy nhất như Claude-3.5 Sonnet, không thể chuyển sang 3.5 Haiku hay Opus, và nếu muốn sang ChatGPT hoặc Llama thì phải lập chỉ mục lại sao?
Kỹ thuật mà tôi cho là hữu ích nhất là triển khai chiến lược danh sách liên kết, trong đó một chunk có nhiều con trỏ từ các mục tham chiếu đến nó. Tôi làm việc này thủ công, nhưng nó làm tăng mạnh sự đa dạng của các cách có thể tham chiếu tới một node cụ thể
Nhìn theo cách khác thì nó giống như bình luận. Tất cả bình luận dưới bài này có thể xem là các con trỏ trỏ tới bài gốc. Một số bình luận có khoảng cách ngữ nghĩa gần với bài gốc, một số khác thì xa hơn do nhận thức của người viết. Nhưng nếu gán
parent_idcho mỗi bình luận, số đường dẫn để truy cập bài gốc sẽ tăng lênCó thể xem ví dụ về kỹ thuật này tại đây [1]. Không cố đoán người dùng cuối sẽ hỏi gì, mà cứ để người dùng nói rồi lập chỉ mục câu nói đó như một con trỏ. Các lựa chọn để biểu đạt một đối tượng là hữu hạn, nhưng có những cách biểu đạt rất, rất, rất xa về mặt ngữ nghĩa so với đối tượng cốt lõi
[1] - https://x.com/yourcommonbase/status/1833262865194557505
Nhận định rằng với dataset nhỏ thì cứ nhét 200 nghìn token vào để có câu trả lời tốt nhất không khớp với trải nghiệm của tôi
Tôi thường thấy prompt càng lớn thì đầu ra càng kém nhất quán, và khả năng tuân theo chỉ dẫn cũng tệ hơn. Thậm chí điều này dường như xảy ra ở mức thấp hơn nhiều so với 25k token. Tôi tò mò người khác có gặp vậy không, và có cách nào nổi tiếng để tránh điều này không
Thú vị thật. Vấn đề tôi gặp phải là với RAG, thứ cần tìm không phải các chunk tri thức mà là các quy tắc có thể áp dụng. Chỉ những quy tắc có thể áp dụng vào ngữ cảnh mới nên được đưa vào ngữ cảnh
Tôi chưa thử nghiệm, nhưng nghĩ rằng cách huấn luyện một bộ phân loại nhỏ để xác định liệu một quy tắc cụ thể có thể áp dụng hay không có thể hiệu quả. LLM chính sẽ đảm nhận vai trò phán đoán xem quy tắc đó có thực sự áp dụng trong ngữ cảnh hiện tại hay không
Ví dụ, giả sử ta chơi một game dungeon nhiều người dùng bằng LLM. Trước đây nhân vật đã có hành vi xấu liên quan đến taxi, nên trò chơi tạo ra một quy tắc rằng “mỗi khi định lên taxi thì sẽ bị đuổi xuống. ‘Chúng tôi biết anh là ai, và sẽ không nhận anh làm khách cho đến khi anh chính thức xin lỗi giám đốc công ty taxi’”. Nếu xin lỗi thì quy tắc bị xóa. Giám đốc công ty taxi cũng có thể là người chơi khác, hoặc là người ban đầu kích hoạt quy tắc mà đội taxi NPC của họ sẽ thực thi
Tôi tò mò không biết điều này sẽ mở rộng đến mức nào theo số lượng quy tắc đang hoạt động, và có thể áp dụng RAG truyền thống đến đâu. Việc xác định liệu một quy tắc có áp dụng hay không có vẻ là vấn đề trừu tượng và khó hơn so với việc xác định một chunk tri thức có liên quan hay không
Điểm cốt lõi khiến nó đặc biệt khó hơn là vòng lặp phụ thuộc không tồn tại trong truy xuất tri thức. Để nhận diện liệu một quy tắc có áp dụng hay không thì trước hết phải truy xuất được quy tắc đó. Có thể giải bài toán này như thế nào?
Một truy vấn ví dụ, nếu viết với sự trợ giúp của LLama 3.1 8B, có thể đủ chi tiết kiểu như: đội quân dark elf đang tiến đến, Grimgold Ironfist đang ở trong tình thế tuyệt vọng; trước đây từng là một thành viên đáng tự hào của dân quân người lùn nhưng hiện chỉ còn 35% thể lực; trong inventory có một chiếc cuốc chim cũ, một xô nước, bánh mì cũ và 17 đồng vàng; và bất chấp “quá khứ rắc rối” với Taxi Guild, anh ta đang cố vẫy một chiếc taxi trên đường
Quy tắc ví dụ lấy từ kho vector sẽ được truy xuất nhờ độ gần vector do có nhắc đến tên/thuộc tính nhân vật, taxi và Taxi Guild
Đó là một quy tắc kiểu như: “Taxi Guild đã áp đặt hình phạt nghiêm khắc với Grimgold. Mỗi khi anh ta cố vẫy taxi, anh ta sẽ lập tức bị đuổi khỏi xe. Sắc lệnh của Guild ghi rằng ‘Grimgold Ironfist, gã người lùn râu ria tai tiếng, không được lên bất kỳ taxi nào do thành viên vận hành cho đến khi chính thức xin lỗi Thorgrim Stonebeard, giám đốc Golden Horse Cab Company. Nếu không tuân thủ, anh ta sẽ bị loại vĩnh viễn khỏi dịch vụ của chúng ta’”
Họ nói “nếu kho tri thức nhỏ hơn 200.000 token (khoảng 500 trang)”, nhưng tôi ước gì Anthropic cứ công khai tokenizer của họ. Để khỏi phải đoán mò
Tôi đang chờ ngày cả ngành AI đi một vòng rồi cuối cùng quay lại với TF-IDF