如何使用 Claude 構建 RAG 系統:讓 AI 讀懂你的專屬數據(完整指南)

@undefinedKi
英語2 天前 · 2026年7月11日
206K
150
25
16
575

TL;DR

這份綜合指南說明了如何使用 Claude 建立本地檢索增強生成(RAG)系統,讓使用者能夠高效地查詢自己的文件,同時將 API 成本降至最低。

好的,以下是您提供的英文 Markdown 内容的繁體中文翻譯,已嚴格遵循您的所有指示。


問 Claude 關於你的公司、筆記或檔案,它會一片空白。它從未見過這些資料。它只知道訓練時學到的東西,而你的資料不在其中。

RAG 系統解決了這個問題。它不依賴記憶,而是先在你的文件中查找,擷取相關的部分,然後根據實際找到的內容來回答。你的資料,它的來源,完全不用猜測。

為什麼這比直接把檔案貼到對話框更好:

它具備可擴展性。 你的整個知識庫無法塞進一次對話中。RAG 會儲存所有內容,並只根據每個問題擷取所需的部份。

它更省錢。 貼上檔案意味著 Claude 每次都得重新讀取整個檔案。RAG 只讀取一次,然後僅提取相關部分。與其每次傳送一份 10,000 個 token 的手冊,它可能只傳送 500 個 token 的準確章節。實際的應用中,token 使用量可減少 80% 以上。

它更精準。 給模型一大段文字,它會遺漏中間的細節。給它幾個精確的區塊,答案會更準確。

它保持最新。 更新一次你的檔案,系統就會使用新版本。無需重新貼上。

讀完這份指南,你就能在自己的檔案上一步步建立一個 RAG 系統,不需要博士學位。

你需要準備什麼

在我們碰任何程式碼之前,這裡是完整的清單。好消息是:這個版本只需要一個 API 金鑰,其他所有東西都在你自己的機器上免費運行。

1. Python 3.9 或更新版本。 要檢查你是否已安裝,請打開你的終端機(Mac 上的 Terminal,Windows 上的 Command Prompt),然後輸入 python --version。如果你看到類似 3.11 的訊息,就沒問題。如果沒有,請從 python.org 下載並執行安裝程式。在 Windows 上,安裝時請勾選「Add Python to PATH」,否則下面的指令將無法運作。

2. 一個 Claude API 金鑰,加上一些儲值額度。 這是這份指南需要的唯一金鑰和唯一花費。以下是確切的步驟,一步步點擊:

前往 platform.claude.com,然後登入(或註冊)。

API 需要正數餘額才能運行,所以請先加值。依照提示操作,選擇額度是給個人還是公司,然後你會進入付款畫面。選擇 $5 的「Starting out」選項。這很夠用了:這份指南中的其他東西都是免費且在本機運行的,所以 Claude 是唯一需要花錢的部分,而且每個問題只會花你不到一分錢。額度在購買後一年內有效。

付款後,你會進入你的 Console 儀表板。你應該會在左上方「Organization credits」下方看到你的餘額(例如 $5.00)。

現在取得金鑰。點擊 Get API key(右上角),然後點擊 Create Key。為它取任何你喜歡的名字(例如 my-rag-key),並將工作區保留為 Default。點擊建立,然後複製顯示出來的字串。它以 sk-ant- 開頭,而且你只會看到一次,所以請先把它貼到安全的地方。

這就是整個設定。

步驟 1:加入你的金鑰並載入檔案

1. 建立專案資料夾。 在你的桌面上建立一個新資料夾,命名為 rag-project。所有東西都放在這裡。

2. 打開你的終端機。 Mac 上:Cmd+Space,輸入 Terminal,按 Enter。Windows 上:按開始按鈕,輸入 cmd,按 Enter。

3. 將終端機指向你的資料夾。 輸入 cd 和一個空格,然後將 rag-project 資料夾拖曳到終端機視窗上,並按 Enter。下面的每個指令都在這個資料夾內執行。

bash
1cd Desktop/rag-project

4. 安裝工具。 將此貼到你的終端機並按 Enter(第一次執行可能需要一分鐘):

bash
1pip install anthropic chromadb sentence-transformers pypdf python-dotenv

如果你看到 pip: command not found,請使用 pip3 代替 pip。當終端機顯示一個新的行且沒有紅色錯誤訊息時,就完成了。

5. 建立你的程式碼檔案。 在 rag-project 裡面,建立一個名為 [rag.py](https://rag.py/) 的空檔案。用任何文字編輯器打開它。

6. 建立你的金鑰檔案。 在同一個資料夾中,建立一個名為 .env 的檔案(以點開頭,前面沒有名稱)。將以下內容貼入,並在 = 後面放入你在設定時建立的真正金鑰,不要有空格,不要有引號:

text
1ANTHROPIC_API_KEY=sk-ant-paste-your-real-key-here

將金鑰放在 .env 檔案中而非程式碼中,意味著如果你分享腳本或將其放到 GitHub 上,金鑰也不會洩漏。

7. 載入金鑰。 將下列程式碼放在 [rag.py](https://rag.py/) 的最上方:

python
1import os
2from dotenv import load_dotenv
3
4load_dotenv() # 讀取你的 .env 檔案
5api_key = os.getenv("ANTHROPIC_API_KEY")

8. 建立你的知識庫。 在 rag-project 裡面,建立一個名為 documents 的資料夾。將任何 .txt、.md 或 .pdf 檔案丟進去:你的筆記、產品文件、會議記錄,任何東西都可以。

8.1. 如果你還沒有檔案,可以使用這個測試檔案。 在 documents 資料夾中建立 notes.txt,並貼入以下內容:

Project Northstar 是我們用來追蹤客戶意見回饋的內部工具。它於 2026 年 3 月上線,由平台團隊維護。首席工程師是 Dana Reyes。意見回饋會在每週五檢視。Northstar 取代了我們在 2025 年使用的舊版試算表系統。

最後,你會問 Claude 關於 Northstar 的問題,並看著它根據這個檔案回答。

9. 加入讀取檔案的程式碼。 在步驟 7 的程式碼下方,於 [rag.py](https://rag.py/) 中:

python
1from pathlib import Path
2from pypdf import PdfReader
3
4def load_documents(folder="documents"):
5 docs = []
6 for file in Path(folder).iterdir():
7 if file.suffix in [".txt", ".md"]:
8 text = file.read_text(encoding="utf-8")
9 docs.append({"source": file.name, "text": text})
10 elif file.suffix == ".pdf":
11 reader = PdfReader(str(file))
12 text = "\n".join(page.extract_text() or "" for page in reader.pages)
13 docs.append({"source": file.name, "text": text})
14 return docs
15
16documents = load_documents()
17print(f"已載入 {len(documents)} 個文件。")

10. 執行它。 儲存 [rag.py](https://rag.py/),然後在你的終端機中:

bash
1python rag.py

你應該會看到:

已載入 1 個文件。

如果你看到「已載入 0 個文件」,表示 documents 資料夾是空的或在錯誤的位置。它必須直接位於 rag-project 資料夾內,與 rag.py 並列。

步驟 2:將你的檔案分割成區塊

現在每個檔案都是一大塊文字。在我們搜尋它之前,需要將其切割成稱為區塊的較小片段。原因如下:當有人提出問題時,系統會找到匹配的區塊,並只將這些區塊傳送給 Claude。如果你的區塊是整份 50 頁的文件,你會傳送太多內容。如果它們是單一句子,則會失去上下文。小段落是最佳選擇。

1. 加入分割區塊的程式碼。 在步驟 10 的程式碼下方,於 [rag.py](https://rag.py/) 中:

python
1def chunk_text(text, chunk_size=500, overlap=100):
2 words = text.split()
3 chunks = []
4 start = 0
5 while start < len(words):
6 end = start + chunk_size
7 chunk = " ".join(words[start:end])
8 chunks.append(chunk)
9 start = end - overlap # 稍微倒退,讓區塊之間有重疊
10 return chunks

這裡有兩個數字需要理解,用白話文來說:

  • chunk_size=500 表示每個區塊大約 500 個字。大到足以容納一個完整的概念,小到足以保持精確。
  • overlap=100 表示每個區塊會重複前一個區塊的最後 100 個字。這很重要,因為答案可能剛好落在兩個區塊的交界處。沒有重疊,一個被從中間切斷的句子可能會遺失。重疊確保沒有想法會從裂縫中掉落。

2. 將每個文件都轉換成區塊。 在下方加入:

python
1all_chunks = []
2for doc in documents:
3 for chunk in chunk_text(doc["text"]):
4 all_chunks.append({"source": doc["source"], "text": chunk})
5
6print(f"從 {len(documents)} 個文件建立了 {len(all_chunks)} 個區塊。")

請注意,每個區塊都帶有它的 source(它來自的檔案名稱)。我們會全程保持這個關聯,這樣當 Claude 稍後回答時,它可以告訴你答案來自哪個檔案。

3. 執行它。 儲存 [rag.py](https://rag.py/),然後在你的終端機中:

bash
1python rag.py

你應該會看到類似這樣的訊息:

已載入 1 個文件。

從 1 個文件建立了 1 個區塊。

這個小的測試檔案因為很短,所以只變成一個區塊。真正的文件會產生很多區塊。如果你在資料夾中放入一個長 PDF,你可能會看到幾十個或幾百個區塊,這正是你想要的。

步驟 3:將你的區塊轉換成嵌入向量

這一步讓電腦能夠根據意義而非確切的詞彙來搜尋。每個區塊都會被轉換成一個數字列表(一個嵌入向量),用來捕捉它的主題。意義相似的區塊最終會有相似的數字。稍後,當問題進來時,我們也會將問題轉換成數字,並找到最接近的匹配項。

執行此操作的模型會在你的機器上本地運行。它會下載一次,然後離線免費運行,你的檔案永遠不會離開你的電腦。

1. 載入嵌入模型。 在步驟 2 的程式碼下方,於 rag.py 中:

python
1from sentence_transformers import SentenceTransformer
2
3print("正在載入嵌入模型(首次執行會下載,約 90 MB)...")
4embedder = SentenceTransformer("all-MiniLM-L6-v2")

你第一次執行此操作時,它會下載模型,所以請給它一點時間。之後每次執行都會立即完成,因為它已經在你的機器上了。

2. 將每個區塊轉換成嵌入向量。 在下方加入:

python
1chunk_texts = [chunk["text"] for chunk in all_chunks]
2embeddings = embedder.encode(chunk_texts)
3
4print(f"建立了 {len(embeddings)} 個嵌入向量。")
5print(f"每個嵌入向量是一個包含 {len(embeddings[0])} 個數字的列表。")

embedder.encode(...) 接收你的區塊文字列表,並為每個區塊返回一個嵌入向量。就是這麼簡單。

3. 執行它。 儲存 rag.py,然後在你的終端機中:

bash
1python rag.py

第一次執行會暫停,等待模型下載,然後你應該會看到類似這樣的訊息:

已載入 1 個文件。

從 1 個文件建立了 1 個區塊。

正在載入嵌入模型(首次執行會下載,約 90 MB)...

建立了 1 個嵌入向量。

每個嵌入向量是一個包含 384 個數字的列表。

這行「384 個數字」讓整個概念具體化:你的文字現在變成了一行數字,電腦可以進行比較。你不需要自己閱讀或理解這些數字。下一步的資料庫會為你處理所有比較工作。

如果下載因連線錯誤而失敗,只需再次執行指令即可。它會從中斷的地方繼續。

步驟 4:將所有內容儲存到你的向量資料庫

現在我們將區塊及其嵌入向量放入 Chroma,你的本地資料庫。這使得搜尋變得快速:與其每次手動將你的問題與每個區塊進行比較,Chroma 會將它們儲存好,隨時可用,並為你進行匹配。它會儲存到你機器上的一個資料夾中,所以你只需要建立一次。

1. 設定資料庫。 在步驟 3 的程式碼下方,於 rag.py 中:

python
1import chromadb
2
3client = chromadb.PersistentClient(path="chroma_db")
4collection = client.get_or_create_collection("my_documents")

PersistentClient(path="chroma_db") 告訴 Chroma 儲存到一個名為 chroma_db 的資料夾中(它會自動建立,就在你的腳本旁邊)。因為它儲存在磁碟上,你的資料在腳本執行完畢後仍然存在。一個 collection 只是一個命名的盒子,你的區塊就放在裡面。

2. 將你的區塊加入資料庫。 在下方加入:

python
1collection.add(
2 ids=[str(i) for i in range(len(all_chunks))],
3 embeddings=[emb.tolist() for emb in embeddings],
4 documents=[chunk["text"] for chunk in all_chunks],
5 metadatas=[{"source": chunk["source"]} for chunk in all_chunks],
6)
7
8print(f"已將 {collection.count()} 個區塊儲存到資料庫中。")

這裡用白話文解釋每行程式碼交給 Chroma 的內容:ids 為每個區塊提供一個唯一的標籤(0, 1, 2...),embeddings 是步驟 3 中的數字,documents 是實際的區塊文字,而 metadatas 則攜帶檔案名稱,以便我們稍後可以顯示來源。Chroma 將這四者全部綁定在一起。

3. 執行它。 儲存 rag.py,然後在你的終端機中:

bash
1python rag.py

你應該會看到:

已將 1 個區塊儲存到資料庫中。

有一件事日後需要知道。 現在每次執行腳本時,它都會再次加入區塊,因此計數可能會在重複執行時攀升(1,然後 2,然後 3...)。這在我們建置的過程中沒問題。要從頭開始,請刪除 chroma_db 資料夾並再次執行。在最終版本中,我們會妥善處理這個問題,以避免重複。

步驟 5:搜尋你的文件

這就是 RAG 的「檢索」部分,也就是名稱中的 R。我們接受一個問題,將其轉換成嵌入向量,就像我們對區塊所做的那樣,然後要求 Chroma 提供意義最接近的區塊。這些匹配的區塊就是我們下一步要交給 Claude 的內容。

1. 加入搜尋函數。 在步驟 4 的程式碼下方,於 rag.py 中:

python
1def search(question, n_results=3):
2 question_embedding = embedder.encode([question])[0]
3 results = collection.query(
4 query_embeddings=[question_embedding.tolist()],
5 n_results=n_results,
6 )
7 return results

用白話文逐行解釋它的作用:它使用你對區塊使用的相同模型,將問題轉換成數字(這很重要,兩者必須使用相同的「數字語言」),然後要求 Chroma 提供最接近的匹配項。n_results=3 表示「給我 3 個最相關的區塊」。三個是良好的預設值:足夠的上下文,又不會浪費太多 token。

2. 嘗試搜尋。 在下方加入以下內容來測試:

python
1question = "誰負責 Northstar?意見回饋何時檢視?"
2results = search(question)
3
4for i, doc in enumerate(results["documents"][0]):
5 source = results["metadatas"][0][i]["source"]
6 print(f"\n--- 匹配 {i+1}(來自 {source})---")
7 print(doc)

這會針對你的資料庫執行一個真實的問題,並列印出它找到的區塊,每個區塊都附帶其來源檔案名稱。

3. 執行它。 儲存 rag.py,然後在你的終端機中:

bash
1python rag.py

使用 Northstar 測試檔案,你應該會看到它拉回匹配的區塊,類似於:

--- 匹配 1(來自 notes.txt)---

Project Northstar 是我們用來追蹤客戶意見回饋的內部工具。它於 2026 年 3 月上線,由平台團隊維護。首席工程師是 Dana Reyes。意見回饋會在每週五檢視。Northstar 取代了我們在 2025 年使用的舊版試算表系統。

請注意剛剛發生的事情:你的問題使用了「誰負責」和「檢視」這些詞,但檔案中寫的是「首席工程師」和「每週五檢視」。它仍然匹配了,因為搜尋是基於意義,而不是確切的詞彙。這就是嵌入向量的全部意義,也是為什麼這勝過在檔案中進行純粹的關鍵字搜尋(Ctrl+F)。

如果你有更多檔案,你會看到所有檔案中排名前 3 的區塊,根據它們與問題的匹配程度排序。

步驟 6:讓 Claude 根據找到的內容回答

這就是「生成」部分,也就是 RAG 中的 G。我們從步驟 5 取得區塊,將它們連同問題一起交給 Claude Opus 4.8,並告訴它只使用該上下文來回答。這可以防止它猜測:Claude 根據你的檔案回答,而不是根據它自己的記憶,並告訴你它使用了哪個檔案。

1. 加入回答函數。 在步驟 5 的程式碼下方,於 rag.py 中:

python
1import anthropic
2
3claude = anthropic.Anthropic(api_key=api_key)
4
5def answer(question):
6 results = search(question)
7 chunks = results["documents"][0]
8 sources = [m["source"] for m in results["metadatas"][0]]
9
10 context = ""
11 for i, chunk in enumerate(chunks):
12 context += f"[來自 {sources[i]}]\n{chunk}\n\n"
13
14 message = claude.messages.create(
15 model="claude-opus-4-8",
16 max_tokens=1024,
17 system=(
18 "你只能使用提供的上下文來回答問題。"
19 "如果答案不在上下文中,請說你不知道。"
20 "始終說明你的答案來自哪個檔案。"
21 ),
22 messages=[
23 {
24 "role": "user",
25 "content": f"上下文:\n{context}\n問題: {question}",
26 }
27 ],
28 )
29 return message.content[0].text

用白話文解釋這裡發生了什麼:我們搜尋相關的區塊,將它們拼接成一個 context 區塊(每個區塊都標有其檔案名稱),然後將該區塊連同問題一起發送給 Claude。system 指令是關鍵部分。它告訴 Claude 三件事:僅根據上下文回答,當答案不在其中時要承認,並指出來源檔案。這三個規則使答案可信,而不是編造出來的。

model="claude-opus-4-8" 是確切的模型名稱(使用破折號,不是點)。max_tokens=1024 限制了答案的長度。

2. 提出一個問題。 在下方加入:

python
1question = "誰負責 Northstar?意見回饋何時檢視?"
2print(answer(question))

3. 執行它。 儲存 rag.py,然後在你的終端機中:

bash
1python rag.py

你應該會得到一個根據你的檔案建立的真正答案,類似於:

Dana Reyes 是負責 Project Northstar 的首席工程師,意見回饋會在每週五檢視。(來源:notes.txt)

這是一個完整的 RAG 系統在運作。Claude 在訓練期間從未見過這個檔案,它不可能知道 Dana Reyes 是誰,但它正確地回答了問題,並準確告訴你答案來自哪裡。問它一個不在你檔案中的問題,它會說不知道,而不是編造一個答案。這個「不知道」是功能,不是失敗:它正是可信賴工具與胡亂猜測工具之間的區別。

步驟 7:將其變成一個真正可用的工具

現在,每次你想問問題,都必須編輯程式碼並重新執行整個腳本。更糟的是,每次執行都會重新讀取你的檔案並重新加入資料庫,導致區塊不斷累積。讓我們解決這兩個問題:只建立一次資料庫,然後讓你在一個迴圈中提問,直接在終端機中輸入。

1. 修正重複加入的問題。 找到步驟 4 中負責加入區塊的程式碼區塊(collection.add(...) 部分),並將其替換為這個版本,它只在資料庫為空時才建立:

python
1if collection.count() == 0:
2 collection.add(
3 ids=[str(i) for i in range(len(all_chunks))],
4 embeddings=[emb.tolist() for emb in embeddings],
5 documents=[chunk["text"] for chunk in all_chunks],
6 metadatas=[{"source": chunk["source"]} for chunk in all_chunks],
7 )
8 print(f"已將 {collection.count()} 個區塊儲存到資料庫中。")
9else:
10 print(f"資料庫已有 {collection.count()} 個區塊,跳過重建。")

現在,繁重的工作(讀取檔案、建立嵌入向量、填充資料庫)只在第一次執行時發生。之後的執行會直接跳過,進入回答階段。

2. 加入問題迴圈。rag.py 的最底部,將步驟 6 中的單一測試問題替換為:

python
1print("\n詢問關於文件的問題(或輸入 'quit' 離開)。\n")
2
3while True:
4 question = input("你: ")
5 if question.lower() in ["quit", "exit"]:
6 break
7 print("\nClaude: " + answer(question) + "\n")

input("你: ") 會等待你輸入問題並按 Enter。while True 讓它持續運行,這樣你就可以問任意多個問題。輸入 quit 會停止它。

3. 執行它。 儲存 rag.py,然後在你的終端機中:

bash
1python rag.py

現在你可以直接與你的檔案對話了:

詢問關於文件的問題(或輸入 'quit' 離開)。

你: 誰是 Northstar 的首席工程師?

Claude: Project Northstar 的首席工程師是 Dana Reyes。(來源:notes.txt)

你: 它取代了什麼?

Claude: Northstar 取代了在 2025 年使用的舊版試算表系統。(來源:notes.txt)

你: quit

這就是你完成的 RAG 系統。它會讀取你的檔案一次,記住它們,並根據需求回答關於它們的問題,每次都會提供來源。

有一件事需要知道,當你加入新檔案時。 由於資料庫現在只建立一次,將新檔案放入 documents 資料夾並不會自動顯示出來。要載入新檔案,請刪除 chroma_db 資料夾,然後執行一次腳本。它會從頭開始重建,包含資料夾中的所有內容。

可選:在你的瀏覽器中給它一個聊天視窗

終端機可以運作,但如果你想要一個真正的聊天視窗,Streamlit 可以用大約 20 行程式碼就加入一個。

1. 安裝它。 在你的終端機中:

bash
1pip install streamlit

2. 在同一個資料夾中建立 app.py 並貼入以下內容。它會重複使用你的 [rag.py](https://rag.py/) 中的 answer 函數:

python
1import streamlit as st
2from rag import answer
3
4st.title("與你的文件聊天")
5
6if "history" not in st.session_state:
7 st.session_state.history = []
8
9question = st.chat_input("詢問關於你的檔案的問題...")
10
11if question:
12 reply = answer(question)
13 st.session_state.history.append((question, reply))
14
15for q, a in st.session_state.history:
16 st.chat_message("user").write(q)
17 st.chat_message("assistant").write(a)

3. 執行它。 在你的終端機中(注意:是 streamlit run,不是 python):

bash
1streamlit run app.py

它會自動在你的瀏覽器中打開一個聊天視窗。輸入問題,獲得帶有來源的答案,就像終端機一樣,但看起來更美觀。

注意:為了讓它運作,步驟 7 中的問題迴圈在匯入時不應執行。將 rag.py 底部的該迴圈包裹在 if __name__ == "__main__": 中,這樣它只會在直接執行 rag.py 時觸發,而不會在 app.py 匯入它時觸發。

讓它也能回答一般問題

如果你希望它也能回答一般問題。 目前系統只根據你的檔案回答,所以像「委內瑞拉的首都是哪裡?」這樣的問題會得到「這不在文件中」的回答,即使 Claude 知道答案。如果你希望它退而使用自己的知識,請打開 rag.py,找到步驟 6 中的 system=(...) 區塊,並交換這一行:


python
1「如果答案不在上下文中,就說你不知道。」

改成這樣:

python
1「如果答案不在上下文中,就從你的一般知識中回答,但要說明你正在這麼做。」

儲存並重新執行。現在它會先從你的檔案中找答案,如果檔案內容不足,則回退到一般知識,並告知你使用的是哪一種來源。

總結

你剛剛建立了一個可運作的 RAG 系統。它會讀取你自己的檔案,找出相關的部分,並讓 Claude 根據這些內容回答問題,同時每次都附上精確的來源。這個架構可以從幾則筆記擴展到你的整個知識庫。

從這裡開始,你可以把它指向任何地方:你的 Obsidian 筆記庫、你的工作文件、你保存的研究資料。把檔案丟進去,重建一次,然後開始提問。你在這裡學到的一切——分段、嵌入、搜尋、回答——正是你見過的所有「與文件對話」工具背後的相同核心。

如果這篇文章對你有幫助,歡迎到我的個人檔案按追蹤。我寫關於科技、AI 和真正能運作的系統。

再會,

[@undefinedKi]([https://x.com/@undefinedKi](https://x.com/@undefinedKi))

二次創作

使用 YouMind 創作爆款文章

收集素材、拆解爆點、生成視覺資產、撰寫內容,並在一個 AI 工作空間裡完成分發。

了解 YouMind
寫給創作者

把你的 Markdown 變成乾淨的 𝕏 文章

圖片上傳、表格、程式碼區塊,往 𝕏 上手動重排太痛苦。YouMind 把整篇 Markdown 一鍵轉成乾淨、可直接發佈的 𝕏 文章草稿。

試試 Markdown 轉 𝕏

更多可拆解樣本

近期爆款文章

探索更多爆款文章