Integrazione di Milvus con gli agenti OpenAI: Guida passo-passo
Questo quaderno mostra come creare un agente che può interrogare Milvus usando il linguaggio naturale attraverso la chiamata di funzione. Combineremo il framework Agenti di OpenAI con le potenti capacità di ricerca vettoriale di Milvus per creare un'esperienza di ricerca piacevole.
Agenti OpenAI
L'SDK OpenAI Agents consente di costruire applicazioni di intelligenza artificiale agenziali in un pacchetto leggero e facile da usare, con pochissime astrazioni. Si tratta di un aggiornamento pronto per la produzione della loro precedente sperimentazione di agenti, Swarm. L'SDK Agents ha un insieme molto ridotto di primitive:
- Agenti, che sono LLM dotati di istruzioni e strumenti.
- Handoff, che consentono agli agenti di delegare ad altri agenti compiti specifici.
- Guardrail, che consentono di convalidare gli input agli agenti.
In combinazione con Python, queste primitive sono sufficientemente potenti per esprimere relazioni complesse tra strumenti e agenti e consentono di creare applicazioni reali senza una curva di apprendimento troppo ripida. Inoltre, l'SDK è dotato di un tracing integrato che consente di visualizzare e debuggare i flussi agenziali, nonché di valutarli e persino di mettere a punto i modelli per l'applicazione.
Milvus
Milvus è un database vettoriale open source ad alte prestazioni e altamente scalabile che funziona in modo efficiente in un'ampia gamma di ambienti, dal computer portatile ai sistemi distribuiti su larga scala. È disponibile sia come software open-source che come offerta cloud.
Configurazione e dipendenze
Per prima cosa, dobbiamo configurare il nostro ambiente con le librerie necessarie e inizializzare asyncio per la compatibilità con Jupyter.
$ pip install openai pymilvus pydantic nest_asyncio
Se si utilizza Google Colab, per abilitare le dipendenze appena installate, potrebbe essere necessario riavviare il runtime (fare clic sul menu "Runtime" nella parte superiore dello schermo e selezionare "Restart session" dal menu a discesa).
import asyncio
import nest_asyncio
from dotenv import load_dotenv
load_dotenv()
nest_asyncio.apply()
Utilizzeremo i modelli di OpenAI. È necessario preparare la chiave api OPENAI_API_KEY come variabile d'ambiente.
import os
os.environ["OPENAI_API_KEY"] = "sk-***********"
Connessione a Milvus e creazione di uno schema
Ora ci colleghiamo alla nostra istanza di Milvus e creiamo uno schema per la nostra collezione. Questo schema definirà la struttura dei nostri dati, tra cui:
- Un campo ID come chiave primaria
- Un campo di testo per memorizzare il contenuto del documento
- Un campo vettoriale rado per memorizzare le incorporazioni BM25.
Ricerca a tutto testo in Milvus 2.5
- Sistema unificato per la ricerca vettoriale e per parole chiave (API unificate)
- Algoritmo sparse-BM25 incorporato (simile all'uso di Elasticsearch, ma basato su vettori)
- Non è necessario generare manualmente gli embeddings per la ricerca per parole chiave

Installare Milvus con Docker
Prima di eseguire questo esempio, assicuratevi di installare Milvus e di avviarlo con Docker; date un'occhiata alla nostra documentazione - 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}
Impostazione di BM25 per la ricerca full-text
Milvus supporta la ricerca full-text attraverso le funzioni di BM25. Qui definiamo una funzione che convertirà automaticamente i nostri dati testuali in rappresentazioni vettoriali rade ottimizzate per la ricerca testuale.
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': {}}]}
Creare la raccolta e caricare i dati di esempio
Ora creeremo la nostra collezione con i parametri dello schema e dell'indice, quindi caricheremo alcuni dati di esempio sul reperimento delle informazioni e su 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}
Definire i tipi di output per i risultati strutturati
Per rendere i risultati della ricerca più strutturati e più facili da utilizzare, definiremo i modelli Pydantic che specificano il formato dei risultati della ricerca.
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
Creare uno strumento di ricerca personalizzato
Successivamente, creeremo uno strumento funzionale personalizzato che il nostro agente potrà usare per cercare nel database di Milvus. Questo strumento
- Accetta il nome di una collezione, il testo della query e un parametro di limite.
- Eseguire una ricerca BM25 sulla collezione Milvus.
- restituire i risultati in un formato strutturato
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)}"
Creare l'agente
Ora creeremo un agente in grado di utilizzare il nostro strumento di ricerca. Gli daremo istruzioni su come gestire le richieste di ricerca e specificheremo che deve restituire i risultati nel nostro formato strutturato.
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.