整合 Milvus 文字嵌入功能與 LangChain
本指南示範如何使用 Milvus 2.6 的文字嵌入功能(也稱為 Data In Data Out)與 LangChain。此功能可讓 Milvus 伺服器自動將原始文字轉換成向量嵌入,簡化客戶端程式碼並集中管理 API 金鑰。
Milvus是全球最先進的開放原始碼向量資料庫,專門為支援嵌入相似性搜尋和人工智能應用程式而打造。LangChain是由大型語言模型 (LLM) 驅動的應用程式開發框架。透過整合 Milvus 的文字嵌入功能,您可以在 LangChain 應用程式中實現更簡單、更有效率的向量搜尋解決方案。
先決條件
執行本教學之前,請確認已經安裝下列相依性:
! pip install --upgrade langchain-milvus langchain-core langchain-openai
如果您使用的是 Google Colab,為了啟用剛安裝的相依性,您可能需要重新啟動運行時(點擊螢幕上方的 "Runtime 「菜單,從下拉菜單中選擇 」Restart session")。
配置 Milvus 伺服器
重要:文字嵌入功能(資料進入資料輸出)功能僅在Milvus Server 中可用。Milvus Lite 不支援此功能。您需要使用以 Docker/Kubernetes 部署的 Milvus 伺服器。
在使用文字嵌入功能之前,您需要在 Milvus 伺服器上設定嵌入服務供應商的憑證。
在 credential 下方宣告您的金鑰:
您可以列出一個或多個 API 金鑰 - 給每個金鑰一個您發明的標籤,稍後會參考。
# milvus.yaml
credential:
apikey_dev:
apikey: <YOUR_OPENAI_API_KEY>
告訴 Milvus 哪個金鑰用於 OpenAI 的呼叫
在同一個檔案中,將 OpenAI 提供者指向您希望它使用的標籤。
function:
textEmbedding:
providers:
openai:
credential: apikey_dev
# url: https://api.openai.com/v1/embeddings # (optional) custom url
更多設定方法,請參考Milvus Embedding Function 文件。
啟動 Milvus 服務
確保 Milvus 伺服器正在執行,且已啟用嵌入功能。您可以使用Docker或Kubernetes 部署 Milvus 伺服器。注意:Milvus Lite 不支援文字嵌入功能。
瞭解嵌入:客戶端 vs 伺服器端
在深入瞭解使用方式之前,讓我們先了解兩種嵌入方式的差異。
使用 LangChain 的Embeddings class 嵌入 (用戶端)
在傳統的 LangChain 方法中,嵌入的產生是在客戶端使用Embeddings class。您的應用程式需要使用該類的embed_query 方法來呼叫嵌入 API,然後將產生的向量存入 Milvus。
from langchain_openai import OpenAIEmbeddings
from langchain_milvus import Milvus
# Generate embedding on client side
embeddings = OpenAIEmbeddings()
vector = embeddings.embed_query("Hello, world!")
# [0.123, -0.456, ...] A vector of floats
vector_store = Milvus(
embedding_function=embeddings,
connection_args={"uri": "http://localhost:19530"},
collection_name="traditional_approach_collection",
)
序列圖:
特性:
- 用戶端直接呼叫嵌入式 API
- 需要在客戶端管理 API 金鑰
- 資料流程:文字 → 客戶端 → 嵌入 API → 向量 → Milvus
Milvus 文字嵌入功能 (伺服器端資料輸入資料輸出)
Milvus 2.6 的文字嵌入功能 (Data In Data Out) 可讓 Milvus 伺服器自動將原始文字轉換成向量嵌入。客戶端只需要提供文字,Milvus 就會自動處理嵌入的產生。
序列圖:
特性:
- Milvus 伺服器呼叫嵌入式 API
- API 金鑰由伺服器端集中管理
- 資料流程:文字 → Milvus → 嵌入式 API → 向量(儲存在 Milvus 中)
兩種方法的比較
| 特徵 | LangChain 嵌入 (用戶端) | Milvus 文字嵌入功能 (伺服器端) |
|---|---|---|
| 處理位置 | 用戶端應用程式 | Milvus 伺服器 |
| API 呼叫 | 用戶端直接呼叫嵌入 API | Milvus 伺服器呼叫嵌入式 API |
| API 金鑰管理 | 需要在客戶端管理 | 在伺服器端集中管理,更安全 |
| 程式碼複雜性 | 需要在客戶端管理 API 金鑰和呼叫 | 只需要在Milvus配置一次 |
| 使用案例 | - 需要用戶端控制嵌入過程 - 需要在客戶端快取嵌入結果 - 需要支援多種嵌入模型切換 | - 簡化客戶端程式碼 - 在伺服器端集中管理 API 金鑰 - 需要批量處理大量文件 - 希望減少客戶端與外部 API 的互動 - 需要結合 Milvus 內建功能,如 BM25 |
| Milvus 版本要求 | 所有版本(包括 Milvus Lite) | 不支援 Milvus Lite |
本教學主要介紹 Milvus 伺服器端 Text Embedding Function (Data In Data Out) 方法,這是 Milvus 2.6 推出的新功能,可以大幅簡化客戶端程式碼並提高安全性。
使用文字嵌入功能
範例 1:僅在伺服器端嵌入
這是最簡單的使用案例,完全依賴 Milvus 伺服器產生嵌入。客戶端不需要任何嵌入功能。
from langchain_milvus import Milvus
from langchain_milvus.function import TextEmbeddingBuiltInFunction
from langchain_core.documents import Document
# Create Text Embedding Function
text_embedding_func = TextEmbeddingBuiltInFunction(
input_field_names="text", # Input field name (field containing text)
output_field_names="vector", # Output field name (field storing vectors)
dim=1536, # Vector dimension (must specify)
params={
"provider": "openai", # Service provider
"model_name": "text-embedding-3-small", # Model name
"credential": "apikey_dev", # Optional: use credential label configured in milvus.yaml
},
)
# Create Milvus vector store
# Note: embedding_function=None, because embedding is done on server side
vector_store = Milvus(
embedding_function=None, # Do not use client-side embedding
builtin_function=text_embedding_func,
connection_args={"uri": "http://localhost:19530"},
collection_name="my_collection",
# consistency_level="Strong", # Strong consistency level, default is "Session"
auto_id=True,
# drop_old=True, # If you want to drop old collection and create a new one
)
對於connection_args :
- 必須使用 Milvus 伺服器:文字嵌入功能功能只在 Milvus 伺服器上提供,不支援 Milvus Lite。
- 使用伺服器 uri,例如
http://localhost:19530(本地 Docker 部署) 或http://your-server:19530(遠端伺服器)。 - 如果使用Zilliz Cloud,請使用 Public Endpoint 作為
uri,並設定token參數。
新增文件時,您只需要提供文字,不需要預先計算向量。Milvus 會自動呼叫 OpenAI API 來產生 embeddings。
# Add documents (only need to provide text, no need to pre-compute vectors)
documents = [
Document(page_content="Milvus simplifies semantic search through embeddings."),
Document(
page_content="Vector embeddings convert text into searchable numeric data."
),
Document(
page_content="Semantic search helps users find relevant information quickly."
),
]
vector_store.add_documents(documents)
[462726375729313252, 462726375729313253, 462726375729313254]
搜尋時,直接使用文字查詢,Milvus 會自動將查詢文字轉換成向量進行搜尋。
# Search (directly use text query)
results = vector_store.similarity_search(
query="How does Milvus handle semantic search?", k=2
)
for doc in results:
print(f"Content: {doc.page_content}")
print(f"Metadata: {doc.metadata}\n")
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1765186679.227345 12227536 fork_posix.cc:71] Other threads are currently calling into gRPC, skipping fork() handlers
Content: Milvus simplifies semantic search through embeddings.
Metadata: {'pk': 462726375729313252}
Content: Semantic search helps users find relevant information quickly.
Metadata: {'pk': 462726375729313254}
範例 2:結合文字嵌入與 BM25 (混合搜尋)
結合語意搜尋 (文字嵌入) 與關鍵字搜尋 (BM25) 可實現更強大的混合搜尋功能。語意搜尋擅長於理解查詢意圖,而關鍵字搜尋則擅長於精確匹配。
from langchain_milvus import Milvus
from langchain_milvus.function import TextEmbeddingBuiltInFunction, BM25BuiltInFunction
# Text Embedding Function (semantic search)
text_embedding_func = TextEmbeddingBuiltInFunction(
input_field_names="text",
output_field_names="vector_dense",
dim=1536,
params={
"provider": "openai",
"model_name": "text-embedding-3-small",
},
)
# BM25 Function (keyword search)
bm25_func = BM25BuiltInFunction(
input_field_names="text",
output_field_names="vector_sparse",
)
# Create Milvus vector store
vector_store = Milvus(
embedding_function=None,
builtin_function=[text_embedding_func, bm25_func],
connection_args={"uri": "http://localhost:19530"},
vector_field=["vector_dense", "vector_sparse"],
collection_name="hybrid_search_collection",
# consistency_level="Strong", # Strong consistency level, default is "Session"
auto_id=True,
# drop_old=True, # If you want to drop old collection and create a new one
)
# Add documents
documents = [
Document(page_content="Machine learning and artificial intelligence"),
Document(page_content="The cat sat on the mat"),
]
vector_store.add_documents(documents)
[462726375729313255, 462726375729313256]
使用WeightedRanker 來控制語意搜尋與關鍵字搜尋的權重。當密集權重較高時,結果會更偏向語意相似性;當稀疏權重較高時,結果會更偏向關鍵字匹配。
# Hybrid search, use WeightedRanker to control weights
# 70% semantic search, 30% keyword search
results = vector_store.similarity_search(
query="AI technology",
k=2,
ranker_type="weighted",
ranker_params={"weights": [0.7, 0.3]},
)
# If you want to be more biased towards keyword matching, you can adjust weights
# 30% semantic search, 70% keyword search
results_keyword_focused = vector_store.similarity_search(
query="cat mat",
k=2,
ranker_type="weighted",
ranker_params={"weights": [0.3, 0.7]},
)
results
[Document(metadata={'pk': 462726375729313255}, page_content='Machine learning and artificial intelligence'),
Document(metadata={'pk': 462726375729313256}, page_content='The cat sat on the mat')]
results_keyword_focused
[Document(metadata={'pk': 462726375729313256}, page_content='The cat sat on the mat'),
Document(metadata={'pk': 462726375729313255}, page_content='Machine learning and artificial intelligence')]
總結
恭喜您!您已學會如何在 LangChain 中使用 Milvus 的文字嵌入功能 (Data In Data Out)。透過將嵌入產生移至伺服器端,您可以簡化客戶端程式碼,集中管理 API 金鑰,並輕鬆實現混合搜尋。結合Text Embedding Function與BM25,Milvus為您提供強大的向量搜尋功能。