DigiHouse
日本語

TECH ARTICLE · 7 MIN READ

Blog / DigiHouse

W12|ChromaDB 在地 knowledge planning 與資料安全

W12 第三小時實作:像在自己的筆記櫃找資料一樣,將公開小文件加入 ChromaDB,檢索來源後再回答。

本週完成成果

你會建立一個小型在地知識庫,把文件切成可追蹤片段、加入 Chroma collection,再用問題找回最相關片段;回答必須附來源,不讓模型憑空補完。

完成標準|個人 ChromaDB 測試可加入並查詢三筆公開文件;小組 RAG 流程保留來源 ID、拒答條件與資料分級;不使用個資、NDA 或同學作業。

課前準備

步驟 1|資料分級:只選三份可公開、可授權使用的短文件,例如課程公開說明、自製 FAQ、公開校規節錄。

預期結果|每份文件記錄標題、URL/來源、日期與授權;敏感資料不進測試。

步驟 2|Codespaces:建立隔離資料目錄,確認它不會被誤提交大型索引。

bash
mkdir -p codes/rag/data codes/rag/chroma
printf "codes/rag/chroma/
" >> .gitignore

預期結果|向量索引在忽略清單;可重建的資料庫不進 Git。

步驟 3|Codespaces:核對 requirements 與磁碟,再安裝本週鎖定版本。

bash
df -h .
python -m pip install -r courseware/gs3073-b/requirements-week12.txt

預期結果|ChromaDB 可 import;不以全域 pip 隨機升級。

第三小時|個人技術實作

故事開始|期末考前問同學「老師有沒有說報告頁數?」同學先翻課程公告再回答,比憑印象可靠。RAG 就像先到自己的資料櫃找相關頁面,再把找到的內容交給模型整理。

老師先問|把文件放進向量資料庫後,答案就一定正確嗎?不是。檢索可能找錯片段,原始文件也可能過期;所以要顯示來源、分數與查閱日期。

生活比喻|Chroma collection 像一個有索引的抽屜;chunk 是抽屜裡有編號的小卡;query 是拿問題去找最相近的卡,而不是直接產生答案。

先看全程地圖|先看懂資料與決策怎麼移動,再開始操作。圖中的箭頭代表下一步,不代表可以跳過人工確認。

text
┌──────────┐ → ┌──────────┐ → ┌──────────┐
│ 核准文件  │   │ 切片+來源ID│   │ Chroma 索引│
└──────────┘   └──────────┘   └────┬─────┘
                                    ↓
┌──────────┐ ← ┌──────────┐ ← ┌──────────┐
│ 附來源回答│   │ 足夠才回答│   │ 問題檢索  │
└──────────┘   └──────────┘   └──────────┘

步驟 4|個人:建立記憶體內 Chroma client,加入三筆自製公開文字。

python
import chromadb

client = chromadb.Client()
collection = client.get_or_create_collection('course-faq')
collection.upsert(
    ids=['faq-1', 'faq-2', 'faq-3'],
    documents=['期中發表包含 Pitch 與 Demo。', 'API key 不得提交到 GitHub。', '課後作業需保留 commit。'],
)
print(collection.count())

預期結果|week12_chromadb_test.py 顯示 3;重跑不會因相同 ID 無限增加。

步驟 5|個人:用問題檢索兩筆結果,印出 ID、文字與距離。

python
result = collection.query(query_texts=['金鑰可以上傳嗎?'], n_results=2)
print(result['ids'][0])
print(result['documents'][0])
print(result['distances'][0])

預期結果|第一筆應接近 API key 規則;若不是,記錄實際結果,不手改輸出。

步驟 6|小組:在 codes/rag 定義文件 manifest,讓每個 chunk 都能回到來源。

yaml
- id: faq-2
  title: W2 安全規則
  source: course-material
  accessed_on: 2026-08-04
  sensitivity: public
  text: API key 不得提交到 GitHub。

預期結果|每筆有穩定 ID、來源日期與敏感度。

步驟 7|小組:設計拒答:找不到足夠相關來源時,回答「目前資料不足」並列出可查位置。

預期結果|不要求模型用常識補一個看似合理的答案。

課堂收束|把回答中的每一句重點指回來源卡片。指不回去的句子就刪除、改成推測標記,或回覆資料不足。

指定閱讀與課後作業

指定閱讀|依課綱完成個人 ChromaDB 增加與檢索測試;collection、ID、upsert 與 query 以 Chroma 官方 Getting Started 為準。

課後作業方向|個人繳交小型測試;小組在 feat-rag 分支完成「讀取文件→切片→寫入 Chroma→查詢→把結果交給模型」骨架,只使用公開安全資料。

步驟 8|個人:為三筆文件加入來源 metadata,查詢時一併顯示。

預期結果|結果能指出 source 與 accessed_on。

步驟 9|小組:提交 codes/rag 程式與 README,不提交 chroma 資料庫本體。

bash
git add week12_chromadb_test.py codes/rag .gitignore README.md
git commit -m 'W12: build source-traceable local retrieval'
git push -u origin HEAD

預期結果|Repo 包含重建方式、來源 manifest、拒答規則,不含敏感文件或索引。

驗收方式

bash
python week12_chromadb_test.py
git check-ignore codes/rag/chroma || true
rg -n "source|accessed_on|資料不足" codes/rag README.md

通過條件|三筆文件可 upsert/query;結果附來源;索引被忽略;低相關時拒答;資料全為公開安全。

應提交的 Repo 檔案

必交|week12_chromadb_test.py、codes/rag/。只提交課綱指定成果與重現所需說明;不得提交 API key、個資、私人對話、未授權資料或大型模型檔。

常見問題與排除

問題 1|重跑後重複資料:使用穩定 ID 與 upsert,不用每次產生隨機 ID。

問題 2|第一次 embedding 下載失敗:依教師準備環境或固定模型處理,不改用未知外部服務上傳文件。

問題 3|查到不相關內容:檢查 chunk 太長/太短、查詢語句與 n_results,並保留失敗案例。

引用資料

國立中央大學授課課綱/劉書銘老師,《劉書銘老師課程大綱_基礎模型與生成式人工智慧-更新版.pdf》;教師提供附件。用途:W1–W16 時段、實作主題、評量與交付物。

Chroma,《Getting Started》;https://docs.trychroma.com/docs/overview/getting-started;查閱日期:2026-08-04。用途:W12 collection、document、ID、query 與本機向量檢索。

Python Software Foundation,《JSON encoder and decoder》;https://docs.python.org/3/library/json.html;查閱日期:2026-08-04。用途:W6 JSON 讀取、解析與輸出。