5.1 Reranker là gì: một việc duy nhất, làm rất tốt
Bạn đã có retrieval chạy được. Người dùng hỏi một câu, hệ thống trả về 100 đoạn văn bản, bạn nhồi 5 đoạn đầu vào prompt của LLM. Rồi bạn ngồi đọc log và thấy một chuyện làm bạn khó chịu: đoạn đúng có trong 100 đoạn đó — nó nằm ở hạng 37.
Đoạn hạng 37 không bao giờ tới được LLM. Với người dùng, hệ thống của bạn “không tìm được”, dù thực ra nó đã tìm được rồi và chỉ xếp sai chỗ.
Reranker sinh ra cho đúng một việc đó:
Nhận một câu hỏi + một danh sách ứng viên đã có. Đọc lại từng ứng viên cùng với câu hỏi. Xếp lại thứ tự. Hết.
Nó không đi tìm tài liệu mới. Nó không sinh câu trả lời. Nó không sửa được việc đoạn đúng vắng mặt trong 100 đoạn kia — chuyện đó là 5.4, và là chỗ đa số hệ RAG tiêu tiền sai.
Chỗ nó đứng trong pipeline
Phần tiêu đề “Chỗ nó đứng trong pipeline” ┌─────────────────────┐ câu hỏi ──┬──► BM25 ──► 100 ─┤ │ │ (lexical) │ RERANKER │──► 5 ──► LLM └──► vector ANN ──► 100 ─┤ (đọc lại từng cặp)│ (dense) └─────────────────────┘ │ │ rẻ, gần miễn phí đắt, nhưng chỉ chạy trên toàn corpus chạy trên 100 đoạnHai giai đoạn, hai loại chi phí, và đó chính là lý do kiến trúc này tồn tại:
| Stage 1 — retrieval | Stage 2 — rerank | |
|---|---|---|
| Chạy trên | toàn bộ corpus (1M, 100M doc) | chỉ top-k (25–200 doc) |
| Nên tối ưu cho | đừng bỏ sót (recall) | xếp cho đúng (precision ở đỉnh) |
| Được phép tốn | gần như không | vài chục đến vài trăm ms |
| Có biết câu hỏi khi tính toán? | không (vector doc tính trước) | có (xem 5.2) |
Dòng cuối là cả bí mật của reranking. Xem 5.2.
Một ví dụ xếp lại, làm bằng tay
Phần tiêu đề “Một ví dụ xếp lại, làm bằng tay”Câu hỏi: “tiền đã bị trừ mà đơn không thành công” — đây là truy vấn thật trong golden set của cẩm nang (lớp B, paraphrase). BM25 trên corpus này trả về top-1 là “Hoá đơn VAT”, trong khi đáp án đúng là “Thanh toán thất bại”; nDCG@5 của truy vấn này chỉ 0.14 (baseline đã đo).
Giả sử stage 1 trả về 6 ứng viên như dưới. Cột BM25 là thứ tự vào, cột reranker là thứ tự ra:
| doc | nội dung (rút gọn) | BM25 | hạng vào | điểm reranker | hạng ra |
|---|---|---|---|---|---|
d012 | Hoá đơn VAT: xuất hoá đơn cho đơn hàng đã trừ tiền… | 8,4 | 1 | −2,1 | 4 |
d031 | Bảng giá: tiền thuê bao trừ vào ngày 1 hàng tháng | 7,9 | 2 | −5,6 | 6 |
d008 | Thanh toán thất bại: giao dịch bị hoàn trong 3–5 ngày làm việc | 5,1 | 3 | +7,8 | 1 |
d019 | Hoàn tiền: điều kiện và thời gian hoàn | 4,7 | 4 | +4,2 | 2 |
d022 | Lịch sử giao dịch: tra soát trạng thái đơn | 4,1 | 5 | +1,3 | 3 |
d006 | Không hỗ trợ tiền mã hoá | 3,8 | 6 | −4,9 | 5 |
(Điểm reranker ở đây là ví dụ dựng để thấy cơ chế, không phải số đo trên corpus — Module 4 của cẩm nang chưa đo. Xem ràng buộc số liệu.)
Đọc bảng này chậm lại một chút, vì nó cho thấy đúng ba việc reranker làm:
d008từ hạng 3 lên hạng 1. Nó không chứa chữ “tiền”, không chứa “trừ” — BM25 không có cách nào yêu nó. Reranker đọc “giao dịch bị hoàn” cạnh câu hỏi “tiền đã bị trừ mà đơn không thành công” và thấy đây là câu trả lời.d012từ hạng 1 xuống hạng 4. Nó trúng đủ ba từ khoá “đơn”, “trừ tiền” — điểm BM25 cao nhất bảng. Nhưng nó nói về xuất hoá đơn, không về giao dịch lỗi. Đây là loại lỗi mà thêm từ khoá không chữa được: trúng từ, sai việc.d031vàd006bị đẩy xuống đáy. Cả hai đều “cùng chủ đề tiền” — thứ mà embedding rất dễ nhầm là liên quan. Reranker phân biệt được cùng chủ đề và trả lời được câu này.
Vì sao không rerank luôn cả corpus?
Phần tiêu đề “Vì sao không rerank luôn cả corpus?”Vì bạn không đủ tiền. Con số cụ thể ở 5.9, nhưng trực giác thì đơn giản: reranker phải chạy một lượt forward pass cho mỗi cặp (câu hỏi, tài liệu). Không có cách nào tính trước, vì nó cần cả hai mới tính được.
50 doc → 50 forward pass → được, corpus của cẩm nang này nhỏ100 doc → 100 forward pass → chuẩn production10.000 doc → 10.000 forward pass → chậm gấp 100 lần, không ai làm1M doc → 1M forward pass → vô nghĩaCòn stage 1 thì tra một inverted index hoặc một đồ thị HNSW: không đọc tài liệu nào, chỉ nhảy trên cấu trúc dữ liệu. Trên corpus 50 doc của cẩm nang, BM25 mất 0,03 ms/truy vấn (baseline đã đo).
Hai giai đoạn tồn tại vì hai loại chi phí này chênh nhau hàng nghìn lần. Bạn dùng cái rẻ để thu hẹp, dùng cái đắt để quyết định.
Ba cái tên rất dễ lẫn
Phần tiêu đề “Ba cái tên rất dễ lẫn”Trước khi đi tiếp, tách cho rõ — 1.3 đã nói về ba loại model, đây là lát cắt riêng cho reranking:
| Tên | Đầu vào | Đầu ra | Tính trước được? |
|---|---|---|---|
| Embedding model (bi-encoder) | một đoạn văn bản | một vector | được — index sẵn toàn corpus |
| Reranker (cross-encoder) | một cặp (câu hỏi, đoạn) | một số | không |
| LLM sinh | prompt | văn bản | không |
Reranker không trả về văn bản và không trả về vector. Nó trả về một con số duy nhất cho mỗi cặp. Con số đó có nghĩa gì, và vì sao bạn không nên đặt ngưỡng cứng lên nó, là 5.3.
Vậy có nên làm không?
Phần tiêu đề “Vậy có nên làm không?”Reranking là kỹ thuật có tỷ lệ lợi ích / công sức cao nhất trong toàn bộ pipeline RAG, vì ba lý do rất tầm thường:
- Không phải index lại gì cả. Cắm vào sau retrieval hiện có, gỡ ra cũng dễ.
- Không phải huấn luyện gì cả. Model có sẵn dùng ngay (5.8).
- Chỉ chạm vào top-k, nên chi phí bị chặn trên và bạn biết trước con số đó.
→ Nên áp dụng vào AI Agent: nhưng sau khi đo recall@k của stage 1, không
phải trước. Nếu recall@100 đang là 0,6 thì reranker hoàn hảo cũng chỉ đưa bạn tới 0,6.
Đó là 5.4, và nên là mục tiếp theo bạn đọc nếu chỉ đọc
được hai mục của Phần 5.