Milvus 與 OpenAI Agents 的整合:逐步指南
本手冊將介紹如何透過 Function Calling 建立一個可以使用自然語言查詢 Milvus 的 Agents。我們將結合 OpenAI 的 Agents 架構與 Milvus 強大的向量搜尋功能,創造出優質的搜尋體驗。
OpenAI Agents
OpenAI Agents SDK 可讓您以輕量、易用且抽象程度極低的套件,建立代理式 AI 應用程式。這是他們之前代理實驗 Swarm 的生產就緒升級版。Agents SDK 有一套非常小的基元:
- 代理 (Agents),也就是配備了指令與工具的 LLM。
- 交接 (Handoffs),可讓代理委派其他代理執行特定任務
- Guardrails (護欄),可讓代理的輸入得到驗證。
結合 Python,這些基元功能強大,足以表達工具與代理之間的複雜關係,讓您不需經過艱辛的學習就能建立真實世界的應用程式。此外,SDK 還內建追蹤功能,讓您可視化和除錯您的代理流程,以及評估它們,甚至針對您的應用程式微調模型。
Milvus
Milvus 是一個高效能、高度可擴充的開放原始碼向量資料庫,可在從筆記型電腦到大型分散式系統等各種環境中有效率地執行。它同時提供開放原始碼軟體與雲端服務。
設定與相依性
首先,我們需要使用必要的函式庫設定環境,並初始化 asyncio 以取得 Jupyter 的相容性。
$ pip install openai pymilvus pydantic nest_asyncio
如果您使用的是 Google Colab,為了啟用剛安裝的相依性,您可能需要重新啟動執行時(點選畫面頂端的「Runtime」功能表,並從下拉式功能表中選擇「Restart session」)。
import asyncio
import nest_asyncio
from dotenv import load_dotenv
load_dotenv()
nest_asyncio.apply()
我們將使用 OpenAI 的模型。您應該準備api key OPENAI_API_KEY 作為環境變數。
import os
os.environ["OPENAI_API_KEY"] = "sk-***********"
連接至 Milvus 並建立模式
現在我們將連線到 Milvus 實例,並為我們的集合建立一個模式。這個模式將定義我們的資料結構,包括
- 一個 ID 欄位作為主索引鍵
- 一個文字欄位來儲存我們的文件內容
- 儲存 BM25 內嵌的稀疏向量欄位
Milvus 2.5 中的全文檢索
- 向量與關鍵字搜尋的統一系統 (統一 API)
- 內建稀疏 BM25 演算法 (類似 Elasticsearch 的使用,但以向量為基礎)
- 不需要手動產生關鍵字搜尋的 embeddings

使用 Docker 安裝 Milvus
在執行本範例之前,請務必安裝 Milvus 並使用 Docker 啟動它,請參閱我們的說明文件 - https://milvus.io/docs/install_standalone-docker.md。
from pymilvus import DataType, FunctionType, MilvusClient
client = MilvusClient(uri="http://localhost:19530")
schema = client.create_schema()
# Simple schema that handles both text and vectors
schema.add_field(
field_name="id", datatype=DataType.INT64, is_primary=True, auto_id=True
)
schema.add_field(
field_name="text", datatype=DataType.VARCHAR, max_length=1000, enable_analyzer=True
)
schema.add_field(field_name="sparse", datatype=DataType.SPARSE_FLOAT_VECTOR)
{'auto_id': False, 'description': '', 'fields': [{'name': 'id', 'description': '', 'type': <DataType.INT64: 5>, 'is_primary': True, 'auto_id': True}, {'name': 'text', 'description': '', 'type': <DataType.VARCHAR: 21>, 'params': {'max_length': 1000, 'enable_analyzer': True}}, {'name': 'sparse', 'description': '', 'type': <DataType.SPARSE_FLOAT_VECTOR: 104>}], 'enable_dynamic_field': False}
為全文檢索設定 BM25
Milvus 透過 BM25 函式支援全文檢索。這裡我們定義了一個函數,它會自動將我們的文字資料轉換成最適合文字搜尋的稀疏向量表示。
from pymilvus import Function
# Milvus handles tokenization and BM25 conversion
bm25_function = Function(
name="text_bm25_emb", # Function name
input_field_names=["text"], # Name of the VARCHAR field containing raw text data
output_field_names=[
"sparse"
], # Name of the SPARSE_FLOAT_VECTOR field reserved to store generated embeddings
function_type=FunctionType.BM25,
)
schema.add_function(bm25_function)
{'auto_id': False, 'description': '', 'fields': [{'name': 'id', 'description': '', 'type': <DataType.INT64: 5>, 'is_primary': True, 'auto_id': True}, {'name': 'text', 'description': '', 'type': <DataType.VARCHAR: 21>, 'params': {'max_length': 1000, 'enable_analyzer': True}}, {'name': 'sparse', 'description': '', 'type': <DataType.SPARSE_FLOAT_VECTOR: 104>, 'is_function_output': True}], 'enable_dynamic_field': False, 'functions': [{'name': 'text_bm25_emb', 'description': '', 'type': <FunctionType.BM25: 1>, 'input_field_names': ['text'], 'output_field_names': ['sparse'], 'params': {}}]}
建立資料集並載入樣本資料
現在我們使用模式和索引參數建立集合,然後載入一些關於資訊檢索和 Milvus 的範例資料。
index_params = client.prepare_index_params()
index_params.add_index(field_name="sparse", index_type="AUTOINDEX", metric_type="BM25")
if client.has_collection("demo"):
client.drop_collection("demo")
client.create_collection(
collection_name="demo",
schema=schema,
index_params=index_params,
)
## 3. Loading Test Data
client.insert(
"demo",
[
{
"text": "Information retrieval helps users find relevant documents in large datasets."
},
{
"text": "Search engines use information retrieval techniques to index and rank web pages."
},
{
"text": "The core of IR is matching user queries with the most relevant content."
},
{
"text": "Vector search is revolutionising modern information retrieval systems."
},
{
"text": "Machine learning improves ranking algorithms in information retrieval."
},
{
"text": "IR techniques include keyword-based search, semantic search, and vector search."
},
{
"text": "Boolean retrieval is one of the earliest information retrieval methods."
},
{"text": "TF-IDF is a classic method used to score document relevance in IR."},
{
"text": "Modern IR systems integrate deep learning for better contextual understanding."
},
{
"text": "Milvus is an open-source vector database designed for AI-powered search."
},
{
"text": "Milvus enables fast and scalable similarity search on high-dimensional data."
},
{
"text": "With Milvus, developers can build applications that support image, text, and video retrieval."
},
{
"text": "Milvus integrates well with deep learning frameworks like PyTorch and TensorFlow."
},
{
"text": "The core of Milvus is optimised for approximate nearest neighbour (ANN) search."
},
{
"text": "Milvus supports hybrid search combining structured and unstructured data."
},
{
"text": "Large-scale AI applications rely on Milvus for efficient vector retrieval."
},
{"text": "Milvus makes it easy to perform high-speed similarity searches."},
{"text": "Cloud-native by design, Milvus scales effortlessly with demand."},
{
"text": "Milvus powers applications in recommendation systems, fraud detection, and genomics."
},
{
"text": "The latest version of Milvus introduces faster indexing and lower latency."
},
{"text": "Milvus supports HNSW, IVF_FLAT, and other popular ANN algorithms."},
{
"text": "Vector embeddings from models like OpenAI’s CLIP can be indexed in Milvus."
},
{
"text": "Milvus has built-in support for multi-tenancy in enterprise use cases."
},
{
"text": "The Milvus community actively contributes to improving its performance."
},
{
"text": "Milvus integrates with data pipelines like Apache Kafka for real-time updates."
},
{
"text": "Using Milvus, companies can enhance search experiences with vector search."
},
{
"text": "Milvus plays a crucial role in powering AI search in medical research."
},
{"text": "Milvus integrates with LangChain for advanced RAG pipelines."},
{
"text": "Open-source contributors continue to enhance Milvus’ search performance."
},
{
"text": "Multi-modal search in Milvus enables applications beyond text and images."
},
{"text": "Milvus has an intuitive REST API for easy integration."},
{"text": "Milvus’ FAISS and HNSW backends provide flexibility in indexing."},
{
"text": "The architecture of Milvus ensures fault tolerance and high availability."
},
{"text": "Milvus integrates seamlessly with LLM-based applications."},
{"text": "Startups leverage Milvus to build next-gen AI-powered products."},
{"text": "Milvus Cloud offers a managed solution for vector search at scale."},
{
"text": "The future of AI search is being shaped by Milvus and similar vector databases."
},
],
)
{'insert_count': 37, 'ids': [456486814660619140, 456486814660619141, 456486814660619142, 456486814660619143, 456486814660619144, 456486814660619145, 456486814660619146, 456486814660619147, 456486814660619148, 456486814660619149, 456486814660619150, 456486814660619151, 456486814660619152, 456486814660619153, 456486814660619154, 456486814660619155, 456486814660619156, 456486814660619157, 456486814660619158, 456486814660619159, 456486814660619160, 456486814660619161, 456486814660619162, 456486814660619163, 456486814660619164, 456486814660619165, 456486814660619166, 456486814660619167, 456486814660619168, 456486814660619169, 456486814660619170, 456486814660619171, 456486814660619172, 456486814660619173, 456486814660619174, 456486814660619175, 456486814660619176], 'cost': 0}
定義結構化結果的輸出類型
為了讓我們的搜尋結果更有條理且更容易使用,我們將定義 Pydantic 模型,指定搜尋結果的格式。
from pydantic import BaseModel
# Simplified output model for search results
class MilvusSearchResult(BaseModel):
id: int
text: str
class MilvusSearchResults(BaseModel):
results: list[MilvusSearchResult]
query: str
建立自訂搜尋工具
接下來,我們將建立一個自訂功能工具,讓我們的代理可用來搜尋 Milvus 資料庫。這個工具將會
- 接受集合名稱、查詢文字和限制參數
- 針對 Milvus 資料庫執行 BM25 搜尋
- 以結構化格式傳回結果
import json
from typing import Any
from pymilvus import MilvusClient
from agents import function_tool, RunContextWrapper
@function_tool
async def search_milvus_text(
ctx: RunContextWrapper[Any], collection_name: str, query_text: str, limit: int
) -> str:
"""Search for text documents in a Milvus collection using full text search.
Args:
collection_name: Name of the Milvus collection to search.
query_text: The text query to search for.
limit: Maximum number of results to return.
"""
try:
# Initialize Milvus client
client = MilvusClient()
# Prepare search parameters for BM25
search_params = {"metric_type": "BM25", "params": {"drop_ratio_search": 0.2}}
# Execute search with text query
results = client.search(
collection_name=collection_name,
data=[query_text],
anns_field="sparse",
limit=limit,
search_params=search_params,
output_fields=["text"],
)
return json.dumps(
{"results": results, "query": query_text, "collection": collection_name}
)
except Exception as e:
print(f"Exception is: {e}")
return f"Error searching Milvus: {str(e)}"
建立代理程式
現在我們要建立一個可以使用搜尋工具的代理程式。我們將指示它如何處理搜尋要求,並指定它應該以我們的結構化格式傳回結果。
from agents import Agent, Runner, WebSearchTool, trace
async def main():
agent = Agent(
name="Milvus Searcher",
instructions="""
You are a helpful agent that can search through Milvus vector database using full text search. Return the results in a structured format.
""",
tools=[
WebSearchTool(user_location={"type": "approximate", "city": "New York"}),
search_milvus_text,
],
output_type=MilvusSearchResults,
)
with trace("Milvus search example"):
result = await Runner.run(
agent,
"Find documents in the 'demo' collection that are similar to this concept: 'information retrieval'",
)
# print(result.final_output.results)
formatted_results = "\n".join(
f"{i+1}. ID: {res.id}, Text: {res.text}"
for i, res in enumerate(result.final_output.results)
)
print(f"Search results:\n{formatted_results}")
asyncio.run(main())
Search results:
1. ID: 456486814660619146, Text: Boolean retrieval is one of the earliest information retrieval methods.
2. ID: 456486814660619144, Text: Machine learning improves ranking algorithms in information retrieval.
3. ID: 456486814660619143, Text: Vector search is revolutionising modern information retrieval systems.
4. ID: 456486814660619140, Text: Information retrieval helps users find relevant documents in large datasets.
5. ID: 456486814660619141, Text: Search engines use information retrieval techniques to index and rank web pages.