Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 7 — Ghép thành agent RAG hoàn chỉnh

Đã đọc 0/9 mục · còn khoảng 3 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Đến đây bạn đã có đủ mảnh ghép: chunking, embedding, retrieval, rerank, query rewriting, hybrid. Bài này lắp chúng thành một agent RAG biết tự quyết định khi nào tra cứu, tra cứu nhiều vòng, và trả lời có trích dẫn.

Khác biệt: RAG tĩnh vs. Agentic RAG

  • RAG tĩnh: mọi câu hỏi → luôn retrieval một lần → trả lời. Đơn giản nhưng cứng nhắc.
  • Agentic RAG: agent tự quyết định có cần retrieval không, viết lại truy vấn, đánh giá kết quả đủ chưa, và retrieval lại nếu thiếu.

Kiến trúc agent RAG

Câu hỏi
  │
  ├─ Cần dữ kiện? ──No──► Trả lời trực tiếp
  │        │Yes
  ▼        ▼
Rewrite → Retrieve(k=20) → Rerank(top5) → Đủ tin cậy?
                                              │No → Rewrite khác / hybrid → lặp (tối đa N vòng)
                                              │Yes
                                              ▼
                                    LLM sinh trả lời + trích dẫn

Retrieval như một tool

Trong agent, retrieval được bọc thành tool để LLM tự gọi:

def search_docs_tool(query: str) -> str:
    cands = retrieve(query, k=20)
    top = rerank(query, cands, top_n=5)
    if not top or top[0]["score"] < THRESHOLD:
        return "NO_RESULT"
    return "\n\n".join(f"[{c['source']} p{c['page']}] {c['text']}" for c in top)
Agent nhận được cả nội dung lẫn nguồn để trích dẫn.

Vòng lặp agent

def agent_answer(question, max_loops=3):
    query = rewrite(history, question)
    for _ in range(max_loops):
        ctx = search_docs_tool(query)
        if ctx == "NO_RESULT":
            query = broaden(query)   # nới truy vấn / đổi sang hybrid
            continue
        decision = llm(f"Context:\n{ctx}\n\nCâu hỏi: {question}\n"
                       "Đủ để trả lời chưa? Nếu thiếu, nêu truy vấn bổ sung.")
        if "ĐỦ" in decision:
            return generate_with_citations(question, ctx)
        query = extract_followup_query(decision)
    return "Không tìm thấy đủ thông tin trong tài liệu để trả lời chắc chắn."

Prompt sinh trả lời có trích dẫn

Bạn là trợ lý trả lời DỰA HOÀN TOÀN vào context dưới.
- Nếu context không chứa câu trả lời, nói rõ "không có trong tài liệu".
- Mỗi ý phải kèm trích dẫn nguồn dạng [nguồn pX].
- Không suy diễn ngoài context.

Context:
{context}

Câu hỏi: {question}
Ràng buộc "dựa hoàn toàn vào context" + "nói rõ khi không có" là hai câu chống hallucination hiệu quả nhất.

Ví dụ luồng chạy

Hỏi: "Nhân viên thử việc có được nghỉ phép năm không?"

  • Rewrite → "chính sách phép năm cho nhân viên thử việc".
  • Retrieve + rerank → chunk về "phép năm áp dụng sau khi ký HĐ chính thức".
  • LLM đánh giá: đủ → trả lời "Theo mục 4.1, nhân viên thử việc chưa được tính phép năm... [quy-che-2026 p3]".

Checklist agent RAG

  • [ ] Có cổng quyết định "có cần retrieval không".
  • [ ] Retrieval bọc thành tool, trả cả nội dung lẫn nguồn.
  • [ ] Giới hạn số vòng lặp (tránh loop vô hạn tốn token).
  • [ ] Prompt ràng buộc "chỉ dùng context" + bắt buộc trích dẫn.
  • [ ] Có nhánh trả lời "không tìm thấy" khi dưới ngưỡng.

Sai lầm thường gặp

  • Luôn retrieval kể cả câu chào hỏi: chậm, tốn tiền, nhiễu.
  • Vòng lặp không giới hạn: agent retrieval mãi, đốt token, treo.
  • Không truyền nguồn qua tool: agent trả lời đúng nhưng không trích dẫn được.
  • Prompt không cấm suy diễn: agent "đắp" thêm kiến thức chung ngoài tài liệu → sai chính sách công ty.
  • Bỏ nhánh từ chối: khi không có dữ liệu, agent bịa thay vì nói "không có trong tài liệu".
Bài cuối: vận hành thực tế — index freshness, cập nhật và giám sát.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi