LangChain Retrieval 與資料查詢:使用不同向量庫(FAISS、Pinecone、Weaviate、Qdrant)
簡介
在 LLM(大型語言模型)日益普及的今天,向量檢索(Vector Retrieval) 已成為讓模型取得外部知識的關鍵技術。LangChain 作為一套串接 LLM、工具與資料的框架,提供了統一的 Retrieval API,讓開發者可以輕鬆切換不同的向量資料庫(Vector Store)。本篇文章將聚焦 FAISS、Pinecone、Weaviate、Qdrant 四大常見向量庫,說明它們的特性、在 LangChain 中的使用方式,以及實務上需要留意的細節。即使你是剛接觸 Retrieval 的新手,也能在閱讀完本文後,快速上手並選擇最適合自己的向量庫。
核心概念
1. 為什麼需要向量庫?
LLM 本身只記得訓練期間的語言結構,對於最新的產品說明、公司內部文件或專業領域的知識往往不具備。透過 Embedding(向量化)將文字轉成高維向量後,向量庫可以在 向量空間中快速找出最相似的資料,再把這些結果餵回 LLM,完成所謂的「檢索增強生成(RAG)」。
2. LangChain 的 Retrieval 抽象層
LangChain 把向量庫封裝成 VectorStoreRetriever,只要實作 addDocuments、similaritySearch 兩個核心方法,就能與任何支援的向量庫整合。這意味著:
- 程式碼幾乎不需要改動,只要換掉
FAISS.from_documents→Pinecone.from_documents即可。 - 可同時使用多個向量庫,例如先在本機的 FAISS 做快速原型,之後再遷移至雲端的 Pinecone 以支援大規模查詢。
3. 四大向量庫概覽
| 向量庫 | 部署方式 | 特色 | 適合情境 |
|---|---|---|---|
| FAISS | 本機 / Docker | 高效的相似度搜尋演算法(Flat、IVF、HNSW) | 開發階段、資料量 ≤ 百萬 |
| Pinecone | 雲端服務(SaaS) | 完全托管、即時擴容、內建過期策略 | 大規模商業應用、需要 SLA |
| Weaviate | 本機、K8s、雲端 | 支援 GraphQL / REST、內建向量化模型、可加入結構化屬性 | 多模態搜尋、混合向量+屬性查詢 |
| Qdrant | 本機、Docker、K8s | 支援 filter、payload,向量距離可自訂 | 需要高彈性過濾條件的應用 |
下面分別示範如何在 LangChainJS(Node.js)中建立這四種向量庫的 Retriever,並搭配 OpenAI Embedding 產生向量。
程式碼範例
3.1 安裝必要套件
npm install langchain openai @langchain/community
# 各向量庫的 client
npm install @pinecone-database/pinecone-client weaviate-client qdrant-client
3.2 共通的 Embedding 產生程式
import { OpenAIEmbeddings } from "@langchain/community/embeddings/openai";
const embeddings = new OpenAIEmbeddings({
openAIApiKey: process.env.OPENAI_API_KEY,
});
3.3 FAISS(本機)
import { FAISS } from "@langchain/community/vectorstores/faiss";
import { Document } from "langchain/document";
// 假設已有文件陣列
const docs = [
new Document({ pageContent: "LangChain 是什麼?", metadata: { id: 1 } }),
new Document({ pageContent: "FAISS 支援哪些索引類型?", metadata: { id: 2 } }),
];
// 建立 FAISS 向量庫
const faissStore = await FAISS.fromDocuments(docs, embeddings);
// 以查詢字串取得相似文件
const query = "FAISS 的 HNSW 索引怎麼用?";
const results = await faissStore.similaritySearch(query, 3);
console.log(results.map(r => r.pageContent));
說明:FAISS 完全在本機運算,適合開發測試或資料量不大時使用。若資料量超過數十萬,建議改用
IVF或HNSW索引以提升效能。
3.4 Pinecone(雲端)
import { PineconeClient } from "@pinecone-database/pinecone-client";
import { PineconeStore } from "@langchain/community/vectorstores/pinecone";
const pinecone = new PineconeClient();
await pinecone.init({
environment: process.env.PINECONE_ENV,
apiKey: process.env.PINECONE_API_KEY,
});
const indexName = "langchain-demo";
const pineconeIndex = pinecone.Index(indexName);
// 建立 Pinecone 向量庫(若索引不存在需先於控制台建立)
const pineconeStore = await PineconeStore.fromDocuments(
docs,
embeddings,
{ pineconeIndex, namespace: "demo" }
);
// 查詢
const pineconeResults = await pineconeStore.similaritySearch(query, 4);
console.log(pineconeResults.map(r => r.metadata.id));
說明:Pinecone 自動管理向量分片與複寫,適合需要 高可用、水平擴展 的服務。可設定
metadata以支援過濾(filter)功能。
3.5 Weaviate(圖形化 API)
import weaviate, { WeaviateClient } from "weaviate-client";
import { WeaviateStore } from "@langchain/community/vectorstores/weaviate";
const client = weaviate.client({
scheme: "https",
host: process.env.WEAVIATE_HOST,
});
const weaviateStore = await WeaviateStore.fromDocuments(
docs,
embeddings,
{
client,
indexName: "LangChainDocs", // 需預先在 Weaviate 建立 class
textKey: "content",
}
);
// 使用 filter 篩選特定屬性
const weaviateResults = await weaviateStore.similaritySearch(
query,
5,
{ where: { path: ["metadata", "category"], operator: "Equal", valueString: "LLM" } }
);
console.log(weaviateResults);
說明:Weaviate 允許 向量 + 結構化屬性 同時搜尋,特別適合「文件 + 標籤」的混合查詢場景。
3.6 Qdrant(高彈性過濾)
import { QdrantClient } from "qdrant-client";
import { QdrantStore } from "@langchain/community/vectorstores/qdrant";
const qdrant = new QdrantClient({
url: process.env.QDRANT_URL,
apiKey: process.env.QDRANT_API_KEY,
});
const qdrantStore = await QdrantStore.fromDocuments(
docs,
embeddings,
{
client: qdrant,
collectionName: "langchain_collection",
}
);
// 加入過期時間(payload)作為 filter
const qdrantResults = await qdrantStore.similaritySearch(
query,
3,
{ filter: { must: [{ key: "expireAt", match: { value: "2025-01-01" } }] } }
);
console.log(qdrantResults);
說明:Qdrant 支援 payload filter,可在向量相似度之外加上時間、類別、分數等條件,適合需要「資料過期」或「分層權限」的企業應用。
常見陷阱與最佳實踐
| 陷阱 | 可能的後果 | 解決方案 / Best Practice |
|---|---|---|
| 向量維度不一致 | 搜尋結果全部為空或拋出錯誤 | 確保所有文件使用相同的 Embedding 模型(例如 text-embedding-ada-002) |
未設定 metadata 的唯一鍵 |
同一筆文件會重複寫入,導致搜尋結果重複 | 在 Document 的 metadata 中加入唯一 id,或使用向量庫的 upsert 功能 |
| 過度依賴單一向量庫 | 雲端服務斷線或本機資源不足時系統失效 | 透過 抽象層(LangChain Retriever)保持可切換性,甚至同時佈署兩個向量庫作備援 |
忘記設定索引參數(如 metric、efConstruction) |
查詢速度慢或召回率低 | 依資料規模選擇合適的索引類型(FAISS IVF、Pinecone metric='cosine'、Qdrant hnsw_config) |
| 不考慮向量庫成本 | 雲端服務費用激增 | 先在本機的 FAISS 完成驗證,僅在正式上線時遷移至 Pinecone / Qdrant,並設定 TTL 或 分層儲存 |
其他實用技巧
- 批次寫入:一次寫入大量文件會減少 API 呼叫次數,提升效能。LangChain 的
addDocuments支援batchSize參數。 - 向量正規化:若使用 cosine 相似度,建議在嵌入完成後自行正規化向量,以避免不同模型產生的尺度差異。
- 多模態向量:Weaviate 與 Qdrant 均支援圖像、音訊向量,可將文字、圖像一起儲存於同一 collection,實現跨模態檢索。
實際應用場景
| 場景 | 使用向量庫 | 為何選擇 |
|---|---|---|
| 客服機器人 | Pinecone | 高可用、即時擴容,且支援向量過期(舊 FAQ 自動刪除) |
| 內部文件搜尋 | FAISS(開發) → Qdrant(正式) | 初期快速原型 → 正式上線後需要複雜過濾(部門、機密等) |
| 電商商品推薦 | Weaviate | 同時利用商品描述向量 + 結構化屬性(價格、庫存)做混合排序 |
| 醫療文獻檢索 | Qdrant | 需要依發表日期、關鍵字做嚴格過濾,且向量相似度必須高精度 |
總結
- 向量檢索是 RAG 流程的關鍵,選對向量庫能顯著提升系統的回應速度與召回品質。
- FAISS、Pinecone、Weaviate、Qdrant 各有優勢:FAISS 適合本機快速驗證;Pinecone 提供雲端托管與自動擴容;Weaviate 結合圖形化 API 與結構化屬性;Qdrant 則在過濾彈性上最為突出。
- 使用 LangChain 的 抽象層,只要把
VectorStoreRetriever換成不同實作,即可在四種向量庫之間無縫切換,降低未來遷移成本。 - 請特別留意 向量維度、metadata 唯一性、索引參數 與 成本控制,這些常見陷阱如果不加以管理,會直接影響服務的穩定性與可擴展性。
透過本文提供的程式碼範例與最佳實踐,你現在應該能夠在 LangChain 中快速建立、測試並部署任意一種向量庫,讓你的應用具備即時、精準的知識檢索能力。祝開發順利,打造出更聰明的 AI 服務!