{"product_id":"rag-với-claude-xay-dựng-hệ-thống-truy-xuất-thong-tin-từ-a-dến-z","title":"RAG với Claude — Xây dựng hệ thống truy xuất thông tin từ A đến Z","description":"\n\u003cp\u003eTrong bài hướng dẫn này, bạn sẽ xây dựng một hệ thống \u003cstrong\u003eRetrieval Augmented Generation (RAG)\u003c\/strong\u003e hoàn chỉnh sử dụng Claude. Chúng ta sẽ đi qua 3 cấp độ: RAG cơ bản (71% accuracy) → Summary Indexing (78%) → Reranking (81%), kèm hệ thống đánh giá bài bản với 5 metrics.\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, sử dụng Claude Documentation làm knowledge base demo.\u003c\/p\u003e\n\n\u003ch2\u003eRAG là gì và tại sao cần thiết?\u003c\/h2\u003e\n\n\u003cp\u003eClaude rất giỏi nhiều tác vụ, nhưng sẽ gặp khó khi trả lời câu hỏi \u003cstrong\u003eđặc thù cho business của bạn\u003c\/strong\u003e. RAG giải quyết vấn đề này bằng cách cho Claude truy cập vào knowledge base nội bộ — tài liệu hỗ trợ khách hàng, FAQ nội bộ, tài liệu pháp lý, code documentation — khi trả lời câu hỏi.\u003c\/p\u003e\n\n\u003cp\u003eDoanh nghiệp đang ngày càng xây dựng ứng dụng RAG cho:\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003eCustomer support\u003c\/strong\u003e — Trả lời dựa trên knowledge base sản phẩm\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eQ\u0026amp;A nội bộ\u003c\/strong\u003e — Tìm thông tin trong tài liệu công ty\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003ePhân tích tài chính, pháp lý\u003c\/strong\u003e — Truy xuất điều khoản liên quan\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eCode generation\u003c\/strong\u003e — Tham chiếu API docs khi sinh code\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eLevel 1: RAG cơ bản (Naive RAG)\u003c\/h2\u003e\n\n\u003cp\u003ePipeline cơ bản gồm 3 bước:\u003c\/p\u003e\n\n\u003col\u003e\n  \u003cli\u003e\n\u003cstrong\u003eChunk tài liệu theo heading\u003c\/strong\u003e — Chia Claude Documentation thành các phần nhỏ theo tiêu đề\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eEmbed mỗi chunk\u003c\/strong\u003e — Chuyển thành vector bằng Voyage AI embeddings\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eCosine similarity\u003c\/strong\u003e — Khi có câu hỏi, tìm chunks tương tự nhất rồi đưa vào prompt Claude\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003cpre\u003e\u003ccode\u003eclass VectorDB:\n    def __init__(self, embedding_model=\"voyage-2\"):\n        self.voyage_client = voyageai.Client()\n        self.model = embedding_model\n        self.embeddings = []\n        self.metadata = []\n\n    def add_documents(self, documents):\n        # Embed theo batch 128 chunks\n        for batch in chunks(documents, 128):\n            embeddings = self.voyage_client.embed(\n                [doc['text'] for doc in batch],\n                model=self.model\n            )\n            self.embeddings.extend(embeddings)\n            self.metadata.extend(batch)\n\n    def search(self, query, k=5):\n        query_embedding = self.voyage_client.embed(\n            [query], model=self.model\n        )[0]\n        # Cosine similarity\n        scores = cosine_similarity(\n            [query_embedding], self.embeddings\n        )[0]\n        top_k = np.argsort(scores)[-k:][::-1]\n        return [self.metadata[i] for i in top_k]\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eHệ thống đánh giá — Đo lường trước khi cải tiến\u003c\/h2\u003e\n\n\u003cp\u003eMột sai lầm phổ biến khi xây RAG là đánh giá theo \u003cem\u003e\"vibes\"\u003c\/em\u003e — chạy vài câu hỏi, thấy ổn rồi deploy. Cách làm đúng: xây evaluation suite \u003cstrong\u003etrước khi tối ưu\u003c\/strong\u003e.\u003c\/p\u003e\n\n\u003ch3\u003eDataset đánh giá\u003c\/h3\u003e\n\n\u003cp\u003e100 samples, mỗi sample gồm:\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003eCâu hỏi (có sample cần tổng hợp từ nhiều chunk)\u003c\/li\u003e\n  \u003cli\u003eGolden chunks — chunks chính xác cần truy xuất\u003c\/li\u003e\n  \u003cli\u003eĐáp án đúng để so sánh end-to-end\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003e5 metrics quan trọng\u003c\/h3\u003e\n\n\u003cp\u003e\u003cstrong\u003eRetrieval metrics\u003c\/strong\u003e (đánh giá phần truy xuất):\u003c\/p\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n\u003cth\u003eMetric\u003c\/th\u003e\n\u003cth\u003eÝ nghĩa\u003c\/th\u003e\n\u003cth\u003eCông thức\u003c\/th\u003e\n\u003c\/tr\u003e\n  \u003c\/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cstrong\u003ePrecision\u003c\/strong\u003e\u003c\/td\u003e\n      \u003ctd\u003eTrong các chunks truy xuất được, bao nhiêu % là đúng?\u003c\/td\u003e\n      \u003ctd\u003eTrue Positives \/ Total Retrieved\u003c\/td\u003e\n    \u003c\/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cstrong\u003eRecall\u003c\/strong\u003e\u003c\/td\u003e\n      \u003ctd\u003eTrong tất cả chunks đúng tồn tại, bao nhiêu % được tìm thấy?\u003c\/td\u003e\n      \u003ctd\u003eTrue Positives \/ Total Correct\u003c\/td\u003e\n    \u003c\/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cstrong\u003eF1 Score\u003c\/strong\u003e\u003c\/td\u003e\n      \u003ctd\u003eTrung bình harmonic của Precision và Recall\u003c\/td\u003e\n      \u003ctd\u003e2 × (P × R) \/ (P + R)\u003c\/td\u003e\n    \u003c\/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cstrong\u003eMRR\u003c\/strong\u003e\u003c\/td\u003e\n      \u003ctd\u003eChunk đúng đầu tiên xuất hiện ở vị trí nào?\u003c\/td\u003e\n      \u003ctd\u003e1\/|Q| × Σ(1\/rank_i)\u003c\/td\u003e\n    \u003c\/tr\u003e\n  \u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003cp\u003e\u003cstrong\u003eEnd-to-end metric:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003eAccuracy\u003c\/strong\u003e — Dùng Claude làm judge đánh giá câu trả lời cuối cùng có đúng không\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eLevel 2: Summary Indexing — Embed thông minh hơn\u003c\/h2\u003e\n\n\u003cp\u003eThay vì embed raw chunks, chúng ta tạo \u003cstrong\u003etóm tắt 2-3 câu\u003c\/strong\u003e cho mỗi chunk bằng Claude, rồi embed \u003ccode\u003eheading + summary + original content\u003c\/code\u003e cùng nhau.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003edef create_summary(chunk_text):\n    response = client.messages.create(\n        model=\"claude-haiku-4-5\",\n        messages=[{\n            \"role\": \"user\",\n            \"content\": f\"\"\"Tóm tắt đoạn text sau trong 2-3 câu:\n{chunk_text}\"\"\"\n        }],\n        max_tokens=150\n    )\n    return response.content[0].text\n\n# Kết hợp khi embed\ncombined_text = f\"{heading}\\n{summary}\\n{original_text}\"\nembedding = voyage_client.embed(combined_text)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eSummary giúp embeddings \u003cstrong\u003ecapture ý nghĩa chính xác hơn\u003c\/strong\u003e — thay vì chỉ dựa vào từ ngữ thô trong chunk.\u003c\/p\u003e\n\n\u003ch3\u003eKết quả sau Summary Indexing\u003c\/h3\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n\u003cth\u003eMetric\u003c\/th\u003e\n\u003cth\u003eBasic RAG\u003c\/th\u003e\n\u003cth\u003e+ Summary\u003c\/th\u003e\n\u003cth\u003eThay đổi\u003c\/th\u003e\n\u003c\/tr\u003e\n  \u003c\/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n\u003ctd\u003eAvg Precision\u003c\/td\u003e\n\u003ctd\u003e0.43\u003c\/td\u003e\n\u003ctd\u003e0.43\u003c\/td\u003e\n\u003ctd\u003e—\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eAvg Recall\u003c\/td\u003e\n\u003ctd\u003e0.66\u003c\/td\u003e\n\u003ctd\u003e0.67\u003c\/td\u003e\n\u003ctd\u003e+0.01\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eAvg F1\u003c\/td\u003e\n\u003ctd\u003e0.52\u003c\/td\u003e\n\u003ctd\u003e0.52\u003c\/td\u003e\n\u003ctd\u003e—\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eAvg MRR\u003c\/td\u003e\n\u003ctd\u003e0.74\u003c\/td\u003e\n\u003ctd\u003e0.80\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003e+0.06\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eE2E Accuracy\u003c\/td\u003e\n\u003ctd\u003e71%\u003c\/td\u003e\n\u003ctd\u003e78%\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003e+7%\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n  \u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003cp\u003eMRR cải thiện mạnh (+0.06) nghĩa là chunk đúng được \u003cstrong\u003exếp hạng cao hơn đáng kể\u003c\/strong\u003e. End-to-end accuracy nhảy từ 71% lên 78%.\u003c\/p\u003e\n\n\u003ch2\u003eLevel 3: Reranking với Claude (81%)\u003c\/h2\u003e\n\n\u003cp\u003eBước cuối: dùng Claude đánh giá lại và sắp xếp thứ tự các chunks đã truy xuất.\u003c\/p\u003e\n\n\u003ch3\u003ePipeline 2 giai đoạn\u003c\/h3\u003e\n\n\u003col\u003e\n  \u003cli\u003e\n\u003cstrong\u003eOver-retrieve\u003c\/strong\u003e — Lấy 20 chunks thay vì 3 (cast a wider net)\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eRerank với Claude\u003c\/strong\u003e — Đưa 20 summaries + query cho Claude, yêu cầu chọn và xếp hạng top 3 liên quan nhất\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003cpre\u003e\u003ccode\u003edef rerank_results(query, results, k=3):\n    summaries = \"\\n\".join([\n        f\"[{i}] {r['summary']}\" for i, r in enumerate(results)\n    ])\n    response = client.messages.create(\n        model=\"claude-sonnet-4-6\",\n        messages=[{\n            \"role\": \"user\",\n            \"content\": f\"\"\"Query: {query}\n\nDocuments:\n{summaries}\n\nChọn {k} documents liên quan nhất.\nTrả về indices theo thứ tự relevance giảm dần.\nFormat: [index1, index2, index3]\"\"\"\n        }],\n        max_tokens=100\n    )\n    indices = parse_indices(response.content[0].text)\n    return [results[i] for i in indices[:k]]\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eKết quả cuối cùng\u003c\/h3\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n\u003cth\u003eMetric\u003c\/th\u003e\n\u003cth\u003eBasic\u003c\/th\u003e\n\u003cth\u003e+ Summary\u003c\/th\u003e\n\u003cth\u003e+ Reranking\u003c\/th\u003e\n\u003c\/tr\u003e\n  \u003c\/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n\u003ctd\u003eAvg Precision\u003c\/td\u003e\n\u003ctd\u003e0.43\u003c\/td\u003e\n\u003ctd\u003e0.43\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003e0.44\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eAvg Recall\u003c\/td\u003e\n\u003ctd\u003e0.66\u003c\/td\u003e\n\u003ctd\u003e0.67\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003e0.69\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eAvg F1\u003c\/td\u003e\n\u003ctd\u003e0.52\u003c\/td\u003e\n\u003ctd\u003e0.52\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003e0.54\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eAvg MRR\u003c\/td\u003e\n\u003ctd\u003e0.74\u003c\/td\u003e\n\u003ctd\u003e0.80\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003e0.87\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eE2E Accuracy\u003c\/td\u003e\n\u003ctd\u003e71%\u003c\/td\u003e\n\u003ctd\u003e78%\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003e81%\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n  \u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003cp\u003eTừ 71% lên 81% accuracy — \u003cstrong\u003ecải thiện 14% tương đối\u003c\/strong\u003e. MRR từ 0.74 lên 0.87 nghĩa là chunk đúng gần như luôn ở vị trí đầu tiên.\u003c\/p\u003e\n\n\u003ch2\u003eBest practices cho production RAG\u003c\/h2\u003e\n\n\u003ch3\u003e1. Luôn đánh giá retrieval và end-to-end riêng biệt\u003c\/h3\u003e\n\u003cp\u003eRetrieval tốt nhưng generation kém (hoặc ngược lại) cần giải pháp khác nhau. Đánh giá riêng giúp bạn biết cần tối ưu ở đâu.\u003c\/p\u003e\n\n\u003ch3\u003e2. Invest vào evaluation dataset\u003c\/h3\u003e\n\u003cp\u003eDataset đánh giá chất lượng cao là \u003cstrong\u003etài sản quan trọng nhất\u003c\/strong\u003e của hệ thống RAG. Dành thời gian tạo dataset đa dạng, bao gồm cả câu hỏi dễ và khó.\u003c\/p\u003e\n\n\u003ch3\u003e3. Summary Indexing cho ROI tốt nhất\u003c\/h3\u003e\n\u003cp\u003eSummary Indexing là kỹ thuật cho \u003cstrong\u003ecải thiện lớn nhất với effort thấp nhất\u003c\/strong\u003e. Bắt đầu từ đây trước khi thêm complexity.\u003c\/p\u003e\n\n\u003ch3\u003e4. Reranking khi cần precision cao\u003c\/h3\u003e\n\u003cp\u003eReranking thêm latency (~200ms) nhưng cải thiện đáng kể precision. Phù hợp khi câu trả lời cần chính xác tuyệt đối (pháp lý, y tế, tài chính).\u003c\/p\u003e\n\n\u003ch3\u003e5. Dùng Promptfoo cho systematic evaluation\u003c\/h3\u003e\n\u003cp\u003eJupyter Notebook tốt cho prototyping, nhưng khi dataset lớn và prompts nhiều, cần tooling chuyên biệt. \u003cstrong\u003ePromptfoo\u003c\/strong\u003e giúp so sánh models, hyperparameters, và prompts tự động.\u003c\/p\u003e\n\n\u003ch2\u003eÁp dụng cho dự án của bạn\u003c\/h2\u003e\n\n\u003col\u003e\n  \u003cli\u003e\n\u003cstrong\u003eCustomer support bot\u003c\/strong\u003e — RAG trên FAQ + product docs\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eInternal knowledge assistant\u003c\/strong\u003e — RAG trên wiki nội bộ\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eLegal assistant\u003c\/strong\u003e — RAG trên hợp đồng, luật, quy định\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eCode assistant\u003c\/strong\u003e — RAG trên codebase + API documentation\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003cp\u003eBước tiếp theo: Đọc thêm về \u003ca href=\"\/en\/collections\/nang-cao\"\u003eContextual Retrieval\u003c\/a\u003e để nâng cấp RAG lên level tiếp theo, và \u003ca href=\"\/en\/collections\/nang-cao\"\u003ePrompt Engineering nâng cao\u003c\/a\u003e để tối ưu prompts trong pipeline.\u003c\/p\u003e\n","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721706553556,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/rag-v_i-claude-xay-d_ng-h_-th_ng-truy-xu_t-thong-tin-t_-a-d_n-z.jpg?v=1774521696","url":"https:\/\/claude.vn\/en\/products\/rag-v%e1%bb%9bi-claude-xay-d%e1%bb%b1ng-h%e1%bb%87-th%e1%bb%91ng-truy-xu%e1%ba%a5t-thong-tin-t%e1%bb%ab-a-d%e1%ba%bfn-z","provider":"CLAUDE.VN","version":"1.0","type":"link"}