Startseite / Artikel / Praktische Hinweise: Wie Qdrant die Kosten für RAG-Token um 67 % mit dem eingebetteten ColBERT senkte

Praktische Hinweise: Wie Qdrant die Kosten für RAG-Token um 67 % mit dem eingebetteten ColBERT senkte

Schritt-für-Schritt-Anleitung zu den Praktischen Hinweisen: Wie Qdrant die Kosten für RAG-Token um 67 % mit Native ColBERT senkte – Verträge, Überprüfungen sowie Code-Blöcke für Teams, die dieses Muster einsetzen.

1929 Wörter

Die folgenden Notizen skizzieren einen praktischen Ansatz zu dem Thema „Wie Qdrant die Kosten für RAG-Token um 67 % mit Native ColBERT Reranking senkte“. Der Fokus liegt auf Verträgen, Überprüfungen und Code-Platzhaltern statt auf motivierenden Formulierungen. Während der Überblicksphase sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsindikatoren sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Dokumentieren Sie sowohl den erfolgreichen Ablauf als auch den Fehlerbehebungsprozess gemeinsam. Wiederholte Versuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen.

Die Seite, die wir nicht benötigen

Die von uns genutzte Seite funktioniert am besten, wenn sie als messbare Oberfläche betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs einen erfolgreichen Fall, einen Fehlerfall sowie die Notizen zur Rücksetzung. Ziehen Sie kleine, testbare Einheiten vor umfangreichen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufverfahren. Legen Sie Budgetgrenzen pro Turnus und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext stark; feste Obergrenzen verhindern, dass Demonstrationen zu unerwarteten Rechnungen werden.

Warum Qdrant gegenüber allen anderen?

Die Phase „Warum Qdrant gegenüber allen anderen?“ funktioniert am besten, wenn sie als messbare Ebene betrachtet wird. Erfassen Sie ein Beispiel für einen erfolgreichen Ablauf, einen Fall von Versagen sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Ergebnisdokumente, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Legen Sie Budgets für Tokens pro Runde und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext oft übermäßig; feste Obergrenzen verhindern, dass Demonstrationen zu unerwarteten Rechnungen werden.

Was wir tatsächlich bauen

Die Phase „What We Are Actually“ funktioniert am besten, wenn sie als messbare Ebene betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Erfassen Sie außerdem die Laufzeiten sowie die Kosten für Tokens oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn sich der Prozess von einer Demo in gemeinsam genutzte Umgebungen verschiebt. Legen Sie Budgets für Tokens pro Runde und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext stark – feste Obergrenzen verhindern, dass Demos zu unerwarteten Rechnungen werden. Die Phase „What We Are Actually“ funktioniert am besten, wenn sie als messbare Ebene betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Dokumentieren Sie den erfolgreichen Ablauf sowie den Wiederherstellungsprozess gemeinsam. Wiederholversuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt und nicht zu späteren Optimierungen.

Zusammenfassung der Kosten- und Leistungsvergleiche

In der Phase des Zusammenfassens der Kosteneffizienz-Benchmarks sollten die Eingabedaten, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Es sind kleinere, testbare Einheiten vorzuziehen statt umfangreicher Skripte. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufschema. Bei dem nächsten Schritt, der aus Code oder einem Toolaufruf besteht, sind strukturierte Ausgaben mit Schema-Validierung vor freiformiger Prosa zu bevorzugen.

Einrichten des Sammlungsschemas

Zur Phase des Aufbaus der Sammlung sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Wählen Sie bei dem nächsten Schritt, der Code oder ein Toolaufruf ist, strukturierte Ausgaben mit Schema-Validierung vor freien Texten.

from qdrant_client import QdrantClient, models
# ADDED: Load FastEmbed models locally on CPU
from fastembed import TextEmbedding, LateInteractionTextEmbedding
COLLECTION_NAME = "legal_discovery"
DENSE_DIM = 384  # BAAI/bge-small-en-v1.5
COLBERT_DIM = 128  # colbert-ir/colbertv2.0
# ADDED: Instantiate the vector models
dense_model = TextEmbedding("BAAI/bge-small-en-v1.5")
colbert_model = LateInteractionTextEmbedding("colbert-ir/colbertv2.0")
client = QdrantClient("<http://localhost:6333>")
client.create_collection(
    collection_name=COLLECTION_NAME,
    vectors_config={
        "dense": models.VectorParams(
            size=DENSE_DIM,
            distance=models.Distance.COSINE,
            quantization_config=models.BinaryQuantization(
                binary=models.BinaryQuantizationConfig(always_ram=True),
            ),
        ),
        "colbert": models.VectorParams(
            size=COLBERT_DIM,
            distance=models.Distance.COSINE,
            multivector_config=models.MultiVectorConfig(
                comparator=models.MultiVectorComparator.MAX_SIM
            ),
            on_disk=True,
            hnsw_config=models.HnswConfigDiff(m=0),
        ),
    },
)

Der einheitliche Abfragen-Pipeline

Für die Phase des Unified Query Pipelines sollten vor der Codeänderung Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Erhalten Sie neben den funktionalen Ergebnissen auch Aufzeichnungen der Laufzeiten sowie der Kosten für Token oder Abfragen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Prozess von Demonstrationsumgebungen in gemeinsam genutzte Umgebungen übergeht. Wählen Sie bei dem nächsten Schritt, der ein Codeabschnitt oder einen Toolaufruf ist, strukturierte Ausgaben mit Schema-Validierung statt freier Prosa. Für die Phase des Unified Query Pipelines sollten vor der Codeänderung Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Dokumentieren Sie sowohl den erfolgreichen Ablauf als auch die Notfallbehandlung gemeinsam. Wiederholungsversuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen.

# ADDED: Generate query embeddings (ColBERT uses query_embed to add prefix padding)
dense_query = next(dense_model.query_embed(query)).tolist()
colbert_query = next(colbert_model.query_embed(query)).tolist()
# Run the two-stage query in one network round-trip
results = client.query_points(
    collection_name=COLLECTION_NAME,
    prefetch=models.Prefetch(
        query=dense_query,
        using="dense",
        limit=prefetch_limit,
        params=models.SearchParams(
            quantization=models.QuantizationSearchParams(rescore=False),
        ),
    ),
    query=colbert_query,
    using="colbert",
    limit=top_k,
    with_payload=True,
)

Von Blöcken zu Sätzen

Beim Arbeiten am Schritt „Von Blöcken zu Sätzen“ sollten Sie zunächst den Ablaufplan aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Ziehen Sie kleine, testbare Einheiten vor großen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortungsbereich verweisen und nicht auf ein verworrenes Ablaufschema. Cachen Sie stabile Systemanweisungen sowie Tool-Schemata. Das erneute Senden identischer Vorlagen ist eine häufige Ursache für Ressourcenverschwendung.

import re
import numpy as np
# ADDED: Basic sentence splitter regex
SENTENCE_SPLIT = re.compile(r"(?<=[.;])\s+(?=[A-Z])")
def max_sim(query_vecs: np.ndarray, doc_vecs: np.ndarray) -> float:
    # Compute token-to-token similarity matrix
    sims = query_vecs @ doc_vecs.T  # (num_query_tokens, num_doc_tokens)
    # Sum the maximum similarity scores along the document axis
    return float(sims.max(axis=1).sum())
def isolate_sentences(chunk_text: str, query_vecs: np.ndarray, colbert_model, top_n: int = 1):
    # ADDED: Split chunk text into candidate sentences
    sentences = [s.strip() for s in SENTENCE_SPLIT.split(chunk_text) if len(s.strip()) > 15]
    if not sentences:
        return [(chunk_text, 0.0)]
    # Embed each sentence locally using ColBERT
    sentence_vecs = list(colbert_model.embed(sentences))
    scored = [(sentences[i], max_sim(query_vecs, sentence_vecs[i])) for i in range(len(sentences))]
    scored.sort(key=lambda pair: pair[1], reverse=True)
    return scored[:top_n]
def build_optimized_prompt(query: str, chunk_texts: list[str], colbert_model) -> str:
    query_vecs = next(colbert_model.query_embed(query))
    context_parts = []
for i, text in enumerate(chunk_texts):
        top_sentences = isolate_sentences(text, query_vecs, colbert_model, top_n=1)
        isolated_text = " ".join(s for s, _ in top_sentences)
        context_parts.append(f"[Source Chunk {i+1}]: {isolated_text}")
    context_str = "\n\n".join(context_parts)
    return f"Context:\n{context_str}\n\nQuestion: {query}\nAnswer:"

Die goldene Regel zur Blöckengröße: Warum Blöckenbegrenzungen für die Genauigkeit wichtig sind

Beim Arbeiten an der Phase „Die goldene Regel“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsindikatoren sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Ergebnisdokumente, definieren Sie Erfolgsprüfungen und lehnen Sie stille, teilweise abgeschlossene Abläufe ab. Cachen Sie stabile Systemanweisungen sowie Tool-Schemata. Das erneute Senden identischer Vorlagen ist eine häufige Ursache für Ressourcenverschwendung.

Der Kompromiss spricht für sich

Beim Arbeiten an der Phase „The Tradeoff Speaks for“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Notieren Sie außerdem die Laufzeiten sowie die Kosten für Tokens oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Prozess von einer Demo in gemeinsam genutzte Umgebungen übergeht. Speichern Sie stabile Systemanweisungen sowie Tool-Schemata im Cache. Das erneute Senden identischer Voranmeldungen ist eine häufige Ursache für unnötige Ressourcenverbrauch. Beim Arbeiten an der Phase „The Tradeoff Speaks for“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgssignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf sowie den Notfallweg. Wiederholte Versuche, menschliche Kontrollpunkte und die Handhabung von Fehlern gehören zum Produkt selbst, nicht zu späteren Optimierungen.

Welche finanziellen Auswirkungen gibt es?

Die Finanzphase funktioniert am besten, wenn sie als messbarer Bereich betrachtet wird. Erfassen Sie einen erfolgreichen Fallbeispiel, einen Fehlerfall sowie die Notizen zum Rollback, bevor Sie den Umfang erweitern. Ziehen Sie kleine, testbare Einheiten vor großen, komplexen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf. Legen Sie Budgetgrenzen pro Schritt und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext stark; feste Obergrenzen verhindern, dass Demonstrationen zu unerwarteten Rechnungen werden.

Design-Erkenntnisse für die Produktion

Die Design-Erkenntnisse für die Produktionsebene funktionieren am besten, wenn sie als messbare Größe betrachtet werden. Erfassen Sie eine „goldene“ Transkription, einen Fehlerfall sowie die Notizen zum Rollback, bevor Sie den Umfang erweitern. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Erzeugnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Legen Sie Budgetgrenzen pro Schritt und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext oft übermäßig; feste Obergrenzen verhindern, dass Demonstrationen zu unerwarteten Rechnungen werden.

GitHub

Die GitHub-Phase funktioniert am besten, wenn sie als messbarer Bereich betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Erfassen Sie außerdem die Laufzeiten sowie die Kosten für Token oder Abfragen zusammen mit den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Prozess von einer Demo in gemeinsame Umgebungen übergeht. Legen Sie Budgets für Token pro Durchgang und pro Sitzung fest. Agentenbasierte Tools erweitern den Kontext stark – feste Obergrenzen verhindern, dass Demos zu unerwarteten Rechnungen werden. Die GitHub-Phase funktioniert am besten, wenn sie als messbarer Bereich betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Dokumentieren Sie den erfolgreichen Ablauf sowie den Wiederherstellungsprozess gemeinsam. Wiederholversuche, menschliche Kontrollen sowie die Handhabung von Fehlern gehören zum Produkt und nicht zu späteren Optimierungen.

Referenzen

Zur Phase der Referenzen sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Vorzuziehen sind kleine, testbare Einheiten statt umfangreicher Skripte. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufverfahren. Bei dem nächsten Schritt, der aus Code oder einem Toolaufruf besteht, sind strukturierte Ausgaben mit Schema-Validierung vor freiformiger Prosa zu bevorzugen.

Operative Checkliste

Zur Phase der operativen Checkliste sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen.

Halten Sie die Konfiguration außerhalb des Anwendungscode. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort zusammengefasst sein, den Betreiber überprüfen können, ohne den gesamten Codeverlauf durchlesen zu müssen.

Wählen Sie bei dem nächsten Schritt, der eine Codegenerierung oder einen Toolaufruf beinhaltet, strukturierte Ausgaben mit Schema-Validierung vor. Freiform-Prosa ist weniger geeignet.

Messen Sie die Trefferquote anhand eines festgelegten Fragekatalogs, bevor Sie die Prompts anpassen. Ein häufiges Wechseln der Prompts löst in der Regel kein schwaches Abrufverhalten.

Festlegen Sie die Versionsnummern der Abhängigkeiten und speichern Sie den Bild-Digest, mit dem die Demo ausgeführt wurde. Reproduzierbarkeit ist besser als „stilles“ Fachwissen.

Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskriterien und lehnen Sie stille, unvollständige Ergebnisse ab.

Vor der Einführung des Stacks sollten Versionen eingefroren werden, ein „goldener“ Transkript für den kritischen Pfad erstellt und die Rollback-Schritte bestätigt werden. Gemeinsam genutzte Umgebungen benötigen Rate Limits, Überprüfungen der Nutzerzuordnung sowie einen klaren Verantwortlichen für die Rotation von Geheimnissen. Man sollte langweilige Zuverlässigkeit vor cleveren, einmaligen Demonstrationen bevorzugen.

Batch-Hinweis für 98b4b4d4d553: Halten Sie die Anbieter-Schlüssel außerhalb des Repositories, legen Sie eine Obergrenze für Tokens pro Sitzung fest und speichern Sie die Transkripte neben den Evaluierungs-Fixtures, damit spätere Modellwechsel vergleichbar bleiben.