{"product_id":"contextual-retrieval-nang-cấp-rag-với-embeddings-ngữ-cảnh","title":"Contextual Retrieval — Nâng cấp RAG với embeddings ngữ cảnh","description":"\n\u003cp\u003eTrong bài hướng dẫn này, bạn sẽ xây dựng hệ thống \u003cstrong\u003eContextual Retrieval\u003c\/strong\u003e — một kỹ thuật nâng cấp RAG giúp giảm tỷ lệ truy xuất sai đến \u003cstrong\u003e35%\u003c\/strong\u003e. Chúng ta sẽ đi qua từng bước: RAG cơ bản → Contextual Embeddings → BM25 Hybrid Search → Reranking, với kết quả đo lường cụ thể trên dataset thực.\u003c\/p\u003e\n\n\u003cp\u003eBài viết dựa trên \u003cstrong\u003eClaude Cookbooks chính thức\u003c\/strong\u003e của Anthropic, được dịch và biên soạn lại cho độc giả Việt Nam.\u003c\/p\u003e\n\n\u003ch2\u003eVấn đề của RAG truyền thống\u003c\/h2\u003e\n\n\u003cp\u003eTrong RAG truyền thống, tài liệu được chia thành các \u003cstrong\u003echunk nhỏ\u003c\/strong\u003e để embedding và truy xuất hiệu quả. Tuy nhiên, điều này tạo ra một vấn đề quan trọng: \u003cstrong\u003emỗi chunk riêng lẻ thiếu ngữ cảnh\u003c\/strong\u003e từ tài liệu gốc.\u003c\/p\u003e\n\n\u003cp\u003eVí dụ, một chunk chứa đoạn code \u003ccode\u003edef process_data(input):\u003c\/code\u003e không cho biết nó thuộc file nào, module nào, hay giải quyết bài toán gì. Khi người dùng hỏi \u003cem\u003e\"Làm sao xử lý dữ liệu đầu vào?\"\u003c\/em\u003e, hệ thống có thể trả về chunk không liên quan vì embedding không capture đủ context.\u003c\/p\u003e\n\n\u003cp\u003e\u003cstrong\u003eContextual Embeddings\u003c\/strong\u003e giải quyết vấn đề này bằng cách thêm mô tả ngữ cảnh vào mỗi chunk trước khi embedding.\u003c\/p\u003e\n\n\u003ch2\u003eKiến trúc hệ thống\u003c\/h2\u003e\n\n\u003cp\u003ePipeline gồm 5 bước tiến hóa:\u003c\/p\u003e\n\n\u003col\u003e\n  \u003cli\u003e\n\u003cstrong\u003eBaseline RAG\u003c\/strong\u003e — Chunk + Embed + Cosine similarity (87% Pass@10)\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eContextual Embeddings\u003c\/strong\u003e — Thêm context cho mỗi chunk (92% Pass@10)\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eContextual BM25\u003c\/strong\u003e — Kết hợp semantic + keyword search (93% Pass@10)\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eReranking\u003c\/strong\u003e — Dùng model chuyên biệt sắp xếp lại kết quả (95% Pass@10)\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003ch2\u003eBước 1: Baseline RAG — Điểm xuất phát (87%)\u003c\/h2\u003e\n\n\u003cp\u003ePipeline cơ bản nhất gồm 3 bước:\u003c\/p\u003e\n\n\u003col\u003e\n  \u003cli\u003e\n\u003cstrong\u003eChunk tài liệu\u003c\/strong\u003e theo heading — mỗi chunk chứa nội dung dưới một subheading\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eEmbed mỗi chunk\u003c\/strong\u003e thành vector bằng Voyage AI\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eCosine similarity\u003c\/strong\u003e để tìm chunk liên quan nhất khi có query\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003cp\u003eVới dataset 737 chunks từ 9 codebase và 248 câu hỏi đánh giá, baseline đạt:\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003ePass@5: 80.92%\u003c\/li\u003e\n  \u003cli\u003ePass@10: 87.15%\u003c\/li\u003e\n  \u003cli\u003ePass@20: 90.06%\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eTốt, nhưng vẫn bỏ sót \u003cstrong\u003e13% golden chunks\u003c\/strong\u003e trong top 10 kết quả.\u003c\/p\u003e\n\n\u003ch2\u003eBước 2: Contextual Embeddings — Thêm ngữ cảnh (92%)\u003c\/h2\u003e\n\n\u003cp\u003eÝ tưởng cốt lõi: dùng Claude sinh một đoạn mô tả ngắn (2-3 câu) cho mỗi chunk, giải thích chunk đó chứa gì và nằm ở đâu trong tài liệu gốc. Đoạn mô tả này được \u003cstrong\u003eghép vào trước chunk\u003c\/strong\u003e trước khi embedding.\u003c\/p\u003e\n\n\u003ch3\u003eCách hoạt động\u003c\/h3\u003e\n\n\u003cpre\u003e\u003ccode\u003edef generate_context(document, chunk):\n    \"\"\"Dùng Claude sinh ngữ cảnh cho chunk\"\"\"\n    response = client.messages.create(\n        model=\"claude-haiku-4-5\",\n        messages=[{\n            \"role\": \"user\",\n            \"content\": f\"\"\"Đây là tài liệu nguồn:\n\u0026lt;document\u0026gt;{document}\u0026lt;\/document\u0026gt;\n\nĐây là chunk cần thêm ngữ cảnh:\n\u0026lt;chunk\u0026gt;{chunk}\u0026lt;\/chunk\u0026gt;\n\nViết 2-3 câu ngắn mô tả chunk này chứa gì\nvà vị trí của nó trong tài liệu. Chỉ trả về\nmô tả, không giải thích thêm.\"\"\"\n        }],\n        max_tokens=200\n    )\n    return response.content[0].text\n\n# Ghép context + chunk rồi mới embed\ncontextualized_text = context + \"\\n\\n\" + chunk\nembedding = voyage_client.embed(contextualized_text)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003ePrompt Caching — Giảm chi phí 69%\u003c\/h3\u003e\n\n\u003cp\u003eVì tất cả chunks cùng một tài liệu đều cần context từ cùng document đó, \u003cstrong\u003eprompt caching\u003c\/strong\u003e phát huy tác dụng cực lớn:\u003c\/p\u003e\n\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003eChunk đầu tiên\u003c\/strong\u003e: Ghi toàn bộ document vào cache (trả phí nhỏ)\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eCác chunk sau\u003c\/strong\u003e: Đọc document từ cache (giảm 90% chi phí token)\u003c\/li\u003e\n  \u003cli\u003eCache tồn tại 5 phút — đủ thời gian xử lý tất cả chunks trong một document\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eTrên dataset 737 chunks: \u003cstrong\u003e61.83% input tokens\u003c\/strong\u003e được đọc từ cache. Chi phí giảm từ ~$9.20 xuống ~$2.85 (tiết kiệm 69%).\u003c\/p\u003e\n\n\u003ch3\u003eKết quả\u003c\/h3\u003e\n\n\u003cp\u003eContextual Embeddings cải thiện đáng kể:\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003ePass@5: 80.92% → \u003cstrong\u003e88.12%\u003c\/strong\u003e (+7.2 điểm)\u003c\/li\u003e\n  \u003cli\u003ePass@10: 87.15% → \u003cstrong\u003e92.34%\u003c\/strong\u003e (+5.2 điểm)\u003c\/li\u003e\n  \u003cli\u003ePass@20: 90.06% → \u003cstrong\u003e94.29%\u003c\/strong\u003e (+4.2 điểm)\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eGiảm \u003cstrong\u003e30-40% lỗi truy xuất\u003c\/strong\u003e ở mọi mức k. Cải thiện mạnh nhất ở Pass@5 — chunk đúng không chỉ được tìm thấy nhiều hơn mà còn \u003cstrong\u003exếp hạng cao hơn\u003c\/strong\u003e.\u003c\/p\u003e\n\n\u003ch2\u003eBước 3: Contextual BM25 — Hybrid Search (93%)\u003c\/h2\u003e\n\n\u003cp\u003eSemantic search (embedding) giỏi hiểu ý nghĩa, nhưng có thể bỏ sót các keyword chính xác. \u003cstrong\u003eBM25\u003c\/strong\u003e (thuật toán xếp hạng keyword xác suất) bổ khuyết điểm này.\u003c\/p\u003e\n\n\u003ch3\u003eKết hợp hai nguồn bằng Reciprocal Rank Fusion\u003c\/h3\u003e\n\n\u003cpre\u003e\u003ccode\u003edef retrieve_hybrid(query, k=10):\n    # 1. Lấy top 150 từ semantic search\n    semantic_results = vector_db.search(query, k=150)\n\n    # 2. Lấy top 150 từ BM25 (search cả chunk + context)\n    bm25_results = elasticsearch.search(query, k=150)\n\n    # 3. Kết hợp bằng weighted Reciprocal Rank Fusion\n    # 80% trọng số cho semantic, 20% cho BM25\n    combined = reciprocal_rank_fusion(\n        semantic_results,\n        bm25_results,\n        weights=[0.8, 0.2]\n    )\n\n    return combined[:k]\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eThay vì search raw chunk, BM25 search cả \u003cstrong\u003echunk lẫn contextual description\u003c\/strong\u003e — nghĩa là keyword có thể match trong mô tả ngữ cảnh mà Claude đã sinh.\u003c\/p\u003e\n\n\u003cp\u003e\u003cstrong\u003eKết quả: 93.21% Pass@10\u003c\/strong\u003e — BM25 bắt được các query mà semantic search bỏ sót (tên hàm cụ thể, thuật ngữ chuyên ngành).\u003c\/p\u003e\n\n\u003ch2\u003eBước 4: Reranking — Tinh chỉnh thứ hạng (95%)\u003c\/h2\u003e\n\n\u003cp\u003eReranking là kỹ thuật 2 giai đoạn:\u003c\/p\u003e\n\u003col\u003e\n  \u003cli\u003e\n\u003cstrong\u003eGiai đoạn 1 — Truy xuất rộng\u003c\/strong\u003e: Lấy nhiều ứng viên hơn cần thiết (100 chunks)\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eGiai đoạn 2 — Chọn lọc chính xác\u003c\/strong\u003e: Dùng reranking model (Cohere rerank-english-v3.0) chấm điểm và chỉ giữ top-k\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003cp\u003eTại sao hiệu quả? Embedding và BM25 được tối ưu cho \u003cstrong\u003etốc độ\u003c\/strong\u003e trên hàng triệu tài liệu. Reranking model chậm hơn nhưng \u003cstrong\u003echính xác hơn\u003c\/strong\u003e — có thể phân tích sâu trên tập nhỏ ứng viên.\u003c\/p\u003e\n\n\u003cp\u003e\u003cstrong\u003eKết quả: 95.26% Pass@10\u003c\/strong\u003e — giảm 47% lỗi truy xuất so với baseline.\u003c\/p\u003e\n\n\u003ch2\u003eTổng kết: So sánh các kỹ thuật\u003c\/h2\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n\u003cth\u003eApproach\u003c\/th\u003e\n\u003cth\u003ePass@5\u003c\/th\u003e\n\u003cth\u003ePass@10\u003c\/th\u003e\n\u003cth\u003ePass@20\u003c\/th\u003e\n\u003c\/tr\u003e\n  \u003c\/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n\u003ctd\u003eBaseline RAG\u003c\/td\u003e\n\u003ctd\u003e80.92%\u003c\/td\u003e\n\u003ctd\u003e87.15%\u003c\/td\u003e\n\u003ctd\u003e90.06%\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003e+ Contextual Embeddings\u003c\/td\u003e\n\u003ctd\u003e88.12%\u003c\/td\u003e\n\u003ctd\u003e92.34%\u003c\/td\u003e\n\u003ctd\u003e94.29%\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003e+ Hybrid Search (BM25)\u003c\/td\u003e\n\u003ctd\u003e86.43%\u003c\/td\u003e\n\u003ctd\u003e93.21%\u003c\/td\u003e\n\u003ctd\u003e94.99%\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003e+ Reranking\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003e92.15%\u003c\/strong\u003e\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003e95.26%\u003c\/strong\u003e\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003e97.45%\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n  \u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003ch2\u003eTrade-offs và khuyến nghị\u003c\/h2\u003e\n\n\u003cp\u003eMỗi kỹ thuật thêm complexity và chi phí:\u003c\/p\u003e\n\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003eContextual Embeddings\u003c\/strong\u003e: Chi phí ingestion một lần (~$3 cho 737 chunks với prompt caching). Không có chi phí per-query.\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eHybrid Search\u003c\/strong\u003e: Cần hạ tầng Elasticsearch. Không thêm chi phí per-query.\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eReranking\u003c\/strong\u003e: Thêm 100-200ms latency và ~$0.002 per query.\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003eChọn approach theo nhu cầu\u003c\/h3\u003e\n\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003eVolume cao, tiết kiệm chi phí\u003c\/strong\u003e: Contextual Embeddings alone (92% Pass@10, không có per-query costs)\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eAccuracy tối đa, chấp nhận latency\u003c\/strong\u003e: Full reranking pipeline (95% Pass@10)\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eCân bằng production\u003c\/strong\u003e: Hybrid search (93% Pass@10, không per-query costs)\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eÁp dụng thực tế\u003c\/h2\u003e\n\n\u003cp\u003eContextual Retrieval áp dụng cho mọi loại dữ liệu:\u003c\/p\u003e\n\n\u003col\u003e\n  \u003cli\u003e\n\u003cstrong\u003eKnowledge base nội bộ\u003c\/strong\u003e — FAQ, tài liệu quy trình công ty\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eCodebase documentation\u003c\/strong\u003e — API docs, README, code comments\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eTài liệu pháp lý\u003c\/strong\u003e — Hợp đồng, quy định, luật\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eTài liệu tài chính\u003c\/strong\u003e — Báo cáo, phân tích, dữ liệu thị trường\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003cp\u003e\u003cstrong\u003eKhuyến nghị\u003c\/strong\u003e: Bắt đầu với Contextual Embeddings — đây là kỹ thuật cho \u003cstrong\u003eROI tốt nhất\u003c\/strong\u003e (cải thiện lớn nhất với chi phí thấp nhất). Chỉ thêm BM25 và reranking khi cần tối ưu thêm 2-3%.\u003c\/p\u003e\n\n\u003cp\u003eBước tiếp theo: Đọc thêm về \u003ca href=\"\/en\/collections\/nang-cao\"\u003eRAG với Claude\u003c\/a\u003e và \u003ca href=\"\/en\/collections\/nang-cao\"\u003ePrompt Caching\u003c\/a\u003e để hiểu sâu hơn về hai kỹ thuật nền tảng.\u003c\/p\u003e\n\n\u003chr\u003e\n\u003ch3\u003eBài viết liên quan\u003c\/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/rag-v%E1%BB%9Bi-pinecone-claude-vector-database-cho-ai\"\u003eRAG với Pinecone + Claude — Vector database cho AI\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/rag-v%E1%BB%9Bi-mongodb-claude-xay-chatbot-co-ki%E1%BA%BFn-th%E1%BB%A9c\"\u003eRAG với MongoDB + Claude — Xây chatbot có kiến thức\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/speculative-caching-gi%E1%BA%A3m-time-to-first-token-v%E1%BB%9Bi-cache-d%E1%BB%B1-doan\"\u003eSpeculative Caching — Giảm time-to-first-token với cache dự đoán\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/claude-cho-data-xay-d%E1%BB%B1ng-dashboard-t%E1%BB%AB-d%E1%BB%AF-li%E1%BB%87u\"\u003eClaude cho Data: Xây dựng Dashboard từ dữ liệu\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/claude-cho-engineering-debug-va-x%E1%BB%AD-ly-l%E1%BB%97i\"\u003eClaude cho Engineering: Debug và xử lý lỗi\u003c\/a\u003e\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721706225876,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/contextual-retrieval-nang-c_p-rag-v_i-embeddings-ng_-c_nh.jpg?v=1774521545","url":"https:\/\/claude.vn\/en\/products\/contextual-retrieval-nang-c%e1%ba%a5p-rag-v%e1%bb%9bi-embeddings-ng%e1%bb%af-c%e1%ba%a3nh","provider":"CLAUDE.VN","version":"1.0","type":"link"}