milvus-logo
LFAI
Home
  • Integrationen

Milvus Hybrid Search Retriever

Überblick

Milvus ist eine Open-Source-Vektordatenbank, die für die Einbettung von Ähnlichkeitssuche und KI-Anwendungen entwickelt wurde. Milvus macht die Suche nach unstrukturierten Daten zugänglicher und bietet eine konsistente Benutzererfahrung unabhängig von der Einsatzumgebung.

Dies wird Ihnen den Einstieg in die Milvus Hybrid Search erleichtern, die die Stärken der dichten und spärlichen Vektorsuche kombiniert. Eine detaillierte Dokumentation aller MilvusCollectionHybridSearchRetriever Funktionen und Konfigurationen finden Sie in der API-Referenz.

Siehe auch die Milvus Multi-Vector Search Dokumentation.

Einzelheiten zur Integration

RetrieverSelbst gehostetCloud-AngebotPaket
MilvusCollectionHybridSearchRetrieverlangchain_milvus

einrichten.

Wenn Sie eine automatische Nachverfolgung von einzelnen Abfragen wünschen, können Sie auch Ihren LangSmith API-Schlüssel setzen, indem Sie unten den Kommentar entfernen:

# os.environ["LANGSMITH_API_KEY"] = getpass.getpass("Enter your LangSmith API key: ")
# os.environ["LANGSMITH_TRACING"] = "true"

Installation

Dieser Retriever befindet sich in dem Paket langchain-milvus. Für diese Anleitung sind die folgenden Abhängigkeiten erforderlich:

%pip install --upgrade --quiet pymilvus[model] langchain-milvus langchain-openai
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_milvus.retrievers import MilvusCollectionHybridSearchRetriever
from langchain_milvus.utils.sparse import BM25SparseEmbedding
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from pymilvus import (
    Collection,
    CollectionSchema,
    DataType,
    FieldSchema,
    WeightedRanker,
    connections,
)

Starten Sie den Milvus-Dienst

Bitte lesen Sie in der Milvus-Dokumentation nach, wie Sie den Milvus-Dienst starten.

Nach dem Start von Milvus müssen Sie Ihre Milvus-Verbindungs-URI angeben.

CONNECTION_URI = "http://localhost:19530"

OpenAI API-Schlüssel vorbereiten

Bitte lesen Sie in der OpenAI-Dokumentation nach, um Ihren OpenAI-API-Schlüssel zu erhalten, und setzen Sie ihn als Umgebungsvariable.

export OPENAI_API_KEY=<your_api_key>

Vorbereiten der dichten und spärlichen Einbettungsfunktionen

Lassen Sie uns 10 gefälschte Beschreibungen von Romanen fiktiv darstellen. In der tatsächlichen Produktion kann das eine große Menge an Textdaten sein.

texts = [
    "In 'The Whispering Walls' by Ava Moreno, a young journalist named Sophia uncovers a decades-old conspiracy hidden within the crumbling walls of an ancient mansion, where the whispers of the past threaten to destroy her own sanity.",
    "In 'The Last Refuge' by Ethan Blackwood, a group of survivors must band together to escape a post-apocalyptic wasteland, where the last remnants of humanity cling to life in a desperate bid for survival.",
    "In 'The Memory Thief' by Lila Rose, a charismatic thief with the ability to steal and manipulate memories is hired by a mysterious client to pull off a daring heist, but soon finds themselves trapped in a web of deceit and betrayal.",
    "In 'The City of Echoes' by Julian Saint Clair, a brilliant detective must navigate a labyrinthine metropolis where time is currency, and the rich can live forever, but at a terrible cost to the poor.",
    "In 'The Starlight Serenade' by Ruby Flynn, a shy astronomer discovers a mysterious melody emanating from a distant star, which leads her on a journey to uncover the secrets of the universe and her own heart.",
    "In 'The Shadow Weaver' by Piper Redding, a young orphan discovers she has the ability to weave powerful illusions, but soon finds herself at the center of a deadly game of cat and mouse between rival factions vying for control of the mystical arts.",
    "In 'The Lost Expedition' by Caspian Grey, a team of explorers ventures into the heart of the Amazon rainforest in search of a lost city, but soon finds themselves hunted by a ruthless treasure hunter and the treacherous jungle itself.",
    "In 'The Clockwork Kingdom' by Augusta Wynter, a brilliant inventor discovers a hidden world of clockwork machines and ancient magic, where a rebellion is brewing against the tyrannical ruler of the land.",
    "In 'The Phantom Pilgrim' by Rowan Welles, a charismatic smuggler is hired by a mysterious organization to transport a valuable artifact across a war-torn continent, but soon finds themselves pursued by deadly assassins and rival factions.",
    "In 'The Dreamwalker's Journey' by Lyra Snow, a young dreamwalker discovers she has the ability to enter people's dreams, but soon finds herself trapped in a surreal world of nightmares and illusions, where the boundaries between reality and fantasy blur.",
]

Wir werden OpenAI Embedding verwenden, um dichte Vektoren zu erzeugen, und den BM25-Algorithmus, um spärliche Vektoren zu erzeugen.

Initialisierung der dichten Einbettungsfunktion und Ermittlung der Dimension

dense_embedding_func = OpenAIEmbeddings()
dense_dim = len(dense_embedding_func.embed_query(texts[1]))
dense_dim
1536

Initialisierung der Sparse-Embedding-Funktion.

Beachten Sie, dass die Ausgabe der Sparse Embedding-Funktion eine Menge von Sparse-Vektoren ist, die den Index und das Gewicht der Schlüsselwörter des Eingabetextes darstellen.

sparse_embedding_func = BM25SparseEmbedding(corpus=texts)
sparse_embedding_func.embed_query(texts[1])
{0: 0.4270424944042204,
 21: 1.845826690498331,
 22: 1.845826690498331,
 23: 1.845826690498331,
 24: 1.845826690498331,
 25: 1.845826690498331,
 26: 1.845826690498331,
 27: 1.2237754316221157,
 28: 1.845826690498331,
 29: 1.845826690498331,
 30: 1.845826690498331,
 31: 1.845826690498331,
 32: 1.845826690498331,
 33: 1.845826690498331,
 34: 1.845826690498331,
 35: 1.845826690498331,
 36: 1.845826690498331,
 37: 1.845826690498331,
 38: 1.845826690498331,
 39: 1.845826690498331}

Erstellen der Milvus-Sammlung und Laden der Daten

Initialisieren der Verbindungs-URI und Herstellen der Verbindung

connections.connect(uri=CONNECTION_URI)

Definieren von Feldnamen und deren Datentypen

pk_field = "doc_id"
dense_field = "dense_vector"
sparse_field = "sparse_vector"
text_field = "text"
fields = [
    FieldSchema(
        name=pk_field,
        dtype=DataType.VARCHAR,
        is_primary=True,
        auto_id=True,
        max_length=100,
    ),
    FieldSchema(name=dense_field, dtype=DataType.FLOAT_VECTOR, dim=dense_dim),
    FieldSchema(name=sparse_field, dtype=DataType.SPARSE_FLOAT_VECTOR),
    FieldSchema(name=text_field, dtype=DataType.VARCHAR, max_length=65_535),
]

Erstellen einer Sammlung mit dem definierten Schema

schema = CollectionSchema(fields=fields, enable_dynamic_field=False)
collection = Collection(
    name="IntroductionToTheNovels", schema=schema, consistency_level="Strong"
)

Definieren des Index für dichte und spärliche Vektoren

dense_index = {"index_type": "FLAT", "metric_type": "IP"}
collection.create_index("dense_vector", dense_index)
sparse_index = {"index_type": "SPARSE_INVERTED_INDEX", "metric_type": "IP"}
collection.create_index("sparse_vector", sparse_index)
collection.flush()

Einfügen von Entitäten in die Sammlung und Laden der Sammlung

entities = []
for text in texts:
    entity = {
        dense_field: dense_embedding_func.embed_documents([text])[0],
        sparse_field: sparse_embedding_func.embed_documents([text])[0],
        text_field: text,
    }
    entities.append(entity)
collection.insert(entities)
collection.load()

Instanziierung

Nun können wir unseren Retriever instanziieren, indem wir Suchparameter für sparse und dense Felder definieren:

sparse_search_params = {"metric_type": "IP"}
dense_search_params = {"metric_type": "IP", "params": {}}
retriever = MilvusCollectionHybridSearchRetriever(
    collection=collection,
    rerank=WeightedRanker(0.5, 0.5),
    anns_fields=[dense_field, sparse_field],
    field_embeddings=[dense_embedding_func, sparse_embedding_func],
    field_search_params=[dense_search_params, sparse_search_params],
    top_k=3,
    text_field=text_field,
)

In den Eingabeparametern dieses Retrievers verwenden wir eine dichte Einbettung und eine spärliche Einbettung, um eine hybride Suche in den beiden Feldern dieser Sammlung durchzuführen, und verwenden WeightedRanker für das Reranking. Schließlich werden 3 Top-K Dokumente zurückgegeben.

Verwendung

retriever.invoke("What are the story about ventures?")
[Document(page_content="In 'The Lost Expedition' by Caspian Grey, a team of explorers ventures into the heart of the Amazon rainforest in search of a lost city, but soon finds themselves hunted by a ruthless treasure hunter and the treacherous jungle itself.", metadata={'doc_id': '449281835035545843'}),
 Document(page_content="In 'The Phantom Pilgrim' by Rowan Welles, a charismatic smuggler is hired by a mysterious organization to transport a valuable artifact across a war-torn continent, but soon finds themselves pursued by deadly assassins and rival factions.", metadata={'doc_id': '449281835035545845'}),
 Document(page_content="In 'The Dreamwalker's Journey' by Lyra Snow, a young dreamwalker discovers she has the ability to enter people's dreams, but soon finds herself trapped in a surreal world of nightmares and illusions, where the boundaries between reality and fantasy blur.", metadata={'doc_id': '449281835035545846'})]

Verwendung innerhalb einer Kette

Initialisieren Sie ChatOpenAI und definieren Sie eine Eingabeaufforderungsvorlage

llm = ChatOpenAI()

PROMPT_TEMPLATE = """
Human: You are an AI assistant, and provides answers to questions by using fact based and statistical information when possible.
Use the following pieces of information to provide a concise answer to the question enclosed in <question> tags.

<context>
{context}
</context>

<question>
{question}
</question>

Assistant:"""

prompt = PromptTemplate(
    template=PROMPT_TEMPLATE, input_variables=["context", "question"]
)

Definieren Sie eine Funktion zur Formatierung von Dokumenten

def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

Definieren Sie eine Kette mit dem Retriever und anderen Komponenten

rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

Führen Sie eine Abfrage unter Verwendung der definierten Kette durch

rag_chain.invoke("What novels has Lila written and what are their contents?")
"Lila Rose has written 'The Memory Thief,' which follows a charismatic thief with the ability to steal and manipulate memories as they navigate a daring heist and a web of deceit and betrayal."

Verwerfen der Sammlung

collection.drop()

API-Referenz

Eine ausführliche Dokumentation aller Funktionen und Konfigurationen von MilvusCollectionHybridSearchRetriever finden Sie in der API-Referenz.

Übersetzt vonDeepL

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

War diese Seite hilfreich?