本文 AI 產出,尚未審核

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,只要實作 addDocumentssimilaritySearch 兩個核心方法,就能與任何支援的向量庫整合。這意味著:

  • 程式碼幾乎不需要改動,只要換掉 FAISS.from_documentsPinecone.from_documents 即可。
  • 可同時使用多個向量庫,例如先在本機的 FAISS 做快速原型,之後再遷移至雲端的 Pinecone 以支援大規模查詢。

3. 四大向量庫概覽

向量庫 部署方式 特色 適合情境
FAISS 本機 / Docker 高效的相似度搜尋演算法(Flat、IVF、HNSW) 開發階段、資料量 ≤ 百萬
Pinecone 雲端服務(SaaS) 完全托管、即時擴容、內建過期策略 大規模商業應用、需要 SLA
Weaviate 本機、K8s、雲端 支援 GraphQL / REST、內建向量化模型、可加入結構化屬性 多模態搜尋、混合向量+屬性查詢
Qdrant 本機、Docker、K8s 支援 filterpayload,向量距離可自訂 需要高彈性過濾條件的應用

下面分別示範如何在 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 完全在本機運算,適合開發測試或資料量不大時使用。若資料量超過數十萬,建議改用 IVFHNSW 索引以提升效能。

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 的唯一鍵 同一筆文件會重複寫入,導致搜尋結果重複 Documentmetadata 中加入唯一 id,或使用向量庫的 upsert 功能
過度依賴單一向量庫 雲端服務斷線或本機資源不足時系統失效 透過 抽象層(LangChain Retriever)保持可切換性,甚至同時佈署兩個向量庫作備援
忘記設定索引參數(如 metricefConstruction 查詢速度慢或召回率低 依資料規模選擇合適的索引類型(FAISS IVF、Pinecone metric='cosine'、Qdrant hnsw_config
不考慮向量庫成本 雲端服務費用激增 先在本機的 FAISS 完成驗證,僅在正式上線時遷移至 Pinecone / Qdrant,並設定 TTL分層儲存

其他實用技巧

  1. 批次寫入:一次寫入大量文件會減少 API 呼叫次數,提升效能。LangChain 的 addDocuments 支援 batchSize 參數。
  2. 向量正規化:若使用 cosine 相似度,建議在嵌入完成後自行正規化向量,以避免不同模型產生的尺度差異。
  3. 多模態向量:Weaviate 與 Qdrant 均支援圖像、音訊向量,可將文字、圖像一起儲存於同一 collection,實現跨模態檢索。

實際應用場景

場景 使用向量庫 為何選擇
客服機器人 Pinecone 高可用、即時擴容,且支援向量過期(舊 FAQ 自動刪除)
內部文件搜尋 FAISS(開發) → Qdrant(正式) 初期快速原型 → 正式上線後需要複雜過濾(部門、機密等)
電商商品推薦 Weaviate 同時利用商品描述向量 + 結構化屬性(價格、庫存)做混合排序
醫療文獻檢索 Qdrant 需要依發表日期、關鍵字做嚴格過濾,且向量相似度必須高精度

總結

  • 向量檢索是 RAG 流程的關鍵,選對向量庫能顯著提升系統的回應速度與召回品質。
  • FAISS、Pinecone、Weaviate、Qdrant 各有優勢:FAISS 適合本機快速驗證;Pinecone 提供雲端托管與自動擴容;Weaviate 結合圖形化 API 與結構化屬性;Qdrant 則在過濾彈性上最為突出。
  • 使用 LangChain 的 抽象層,只要把 VectorStoreRetriever 換成不同實作,即可在四種向量庫之間無縫切換,降低未來遷移成本。
  • 請特別留意 向量維度、metadata 唯一性、索引參數成本控制,這些常見陷阱如果不加以管理,會直接影響服務的穩定性與可擴展性。

透過本文提供的程式碼範例與最佳實踐,你現在應該能夠在 LangChain 中快速建立、測試並部署任意一種向量庫,讓你的應用具備即時、精準的知識檢索能力。祝開發順利,打造出更聰明的 AI 服務!