Qdrant 完整教學:從 Docker 啟動到過濾式向量搜尋,建好你的第一個 RAG 底層
向量資料庫選型繞來繞去,Qdrant 是少數自架簡單、過濾功能又夠強的選擇。這篇從 docker run 一路帶到 payload 過濾與索引調校。
Qdrant 完整教學:從 Docker 啟動到過濾式向量搜尋,建好你的第一個 RAG 底層
做 RAG 的人大概都經歷過同一個階段:先用記憶體裡的一個 list 存向量,用 numpy 算 cosine similarity,跑得很開心。然後資料量到十萬筆,查詢開始要幾秒,你才意識到該找個真的向量資料庫了。
Qdrant 是這個階段最常被推薦的選項之一。它是 Rust 寫的開源向量資料庫,自架簡單、記憶體效率好,而且過濾功能是同類產品裡設計得比較完整的。
這篇教學會從零帶到能用:啟動、建表、寫入、搜尋、過濾,以及幾個一開始就該知道的坑。
這是什麼
Qdrant 做的事情,一句話講就是:儲存高維向量,並在幾毫秒內找出跟你查詢向量最相似的那幾筆。
但它不只做相似度計算。每個向量可以掛一份 payload(你可以理解成 metadata),裡面放任何 JSON 資料——文件標題、作者、日期、價格、庫存狀態。搜尋時可以同時做「語意相似」與「payload 條件過濾」,這是它在 RAG 場景最有價值的能力。
為什麼過濾這麼重要?因為很多資訊沒辦法塞進向量裡。官方文件講得很清楚:當物件的某些特性不可能用嵌入向量表達時(例如庫存狀態或價格區間),設定額外條件就變得必要。你不會希望 RAG 推薦一份已經下架三年的舊文件。
能做什麼
實務上最常見的用途有這幾種:
- RAG 的檢索層:把文件切塊、嵌入、存進 Qdrant,查詢時取回最相關的段落餵給 LLM。
- 語意搜尋:站內搜尋不再只靠關鍵字比對,能理解「便宜的筆電」跟「平價筆記型電腦」是同一件事。
- 推薦系統:用商品或內容的嵌入向量找相似項目。
- 去重與相似偵測:找出內容重複或高度相似的資料。
怎麼用(步驟)
步驟一:用 Docker 啟動
最快的起步方式是 Docker:
docker pull qdrant/qdrant
docker run -p 6333:6333 -p 6334:6334 \
-v "$(pwd)/qdrant_storage:/qdrant/storage:z" \
qdrant/qdrant
跑起來之後有三個端口要記住:
localhost:6333— REST APIlocalhost:6333/dashboard— 網頁管理介面(強烈建議打開看看,對除錯很有幫助)localhost:6334— gRPC
那個 -v 掛載很重要。沒掛的話容器一停資料就沒了,這是新手最常見的第一個坑。
步驟二:安裝並連上 client
以 Python 為例:
pip install qdrant-client
from qdrant_client import QdrantClient
client = QdrantClient(url="http://localhost:6333")
官方同時提供 JavaScript、Rust、Java、C# 與 Go 的 client,語法概念一致。
步驟三:建立 collection
Collection 相當於關聯式資料庫裡的 table。建立時要決定兩件事:向量維度與距離度量。
from qdrant_client.models import Distance, VectorParams
client.create_collection(
collection_name="test_collection",
vectors_config=VectorParams(size=4, distance=Distance.DOT),
)
size 必須跟你的嵌入模型輸出維度完全一致,填錯就會在寫入時報錯。距離度量支援內積(DOT)、餘弦(COSINE)與歐氏距離(EUCLID)。
實務建議:如果你用的是 OpenAI 或多數開源嵌入模型,選 COSINE 通常最穩。除非你確定模型輸出已經正規化,否則別預設用 DOT。
步驟四:寫入向量(upsert)
from qdrant_client.models import PointStruct
client.upsert(
collection_name="test_collection",
wait=True,
points=[
PointStruct(
id=1,
vector=[0.05, 0.61, 0.76, 0.74],
payload={"city": "Taipei", "category": "tech", "price": 1200},
),
PointStruct(
id=2,
vector=[0.19, 0.81, 0.75, 0.11],
payload={"city": "Taichung", "category": "food", "price": 300},
),
],
)
注意 wait=True。它會等寫入完成才回傳——測試階段一定要開,不然你會在下一行查不到資料然後懷疑人生。正式環境批次寫入時可以關掉來提升吞吐。
步驟五:搜尋與過濾
這是 Qdrant 最值得學的部分。過濾條件有三種子句,可以任意組合與巢狀嵌套:
must— 全部條件都要滿足,等同 ANDshould— 至少滿足一個,等同 ORmust_not— 全部條件都不能滿足,等同 NOT A AND NOT B
一個實際的例子:
{
"filter": {
"must": [
{ "key": "city", "match": { "value": "Taipei" } }
],
"must_not": [
{ "key": "category", "match": { "value": "food" } }
]
}
}
這段的意思是:城市是台北,而且分類不是食物。除了精確比對之外,還支援範圍查詢(價格區間)、地理空間搜尋、全文比對與巢狀物件過濾。
進階技巧
一定要建 payload 索引。 官方明確建議:對經常拿來過濾的欄位建立 payload 索引,否則過濾會退化成全表掃描。這是效能上最容易踩、也最容易修的坑。
先想清楚 payload 的 schema。 向量可以重算,但 payload 結構改起來很痛。開始前先想好你未來會用什麼條件過濾——時間範圍?權限層級?資料來源?在 RAG 系統裡,「這份文件這個使用者能不能看」的權限過濾幾乎一定會用到,別等做完才加。
用 dashboard 除錯。 localhost:6333/dashboard 可以直接看 collection 狀態、瀏覽 points、試跑查詢。比一路 print 快得多。
批次寫入時關掉 wait。 大量寫入時 wait=True 會嚴重拖慢速度,改成批次送出後再確認一次即可。
id 用有意義的值。 Qdrant 支援整數與 UUID 作為 id。用你原始資料的主鍵或其雜湊值,重跑索引時才能正確覆蓋而不是產生重複。
注意事項
記憶體規劃要先算。 向量資料庫吃記憶體,粗估方式是「向量數 × 維度 × 4 bytes」再加上索引與 payload 的開銷。一百萬筆 1536 維的向量,光原始向量就大約 6GB。資料量大時要研究 Qdrant 的量化(quantization)與 on-disk 儲存選項。
維度填錯救不回來。 collection 的向量維度一旦建立就不能改,只能重建。換嵌入模型時特別容易踩到。
別把 Qdrant 當主資料庫。 它是檢索層,原始文件與業務資料應該存在你原本的資料庫裡,Qdrant 的 payload 只放檢索與過濾需要的欄位。混在一起後續會很難維護。
自架的營運成本別低估。 Docker 跑起來很簡單,但備份、監控、擴容、版本升級都是要人顧的。團隊沒有維運人力的話,Qdrant Cloud 或其他託管方案可能更划算。
TheAI學院 評語
我自己的經驗是,向量資料庫的選型其實沒有想像中關鍵——Qdrant、Weaviate、Milvus 這幾家在基本的相似度搜尋上差異有限,真正決定 RAG 品質的是切塊策略、嵌入模型與重排序(rerank)。
但如果要挑一個理由選 Qdrant,我會說是過濾功能。它的 must/should/must_not 設計乾淨、可巢狀組合、而且效能有經過認真設計(前提是你有建索引)。在真實的企業 RAG 場景裡,權限過濾與時效過濾是必然需求,這時候過濾能力就從「加分」變成「必要」。
另一個實際的好處是自架門檻低。一行 docker run 就能起來,不需要 Kubernetes、不需要一堆相依服務。對想先在本機驗證想法的團隊來說,這個摩擦係數很重要。
評語:Qdrant 不是最快的,也不是功能最多的,但它是「從想法到跑起來」路徑最短的向量資料庫之一。對台灣多數團隊來說,這個特性比跑分好看更有價值。
給台灣開發者的建議:第一次做 RAG 的話,先用 Docker 在本機跑通整條流程,資料量控制在幾千筆,把注意力放在切塊與檢索品質上,別急著調效能。等品質站穩了再談規模。如果你需要 GPU 來跑嵌入模型或本地 LLM,可以參考我們的 RunPod 教學。想看更多開發相關工具,站上的 AI 開發框架與基建 分類有整理。
資料來源
(本文依官方文件整理,API 語法以官方最新文件為準。)
常見問題
Qdrant 和 Pinecone、Weaviate 該怎麼選?
基本的相似度搜尋能力差異有限。Qdrant 的優勢在自架門檻低(一行 docker run)與過濾功能設計完整;Pinecone 是全託管、免維運但成本較高;Weaviate 內建更多模組化功能。若團隊想先在本機快速驗證,Qdrant 的摩擦最小。
為什麼我的過濾查詢很慢?
最常見的原因是沒有為過濾欄位建立 payload 索引。官方明確建議對經常用來過濾的欄位建索引,否則過濾會退化成全表掃描。這是效能問題中最容易修的一項。
collection 的向量維度可以改嗎?
不行。維度在建立 collection 時就固定,要改只能重建 collection 並重新寫入所有資料。因此換嵌入模型前務必確認新模型的輸出維度,這是換模型時最常踩的坑。
Docker 跑的 Qdrant 重啟後資料會不見嗎?
如果沒有掛載 volume 就會不見。務必在 docker run 時加上 -v 參數,把 qdrant_storage 目錄掛載到容器內的 /qdrant/storage,這是新手最常見的第一個錯誤。