整合 Milvus 文字嵌入功能與 LangChain

Open In Colab GitHub Repository

本指南示範如何使用 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 伺服器正在執行,且已啟用嵌入功能。您可以使用DockerKubernetes 部署 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 呼叫用戶端直接呼叫嵌入 APIMilvus 伺服器呼叫嵌入式 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}

結合語意搜尋 (文字嵌入) 與關鍵字搜尋 (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為您提供強大的向量搜尋功能。