<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Hybride Suche - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Hybride Suche - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/de/search-labs/blog/category/hybrid-search</link>
    </image>
    <link>https://www.elastic.co/de/search-labs/blog/category/hybrid-search</link>
    <atom:link href="https://www.elastic.co/de/search-labs/rss/category/hybrid-search.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[de]]></language>
    <lastBuildDate>Mon, 28 Sep 2026 12:07:35 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Elasticsearch-Vektordatenbank: In Minuten bereitstellen, kostengünstig auf Hunderte Milliarden skalieren]]></title>
    <description><![CDATA[Die schwierigen Aspekte des hybriden Abrufs, bereits erledigt – mit optimierten Standardeinstellungen, Drittanbieter- und nativen Jina AI-Modellen sowie verwalteter GPU-Inferenz, alles sofort einsatzbereit. Erstellen Sie schnelle, skalierbare KI-Apps, keine Infrastruktur.]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch ist eine der weltweit am weitesten verbreiteten Plattformen für Vektor-Workloads und unterstützt semantische Suche, Retrieval-Augmented Generation (RAG) sowie Empfehlungen für Unternehmen wie GitHub, Docusign, Seismic und viele andere. Heute kündigen wir die Elasticsearch-Vektordatenbank an – ein neues serverloses Angebot, das für vektorbasierte Anwendungen optimiert wurde. Sie bringen Ihre Dokumente und Ihre Abfragen mit, und wir kümmern uns um die Einbettungen, das Index-Tuning sowie die Infrastruktur. Und wir halten es kostengünstig und skalierbar. </p><p>Für neue Nutzer ist dies der schnellste Weg, eine hochwertige Vektorsuche in Betrieb zu nehmen. Wenn Sie Elasticsearch bereits nutzen, bietet das neue Angebot eine Vektorsuche auf der Plattform, auf der Ihre Daten bereits gespeichert sind – ganz ohne die Einführung eines neuen Systems. Die Elasticsearch-Vektordatenbank unterstützt verschiedene Szenarien – vom Grounding eines großen Sprachmodells (LLM) über die Bereitstellung von Abruf- und Speicherfunktionen für KI-Agenten bis hin zur Bereitstellung von Hunderten Milliarden Vektoren. <a href="https://cloud.elastic.co/registration?onboarding_token=vector">Starten Sie ein neues Projekt</a> und legen Sie in wenigen Minuten los.</p><h2>Eine Engine für alle Vektor-Anwendungsfälle</h2><p>Die Elasticsearch-Vektordatenbank wurde für alle entwickelt, die Anwendungen mit Vektoren erstellen:</p><ul><li><p><strong>RAG:</strong> Rufen Sie mit dem Abruf dichter und dünnbesetzter Vektoren den passenden Kontext für Ihr LLM ab oder entscheiden Sie sich für die Hybridsuche, die sowohl den Vektor- als auch den lexikalischen Abruf kombiniert. Die Qualität Ihrer Generierung verbessert sich mit der Qualität Ihres Abrufs.</p></li><li><p><strong>KI-Agenten:</strong> Geben Sie Agenten schnellen, gefilterten Zugriff auf Dokumente und Konversationsgedächtnis – mit den niedrigen Latenzen, die mehrstufige Agentenschleifen erfordern.</p></li><li><p><strong>Semantische Suche:</strong> Gleichen Sie nach Bedeutung statt nach Schlagwörtern ab – mit einem einzigen Feldtyp und ganz ohne Pipeline-Code.</p></li><li><p><strong>Empfehlungen und Ähnlichkeit:</strong> Finden Sie die nächsten Nachbarn über Produkte, Bilder oder beliebige andere Inhalte hinweg – und das in großem Maßstab.</p></li></ul><h2>Alles, was Ihre Vektor-Workloads benötigen – standardmäßig optimiert</h2><p>Eine vektorbasierte Anwendung zu erstellen bedeutet, mehrere separate Komponenten miteinander zu verbinden: Einbettungsmodelle einzurichten und zu hosten, Ihre Dokumente damit zu indexieren, die Vektoren effizient zu speichern, das Einbettungsmodell auf jede Abfrage anzuwenden, mit dem Vektorspeicher abzugleichen und schließlich die Dokumente hinter den Treffern abzurufen. Die Elasticsearch-Vektordatenbank übernimmt all das für Sie – ohne zusätzliche Konfiguration oder Einrichtung.</p><h3>Vektorindexierung mit vectordb_document-Indexmodus</h3><p>Der <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector#dense-vector-vectordb-document-mode">vectordb_document</a>-Indexmodus, eine neue Indexkonfiguration, die speziell für vektororientierte Workloads entwickelt wurde, ist standardmäßig aktiviert, sodass Sie die Einstellungen erhalten, die Experten wählen würden. Folgendes wird dadurch aktiviert:</p><ul><li><p><strong>Standardmäßig bfloat16:</strong> Vektoren werden mit der halben Größe von float32 bei vernachlässigbaren Auswirkungen auf den Recall gespeichert, wodurch sich Ihr Festplattenbedarf um etwa die Hälfte reduziert, noch bevor Quantisierung überhaupt ins Spiel kommt.</p></li><li><p><strong>Quellvektoren sind ausgeschlossen:</strong> In Elasticsearch befinden sich Ihre Einbettungen bereits in den Indexstrukturen, die für die Suche verwendet werden; eine zweite Rohkopie in _source würde lediglich den Speicher aufblähen und das Abrufen von Ergebnissen verlangsamen. Wir schließen das Duplikat aus, damit Antworten schneller zurückgegeben werden und Sie weniger speichern müssen.</p></li><li><p><strong>Die richtigen Dateien werden vorab in den Cache geladen:</strong> Die Datenstrukturen, auf die Vektorabfragen zuerst zugreifen, werden vorab in den Arbeitsspeicher geladen, sodass Ihre erste (und auch noch Ihre tausendste) Abfrage blitzschnell ist.</p></li><li><p><strong>Parallele Zusammenführung:</strong> Durch die Zusammenführung werden Segmente zu besser organisierten Vektorstrukturen konsolidiert, was sowohl den Recall als auch die Latenz verbessert, und durch die Multithread-Ausführung dieser Zusammenführungen erreichen Sie Ihr Ziel schneller.</p></li></ul><h3>Vektorspeicherung, Komprimierung und Auto-Tuning</h3><ul><li><p>Ihre Vektoren werden automatisch komprimiert.<a href="https://www.elastic.co/de/search-labs/blog/better-binary-quantization-lucene-elasticsearch"> Better Binary Quantization (BBQ)</a> reduziert den Vektorspeicherbedarf um das bis zu 32-Fache bei Beibehaltung der Trefferquote, und DiskBBQ verringert den Speicherbedarf für Workloads in großem Maßstab noch weiter.<a href="https://www.elastic.co/de/search-labs/blog/vector-quantization-auto-calibration-diskbbq"> </a></p></li><li><p>Entscheiden Sie sich für die<a href="https://www.elastic.co/de/search-labs/blog/vector-quantization-auto-calibration-diskbbq"> automatische Kalibrierung</a>, die die Quantisierung jedes Segments auf Ihre Daten abstimmt und bei jeder Zusammenführung neu abstimmt, wenn sich die Daten verändern. Bei Tests mit 18 Datensätzen verbesserten sich die Abfragen pro Sekunde (QPS) durchschnittlich um 16,7 %, wobei sich der Recall bei den meisten von ihnen erhöhte.</p></li></ul><h3>Einbettungen mit vollständig verwalteter GPU-Inferenz</h3><ul><li><p>Generieren Sie Einbettungen mit nativen <a href="https://www.elastic.co/de/jina-search-models">Embedding- und Reranking-Modellen von Jina AI</a> oder binden Sie Drittanbieter-Modelle ein – alles auf verwalteten GPUs über den <a href="https://www.elastic.co/docs/explore-analyze/elastic-inference/eis">Elastic Inference Service (EIS)</a> und ganz ohne eigene Modellserver. Oder hosten Sie selbst, wenn Sie eine eigene Lösung bevorzugen.</p></li><li><p>Der Feldtyp <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/semantic-text"><strong>semantic_text</strong></a> verarbeitet Chunking und Einbettung sowie Abfragen automatisch – der einfachste Weg zur semantischen Suche auf dem Markt. </p></li></ul><h3>Hybridsuche und gefilterte Vektorsuche</h3><ul><li><p>Die <a href="https://www.elastic.co/de/elasticsearch/hybrid-search">Hybridsuche</a> ist integriert und kombiniert Volltext- und Vektor-Retrieval in einer einzigen Abfrage. Kombinieren Sie die Ergebnisse mit Reciprocal Rank Fusion (RRF) oder einem beliebigen anderen Mischmechanismus nach Ihren Wünschen. Die Vektorsuche ist meist der Teil der Hybridsuche, der sich am schwersten optimal konfigurieren lässt. Mit der Elasticsearch-Vektordatenbank haben Sie alles im Griff und Ihr gesamter Hybrid-Stack wird besser. </p></li><li><p>Mit der <a href="https://www.elastic.co/de/search-labs/blog/filtered-hnsw-knn-search">gefilterten Vektorsuche</a> wenden Sie Metadatenfilter als Teil des Vektorabrufs selbst an und nicht erst im Nachhinein, was den Recall beeinträchtigt.</p></li></ul><h3>Enterprise von Anfang an</h3><p>Sie erhalten außerdem rollenbasierte Zugriffssteuerung (RBAC), Audit Logging und die Compliance-Zertifizierungen, die reinen Vektordatenbanken in der Regel fehlen.</p><h2>Erschwinglich in großem Maßstab und vorhersehbar</h2><p>Die Elasticsearch-Vektordatenbank ist so konzipiert, dass sie auch bei wachsendem Bedarf erschwinglich bleibt: Durch BBQ- und DiskBBQ-Komprimierung, die das Speicherwachstum linear und den Arbeitsspeicherbedarf gering hält, führt die Skalierung auf Hunderte von Milliarden Vektoren nicht zu explodierenden Kosten. Und was Sie tatsächlich bezahlen, basiert auf Zahlen, die Sie bereits kennen: der Zahl der von Ihnen gespeicherten Daten, der Zahl der indexierten Daten und der von Ihnen benötigten Suchkapazität. Schätzen Sie Ihre Dokumentenzahl und die Vektordimensionen sowie Ihre Abfragelast ab, und Sie können bereits vor der Erstellung des Projekts ermitteln, was Sie zahlen werden. Außerdem können Sie Ihre Rechnung am Monatsende Zeile für Zeile nachvollziehen. Es gibt keine undurchsichtigen Recheneinheiten und keine überraschenden Gebühren für Hintergrundoperationen.</p><h2>Erste Schritte mit der Elasticsearch-Vektordatenbank</h2><h3>Ein Serverless-Vektordatenbank-Projekt erstellen</h3><p>Erstellen Sie ein neues <a href="https://cloud.elastic.co/registration?onboarding_token=vector">serverloses Vektordatenbank-Projekt in Elastic Cloud</a>. Leiten Sie Ihre Daten an den Endpoint weiter, und schon können Sie mit dem Indexieren beginnen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt556cbdfba551f248/6aa10b4332b53038406d321a/image1.png" alt="Elastic Cloud Serverless project types: Elasticsearch, Vector Database, Observability and Security" /><h3>Einen Index mit semantic_text erstellen</h3><p>Der Vektorindex-Modus übernimmt die Vektorkonfiguration. Die Verwendung von semantic_text bedeutet, dass die Einrichtung von Einbettungen und Chunking sowie die Indexeinrichtung bei verwalteter GPU-Inferenz für Sie verwaltet werden, ohne dass Sie eine Einbettungs-Pipeline erstellen müssen.</p>PUT my-vectors
{
"mappings": {
"properties": {
"description": { "type": "semantic_text" }
    }
  }
}<h3>Dokumente ingestieren</h3><p>Indexieren Sie Text, und die Einbettungen werden für Sie generiert.</p>POST /my-vectors/_doc
{
  "id": "park_rocky-mountain",
  "title": "Rocky Mountain",
  "description": "Bisected north to south by the Continental Divide, this portion of the Rockies has ecosystems varying from over 150 riparian lakes to montane and subalpine forests to treeless alpine tundra."
}<h3>Eine semantische Suchabfrage ausführen</h3><p>Fragen Sie dasselbe semantische Feld ab, das Sie gerade erstellt haben:</p>GET /my-vectors/_search
{
  "query": {
    "semantic": {
      "field": "description",
      "query": "a mountain range in the middle of north america"
    }
  }
}<p>Und Sie erhalten Ergebnisse zurück:</p>{
  "took": 80,
  "hits": {
    "max_score": 0.7792325,
    "hits": [
      {
        "_index": "my-vectors",
        "_score": 0.7792325,
        "_source": {
          "id": "park_rocky-mountain",
          "title": "Rocky Mountain",
          "description": "Bisected north to south by the Continental Divide, ..."
        }
      }
    ]
  }
}<p>Die semantische Suche ist erst der Anfang. Führen Sie rein textbasierte Abfragen aus oder kombinieren Sie beides zu hybriden Abfragen. Sie können für die volle Kontrolle sogar Ihre eigenen Vektorabfragen erstellen. Folgen Sie dem <a href="https://www.elastic.co/docs/solutions/vector-database/vector-full-text-search">Schnellstart für die semantische Suche</a> in der Dokumentation zur vollständigen Anleitung.</p><h2>Was kommt als Nächstes für die Vektorsuche in Elasticsearch?</h2><p>Wir arbeiten bereits an den nächsten Verbesserungen:</p><ul><li><p><strong>Bessere Multi-Mandanten-Verwaltung:</strong> Wenn Ihre Daten pro Mandant getrennt bleiben müssen, bieten wir Ihnen eine Möglichkeit, dies schneller und mit weniger Code umzusetzen.</p></li><li><p><strong>Automatische Indexoptimierung:</strong> Vom „brandneuen Index“ bis zu „vollständig optimiert“, mit möglichst wenig Feinabstimmung.</p></li><li><p><strong>Kontinuierliche Infrastrukturverbesserungen:</strong> Eine laufende Optimierung der Einstellungen und Infrastruktur der Vektordatenbank, damit Sie stets den besten Durchsatz und die schnellsten Reaktionen erhalten.</p></li></ul><h2>Testen Sie die Elasticsearch-Vektordatenbank auf Elastic Cloud Serverless</h2><p>Gelangen Sie in wenigen Minuten von einem leeren Projekt zu einer hybriden, gefilterten Vektorabfrage – mit produktionsreifen Standardeinstellungen, die das Tuning für Sie übernehmen. Erstellen Sie schnelle, skalierbare KI-Apps, keine Infrastruktur.</p><p>Starten Sie auf <a href="https://cloud.elastic.co/registration?onboarding_token=vector">Elastic Cloud Serverless</a> oder tauchen Sie ein in die <a href="https://www.elastic.co/docs/solutions/vector-database">vollständige Dokumentation</a> und die <a href="https://www.elastic.co/docs/api/doc/elastic-cloud-serverless/group/endpoint-vectordb-projects">API-Referenz.</a></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/vector-database-rag-serverless</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/vector-database-rag-serverless</guid>
    <category><![CDATA[Vektordatenbank]]></category>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <category><![CDATA[Hybride Suche]]></category>
    <dc:creator><![CDATA[Dustin Coates]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4def84aae6aff861/6aa10ab1ee57e53d9b05253c/cover.png" length="0" type="image/png"/>
    <pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[So messen und verbessern Sie den Elasticsearch-Suchabruf: von 0,43 auf 0,75 mit Hybridsuche]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie den Suchabruf in Elasticsearch messen und verbessern können, indem Sie die lexikalische BM25-Suche mit Jina AI-Vektoreinbettungen kombinieren und dabei die rank_eval-API nutzen, um die Verbesserung mit realen Zahlen zu validieren.]]></description>
    <content:encoded><![CDATA[<p><a href="https://www.elastic.co/docs/solutions/search/full-text">Die lexikalische Suche</a> mit dem <a href="https://www.elastic.co/blog/practical-bm25-part-1-how-shards-affect-relevance-scoring-in-elasticsearch">BM25-Ranking-Algorithmus</a> ist günstig, schnell und sehr effektiv für eine breite Palette von Abfragen. Sie hat jedoch einen blinden Fleck: Abfragen, die keine Tokens mit Ihren Dokumenten teilen. In diesem Artikel messen Sie genau, wo BM25 auf der Strecke bleibt. Wir werden die <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/search-rank-eval">Ranking-Evaluations-API</a> von Elasticsearch (<code>rank_eval</code>) verwenden und diese Lücke schließen, indem wir <a href="https://www.elastic.co/search-labs/es/blog/jina-embeddings-v3-elastic-inference-service">Jina AI Einbettungen</a> über den <a href="https://www.elastic.co/docs/explore-analyze/elastic-inference/eis">Elastic Inference Service</a> (EIS) hinzufügen. Sie erfahren, wie der Abruf-Score von <code>0.43</code> auf <code>0.75</code> steigt und verstehen, warum er dies tut.</p><h2>Was ist ein Abruf?</h2><p><a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/search-rank-eval#k-recall">Der Abruf</a> misst auf einer Skala von <code>0</code> bis <code>1</code>, wie viele der Dokumente, die Ihre Nutzer tatsächlich haben möchten, irgendwo in Ihren Suchergebnissen erscheinen. Wenn eine Abfrage drei Produkte anzeigen sollte und Ihre Suche nur zwei davon in den Top 10 zurückgibt, gilt <code>recall@10 = 0.67</code> für diese Abfrage. Es ist eine mengenbasierte Metrik: Die Position der relevanten Dokumente innerhalb dieser <em>k</em> Ergebnisse spielt keine Rolle. Ein relevantes Dokument auf Position 10 zählt genauso wie eines auf Position 1. Ein hoher Abruf-Wert bedeutet, dass Sie keine relevanten Ergebnisse verlieren.</p><p>
</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5ffd147b13705680/6a170a6fe8fbce11a539fc22/b13af2a5d0ca055535d8bfe3dfe4b3d1093ee6da-1457x796.png" alt="Das Venn-Diagramm veranschaulicht die Berechnung des Recall@10-Werts, indem es die Überschneidung zwischen allen relevanten Dokumenten und den Top 10 Ergebnissen von BM25 darstellt. Daraus ergibt sich ein Recall@10-Wert von 0,40." /><p>Das Diagramm zeigt zwei Mengen: alle relevanten Dokumente (links) und die Top 10, die BM25 tatsächlich abgerufen hat (rechts). Nur die Schnittmenge zählt für den Rückruf: <code>prod_1</code> und <code>prod_2</code> wurden gefunden, während <code>prod_3</code>, <code>prod_4</code> und <code>prod_6</code> vollständig übersehen wurden. Ergebnis: <code>Recall@10 = 2/5 = </code><strong><code>0.40</code></strong>.</p><h2>Voraussetzungen</h2><p>Lassen Sie uns zur Sache kommen, um besser zu verstehen, wie das Abrufverfahren funktioniert. Diese Demonstration verwendet Python. Sie können es im begleitenden Notebook verfolgen (<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/relevance-tuning-improving-recall-adding-vectors/notebook.ipynb">notebook.ipynb</a>), wo jeder Codeblock eine ausführbereite Zelle darstellt.</p><p>Der bereitgestellte Code verwendet Folgendes:</p><ul><li><p>Elasticsearch 9.3+</p></li><li><p>Python 3.10+</p></li></ul>pip install elasticsearch pandas plotly python-dotenv<ul><li><p>Eine <code>.env</code>-Datei mit Ihren Elasticsearch-Zugangsdaten</p></li></ul>ELASTICSEARCH_URL=https://your-cluster-url
ELASTICSEARCH_API_KEY=your-api-key<h2>Der Datensatz</h2><p>Wir verwenden einen Produktkatalog mit 1.000 Produkten, der Kategorien wie Schuhe, Elektronik, Werkzeuge und mehr umfasst.</p><p>Jedes Dokument hat vier Felder:</p><p>Feld</p><p>Typ</p><p>`Titel`</p><p>Text</p><p>`Beschreibung`</p><p>Text</p><p>`Marke`</p><p>Keyword</p><p>`Kategorie`</p><p>Keyword</p><p>Der Datensatz wird aus <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/relevance-tuning-improving-recall-adding-vectors/dataset.csv"><code>dataset.csv</code></a> geladen.</p><h2>Die Stärken und Grenzen der lexikalischen Suche</h2><p>BM25 ist der Standard-Ranking-Algorithmus in Elasticsearch und den meisten Suchmaschinen. Er bewertet Dokumente danach, wie oft Ihre Abfragebegriffe darin erscheinen, angepasst an die Dokumentlänge und die Häufigkeit dieser Begriffe im gesamten Index. Sie erhalten zusätzlich <a href="https://www.elastic.co/docs/reference/text-analysis/analyzer-reference">Analyzer</a>: Kleinschreibungsnormalisierung, Stemming und Stoppwort-Entfernung. Eine Suchanfrage nach „Laufschuhen“ liefert Treffer für „Laufschuhe“ und wahrscheinlich auch für „Laufen“.</p><p>Dies funktioniert gut für eine große Gruppe von Abfragen:</p><ul><li><p>„Laufschuhe“ findet sofort Produkte, die genau diesen Begriff im Titel enthalten.</p></li><li><p>„Bluetooth-Lautsprecher“ taucht bei tragbaren Audioprodukten auf, weil die Token wortwörtlich erscheinen.</p></li></ul><p>Die Ergebnisse sind deterministisch und erklärbar: Ein Dokument rangiert hoch, weil die Abfragebegriffe darin erscheinen. Die Relevanzprüfung ist unkompliziert.</p><h3>Wo es fehlschlägt</h3><p>Nun probieren wir diese Abfragen mit demselben Katalog aus:</p><ul><li><p><strong>„Hautpflege-Routine“:</strong> Das Wort „Routine“ kommt in keinem Produkttitel vor. BM25 kann teilweise mit „Hautpflege“ abgestimmt werden, aber Gesichtsseren, Körperöle und Feuchtigkeitscremes werden mit Begriffen wie „Vitamin C“, „Retinol“ oder „Strahlkraft“ beschrieben, von denen sich keine mit der Abfrage überschneidet. Produkte, die eine vollständige Hautpflegeroutine darstellen, sind über den Index verstreut, ohne ein gemeinsames verankerndes Token.</p></li></ul>ID: B06XX6DS3P, Score: 9.0552, Title: Replenix Retinol Smooth + Tighten Body Lotion - Collagen-Boosting, Regenerating Anti-Aging Body Cream, Reduces Appearance of Stretch Marks, 6.7 oz.

  ID: B08XMPKJ1L, Score: 5.2699, Title: Bio-Oil Skincare Body Oil (Natural) Serum for Scars and Stretchmarks, Face and Body Moisturizer Hydrates Skin, with Organic Jojoba Oil and Vitamin E, For All Skin Types, 6.7 oz

  ID: B01CY764KQ, Score: 5.0057, Title: Nike Up Or Down Men Deodorant - Pack of 2 | Long-Lasting Fragrance, Body Spray Combo for Men | Deodorant for Active Living | Nike Men's Deo Set | Ultimate Odor Protection | Grooming Essentials | Signature Nike Scent | High-Performance Men's Deodorant<ul><li><p><strong>„Reisezubehör für Haustiere“:</strong> Dies ist eine Anwendungsfall-Gruppierung, keine Produktkategorie. Eine Hundetragetasche, ein Autositz für Haustiere und eine Transportbox sind alle relevant, aber in ihren Beschreibungen geht es eher um Tragbarkeit, Sicherheit und Komfort als um „Reisezubehör“. BM25 stimmt weitgehend mit „Haustier“ überein, hat aber kein Signal, um reisespezifische Produkte vom Rest des Haustierkatalogs zu unterscheiden.</p></li></ul>ID: B0BVV7BKTW, Score: 7.4371, Title: Large Foldable Travel Duffel Bag with Shoes Compartment

ID: B07TNPHYNV, Score: 6.6455, Title: 40 Pieces Christmas Bronze Jingle Bells Craft Small Bells

ID: B08R8FRW53, Score: 6.6335, Title: CUBY Dog and Cat Sling Carrier
ID: B08QMCQYGM, Score: 6.5259, Title: YTFGGY Whiteboard Pinstripe Tape 6 Rolls 1/8"
ID: B0CP3LQSWM, Score: 6.2994, Title: Portable Dog Water Bottle 32 Oz<p>Das ist ein <strong>Abrufproblem</strong>. Die relevanten Dokumente finden sich in Ihrem Index. BM25 kann sie einfach nicht finden, weil die Wörter des Nutzers und die Wörter des Dokuments nicht genau genug übereinstimmen.</p><p>Das Hinzufügen von Synonymen hilft bei bekannten Fällen. Man kann aber nicht alle Möglichkeiten aufzählen, wie ein Nutzer seine Absicht ausdrücken könnte. An dieser Stelle kommen Vektoren ins Spiel.</p><h2>Warum Sie die Abruf-Rate messen sollten</h2><p>Bevor Sie ein Problem beheben, müssen Sie es quantifizieren.</p><p><a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/search-rank-eval#k-recall"><strong>Recall@k</strong></a> misst, wie viele der Dokumente, die Ihre Nutzer tatsächlich suchen, tatsächlich in Ihren Suchergebnissen erscheinen. Formell:</p>Recall@k = (relevant documents found in top k) / (total relevant documents)<p><a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/search-rank-eval#k-precision"><strong>Precision@k</strong></a> misst die besten k-Ergebnisse und wie viele tatsächlich relevant sind:</p>Precision@k = (relevant documents in top k) / k<p>Hohe Präzision bedeutet, dass die Ergebnisse gut sind. Im E-Commerce ist es oft schlimmer, ein relevantes Produkt zu übersehen (niedrige Abruf-Werte), als ein nicht ganz perfektes Ergebnis anzuzeigen (geringere Präzision), denn ein verstecktes Produkt ist ein verlorener Verkauf.</p><p>Mit der <code>rank_eval</code>-API von Elasticsearch können Sie beides systematisch messen. Sie stellen eine Liste von Abfragen mit jeweils einer Reihe von bewerteten Dokumenten zur Verfügung, und Elasticsearch berechnet für Sie die Metriken für alle Abfragen.</p><h2>Die Bewertung einrichten</h2><p>Die <code>rank_eval</code> API benötigt einen <strong>Bewertungsdatensatz</strong>: ein Mapping von Abfragen zu den Dokumenten, die jeweils relevant sind, zusammen mit einer Relevanznote (0 = nicht relevant, 1 = relevant, 2 = sehr relevant).</p><p>Im Notebook ist dies die <a href="https://www.elastic.co/docs/solutions/search/ranking/learning-to-rank-ltr#learning-to-rank-judgement-list">Bewertungsliste</a>:</p>judgments = [
    # Query 1: "running shoes" BM25 handles well (tokens appear in product titles) 
    {"query_id": "q1", "doc_id": "B09NQJFRW6", "grade": 2, "query": "running shoes"},
    {"query_id": "q1", "doc_id": "B08JMD4LMM", "grade": 2, "query": "running shoes"},
    {"query_id": "q1", "doc_id": "B08VRJ6F2Q", "grade": 2, "query": "running shoes"},
    {"query_id": "q1", "doc_id": "B07S8NRRWR", "grade": 2, "query": "running shoes"},
    {"query_id": "q1", "doc_id": "B01HD620I8", "grade": 2, "query": "running shoes"},
    {"query_id": "q1", "doc_id": "B07DX86321", "grade": 2, "query": "running shoes"},
    {"query_id": "q1", "doc_id": "B0968YVLQ8", "grade": 1, "query": "running shoes"},
    {"query_id": "q1", "doc_id": "B093QJ39ZS", "grade": 1, "query": "running shoes"},
    {"query_id": "q1", "doc_id": "B096FGSC39", "grade": 1, "query": "running shoes"},
    {"query_id": "q1", "doc_id": "B01GVQWVV2", "grade": 1, "query": "running shoes"},

    # Query 2: "skincare routine" intent-based, "routine" never appears in product titles
    {"query_id": "q2", "doc_id": "B08XMPKJ1L", "grade": 2, "query": "skincare routine"},
    {"query_id": "q2", "doc_id": "B0BN3WQB92", "grade": 2, "query": "skincare routine"},
    {"query_id": "q2", "doc_id": "B0BT7B7P5T", "grade": 2, "query": "skincare routine"},
    {"query_id": "q2", "doc_id": "B00NPA2WEY", "grade": 2, "query": "skincare routine"},
    {"query_id": "q2", "doc_id": "B06XX6DS3P", "grade": 1, "query": "skincare routine"},
    {"query_id": "q2", "doc_id": "B07PDRD1KT", "grade": 1, "query": "skincare routine"},
    {"query_id": "q2", "doc_id": "B074J7869B", "grade": 1, "query": "skincare routine"},
    {"query_id": "q2", "doc_id": "B08JV31QW4", "grade": 1, "query": "skincare routine"},
    {"query_id": "q2", "doc_id": "B00K3TVJMQ", "grade": 1, "query": "skincare routine"},

    # Query 3: "study desk setup" intent-based, products are desks/stands/organizers
    {"query_id": "q3", "doc_id": "B08CS35J2T", "grade": 2, "query": "study desk setup"},
    {"query_id": "q3", "doc_id": "B09B3LFDXJ", "grade": 2, "query": "study desk setup"},
    {"query_id": "q3", "doc_id": "B07W58LMND", "grade": 1, "query": "study desk setup"},
    {"query_id": "q3", "doc_id": "B0CHYDX91L", "grade": 1, "query": "study desk setup"},

    # Query 4: "pet travel accessories" use-case grouping, products are carriers/crates/seats
    {"query_id": "q4", "doc_id": "B08R8FRW53", "grade": 2, "query": "pet travel accessories"},
    {"query_id": "q4", "doc_id": "B01MYUYX33", "grade": 2, "query": "pet travel accessories"},
    {"query_id": "q4", "doc_id": "B003C5RKE4", "grade": 2, "query": "pet travel accessories"},
    {"query_id": "q4", "doc_id": "B09GF8GBF6", "grade": 1, "query": "pet travel accessories"},
    {"query_id": "q4", "doc_id": "B0CP3LQSWM", "grade": 1, "query": "pet travel accessories"},
]<p>Die Mischung ist beabsichtigt: <code>q1</code> ist eine Abfrage, die BM25 gut verarbeiten kann (exakte Tokens in Produkttiteln), während <code>q2</code>, <code>q3</code> und <code>q4</code> absichtsbasierte Abfragen sind, bei denen die Absicht des Nutzers als Konzept und nicht als spezifische Produktschlüsselwörter ausgedrückt wird.</p><h2>Messung des BM25-Baseline-Abrufs</h2><p>Richten Sie zuerst den Elasticsearch-Client ein und indexieren Sie die Rohtextdaten:</p>import os
import json
import pandas as pd
import plotly.graph_objects as go
from elasticsearch import Elasticsearch, helpers
from dotenv import load_dotenv

load_dotenv()

es = Elasticsearch(
    os.getenv("ELASTICSEARCH_URL"),
    api_key=os.getenv("ELASTICSEARCH_API_KEY")
)

INDEX_NAME = "ecommerce-products"<p>Erstellen Sie nun die <code>rank_eval</code>-Abfrage für BM25. Jede Abfrage in der Liste kombiniert eine Abfrage mit ihren Bewertungen:</p>judgments_df = pd.DataFrame(judgments)

bm25_requests = []
for query_id, query_text in (
    judgments_df[["query_id", "query"]].drop_duplicates().values
):
    relevant_docs = judgments_df[judgments_df["query_id"] == query_id]
    ratings = [
        {"_index": INDEX_NAME, "_id": row["doc_id"], "rating": row["grade"]}
        for _, row in relevant_docs.iterrows()
    ]

    bm25_requests.append({
        "id": query_id,
        "request": {
            "query": {
                "multi_match": {
                    "query": query_text,
                    "fields": ["title", "description"]
                }
            }
        },
        "ratings": ratings,
    })

bm25_eval = {
    "requests": bm25_requests,
    "metric": {"recall": {"k": 10, "relevant_rating_threshold": 1}},
}

bm25_result = es.rank_eval(index=INDEX_NAME, body=bm25_eval)
print("BM25 Recall@10:", bm25_result.body["metric_score"])<p>Ergebnis:</p>BM25 Recall@10: 0.43<p><code>0.43</code> Das bedeutet, dass BM25 bei allen vier Abfragen nur 43 % der Dokumente findet, die es finden sollte. Das Defizit konzentriert sich auf die absichtsbasierten Suchanfragen: Bei der Suche nach „Hautpflegeroutine“ werden Gesichtsseren und Körperöle nicht erfasst, da „Routine“ nie in den Produkttiteln vorkommt, und bei der Suche nach „Reisezubehör für Haustiere“ werden themenfremde Haustierprodukte gefunden, während Transportboxen und -käfige, die eher im Hinblick auf Tragbarkeit und Sicherheit als auf „Reisezubehör“ beschrieben werden, nicht erfasst werden.</p><p>Dies ist unsere Referenzgrundlage. Jetzt haben wir eine Zahl, die es zu übertreffen gilt.</p><h2>Vektorsuche mit Jina-Embeddings hinzufügen</h2><p><a href="https://www.elastic.co/docs/solutions/search/vector"><code>Vector search</code></a> Dokumente und Abfragen werden als hochdimensionale Vektoren kodiert, eine Art von Vektor, der aus Hunderten oder Tausenden numerischer Werte besteht, wobei jeder Wert ein spezifisches Feature der dargestellten Daten kodiert. Dokumente mit ähnlicher Bedeutung befinden sich im Vektorraum nahe beieinander, selbst wenn sie keine gemeinsamen Wörter enthalten. „Fitnessgeräte“ und „Hantelset“ werden sich in unmittelbarer Nähe befinden, da die Konzepte miteinander verwandt sind. Ich habe Elasticsearch als meine Vektordatenbank gewählt, da es die hybride Suche unterstützt und mir sowohl semantisches Verständnis als auch präzise Stichwortsuche direkt bietet.</p><p><a href="https://www.elastic.co/docs/explore-analyze/elastic-inference/eis">EIS</a> bietet eine fertige Unterstützung für das Einbetten von Modellen über seine <a href="https://www.elastic.co/docs/api/doc/elasticsearch/group/endpoint-inference">Inferenz-API</a>.</p><h3>Schritt 1: Verwendung von Jina-Embeddings v5 als Inferenz-Endpoint</h3>INFERENCE_ENDPOINT_ID = ".jina-embeddings-v5-text-small"<p>Wenn Ihr Cluster GPU-Ressourcen hat (verfügbar in Elastic Cloud und Elasticsearch 9.3+), werden die Einbettungen auf GPU generiert, was deutlich schneller ist als die CPU-Inferenz und den Leistungskompromiss beseitigt, der Vektoren historisch im großen Maßstab teuer gemacht hat.</p><p>Warum genau Jina-Einbettungen? <a href="https://www.elastic.co/search-labs/blog/jina-embeddings-v5-text">jina-embeddings-v5-text</a> ist ein mehrsprachiges Modell (über 119 Sprachen) mit einem Kontextfenster von 32.000 Token und Unterstützung für aufgabenspezifische <a href="https://arxiv.org/abs/2106.09685">Low-Rank Adaptation (LoRA) Adapter</a>. Es eignet sich hervorragend für kurze Produktbeschreibungen. Erfahren Sie mehr über das <code>jina-embeddings-v5-text</code>-Modell <a href="https://huggingface.co/jinaai/jina-embeddings-v5-text-small">hier</a>.</p><h3>Schritt 2: Erstellen Sie den Index mit einem semantischen Feld</h3>index_mappings = {
    "mappings": {
        "properties": {
            "title": {"type": "text", "copy_to": "semantic_field"},
            "description": {"type": "text", "copy_to": "semantic_field"},
            "brand": {"type": "keyword"},
            "category": {"type": "keyword"},
            "semantic_field": {
                "type": "semantic_text",
                "inference_id": INFERENCE_ENDPOINT_ID,
            },
        }
    }
}

if not es.indices.exists(index=INDEX_NAME):
    es.indices.create(index=INDEX_NAME, body=index_mappings)
    print(f"Created index: {INDEX_NAME}")<p>Der <a href="https://www.elastic.co/docs/solutions/search/semantic-search/semantic-search-semantic-text"><code>semantic_text</code></a>-Feldtyp ist hier der Schlüssel. Es handelt sich um eine Abstraktion auf höherer Ebene über <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector"><code>dense_vector</code></a>: Sie verweisen auf einen Inferenz-Endpoint, und Elasticsearch kümmert sich automatisch um die Generierung von Einbettungen.</p><p>Die <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/copy-to"><code>copy_to</code></a>-Eigenschaft auf <code>title</code> und <code>description</code> bedeutet, dass Inhalte aus beiden Feldern in <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/semantic-text"><code>semantic_field</code></a> zur Einbettung fließen, sodass ein einzelner Vektor die vollständige Produktdarstellung erfasst.</p><h3>Schritt 3: Produkte indexieren</h3>def bulk_index(products, index_name):
    actions = []
    for product in products:
        doc_id = product.get("_id")
        source = {k: v for k, v in product.items() if k != "_id"}
        action = {"_index": index_name, "_source": source}
        if doc_id:
            action["_id"] = doc_id
        actions.append(action)

    success, failed = helpers.bulk(es, actions, raise_on_error=False)
    if failed:
        for error in failed:
            print(f"Error: {error}")
    else:
        print(f"Successfully indexed {success} documents")

bulk_index(products, INDEX_NAME)<p>Zur Indexzeit ruft Elasticsearch für jedes Dokument den Inferenz-Endpoint auf und speichert die resultierende Einbettung in <code>semantic_field</code>. Kein zusätzlicher Code für Sie erforderlich.</p><h2>Hybridsuche: Kombination von BM25 und Vektoren mit RRF</h2><p>Das Hinzufügen von Vektoren verbessert den Abruf, aber die Verwendung von Vektoren allein birgt das Risiko, dass die Präzision bei exakten Übereinstimmungen auf der Strecke bleibt. „Laufschuhe“ sollten immer noch wortwörtliche Übereinstimmungen an erster Stelle einordnen. Die Hybridsuche behält die lexikalische Komponente bei, um diese Präzision zu erhalten.</p><p>Hybride Suche mit <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/reciprocal-rank-fusion">Reciprocal Rank Fusion</a> (RRF) kombiniert das Beste von beidem:</p><ul><li><p>BM25 verarbeitet exakte und nahezu exakte Abfragen mit hoher Präzision.</p></li><li><p>Die semantische Suche bewältigt absichtsbasierte und mehrsprachige Abfragen mit hoher Trefferquote.</p></li><li><p>RRF kombiniert die beiden Ranglisten zu einer einzigen Rangliste.</p></li></ul><p>Die RRF-Formel weist jedem Dokument eine Bewertung basierend auf seinem Rang in jeder Ergebnisliste zu:</p>score = sum(1 / (rank_constant + rank))<p>Ein Dokument, das in beiden Listen einen hohen Rang einnimmt, erhält eine höhere kombinierte Punktzahl. <code>rank_constant</code> steuert, wie viel Gewicht Dokumente mit niedrigerem Rang erhalten.</p>hybrid_requests = []

for query_id, query_text in (
    judgments_df[["query_id", "query"]].drop_duplicates().values
):
    relevant_docs = judgments_df[judgments_df["query_id"] == query_id]
    ratings = [
        {"_index": INDEX_NAME, "_id": row["doc_id"], "rating": row["grade"]}
        for _, row in relevant_docs.iterrows()
    ]

    hybrid_requests.append({
        "id": query_id,
        "request": {
            "retriever": {
                "rrf": {
                    "retrievers": [
                        {
                            "standard": {
                                "query": {
                                    "multi_match": {
                                        "query": query_text,
                                        "fields": ["title", "description"],
                                    }
                                }
                            }
                        },
                        {
                            "standard": {
                                "query": {
                                    "match": {
                                        "semantic_field": {"query": query_text}
                                    }
                                }
                            }
                        },
                    ],
                    "rank_window_size": 50,
                    "rank_constant": 5,
                }
            }
        },
        "ratings": ratings,
    })

hybrid_eval = {
    "requests": hybrid_requests,
    "metric": {"recall": {"k": 10, "relevant_rating_threshold": 1}},
}

hybrid_result = es.rank_eval(index=INDEX_NAME, body=hybrid_eval)
print("Hybrid Recall@10:", hybrid_result.body["metric_score"])<p>Ergebnis:</p>Hybrid Recall@10: 0.75<p>Hybrid verbessert sich erheblich gegenüber BM25 (<code>0.43</code>) und erhält die Präzision für exakte Treffer bei Abfragen wie „Laufschuhe“ bei.</p><h2>Ergebnisse: Vorher und Nachher</h2><p>Hier der vollständige Vergleich aller drei Ansätze:</p>methods = {
    "BM25 (Lexical)": bm25_requests,
    "Hybrid (BM25 + Vectors)": hybrid_requests,
}

recall_metric = {"recall": {"k": 10, "relevant_rating_threshold": 1}}

comparison_data = []
for method_name, requests in methods.items():
    result = es.rank_eval(
        index=INDEX_NAME,
        body={"requests": requests, "metric": recall_metric}
    )
    comparison_data.append({
        "method": method_name,
        "recall@10": result.body["metric_score"]
    })

comparison_df = pd.DataFrame(comparison_data)
print(comparison_df.to_string(index=False))<p>Ergebnis:</p><p>Methode</p><p>Recall@10</p><p>BM25 (Lexikalisch)</p><p>0,43</p><p>Hybrid (BM25 + Vektoren)</p><p>0,75</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5a1d72b57056fe64/6a170a71c1e8a56c58f882ab/e49f6c10516b0a48a0ad75962c6590ee07311407-700x500.png" alt="Ein Balkendiagramm vergleicht die Recall@10-Werte zwischen der lexikalischen BM25-Suche und der Hybridsuche, die BM25 mit Vektoren kombiniert. Das Diagramm zeigt, dass die Hybridsuche einen deutlich höheren Abruf erzielt." /><p>Aufschlüsselung nach Abfragen:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt871347f754c866d0/6a170a73839dfa40abdcfeb4/40e36dcb7b34cbf4649c512bcb60cef60f1778a6-700x500.png" alt="Ein gruppiertes Balkendiagramm vergleicht die Recall@10-Werte zwischen der lexikalischen und hybriden Suche in BM25 über vier Produktabfragen hinweg und zeigt, dass die hybride Suche bei jeder Abfrage durchweg besser abschneidet als die lexikalische Abfrage." /><h2>Fazit</h2><p>Im Laufe dieses Beitrags haben wir erfahren, dass die lexikalische BM25-Suche zuverlässig ist, wenn Nutzer exakte Suchanfragen eingeben, aber an Treffsicherheit verliert, wenn sie nach Suchintention statt nach Schlüsselwörtern suchen. Mit <code>rank_eval</code>haben wir eine reproduzierbare Basislinie festgelegt, um diese Lücke mit reellen Zahlen zu messen. Von dort aus haben wir ein <code>semantic_text</code> Feld hinzugefügt, das von Jina-Einbettungen unterstützt wird, und die Bewertung erneut durchgeführt. Das Ergebnis: Die Hybridsuche verbesserte die Trefferquote von <code>0.43</code> auf <code>0.75</code>, während die Genauigkeit bei exakten Suchabfragen erhalten blieb. Die tatsächliche Verbesserung hängt jedoch von der Zusammensetzung Ihrer Suchabfragen ab.</p><p>Das Muster lässt sich über dieses Beispiel hinaus skalieren: Sammeln Sie Relevanzurteile aus den tatsächlichen Abfragen Ihrer Nutzer, führen Sie <code>rank_eval</code> als Baseline aus, fügen Sie <code>semantic_text</code> hinzu und messen Sie erneut. Sie wissen genau, was sich verbessert hat und um wie viel.</p><h2>Wie geht es weiter?</h2><ul><li><p>Tauchen Sie tiefer in Abruf und Vektorsuche ein: <a href="https://www.elastic.co/search-labs/blog/recall-vector-search-quantization">Recall and Vector Search Quantization</a> von Jeff Vestal</p></li><li><p>Fügen Sie ein Reranking hinzu, um die besten Ergebnisse noch präziser zu ermitteln</p></li><li><p>Erkunden Sie die <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html">Elasticsearch-Dokumentation zur Hybridsuche</a></p></li><li><p>Erfahren Sie mehr über <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-rank-eval.html"><code>rank_eval</code></a><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-rank-eval.html"> API</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-relevance-tuning-improve-recall</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-relevance-tuning-improve-recall</guid>
    <category><![CDATA[Hybride Suche]]></category>
    <category><![CDATA[Vektordatenbank]]></category>
    <dc:creator><![CDATA[Jeffrey Rengifo]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt37c9d2971b5a2db3/6a170a75cf4f254223b2d149/492c9b5432a2b9e40cebb3b60f0df019a8c7bf6d-1280x720.png" length="0" type="image/png"/>
    <pubDate>Mon, 04 May 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Entitätsauflösung mit Elasticsearch, Teil 4: Die ultimative Herausforderung]]></title>
    <description><![CDATA[Lösung und Bewertung von Herausforderungen bei der Entitätsauflösung in einem äußerst vielfältigen Datensatz zur „ultimativen Herausforderung“, der entwickelt wurde, um Abkürzungen zu verhindern.]]></description>
    <content:encoded><![CDATA[<p>Wir haben nun die Implementierung intelligenter Entitätsauflösung auf zwei Arten gesehen. Beide Ansätze beginnen auf dieselbe Weise: Aufbereitung und Extraktion der Entitäten, gefolgt vom Abruf der Kandidaten mit Elasticsearch. Anschließend bewerten wir diese Kandidaten mithilfe eines großen Sprachmodells (LLM), entweder durch promptbasierte JSON-Generierung oder durch Funktionsaufrufe, und fordern vom Modell eine transparente Begründung für seine Entscheidung.</p><p>Wie wir im <a href="https://www.elastic.co/search-labs/blog/elasticsearch-entity-resolution-llm-function-calling">vorherigen Beitrag</a> gesehen haben, ist die Konstanz, die durch Funktionsaufrufe ermöglicht wird, nicht nur eine praktische Optimierung, sondern essenziell. Nachdem wir strukturelle Fehler aus dem Evaluationskreislauf entfernt hatten, verbesserten sich die Ergebnisse in Standardszenarien (wie denen im Tier-4-Datensatz) dramatisch.</p><p>Doch eine offensichtliche Frage bleibt noch zu beantworten:</p><p><em>Funktioniert dieser Ansatz noch, wenn es kompliziert wird?</em></p><p>Die Entitätsauflösung in der realen Welt schlägt selten in einfachen Fällen fehl. Sie scheitert, wenn Namen Sprach-, Kultur-, Schrift-, Zeit- und Unternehmensgrenzen überschreiten. Sie scheitert, wenn auf Menschen mit Titeln anstelle von Namen Bezug genommen wird, wenn Unternehmen Namen ändern, wenn Transliterationen nicht konstant sind und wenn Kontext (nicht die Schreibweise) das Einzige ist, was eine Erwähnung mit einer realen Entität verbindet.</p><p>Für den letzten Beitrag dieser Serie haben wir das System einer sogenannten <strong>ultimativen Herausforderung</strong> unterzogen.</p><h2>Was macht dies zur ultimativen Herausforderung?</h2><p>In früheren Auswertungen haben wir das System mit zunehmend komplexeren Datensätzen getestet. Als wir die im vorherigen Beitrag besprochene Stufe 4 erreichten, hatten wir es bereits mit einer Mischung aus Spitznamen, Titeln, mehrsprachigen Namen und semantischen Bezügen zu tun. Diese Tests zeigten, dass die Architektur selbst solide war, aber dass Zuverlässigkeitsprobleme, insbesondere fehlerhaftes JSON, den Rückruf unterdrückten.</p><p>Mit dem implementierten Funktionsaufruf hatten wir endlich eine stabile Grundlage. So konnten wir eine interessantere Frage stellen:</p><p><em>Kann eine einheitliche Pipeline </em><em><strong>viele verschiedene Arten</strong></em><em> von Entitätsauflösungsproblemen gleichzeitig bewältigen?</em></p><p>Der ultimative herausfordernde Datensatz wurde darauf ausgelegt, genau diese Dimension zu erreichen.</p><p>Anstatt sich auf eine einzelne Schwierigkeit (wie Spitznamen oder Transliteration) zu konzentrieren, kombiniert dieser Datensatz <strong>mehr als 50 verschiedene Herausforderungstypen</strong>, darunter:</p><ul><li><p>Kulturelle Namenskonventionen.</p></li><li><p>Titelbasierte Referenzen.</p></li><li><p>Geschäftliche Beziehungen und historische Namensänderungen.</p></li><li><p>Mehrsprachige und skriptübergreifende Erwähnungen.</p></li><li><p>Zusammengesetzte Herausforderungen, die mehrere der oben genannten Punkte kombinieren.</p></li></ul><p>Entscheidend ist, dass es hier nicht um die Optimierung für einen einzigen, eng begrenzten Anwendungsfall geht. Es geht darum zu testen, ob das <em>Entwurfsmuster</em> Bestand hat, wenn sich die Regeln von Entität zu Entität ändern.</p><h2>Der Datensatz auf einen Blick</h2><p>Der ultimativ herausfordernde Datensatz besteht aus:</p><ul><li><p><strong>50 Entitäten</strong>, darunter Personen, Unternehmen und Institutionen.</p></li><li><p><strong>~60 Artikel</strong>, mit unterschiedlicher Struktur und sprachlicher Komplexität.</p></li><li><p><strong>51 verschiedene Herausforderungskategorien</strong>, grob unterteilt in:</p><ul><li><p>Kulturelle Namenskonventionen.</p></li><li><p>Titel und beruflichem Kontext.</p></li><li><p>Geschäfts- und Unternehmensbeziehungen.</p></li><li><p>Mehrsprachigkeit und Transliterationsherausforderungen.</p></li><li><p>Kombinierten und Grenzfall-Szenarien.</p></li></ul></li></ul><p>Zu Beginn der Serie haben wir gesehen, dass die Verwendung von generativer KI (GenKI) zur Erstellung von Datensätzen ein zweischneidiges Schwert sein kann. Ohne sie wäre es äußerst schwierig, ausreichend große und vielfältige Testdaten zusammenzustellen. Aber wenn das Modell nicht kontrolliert wird, neigt es dazu, die Dinge zu einfach zu machen.</p><p>Bei einer frühen Generationsüberprüfung stellten wir beispielsweise fest, dass das Modell Formulierungen wie „der russische Präsident“ als expliziten Aliasnamen für Wladimir Putin enthielt. Das mag heute vernünftig erscheinen, aber es widerspricht dem Zweck der Prüfung der Kontextauflösung. Was passiert, wenn der Artikel Russland in den 1990er Jahren behandelt? Das System sollte die richtige Entität aus dem Kontext ableiten und sich nicht auf einen fest codierten Alias verlassen.</p><p>Aus diesem Grund wurde dieser Datensatz bewusst so konzipiert, dass <strong>Abkürzungen nicht funktionieren</strong>. Pseudonyme werden nicht explizit aufgeführt, wenn das System die Bedeutung erschließen soll. Beschreibende Phrasen sind nicht vorab mit Entitäten verknüpft. Korrekte Treffer hängen oft vom Kontext auf Artikelebene ab, nicht nur vom lokalen Text.</p><p><strong>Wichtiger Hinweis:</strong> Obwohl wir die Fähigkeiten des Systems in verschiedenen Szenarien demonstrieren, ist dies dennoch ein Bildungsprototyp. Produktionssysteme, die die Überwachung von sanktionierten Entitäten in der realen Welt handhaben, würden zusätzliche Validierung, Compliance-Prüfungen, Audit-Trails und eine spezialisierte Handhabung für sensible Anwendungsfälle erfordern.</p><h2>Warum diese Szenarien schwierig sind</h2><p>Im ersten Beitrag dieser Reihe haben wir ein einfaches, aber mehrdeutiges Beispiel vorgestellt: „Das neue Swift-Update ist da!“ Die Herausforderung besteht darin, dass „Swift“ je nach Kontext auf mehrere reale Entitäten aufgelöst werden kann. Dieses Beispiel verdeutlicht eine grundlegendere Wahrheit: Natürliche Sprache ist von Natur aus mehrdeutig.</p><p>Die Entitätsauflösung ist daher nicht nur ein Problem des Zeichenfolgenabgleichs. Menschen verlassen sich routinemäßig auf gemeinsames Wissen, kulturelle Normen und situativen Kontext, um Referenzen zu lösen, und oft merken wir gar nicht, dass wir das tun.</p><p>Betrachten wir ein paar gängige Fälle:</p><ul><li><p>Ein Titel wie „der Präsident“ ist ohne geopolitischen und zeitlichen Kontext bedeutungslos.</p></li><li><p>Ein Firmenname kann sich je nach Zeitpunkt der Artikelveröffentlichung auf ein Mutterunternehmen, eine Tochtergesellschaft oder eine ehemalige Marke beziehen.</p></li><li><p>Der Name einer Person kann in verschiedenen Reihenfolgen, Schriften oder Transliterationen erscheinen, abhängig von Sprache und Kultur.</p></li><li><p>Die gleiche Phrase kann in verschiedenen Kontexten legitimerweise auf unterschiedliche Entitäten verweisen, und das System muss in der Lage sein, Matches genauso zuversichtlich <em>abzulehnen</em>, wie sie zu akzeptieren.</p></li></ul><p>Es gibt kein einzelnes Regelwerk, das all dies sauber abdeckt. Deshalb trennt dieser Prototyp die verschiedenen Bereiche so konsequent:</p><ul><li><p>Elasticsearch schränkt den Kandidatenraum effizient und transparent ein.</p></li><li><p>Das LLM wird nur dort verwendet, wo ein Urteil erforderlich ist, und ist gezwungen, sich selbst zu erklären.</p></li><li><p>Abruf und Schlussfolgerung bleiben getrennte Schritte.</p></li></ul><p>Diese Trennung wird umso wichtiger, je größer die Vielfalt der Herausforderungen ist.</p><h2>So geht das System mit Vielfalt ohne Spezialfälle um</h2><p>Eines der interessantesten Ergebnisse dieser Bewertung ist, was <em>sich nicht geändert hat</em>:</p><ul><li><p>Wir haben <strong>keine</strong> spezielle Logik für japanische Namen hinzugefügt.</p></li><li><p>Wir haben <strong>keine</strong> benutzerdefinierten Regeln für arabische Patronyme hinzugefügt.</p></li><li><p>Wir haben <strong>keine</strong> fest codierten Mappings für historische Firmennamen hinzugefügt.</p></li></ul><p>Stattdessen basierte das System auf denselben Kernzutaten, die früher in der Serie eingeführt wurden:</p><ul><li><p>Mit Kontext angereicherte Entitäten, die für semantische Suchen indexiert sind.</p></li><li><p>Hybrider Abruf (exakt, per Alias und semantisch) in Elasticsearch.</p></li><li><p>Eine kleine, gut definierte Gruppe von Kandidatenmatches.</p></li><li><p>LLM-Bewertung eingeschränkt durch Funktionsaufruf und Minimalschemata.</p></li></ul><p>Das deutet darauf hin, dass die Flexibilität des Systems von <strong>Repräsentation und Architektur</strong> herrührt, nicht von einer ständig wachsenden Sammlung von Regeln.</p><p>Wenn das System erfolgreich ist, liegt das daran, dass die richtigen Kandidaten ermittelt werden und das LLM ausreichend Kontext hat, um zu erklären, warum eine Referenz einer bestimmten Entität zugeordnet wird oder nicht.</p><h2>Ergebnisse: Wie hat es abgeschnitten?</h2><p>Im ultimativ herausfordernden Datensatz erzielte das System folgende Gesamtergebnisse:</p><ul><li><p><strong>Präzision:</strong> ~91 %</p></li><li><p><strong>Rückruf:</strong> ~86 %</p></li><li><p><strong>F1-Score:</strong> ~89 %</p></li><li><p><strong>LLM-Annahmequote:</strong> ~72 %</p></li></ul><h3>Leistung nach Herausforderungstyp</h3><p>Die Aufschlüsselung der Ergebnisse nach Herausforderungstyp zeigt Stärken und Schwächen:</p><p><strong>Die stärkste Leistung (100 % F1-Score)</strong> wurde in folgenden Bereichen beobachtet:</p><ul><li><p>Schriftübergreifender Abgleich (kyrillische, koreanische, chinesische Unternehmen).</p></li><li><p>Hebräische Szenarien (Patronyme, Berufstitel, religiöse Titel, Transliteration).</p></li><li><p>Unternehmenshierarchien (Luft- und Raumfahrt, diversifizierte Fertigungsunternehmen, Konzerne mit mehreren Geschäftsbereichen).</p></li><li><p>Berufsbezeichnungen (akademisch, militärisch, politisch, religiös).</p></li><li><p>Kombinierte japanische Szenarien mit mehreren Schriftsystemen.</p></li></ul><p><strong>Starke Leistung (80–99 % F1-Score)</strong> umfassten:</p><ul><li><p>Internationale politische Persönlichkeiten (98 %).</p></li><li><p>Historische Namensänderungen (90 %).</p></li><li><p>Komplexe Unternehmenshierarchien (89 %).</p></li><li><p>Japanische Firmennamen (93 %).</p></li><li><p>Cross-Script-Transliteration (86 %).</p></li><li><p>Arabische Patronyme (86 %).</p></li></ul><p><strong>Problematischere Bereiche</strong> waren:</p><ul><li><p>Erweiterte Transliteration (Chinesisch, Koreanisch): 0 % F1.</p></li><li><p>Bestimmte japanische Szenarien (Höflichkeitsformen, Namensreihenfolge, Variationen des Schriftsystems): ~67 % F1.</p></li><li><p>Einige arabische Szenarien (Unternehmensnamen, institutionelle Referenzen): ~40 % F1.</p></li></ul><p>Wichtig ist hier, <em>warum</em> das System in diesen Fällen Schwierigkeiten hatte. Die Fehler waren nicht auf das Scheitern des Gesamtansatzes zurückzuführen, sondern auf Einschränkungen in bestimmten Komponenten, insbesondere dem dichten Vektormodell, das für die semantische Suche in bestimmten mehrsprachigen Szenarien verwendet wird.</p><p>Da Abruf und Beurteilung klar getrennt sind, erfordert die Leistungssteigerung keine Neuprogrammierung des Systems. Der Austausch eines leistungsfähigeren mehrsprachigen Einbettungsmodells, die Anreicherung des Entitätskontextes oder die Verfeinerung der Suchstrategien würde die Ergebnisse in diesen Kategorien verbessern, ohne die Kernarchitektur zu verändern.</p><p>Aus architektonischer Sicht ist das der eigentliche Erfolgsmaßstab.</p><h2>Was uns das über das Design verrät</h2><p>Beim Rückblick auf die Serie lassen sich einige Muster erkennen:</p><ul><li><p><strong>Vorbereitung ist wichtiger als kluges Matching. </strong>Die Anreicherung von Entitäten mit Kontextinformationen im Vorfeld reduziert spätere Mehrdeutigkeiten erheblich.</p></li><li><p><strong>LLMs sind als Bewertungs- und nicht als Abrufsysteme am wertvollsten. </strong>Sie um eine Erklärung zu bitten, <em>warum</em> eine Übereinstimmung sinnvoll ist, ist weitaus wirkungsvoller als sie um eine Suche zu bitten.</p></li><li><p><strong>Zuverlässigkeit ermöglicht Genauigkeit. </strong>Der Funktionsaufruf hat nicht nur JSON bereinigt, sondern auch den Abruf von Informationen freigegeben, die bereits in der Abrufphase latent waren.</p></li><li><p><strong>Verallgemeinerung schlägt Spezialisierung. </strong>Eine kleine Anzahl gut gewählter Abstraktionen bewältigte Dutzende von Aufgabentypen ohne benutzerdefinierte Logik.</p></li></ul><p>Aus diesem Grund ist der Prototyp bewusst Elasticsearch-nativ und konservativ in der Verwendung von LLMs. Das Ziel besteht nicht darin, das Suchen zu ersetzen. Es geht darum, das Suchen in Situationen erklärbar zu machen, in denen die Bedeutung wichtig ist.</p><h2>Fazit</h2><p>Die ultimative Herausforderung bestand nicht darin, perfekte Metriken zu verfolgen; es ging darum, eine grundlegendere Frage zu beantworten:</p><p><em>Kann eine transparente, suchbasierte, LLM-gestützte Architektur mit der Mehrdeutigkeit realer Entitäten umgehen, ohne in Regeln oder Blackboxes zu zerfallen?</em></p><p>Für diesen Bildungsprototyp lautet die Antwort ja, mit klaren Vorbehalten in Bezug auf Produktionshärtung, Compliance, Überwachung und Datenqualität. Wenn Sie Systeme erstellen, die begründen müssen, <em>warum</em> ein Entitätsabgleich vorgenommen wurde, ist dieses Muster eine ernsthafte Überlegung wert. Ich hoffe, diese Serie hat gezeigt, dass die Entitätsauflösung kein Mysterium sein muss. Mit der richtigen Aufteilung der Anliegen wird sie zu etwas, worüber man nachdenken, was man messen und verbessern kann.</p><p>Diese Arbeit deutet auch auf ein breiteres architektonisches Muster hin. Daraus entsteht eine leichte, aber wichtige Weiterentwicklung der klassischen Retrieval-Augmented-Generation (RAG). Anstatt die Abfrage direkt in die Generierung einfließen zu lassen, führen wir einen expliziten Bewertungsschritt ein. Das LLM wird zunächst zur Beurteilung und Plausibilitätsprüfung der abgerufenen Kandidaten verwendet, und nur die als geeignet befundenen Ergebnisse dürfen die Generierung erweitern. Sie können sich das als Generation-Augmented Retrieval-Augmented Generation with Evaluation oder GARAGE vorstellen, denn wer weiß nicht ein gutes Akronym zu schätzen?</p><p>Welche anderen Anwendungsfälle könnten von diesem Muster profitieren? Systeme, die Vertrauen, Transparenz und nachvollziehbare Argumentation erfordern, sind natürliche Kandidaten. Die künftige Arbeit in diesem Bereich sollte sich als ebenso überzeugend erweisen wie die Ergebnisse, die wir hier gesehen haben, und ich bin gespannt, wie sich die Gemeinschaft weiter entwickelt.</p><h2>Nächste Schritte: Versuchen Sie es selbst</h2><p>Möchten Sie die ultimative Herausforderung in Aktion sehen? Schauen Sie sich das <a href="https://github.com/jesslm/entity-resolution-lab-public/tree/main/notebooks#:~:text=5%20minutes%20ago-,05_ultimate_challenge_v3.ipynb,-Initial%20public%20lab"><strong>Ultimate Challenge-Notebook</strong></a> für eine vollständige Anleitung mit realen Implementierungen, detaillierten Erklärungen und praktischen Beispielen an.</p><p>Die vollständige Pipeline zur Entitätsauflösung demonstriert die Kernkonzepte und die Architektur, die für den produktiven Einsatz erforderlich sind. Sie können es als Grundlage nutzen, um Systeme zu entwickeln, die Nachrichtenartikel überwachen, Erwähnungen von Entitäten verfolgen und Fragen beantworten, welche Entitäten in welchen Artikeln erscheinen – und das alles, während Transparenz und Erklärbarkeit erhalten bleiben.
</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/entity-resolution-elasticsearch-llm-challenges</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/entity-resolution-elasticsearch-llm-challenges</guid>
    <category><![CDATA[KI]]></category>
    <category><![CDATA[Hybride Suche]]></category>
    <dc:creator><![CDATA[Jessica Moszkowicz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc58be329ffebcd60/6a17043e47d49c0bc62d88ab/70fb0ff949f6db9ac9b8a28ecb4329ab915ebf46-720x420.png" length="0" type="image/png"/>
    <pubDate>Fri, 13 Mar 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Entitätsauflösung mit Elasticsearch & LLMs, Teil 2: Abgleich von Entitäten mit LLM-Bewertung und semantischer Suche]]></title>
    <description><![CDATA[Verwendung semantischer Suche und transparenter LLM-Bewertung zur Entitätsauflösung in Elasticsearch.]]></description>
    <content:encoded><![CDATA[<p>In<a href="https://www.elastic.co/search-labs/blog/entity-resolution-llm-elasticsearch"> Teil 1</a> haben wir unsere Watchlist vorbereitet und Entitätserwähnungen extrahiert. Nun können wir die schwierige Frage beantworten: Auf welche Entität bezieht sich die Erwähnung eigentlich? Kehren wir zu dem Beispiel im ersten Blog dieser Serie zurück, das verdeutlicht, warum wir eine Entitätsauflösung benötigen: „Das Swift-Update ist da!“ Stellen Sie sich vor, diese Überschrift wird von etwas mehr Kontext begleitet:</p><ol><li><p>Das neue Swift-Update ist da! Entwickler sind gespannt darauf, die neuen Features auszuprobieren.</p></li><li><p>Das neue Swift-Update ist da! Das neue Album erscheint nächsten Monat.</p></li></ol><p>Mit diesem zusätzlichen Kontext sollten wir den Namen „Swift“ der richtigen Entität zuordnen können.</p><p>Im <a href="https://www.elastic.co/search-labs/blog/entity-resolution-llm-elasticsearch">vorherigen Beitrag</a> haben wir unsere Watchlist eingerichtet und die Entitäten mit zusätzlichem Kontext angereichert. Anhand unserer obigen Beispiele müssen wir mindestens die folgenden beiden Elemente in der Liste haben: Taylor Swift und Swift Programming Language. Wir haben auch besprochen, wie wir Entitätserwähnungen aus Text extrahieren. Beide Beispiele würden „Swift“ extrahieren. Mit diesen Zutaten, der angereicherten Watchlist und den extrahierten Entitäten, sind wir endlich bereit, den Star der Show vorzustellen: den Entitätsabgleich.</p><p><strong>Denken Sie daran:</strong> Dies ist ein pädagogischer Prototyp, der entwickelt wurde, um Konzepte zum Abgleich von Entitäten zu vermitteln. Produktionssysteme könnten verschiedene große Sprachmodelle (LLMs), benutzerdefinierte Abgleichsregeln, spezialisierte Bewertungspipelines oder Ensemble-Ansätze verwenden, die mehrere Abgleichsstrategien kombinieren.</p><h2>Das Problem: Warum der Abgleich schwierig ist</h2><p>Die menschliche Sprache ist eine bemerkenswerte Sache. Eine ihrer interessantesten Eigenschaften ist ihre unendliche Kreativität. Wir können eine unendliche Anzahl neuer Sätze erzeugen und verstehen. Ist es dann verwunderlich, dass exakte Übereinstimmungen bei der Entitätsauflösung selten sind? Autoren bemühen sich, kreativ zu sein, wenn sie können. Es wäre ziemlich mühsam, wenn wir immer die vollständigen Namen schreiben und lesen müssten, wenn eine Entität erwähnt wird. Exakte Übereinstimmungen sind zwar einfach, aber die Realität sieht so aus, dass wir einen ausgefeilteren Ansatz zur Entitätsauflösung benötigen: einen, der robust genug ist, um zumindest einen Teil der grenzenlosen Kreativität menschlicher Autoren zu bewältigen. Deshalb unterteilen wir das Problem in zwei Schritte: Mit Elasticsearch werden plausible Kandidaten skaliert abgerufen, und anschließend wird mit einem LLM beurteilt, ob sich diese Kandidaten tatsächlich auf dieselbe reale Entität beziehen.</p><h2>Die Lösung: Dreistufiger Abgleich mit transparenter LLM-Bewertung</h2><p>Wir befinden uns mitten in einem Paradigmenwechsel in der Art und Weise, wie wir Computer nutzen. Genauso wie der Aufstieg des Internets uns vom lokalen Computing zu einem global vernetzten Netzwerk geführt hat, verändert die generative KI grundlegend die Art und Weise, wie Inhalte, Code und Informationen erstellt werden. Tatsächlich wurde der pädagogische Prototyp, der diese Serie begleitet, fast ausschließlich „Vibe-codiert“ unter Verwendung eines LLMs mit sorgfältiger Eingabe durch den Autor. Das soll nicht heißen, dass LLMs die Produktivität der menschlichen Sprache erreicht haben oder erreichen werden, aber es bedeutet, dass wir jetzt eine leistungsstarke Ressource haben, die uns bei der Entitätsauflösung unterstützt.</p><p>Ein häufiges Muster, das wir mit GenAI verwenden, ist Retrieval-Augmented Generation (RAG). Hier bedeutet <em>Abrufen</em> das Abrufen von Entitätskandidaten (nicht das Generieren von Antworten), und das LLM wird ausschließlich für die Bewertung und Erklärung von Übereinstimmungen verwendet. Obwohl wir ein LLM um Unterstützung bei der End-to-End-Lösung von Entitäten bitten <em>könnten</em>, ist das sowohl zeitlich als auch finanziell kostspielig. RAG hilft LLMs bei ihrer Arbeit, indem es effizientere Wege nutzt, um dem LLM Kontext bereitzustellen, und ermöglicht es dem LLM so, effizient bei der Entitätsauflösung zu helfen.</p><p>Für den Abrufteil von RAG greifen wir erneut auf Elasticsearch zurück. Zunächst ermitteln wir potenzielle Übereinstimmungen mithilfe einer Kombination aus exaktem Abgleich, Abgleich mit Aliasen und hybrider Suche, die Stichwort- und semantische Suche kombiniert. Sobald wir diese potenziellen Übereinstimmungen gefunden haben, schicken wir sie an ein LLM zur Bewertung. Das LLM fungiert als der letzte Übereinstimmungsbewerter. Wir lassen das LLM außerdem seine Argumentation erläutern, was ein wichtiges Unterscheidungsmerkmal zu anderen Entitätsauflösungssystemen darstellt. Ohne diese Erklärungen ist die Entitätsauflösung eine Blackbox; mit ihnen können wir selbst sehen, warum eine Übereinstimmung Sinn ergibt.</p><h2>Schlüsselkonzepte: Drei-Schritte-Abgleich, hybride Suche und transparente LLM-Bewertung</h2><p><strong>Was ist der Drei-Schritte-Abgleich?</strong> Zu Beginn dieses Projekts haben wir die Hypothese aufgestellt, dass die semantische Suche ein entscheidender Bestandteil des Systems sein wird, aber nicht jeder Abgleich erfordert eine so ausgefeilte Suche. Um effizient Übereinstimmungen zu finden, gehen wir das Problem progressiv an. Zuerst überprüfen wir exakte Übereinstimmungen mit der Stichwortsuche. Wenn wir eine solche Übereinstimmung finden, ist unsere Arbeit getan und wir können weitermachen. Wenn der exakte Abgleich fehlschlägt, wenden wir uns dem Aliasabgleich zu. Im Prototyp wird der Einfachheit halber auch der Aliasabgleich mit Stichwörtern durchgeführt. In der Produktion können Sie diesen Schritt durch Normalisierung, Transliterationsregeln, Fuzzy Matching oder kuratierte Aliastabellen erweitern. Wenn wir in den ersten beiden Schritten immer noch keinen potenziellen Treffer gefunden haben, dann ist es an der Zeit, die semantische Suche über die hybride Suche von Elasticsearch mit Reciprocal Rank Fusion (RRF) einzuführen.</p><p><strong>Was ist die hybride Suche?</strong> In Elasticsearch können wir die semantische Suche nutzen, um bedeutungsvolle Übereinstimmungen zu finden, die Kontext berücksichtigen. Elasticsearch wird häufig für Vektorsuche und hybride Abfrageverfahren eingesetzt. Semantische Ähnlichkeit ist sehr aussagekräftig, aber sie ist kein Ersatz für strukturiertes Filtern (z. B. nach Zeitspannen, Orten oder Identifikatoren) und ist oft unnötig, wenn eine exakte Übereinstimmung verfügbar ist. Elasticsearch hat sich mit der lexikalischen Suche einen Namen gemacht, die sich hervorragend für Aufgaben eignet, bei denen die semantische Suche nicht ausreicht. Um beide Ansätze voll auszuschöpfen, verwenden wir die lexikalische Suche neben der semantischen Suche in einer einzigen hybriden Abfrage. Anschließend führen wir die Ergebnisse zusammen, um mithilfe von RRF die wahrscheinlichsten Übereinstimmungen zu finden. Im Prototyp werden die oberen zwei Ergebnisse zu potenziellen Übereinstimmungen, die zur LLM-Bewertung gesendet werden können.</p><p><strong>Warum die LLM-Bewertung?</strong> LLM-Bewertungen und -Erklärungen ermöglichen es unserem System, Ambiguität und Kontext transparent zu behandeln. Dies ist entscheidend für Fälle wie „der Präsident“, die sich auf mehrere Entitäten beziehen können, abhängig vom Kontext, aber es ermöglicht auch, dass Dinge wie Spitznamen und kulturelle Variationen gut im System funktionieren. Und schließlich müssen wir bei geschäftskritischen Aufgaben, wie der Identifizierung von Personen aus Sanktionslisten, wissen, warum ein Treffer akzeptiert wurde, um dem System vertrauen zu können. Entscheidend ist, dass das LLM nicht den gesamten Korpus durchsucht; es bewertet nur die kleine Anzahl von Kandidaten, die von Elasticsearch zurückgegeben werden.</p><h2>Reale Ergebnisse: Übereinstimmung mit der LLM-Argumentation</h2><p>Eine große Herausforderung bei jeder Aufgabe der natürlichen Sprachverarbeitung ist die Erstellung eines Referenzdokuments, eines „Lösungsschlüssels“, der uns mitteilt, was die zu erwartenden Ergebnisse sind. Ohne diese Grundlage ist es nahezu unmöglich zu beurteilen, wie gut ein System eine Aufgabe erfüllt. Doch die Erstellung eines solchen Dokuments kann ein mühsamer Prozess sein. Für den Prototyp zur Entitätsauflösung haben wir uns erneut an generative KI gewandt, um Unterstützung bei der Einrichtung von Testdaten zu erhalten.</p><p>Zunächst definierten wir mehrere Herausforderungstypen, wie Spitznamen und Transliteration, und baten dann das LLM, eine gestufte Sammlung von Datensätzen zu erstellen, die für das System zunehmend größer und anspruchsvoller werden sollte. Die Erstellung der Datensätze war weniger einfach, als man es sich erhoffen könnte. Das LLM hatte eine starke Neigung zum „Betrügen“, indem es zu einfach wurde, die richtige Antwort zu erhalten. Eine der Herausforderungen konzentrierte sich zum Beispiel auf den semantischen Kontext. Zu dieser Art gehörte beispielsweise die Auflösung von „russischer Autor“ zu „Leo Tolstoi“. Das LLM hat fälschlicherweise „russischer Autor“ als Alias für „Leo Tolstoi“ verwendet, was die Notwendigkeit einer Hybridsuche zum Finden der Übereinstimmung negierte.</p><p>Nach mehreren Refaktorierungen, um Probleme wie dieses zu beheben, hatten wir fünf Datensatzstufen, mit denen wir arbeiten konnten. Die Stufen 1–4 waren zunehmend größer und boten mehr Herausforderungstypen. Stufe 5 war der Datensatz der „ultimativen Herausforderung“, der aus den kniffligsten Beispielen aller Herausforderungstypen bestand. Sämtliche Testdaten sind im <a href="https://github.com/jesslm/entity-resolution-lab-public/tree/main/comprehensive_evaluation">umfassenden Auswertungsverzeichnis</a> verfügbar.</p><p>Zur Evaluierung unseres auf Eingabeaufforderungen basierenden Ansatzes zur Entitätsauflösung konzentrierten wir uns auf den Stufe-4-Datensatz. Ein wichtiger Hinweis ist, dass die Bewertung als kontrolliertes Experiment durchgeführt wurde, so dass wir uns auf die Qualität der Entitätsübereinstimmung konzentrieren konnten. Die Daten der Watchlist wurden vorab mit Kontext angereichert, und Entitäten wurden im Voraus aus dem Artikel extrahiert. Dadurch wurde sichergestellt, dass sich die Bewertung auf den Abgleich und nicht auf die Genauigkeit der Extraktion konzentrierte. Dies isoliert die Qualität der Übereinstimmungen; die Gesamtleistung hängt zusätzlich von der Trefferquote bei der Extraktion und der Qualität der Anreicherung ab.</p><h3>Evaluationsdatensatz</h3><p>Der Evaluierungsdatensatz der Stufe 4 bietet einen umfassenden Test der Leistungsfähigkeit des Systems:[1]</p><ul><li><p><strong>Watchlist-Entitäten:</strong> 66 Entitäten unterschiedlichster Art (Personen, Organisationen, Standorte).</p></li><li><p><strong>Testartikel:</strong> 69 Artikel über reale Szenarien zur Auflösung von Entitäten.</p></li><li><p><strong>Erwartete Übereinstimmungen:</strong> 206 erwartete Entitätsübereinstimmungen in allen Artikeln.</p></li><li><p><strong>Herausforderungstypen: </strong>15 verschiedene Herausforderungstypen, die verschiedene Aspekte der Entitätsauflösung prüfen.</p></li></ul><p>Die in den Datensätzen enthaltenen Herausforderungstypen sind:</p><ul><li><p><strong>Spitznamen:</strong> „Bob Smith“ → „Robert Smith“ (sieben Artikel).</p></li><li><p><strong>Titel und Ehrenbezeichnungen:</strong> „Dr. Sarah Williams“ → „Sarah Williams“ (fünf Artikel).</p></li><li><p><strong>Semantischer Kontext:</strong> „Russischer Autor“ → „Leo Tolstoi“ (acht Artikel).</p></li><li><p><strong>Mehrsprachige Namen:</strong> Umgang mit Namen in verschiedenen Skripten (sechs Artikel).</p></li><li><p><strong>Geschäftseinheiten:</strong> Variationen von Firmennamen (sieben Artikel).</p></li><li><p><strong>Referenzen von Führungskräften: </strong>„Microsoft CEO“ → „Satya Nadella“ (fünf Artikel).</p></li><li><p><strong>Politische Führungspersönlichkeiten:</strong> Titelbasierte Referenzen (fünf Artikel).</p></li><li><p><strong>Initialen:</strong> „J. Smith“ → „John Smith“ (drei Artikel).</p></li><li><p><strong>Varianten der Namensreihenfolge:</strong> Verschiedene Konventionen für die Namensreihenfolge (drei Artikel).</p></li><li><p><strong>Abgekürzte Namen:</strong> Teilweise Namensübereinstimmungen (drei Artikel).</p></li><li><p><strong>Namensaufteilung:</strong> Namen, die über Text verteilt sind (drei Artikel).</p></li><li><p><strong>Fehlende Leerzeichen/Bindestriche:</strong> Formatierungsabweichungen (zwei Artikel).</p></li><li><p><strong>Transliteration:</strong> Skriptübergreifender Namensabgleich (zwei Artikel).</p></li><li><p><strong>Kombinierte Herausforderungen:</strong> Mehrere Herausforderungen in einem Artikel (sechs Artikel).</p></li><li><p><strong>Komplexe Geschäftsbeziehungen:</strong> Hierarchische Geschäftsbeziehungen (fünf Artikel).</p></li></ul><p>Mal sehen, wie die auf Eingabeaufforderungen basierende Entitätsauflösung funktioniert hat.</p><h3>Gesamtleistung</h3><p>Die Ergebnisse zeigen, dass die LLM-gestützte Übereinstimmungsbewertung vielversprechend ist, aber sie offenbaren auch ein erhebliches Zuverlässigkeitsproblem. Da jedes Kandidatenpaar vom LLM bewertet werden muss, können Fehler im strukturierten Ausgang die Akzeptanz und das Erinnern unterdrücken, selbst wenn der Abruf gut funktioniert.</p><p>Metrik</p><p>Wert</p><p>Präzision</p><p>83,8 %</p><p>Abruf</p><p>62,6 %</p><p>F1-Score</p><p>71,7 %</p><p>Gesamtanzahl der Übereinstimmungen</p><p>344</p><p>LLM-Annahmequote</p><p>44,8 %</p><p>Fehlerquote</p><p>30,2 %</p><h3>Das Problem mit der Fehlerrate</h3><p>Zur Erinnerung: Der erste Schritt im Prototyp besteht darin, mithilfe von Elasticsearch potenzielle Übereinstimmungspaare zu erstellen. Jede dieser potenziellen Übereinstimmungen muss vom LLM bewertet werden. Um all diese Übereinstimmungen effizient zu verarbeiten, fassen wir die LLM-Aufrufe in Batches zusammen. Dies reduziert die API-Kosten und die Latenzzeit, aber es besteht auch ein erhöhtes Risiko, dass der Ausgang fehlerhaftes JSON enthält. Mit zunehmender Batchgröße wird das JSON länger und komplexer, wodurch die Wahrscheinlichkeit steigt, dass der LLM ungültiges JSON generiert. Hier liegt der Ursprung der Fehlerquote von 30 %. In der Bewertung haben wir eine Batch-Größe von fünf Übereinstimmungen pro Anfrage verwendet. Selbst bei dieser konservativen Batchgröße beobachten wir immer noch JSON-Parsing-Fehler, welche die Auswertungsergebnisse erheblich verfälschen.</p><h2>Nächstes Ziel: Optimierung der LLM-Integration</h2><p>Nachdem wir nun Entitäten mithilfe semantischer Suche und LLM-Bewertung abgeglichen haben, verfügen wir über eine vollständige Entitätsauflösungspipeline. Dieser Ansatz führt jedoch einen neuen Ausfallmodus ein, wenn die Einschätzung des Modells richtig ist, sein Ausgang jedoch nicht nutzbar ist. Wir können die LLM-Integration im Hinblick auf höhere Zuverlässigkeit und Kosteneffizienz optimieren. Im nächsten Beitrag werden wir untersuchen, wie Sie Funktionsaufrufe für einen strukturierten Ausgang verwenden können, der garantierte Struktur- und Typsicherheit bietet und gleichzeitig Fehler und Kosten reduziert.</p><h2>Probieren Sie es selbst aus</h2><p>Möchten Sie den Entitätsabgleich in Aktion sehen? Schauen Sie sich das <a href="https://github.com/jesslm/entity-resolution-lab-public/tree/main/notebooks#:~:text=5%20minutes%20ago-,03_entity_matching_v3.ipynb,-Initial%20public%20lab">Entitätsabgleich-Notizbuch</a> für eine vollständige Anleitung mit realen Implementierungen, detaillierten Erklärungen und praktischen Beispielen an. Das Notizbuch zeigt Ihnen genau, wie Sie Entitäten mithilfe der dreistufigen Suche, der hybriden Suche mit RRF und der LLM-gestützten Bewertung mit Schlussfolgerungen abgleichen.</p><p><strong>Denken Sie daran:</strong> Dies ist ein pädagogischer Prototyp, der entwickelt wurde, um die Konzepte zu vermitteln. Bei der Entwicklung von Produktionssystemen sollten zusätzliche Faktoren wie Modellauswahl, Kostenoptimierung, Latenzanforderungen, Qualitätsvalidierung, Fehlerbehandlung und Überwachung berücksichtigt werden, die in diesem lernorientierten Prototyp nicht behandelt werden.</p><h2>Anmerkungen</h2><ol><li><p>Diese Datensätze sind synthetisch und für Bildungszwecke konzipiert; sie nähern sich realen Herausforderungen an, sind aber nicht repräsentativ für eine einzelne Produktionsdomäne.</p></li></ol>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-entity-resolution-llm-semantic-search</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-entity-resolution-llm-semantic-search</guid>
    <category><![CDATA[KI]]></category>
    <category><![CDATA[Hybride Suche]]></category>
    <dc:creator><![CDATA[Jessica Moszkowicz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltefc59243d9990405/6a17056ab339d5778f769ebf/473ca4357c7d60f690edbd2a844acda169aca9c3-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 26 Feb 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Sicherstellung semantischer Präzision mit Mindestscore]]></title>
    <description><![CDATA[Verbessern Sie die semantische Präzision durch die Verwendung von Schwellenwerten für die Mindestscore. Der Artikel enthält konkrete Beispiele für die semantische und hybride Suche. ]]></description>
    <content:encoded><![CDATA[<p>Die semantische Suche hat eine Vielzahl von Möglichkeiten für die Suchrelevanz eröffnet. Hochwertige dünn und dicht besetzte Modelle wie ELSER, E5 und Jina Embedding v4 liefern relevante Ergebnisse, die auf der Bedeutung von Wörtern basieren und nicht auf der Übereinstimmung von Schlüsselwörtern. Allerdings liefert die semantische Suche gelegentlich irrelevante Ergebnisse am Ende der Liste oder bei Suchanfragen, für die es keine relevanten Ergebnisse im Index gibt. Diese Eigenschaft von spärlichen und dichten Modellen kann Nutzer verwirren oder wertvolle Token für große Sprachmodelle (LLMs) verschwenden.</p><p>In diesem Artikel erfahren Sie, wie Sie den Parameter „Mindestscore“ verwenden können, um die Genauigkeit Ihrer semantischen Suchergebnisse zu erhöhen. Wenn Sie die in diesem Blogbeitrag bereitgestellten Beispiele testen möchten, besuchen Sie <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/ensuring-semantic-precision-with-minimum-score/ensuring_semantic_precision_with_minimum_score.ipynb">das zugehörige Jupyter-Notizbuch</a>.</p><h2>Hintergrund: Präzision und Abruf</h2><p>In der Suchrelevanz sind <em>Präzision </em>und <em>Recall </em>Schlüsselkonzepte. Lesern, die noch nicht mit diesen Themen vertraut sind, wird dringend empfohlen, sich darüber zu informieren. Nachfolgend eine Zusammenfassung.</p><ul><li><p><strong>Genauigkeit: </strong>Der Anteil der zurückgegebenen Suchergebnisse, die für den Nutzer relevant sind.</p></li><li><p><strong>Recall: </strong>Der Anteil aller relevanten Dokumente im Korpus, die in den Suchergebnissen enthalten sind.</p></li></ul><p>Oder, mit anderen Worten, Präzision gibt <strong>nur </strong>relevante Ergebnisse zurück; und Recall gibt <strong>alle </strong>relevanten Ergebnisse zurück. Wie Sie sich vorstellen können, handelt es sich dabei oft um konkurrierende Anforderungen. Die semantische Suche weist tendenziell eine sehr hohe Trefferquote auf, hat aber mitunter Schwierigkeiten mit der Präzision. Lesen Sie weiter, um zu erfahren, wie Sie diese Eigenschaft umgehen können.</p><h2>Einführung des Mindestscore-Parameters</h2><p>Der ‘min_score’-Parameter ermöglicht es uns, die Präzision zu verbessern, indem ein Mindestscore festgelegt wird, der das Ergebnisset durch Entfernen aller Treffer mit einem Score unter dem definierten Schwellenwert kürzt. Nachfolgend ein einfaches Beispiel:</p>GET search-movies/_search
{
  "retriever": {
    "linear": {
      "min_score": 4,
      "retrievers": [
        ...
      ]
    }
  }
}<h2>Normalisierung des Scores</h2><p>Die Festlegung eines Mindestscores ist schön und gut, aber nicht alle semantischen Modelle liefern einen Score, die sich für einen statischen Schwellenwert eignet. ELSER gibt beispielsweise einen unbegrenzten Score zurück. <a href="https://huggingface.co/intfloat/e5-small#faq">Einige</a> Scores des dichten Modells sind eng gruppiert und nur im Zusammenhang mit der spezifischen Anfrage sinnvoll.</p><p>Für die meisten Fälle der semantischen Suche empfehlen wir, vor der Anwendung von „min_score“ einen Normalisierungsansatz zu verwenden. Durch die Normalisierung wird sichergestellt, dass der Dokumentenscore innerhalb eines definierten Intervalls liegt. Elasticsearch-Retriever bieten zwei solcher <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers/linear-retriever#linear-retriever-normalizers">Normalisierer</a>, ‘l2_norm’ und ‘minmax’. Am häufigsten wird die „minmax“-Methode verwendet, da sie leicht verständlich ist und in vielen Szenarien gut funktioniert. Wichtige Eigenschaften von ‘minmax’ umfassen:</p><ul><li><p>Die Dokumentenscores liegen im Bereich von 0 bis 1.</p></li><li><p>Das Dokument mit der höchsten Punktzahl erhält immer den Score 1.</p></li><li><p>Das Dokument mit der niedrigsten Punktzahl erhält immer den Score 0.</p><ul><li><p>Dies kann die Eignung für die Stichwortsuche beeinträchtigen. Weitere Informationen finden Sie im Abschnitt „Hybride Suche“.</p></li></ul></li></ul><p>Im Folgenden ein Beispiel für eine normalisierte semantische Abfrage mit <code>min_score</code>. Die Größe des Ranking-Fensters wurde auf 500 erhöht, damit wir eine längere Liste von Suchergebnissen zurückgeben können, angefangen bei 100.</p>GET search-movies/_search
{
  "size": 100,
  "_source": [
    "title", "overview"
  ],
  "retriever": {
    "linear": {
      "rank_window_size": 500,
      "min_score": 0.25,
      "retrievers": [
        {
          "normalizer": "minmax",
          "retriever": {
            "standard": {
              "query": {
                "semantic": {
                  "field": "overview_vector",
                  "query": "superhero movie"
                }
              }
            }
          }
        }
      ]
    }
  }
}<p>Die Größe wurde auf einen höheren Wert als in der Produktion üblich eingestellt. So können wir die Qualität der Suchergebnisse inspizieren und die Ergebnisse optimieren.</p><h2>Hybridsuche mit dem linearen Retriever</h2><p>Für die Hybridsuche ist der einfachste Ansatz, alle Scores zu normalisieren, Gewichte zuzuweisen und einen Mindestscore anzuwenden. Beachten Sie, dass Sie durch die Wahl von Gewichtungen mit einer Summe von 1 den Gesamtscore innerhalb eines Bereichs von 0 bis 1 halten. Dadurch lassen sich die Endergebnisse leicht nachvollziehen und die Melodie <code>min_score</code> stimmen. Nachfolgend ein Beispiel:</p>GET search-movies/_search
{
  "size": 100,
  "_source": ["title", "overview","keywords"],
  "retriever": {
    "linear": {
      "rank_window_size": 500,
      "min_score": 0.25,
      "retrievers": [
        {
          "weight": 0.6,
          "normalizer": "minmax",
          "retriever": {
            "standard": {
              "query": {
                "semantic": {
                  "field": "overview_vector",
                  "query": "superhero movie"
                }
              }
            }
          }
        },
        {
          "weight": 0.4,
          "normalizer": "minmax",
          "retriever": {
            "standard": {
              "query": {
                "multi_match": {
                  "query": "superhero movie",
                  "fields": ["overview","keywords", "title"],
                  "type": "cross_fields",
                  "minimum_should_match": "2"
                }
              }
            }
          }
        }
      ]
    }
  }
}<h2>Hybridsuche mit RRF</h2><p>Mit BM25 steuern wir die Präzision oft durch andere Mittel, wie die Verwendung des <code>AND</code>-Operators oder <code>minimum_should_match</code>. Darüber hinaus werden Abfragen, die aus einzelnen, präzisen und seltenen Begriffen bestehen, natürlicherweise zu Suchergebnissen mit wenigen Suchergebnissen führen, die oft alle hochrelevant sind. Dies kann zu Folgendem führen:</p><ul><li><p>Ergebnisse, die weiter hinten im Ergebnis stehen, erhalten im BM25-Retriever einen niedrigen normalisierten Score, selbst wenn der absolute BM25-Score nahe an den Treffern mit den höchsten Scores liegt.</p></li><li><p>Wenn ein sehr niedriger BM25-Score zum semantischen Score hinzugefügt wird, kann die Summe als semantischer Score approximiert werden.</p></li><li><p>Das Fehlen eines BM25-Score-Beitrags kann dazu führen, dass das Dokument von <code>min_score threshold</code> verworfen wird.</p></li></ul><p>Als Lösung können wir stattdessen die reziproke Rangfusion (RRF) verwenden, um BM25- und semantische Ergebnisse zu kombinieren. RRF umgeht die Herausforderung, Scores verschiedener Suchalgorithmen zu vergleichen, indem es sich stattdessen auf die Position in jedem Ergebnis auf konzentriert. In diesem Szenario wird die <code>min_score</code> nur auf den semantischen Retriever angewendet.</p>GET search-movies/_search
{
  "_source": ["title", "overview","keywords"],
  "retriever": {
    "rrf": {
      "rank_window_size": 500,
      "retrievers": [
        {
          "linear": {
            "rank_window_size": 500,
            "min_score": 0.25,
            "retrievers": [
              {
                "normalizer": "minmax",
                "retriever": {
                  "standard": {
                    "query": {
                      "semantic": {
                        "field": "overview_vector",
                        "query": "superhero movie"
                      }
                    }
                  }
                }
              }
            ]
          }
        },
        {
          "standard": {
            "query": {
              "multi_match": {
                "query": "superhero movie",
                "fields": ["overview", "keywords","title"],
                "type": "cross_fields",
                "minimum_should_match": "2"
              }
            }
          }
        }
      ]
    }
  }
}<h2>Fazit</h2><p>Mit <code>min_score</code> haben wir gezeigt, wie wir die Anzahl der Fehlalarme in unseren Ergebnissätzen reduzieren können, die durch den hohen Recall semantischer Suchalgorithmen verursacht werden. Um mehr über Retriever zu erfahren, siehe bitte diesen <a href="https://www.elastic.co/search-labs/blog/elasticsearch-retrievers">Blogbeitrag</a> und die <a href="https://www.elastic.co/docs/solutions/search/retrievers-overview">Elasticsearch-Dokumentation</a>.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/semantic-precision-minimum-score</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/semantic-precision-minimum-score</guid>
    <category><![CDATA[Relevanz]]></category>
    <category><![CDATA[Hybride Suche]]></category>
    <dc:creator><![CDATA[Mattias Brunnert]]></dc:creator>
    <pubDate>Fri, 20 Feb 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Erstellung eines ChatGPT-Konnektors mit Elasticsearch zur Abfrage von GitHub-Issues]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie einen benutzerdefinierten ChatGPT-Konnektor erstellen und einen Elasticsearch MCP-Server bereitstellen, der die hybride Suche verwendet, um interne GitHub Issues abzufragen.]]></description>
    <content:encoded><![CDATA[<p>Kürzlich hat OpenAI <a href="https://help.openai.com/en/articles/11487775-connectors-in-chatgpt">benutzerdefinierte Konnektoren</a> für ChatGPT für Pro-, Business-, Enterprise- und Edu-Abos angekündigt. Sie ergänzen die vorkonfigurierten Konnektoren zum Abrufen von Daten auf Gmail, GitHub, Dropbox usw. Es ist möglich, mithilfe von MCP-Servern benutzerdefinierte Konnektoren zu erstellen.</p><p>Benutzerdefinierte Konnektoren ermöglichen es Ihnen, Ihre vorhandenen ChatGPT-Konnektoren mit zusätzlichen Datenquellen wie Elasticsearch zu kombinieren, um umfassende Antworten zu erhalten.</p><p>In diesem Artikel werden wir einen <a href="https://modelcontextprotocol.io/docs/getting-started/intro">MCP</a>-Server erstellen, der ChatGPT mit einem Elasticsearch-Index verbindet, der Informationen zu internen GitHub Issues und Pull Requests enthält. So können Abfragen in natürlicher Sprache mit Ihren Elasticsearch-Daten beantwortet werden.</p><p>Wir werden den MCP-Server mithilfe von <a href="https://gofastmcp.com/getting-started/welcome">FastMCP</a> auf Google Colab mit ngrok bereitstellen, um eine öffentliche URL zu erhalten, mit der ChatGPT eine Verbindung herstellen kann. Dadurch entfällt die Notwendigkeit einer komplexen Infrastruktureinrichtung.</p><p>Einen umfassenden Überblick über MCP und sein Ökosystem finden Sie unter <a href="https://www.elastic.co/search-labs/blog/mcp-current-state">„Der aktuelle Stand von MCP“</a>.</p><h2>Voraussetzungen</h2><p>Vor Beginn benötigen Sie Folgendes:</p><ul><li><p>Elasticsearch-Cluster (8.X oder höher)</p></li><li><p>Elasticsearch-API-Schlüssel mit Lesezugriff auf Ihren Index</p></li><li><p>Google-Konto (für Google Colab)</p></li><li><p>Ngrok-Konto (das kostenlose Abo genügt)</p></li><li><p>ChatGPT-Konto mit Pro-, Enterprise-, Business- oder Edu-Plan</p></li></ul><h2>Die Anforderungen für ChatGPT MCP-Konnektoren verstehen</h2><p>Für die ChatGPT MCP-Konnektoren müssen zwei Tools implementiert werden: <code>search</code> und <code>fetch</code>. Weitere Einzelheiten finden Sie in den <a href="https://platform.openai.com/docs/mcp#create-an-mcp-server">OpenAI Dokumenten</a>.</p><h3><a href="https://platform.openai.com/docs/mcp#search-tool">Suchtool</a></h3><p>Gibt eine Liste relevanter Ergebnisse aus Ihrem Elasticsearch-Index auf der Grundlage einer Benutzerabfrage zurück.</p><h4>Das erhält es:</h4><ul><li><p>Eine einzelne Zeichenfolge mit der Anfrage des Benutzers in natürlicher Sprache.</p></li><li><p>Beispiel: „Finde Probleme im Zusammenhang mit der Elasticsearch-Migration.“</p></li></ul><h4>Was es zurückgibt: </h4><ul><li><p>Ein Objekt mit einem <code>result</code>-Schlüssel, der ein Array von result-Objekten enthält. Jedes Ergebnis umfasst:</p><ul><li><p><code>id</code> - Eindeutige Dokumentkennung</p></li><li><p><code>title</code> - Titel eines Issues oder Pull Requests (PR)</p></li><li><p><code>url</code> - Link zum Issue/PR</p></li></ul></li></ul><h4>In unserer Implementierung:</h4>return {
    "results": [
        {
            "id": "PR-612",
            "title": "Fix memory leak in WebSocket notification service",
            "url": "https://internal-git.techcorp.com/pulls/612"
        },
        # ... more results
    ]
}<h3><a href="https://platform.openai.com/docs/mcp#fetch-tool">Abrufwerkzeug</a></h3><p>Ruft den vollständigen Inhalt eines bestimmten Dokuments ab.</p><h4>Das erhält es:</h4><ul><li><p>Eine einzelne Zeichenfolge mit der Elasticsearch-Dokument-ID aus dem Suchergebnis</p></li><li><p>Beispiel: „Nenne mir die Details zum PR-578.“</p></li></ul><h4>Was es zurückgibt:</h4><ul><li><p>Ein vollständiges Dokumentobjekt mit:</p><ul><li><p><code>id</code> - Eindeutige Dokumentkennung</p></li><li><p><code>title</code> - Titel eines Issues oder Pull Requests (PR)</p></li><li><p><code>text</code> - Vollständige Beschreibung und Details des Problems/PR</p></li><li><p><code>url</code> - Link zum Issue/PR</p></li><li><p><code>type</code> - Dokumenttyp (Issue, Pull-Request)</p></li><li><p><code>status</code> - Aktueller Status (offen, in Bearbeitung, abgeschlossen)</p></li><li><p><code>priority</code> - Prioritätsstufe (niedrig, mittel, hoch, kritisch)</p></li><li><p><code>assignee</code> - Person, der das Issue/der PR zugewiesen wurde</p></li><li><p><code>created_date</code> - Erstellungsdatum</p></li><li><p><code>resolved_date</code> - Wann das Issue gelöst wurde (falls zutreffend)</p></li><li><p><code>labels</code> - Mit dem Dokument verbundene Tags</p></li><li><p><code>related_pr</code> - Verwandte Pull-Request-ID</p></li></ul></li></ul>return {
    "id": "PR-578",
    "title": "Security hotfix: Patch SQL injection vulnerabilities",
    "text": "Description: CRITICAL SECURITY FIX for ISSUE-1889. Patches SQL...",
    "url": "https://internal-git.techcorp.com/pulls/578",
    "type": "pull_request",
    "status": "closed",
    "priority": "critical",
    "assignee": "sarah_dev",
    "created_date": "2025-09-19",
    "resolved_date": "2025-09-19",
    "labels": "security, hotfix, sql",
    "related_pr": null
}<p><strong>Hinweis</strong>: In diesem Beispiel wird eine flache Struktur verwendet, bei der sich alle Felder auf der Stammebene befinden. Die Anforderungen von OpenAI sind flexibel und unterstützen auch verschachtelte Metadatenobjekte.</p><h2>Datensatz zu GitHub Issues und Pull Requests</h2><p>Für dieses Tutorial verwenden wir einen internen GitHub Datensatz mit Issues und Pull Requests. Dies stellt ein Szenario dar, in dem Sie private, interne Daten über ChatGPT abfragen möchten.</p><p>Den Datensätze finden Sie <a href="https://gist.github.com/TomasMurua/4e7bbdf7a7ebbdffaa663c43578d934a">hier</a>. Wir werden außerdem den Index der Daten mit der <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-bulk">Bulk-API</a> aktualisieren.</p><p>Dieser Datensatz umfasst:</p><ul><li><p>Issues mit Beschreibungen, Status, Priorität und Zuweisungen</p></li><li><p>Pull-Requests mit Codeänderungen, Bewertungen und Deployment-Informationen</p></li><li><p>Beziehungen zwischen Issues und PRs (z. B. PR-578 behebt ISSUE-1889)</p></li><li><p>Labels, Daten und andere Metadaten</p></li></ul><h3>Index-Mappings</h3><p>Der Index verwendet die folgenden <a href="https://www.elastic.co/docs/manage-data/data-store/mapping">Mappings</a>, um die hybride Suche mit <a href="https://www.elastic.co/docs/explore-analyze/machine-learning/nlp/ml-nlp-elser">ELSER</a> zu unterstützen. Das <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/semantic-text">text_semantic</a> wird für die semantische Suche verwendet, während andere Felder die Schlüsselwortsuchen ermöglichen.</p>{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "title": {
        "type": "text"
      },
      "text": {
        "type": "text"
      },
      "text_semantic": {
        "type": "semantic_text",
        "inference_id": ".elser-2-elasticsearch"
      },
      "url": {
        "type": "keyword"
      },
      "type": {
        "type": "keyword"
      },
      "status": {
        "type": "keyword"
      },
      "priority": {
        "type": "keyword"
      },
      "assignee": {
        "type": "keyword"
      },
      "created_date": {
        "type": "date",
        "format": "iso8601"
      },
      "resolved_date": {
        "type": "date",
        "format": "iso8601"
      },
      "labels": {
        "type": "keyword"
      },
      "related_pr": {
        "type": "keyword"
      }
    }
  }
}<h2>Den MCP-Server erstellen</h2><p>Unser MCP-Server implementiert zwei Tools gemäß den OpenAI Spezifikationen und verwendet die hybride Suche, um den semantischen und den textbasierten Abgleich für bessere Ergebnisse zu kombinieren.</p><h3>Suchtool</h3><p>Nutzt hybride Suche mit <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/reciprocal-rank-fusion">RRF</a> (Reciprocal Rank Fusion), die semantische Suche mit Textabgleich kombiniert:</p>@mcp.tool()
    async def search(query: str) -&gt; Dict[str, List[Dict[str, Any]]]:
        """
        Search for internal issues and PRs using hybrid search (semantic + text with RRF).
        Returns list with id, title, and url per OpenAI spec.
        """
        if not query or not query.strip():
            return {"results": []}

        logger.info(f"Searching for: '{query}'")

        try:
            # Hybrid search with RRF (Reciprocal Rank Fusion)
            response = es_client.search(
                index=ELASTICSEARCH_INDEX,
                size=10,
                source=["id", "title", "url", "type", "priority"],
                retriever={
                    "rrf": {
                        "retrievers": [
                            {
                                # Semantic search with ELSER
                                "standard": {
                                    "query": {
                                        "semantic": {
                                            "field": "text_semantic",
                                            "query": query
                                        }
                                    }
                                }
                            },
                            {
                                # Text search (BM25) for keyword matching
                                "standard": {
                                    "query": {
                                        "multi_match": {
                                            "query": query,
                                            "fields": [
                                                "title^3",
                                                "text^2",
                                                "assignee^2",
                                                "type",
                                                "labels",
                                                "priority"
                                            ],
                                            "type": "best_fields",
                                            "fuzziness": "AUTO"
                                        }
                                    }
                                }
                            }
                        ],
                        "rank_window_size": 50,
                        "rank_constant": 60
                    }
                }
            )

            results = []
            if response and 'hits' in response:
                for hit in response['hits']['hits']:
                    source = hit['_source']
                    results.append({
                        "id": source.get('id', hit['_id']),
                        "title": source.get('title', 'Unknown'),
                        "url": source.get('url', '')
                    })

            logger.info(f"Found {len(results)} results")
            return {"results": results}

        except Exception as e:
            logger.error(f"Search error: {e}")
            raise ValueError(f"Search failed: {str(e)}")<h3>Wichtige Punkte:</h3><ul><li><p><strong>Hybride Suche mit RRF:</strong> Kombiniert semantische Suche (ELSER) und Text-Suche (BM25) für bessere Ergebnisse.</p></li><li><p><strong>Multi-Match-Abfrage:</strong> <a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-multi-match-query">Sucht über mehrere Felder hinweg</a> mit Boosting (title^3, text^2, assignee^2). Das Caret-Symbol (^) multipliziert die Relevanzwerte und priorisiert dabei Treffer in Titeln gegenüber solchen im Inhalt.</p></li><li><p><strong>Fuzzy-Matching:</strong> <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/common-options#fuzziness"><code>fuzziness: AUTO</code></a> behebt Tippfehler und Rechtschreibfehler, indem es ungefähre Übereinstimmungen erlaubt.</p></li><li><p><strong>RRF-Parameterabstimmung:</strong></p><ul><li><p><code>rank_window_size: 50</code> - Legt fest, wie viele Top-Ergebnisse von jedem Retriever (semantische und textbasierte) vor dem Zusammenführen berücksichtigt werden.</p></li><li><p><code>rank_constant: 60</code> - Dieser Wert bestimmt, wie viel Einfluss Dokumente in einzelnen Ergebnismengen auf das endgültige Ranking haben.</p></li></ul></li><li><p><strong>Gibt nur die erforderlichen Felder zurück:</strong> <code>id</code>, <code>title</code>, <code>url</code> gemäß OpenAI-Spezifikation, und vermeidet das unnötige Freilegen zusätzlicher Felder.</p></li></ul><h3>Abrufwerkzeug</h3><p>Ruft Dokumentdetails anhand der Dokumenten-ID ab, sofern vorhanden:</p>@mcp.tool()
    async def fetch(id: str) -&gt; Dict[str, Any]:
        """
        Retrieve complete issue/PR details by ID.
        Returns id, title, text, url.
        """
        if not id:
            raise ValueError("ID is required")

        logger.info(f"Fetching: {id}")

        try:
            # Search by the 'id' field (not _id) since IDs are stored as a field
            response = es_client.search(
                index=ELASTICSEARCH_INDEX,
                body={
                    "query": {
                        "term": {
                            "id": id  # Search by your custom 'id' field
                        }
                    },
                    "size": 1
                }
            )

            if not response or not response['hits']['hits']:
                raise ValueError(f"Document with id '{id}' not found")

            hit = response['hits']['hits'][0]
            source = hit['_source']

            result = {
                "id": source.get('id', id),
                "title": source.get('title', 'Unknown'),
                "text": source.get('text', ''),
                "url": source.get('url', ''),
                "type": source.get('type', ''),
                "status": source.get('status', ''),
                "priority": source.get('priority', ''),
                "assignee": source.get('assignee', ''),
                "created_date": source.get('created_date', ''),
                "resolved_date": source.get('resolved_date', ''),
                "labels": source.get('labels', ''),
                "related_pr": source.get('related_pr', '')
            }

            logger.info(f"Fetched: {result['title']}")
            return result

        except Exception as e:
            logger.error(f"Fetch error: {e}")
            raise ValueError(f"Failed to fetch '{id}': {str(e)}")<h3>Wichtige Punkte:</h3><ul><li><p><strong>Suchen nach Dokumenten-ID-Feld:</strong> Verwendet eine Begriffsabfrage im benutzerdefinierten <code>id</code>-Feld.</p></li><li><p><strong>Vollständige Rückgabe des Dokuments:</strong> Mit vollständigem <code>text</code>-Feld mit allen Inhalten</p></li><li><p><strong>Flache Struktur:</strong> Alle Felder auf der Wurzelebene, entsprechend der Dokumentstruktur von Elasticsearch.</p></li></ul><h2>Bereitstellung auf Google Colab</h2><p>Wir nutzen Google Colab, um unseren MCP-Server zu betreiben, und ngrok, um ihn öffentlich zugänglich zu machen, damit ChatGPT eine Verbindung herstellen kann.</p><h3>Schritt 1: Öffnen Sie das Google Colab Notebook</h3><p>Greifen Sie auf unser vorkonfiguriertes Notebook <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/elasticsearch-chatgpt-connector">Elasticsearch MCP für ChatGPT</a> zu.</p><h3>Schritt 2: Konfigurieren Sie Ihre Anmeldeinformationen</h3><p>Sie benötigen drei Informationen:</p><ul><li><p><strong>Elasticsearch URL:</strong> Ihre <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-enterprise/connect-elasticsearch">Elasticsearch-Cluster-URL</a>.</p></li><li><p><strong>Elasticsearch API-Schlüssel:</strong> <a href="https://www.elastic.co/docs/deploy-manage/api-keys/elasticsearch-api-keys">API-Schlüssel</a> mit Lesezugriff auf Ihren Index.</p></li><li><p><strong>Ngrok-Auth-Token:</strong> Kostenloses Token von <a href="https://ngrok.com/">ngrok</a>. Wir nutzen ngrok, um die MCP-URL im Internet sichtbar zu machen, damit ChatGPT sich damit verbinden kann.</p></li></ul><h4>So erhalten Sie Ihr ngrok-Token</h4><ol><li><p>Registrieren Sie sich für ein kostenloses Konto bei <a href="https://ngrok.com/">ngrok</a></p></li><li><p>Gehe zu Ihrem <a href="https://dashboard.ngrok.com/">Dashboard</a></p></li><li><p>Kopieren Sie Ihr Authentifizierungs-Token</p></li></ol><h4>Secrets zu Google Colab hinzufügen</h4><p>Im Google Colab-Notizbuch:</p><ol><li><p>Klicken Sie auf das <strong>Schlüsselsymbol </strong>in der linken Seitenleiste, um <strong>Secrets</strong> zu öffnen.</p></li><li><p>Fügen Sie diese drei Secrets hinzu:</p></li></ol>ELASTICSEARCH_URL=https://your-cluster.elastic.com:443
ELASTICSEARCH_API_KEY=your-api-key
NGROK_TOKEN=your-ngrok-token<p>3. Aktivieren Sie den Notebook-Zugriff für jedes Secret.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5acae97b386277f8/6a17f08f5ea30f74c964b6c2/d5dd6ac19fe816a562c6351fdb0f11369da0e877-609x321.jpg" alt="Hinzufügen von Geheimnissen zu Google Collab" /><h3>Schritt 3: Führen Sie das Notebook aus</h3><ol><li><p>Klicken Sie auf <strong>Runtime</strong> und dann auf <strong>alle ausführen</strong>, um alle Zellen auszuführen.</p></li><li><p>Warten Sie, bis der Server startet (etwa 30 Sekunden)</p></li><li><p>Suchen Sie nach der Ausgabe, die Ihre öffentliche ngrok-URL anzeigt.</p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdd11aacf2deab67c/6a17f091e8fbce81f13a1a41/f185100e8869624bc9e1c7b2b4eb32785e2d89e7-1189x283.png" alt="" /><p>4. Die Ausgabe sieht in etwa so aus:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8891d917fdbaaf48/6a17f092abe0f208c7dfeaf6/e02e625e91ed9136454e4401b184575fb03a336e-1052x465.jpg" alt="Die Ausgabe der Ausführung eines Notebooks in Google Collab" /><h2>Mit ChatGPT verbinden</h2><p>Nun verbinden wir den MCP-Server mit Ihrem ChatGPT-Konto.</p><ol><li><p>Öffnen Sie ChatGPT und gehen Sie zu <strong>Einstellungen</strong>.</p></li><li><p>Navigieren Sie zu <strong>Konnektoren. </strong>Wenn Sie ein Pro-Konto nutzen, müssen Sie den <a href="https://platform.openai.com/docs/guides/developer-mode">Entwicklermodus</a> in den Konnektoren aktivieren.</p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt95efdcb2c39307e7/6a17f094abe0f24d8edfeafa/32c02192912fc0e7e5a52e9399077ba7ae3b4901-739x715.png" alt="Verbindung des MPC-Servers mit einem ChatGPT-Konto" /><p><em>Wenn Sie ChatGPT Enterprise oder Business verwenden, müssen Sie den Konnektor an Ihrem Workspace veröffentlichen.</em></p><p>3. Klicken Sie auf <strong>Erstellen.</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd4c8fc8dd6033918/6a17f095631730de19585b7b/15c53e5ccc381108a9dc0052cca05bf0fc97679a-755x683.png" alt="Hinzufügen eines Konnektors zu ChatGPT" /><p><em><strong>Hinweis</strong></em><em>: In Business-, Enterprise- und Edu-Workspaces können nur Workspace-Inhaber, Administratoren sowie Benutzer, bei denen die entsprechende Einstellung aktiviert ist (für Enterprise/Edu), benutzerdefinierte Konnektoren hinzufügen. Benutzer mit der regulären Mitgliederrolle sind nicht berechtigt, selbst benutzerdefinierte Konnektoren hinzuzufügen.</em></p><p><em>Sobald ein Konnektor von einem Benutzer mit der Inhaber- oder Admin-Rolle hinzugefügt und aktiviert wurde, kann er von allen Mitgliedern des Workspaces verwendet werden.</em></p><p>4. Geben Sie die erforderlichen Informationen ein sowie Ihre ngrok-URL, die mit <code>/sse/</code> endet. Beachten Sie den „/“ nach „sse“. Ohne diesen funktioniert es nicht:</p><ul><li><p><strong>Name:</strong> Elasticsearch MCP</p></li><li><p><strong>Beschreibung: </strong>Benutzerdefiniertes MCP zum Suchen und Abrufen von internen GitHub-Informationen.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd716ad0beeeb1d35/6a17f09714d90c11cc79b6d7/162a85705cc8ac48a3f2f665551d513e0719f93d-479x684.png" alt="Erstellen eines elastischen MCP-Steckers " /><p>5. Klicken Sie auf <strong>Erstellen</strong>, um das benutzerdefinierte MCP zu speichern.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt857794237d7d3b5a/6a17f0983e03d729b74f2d54/97eb5fb0a32b86bfadfb35561f698616f217c049-913x629.png" alt="Speichern des benutzerdefinierten MCP-Konnektors durch Klicken auf „Erstellen“." /><p>Die Verbindung ist sofort hergestellt, wenn Ihr Server läuft. Keine zusätzliche Authentifizierung ist erforderlich, da der Elasticsearch-API-Schlüssel auf Ihrem Server konfiguriert ist.</p><h2>Teste den MCP-Server</h2><p>Bevor Sie Fragen stellen, müssen Sie auswählen, welchen Konnektor ChatGPT verwenden soll.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd1602c48878dc7a9/6a17f09a6df731cca90a0fff/77a6fc1eb263a0eb16aac64f2ecaca5f4ac12ec2-966x568.gif" alt="Auswahl des Konnektors, den ChatGPT verwenden soll" /><h3>Aufforderung 1: Nach Problemen suchen</h3><p>Anfrage: „<strong>Finde Probleme im Zusammenhang mit der Elasticsearch-Migration“ </strong>und bestätigen Sie die Aktionen des aufgerufenen Tools.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6c204ceacf897f61/6a17f09c9da390fb1de4657d/cfd781acbff8cd7c8095bbe29224f8b26d581f77-650x375.png" alt="ChatGPT wird aufgefordert, „Probleme im Zusammenhang mit der Elasticsearch-Migration zu finden“, und die Aktionen des aufgerufenen Tools werden bestätigt." /><p>ChatGPT wird das Tool <code>search</code> mit Ihrer Abfrage aufrufen. Sie können sehen, dass es nach verfügbaren Tools sucht, sich darauf vorbereitet, das Elasticsearch-Tool aufzurufen. Vor jeglichen Aktionen gegenüber dem Tool wird die Bestätigung des Benutzers eingeholt.</p><h4>Anfrage zum Aufruf des Tools:</h4>{
  "query": "Elasticsearch migration issues"
}<h4>Reaktion des Tools:</h4>{
  "results": [
    {
      "id": "PR-598",
      "title": "Elasticsearch 8.x migration - Application code changes",
      "url": "https://internal-git.techcorp.com/pulls/598"
    },
    {
      "id": "ISSUE-1712",
      "title": "Migrate from Elasticsearch 7.x to 8.x",
      "url": "https://internal-git.techcorp.com/issues/1712"
    },
    {
      "id": "RFC-045",
      "title": "Design Proposal: Microservices Migration Architecture",
      "url": "https://internal-git.techcorp.com/rfcs/045"
    }
    // ... 7 more results
  ]
}<p>ChatGPT verarbeitet die Ergebnisse und präsentiert sie in einem natürlichen, gesprächsorientierten Format.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1b4378e7d26b4ad0/6a17f09ddbb4ff4de1fb57bf/9d5b6cff85c7e54ccc2584b8ae96d45495fae8c1-923x1352.png" alt="Wie ChatGPT die Ergebnisse der Tool-Aufrufanfrage und der Tool-Aufrufantwort verarbeitet" /><h3>Hinter den Kulissen</h3><h4>Prompt: „Finde Probleme im Zusammenhang mit der Elasticsearch-Migration.“</h4><p>1. ChatGPT-Anrufe <code>search(“Elasticsearch migration”)</code></p><p>2. Elasticsearch führt eine hybride Suche durch.</p><ul><li><p>Die <strong>semantische Suche</strong> versteht Konzepte wie „Upgrade“ und „<em>Versionskompatibilität“.</em></p></li><li><p><strong>Die Textsuche</strong> findet exakte Treffer für „<em>Elasticsearch</em>“ und „Migration“.</p></li><li><p><strong>RRF</strong> kombiniert und bewertet Ergebnisse beider Ansätze</p></li></ul><p>3. Sie gibt die 10 am besten mit <code>id</code>, <code>title</code>, übereinstimmenden Ergebnisse zurück <code>url</code></p><p>4. ChatGPT identifiziert „<em>ISSUE-1712: Migration von Elasticsearch 7.x auf 8.x</em>“ als relevantestes Ergebnis.</p><h3>Prompt 2: Nenne mir die vollständigen Details</h3><p>Anfrage: <em><strong>„Nenne mir die Details zu ISSUE-1889“</strong></em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8d1a53db8bfe8326/6a17f09f445de966104d021a/5c0db5245535ce67a36056e61e135bddc97ce496-934x629.png" alt="ChatGPT erkennt, dass Sie detaillierte Informationen zu einem bestimmten Problem wünschen, und ruft das entsprechende Tool auf, um sich vor der Durchführung von Aktionen mit dem Benutzer abzustimmen." /><p>ChatGPT erkennt, dass Sie detaillierte Informationen zu einem bestimmten Problem wünschen, ruft das Tool <code>fetch</code> auf holt beim Benutzer die Bestätigung ein, bevor Maßnahmen gegen das Tool ergriffen werden.</p><h4>Anfrage zum Aufruf des Tools:</h4>{
  "id": "ISSUE-1889"
}<h4>Reaktion des Tools:</h4>{
  "id": "ISSUE-1889",
  "title": "SQL injection vulnerability in search endpoint",
  "text": "Description: Security audit identified SQL injection vulnerability in /api/v1/search endpoint. User input from query parameter is not properly sanitized before being used in raw SQL query. Severity: HIGH - Immediate action required Affected Code: - File: services/search/query_builder.py - Line: 145-152 - Issue: String concatenation used instead of parameterized queries Investigation: - @security_team_alice: Confirmed exploitable with UNION-based injection - @sarah_dev: Checking all other endpoints for similar patterns - @john_backend: Found 3 more instances in legacy codebase Remediation: - Rewrite using SQLAlchemy ORM or parameterized queries - Add input validation and sanitization - Implement WAF rules as additional layer - Security regression tests Comments: - @tech_lead_mike: Stop all other work, this is P0 - @sarah_dev: PR-578 ready with fixes for all 4 vulnerable endpoints - @alex_devops: Deployed hotfix to production 2025-09-19 at 14:30 UTC - @security_team_alice: Verified fix, conducting full pentest next week Resolution: All vulnerable endpoints patched. Added pre-commit hooks to catch raw SQL queries. Security training scheduled for team.",
  "url": "https://internal-git.techcorp.com/issues/1889",
  "type": "issue",
  "status": "closed",
  "priority": "critical",
  "assignee": "sarah_dev",
  "created_date": "2025-09-18",
  "resolved_date": "2025-09-19",
  "labels": "security, vulnerability, bug, sql",
  "related_pr": "PR-578"
}<p>ChatGPT fasst die Informationen zusammen und präsentiert sie übersichtlich.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt560958fa3bd212d0/6a17f0a0faa91355ba93c974/410f19f213e94fc4e3c47eeef6e04b69e0c86159-602x462.png" alt="Wie ChatGPT die Informationen synthetisiert und präsentiert " /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcccf35a584e8373b/6a17f0a2505ac3471cad8c2e/54d8ffa117628a1e3afc317c3ab75d4f7731d7ab-767x1600.png" alt="Wie ChatGPT die Informationen präsentiert" /><h3>Hinter den Kulissen</h3><h4>Prompt: „Nenne mir die Details von ISSUE-1889“</h4><ol><li><p>ChatGPT-Anrufe <code>fetch(“ISSUE-1889”)</code></p></li><li><p>Elasticsearch ruft das vollständige Dokument ab</p></li><li><p>Gibt ein vollständiges Dokument mit allen Feldern auf der Stammebene zurück</p></li><li><p>ChatGPT synthetisiert die Informationen und antwortet mit korrekten Zitaten.</p></li></ol><h2>Fazit</h2><p>In diesem Artikel haben wir einen maßgeschneiderten MCP-Server erstellt, der ChatGPT mit Elasticsearch über spezielle <strong>Such-</strong> und <strong>Abruf-</strong>-MCP-Tools verbindet und so natürliche Sprachanfragen zu privaten Daten ermöglicht.</p><p>Dieses MCP-Muster funktioniert für jeden Elasticsearch-Index, jede Dokumentation, jedes Produkt, jedes Log oder andere Daten, die Sie über natürliche Sprache abfragen möchten.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/chatgpt-connector-mcp-server-github-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/chatgpt-connector-mcp-server-github-elasticsearch</guid>
    <category><![CDATA[Agentische KI]]></category>
    <category><![CDATA[Hybride Suche]]></category>
    <dc:creator><![CDATA[Tomás Murúa]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd1602c48878dc7a9/6a17f09a6df731cca90a0fff/77a6fc1eb263a0eb16aac64f2ecaca5f4ac12ec2-966x568.gif" length="0" type="image/gif"/>
    <pubDate>Mon, 01 Dec 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Hybride Suche ohne Probleme: Vereinfachte hybride Suche mit Retrievern]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie die hybride Suche in Elasticsearch mit einem mehrfeldrigen Abfrageformat für lineare und RRF-Retriever vereinfachen und Abfragen erstellen können, ohne vorher Kenntnisse über Ihren Elasticsearch-Index haben zu müssen.]]></description>
    <content:encoded><![CDATA[<p><a href="https://www.elastic.co/what-is/hybrid-search">Die hybride Suche</a> gilt weithin als leistungsstarker Suchansatz, der die Präzision und Geschwindigkeit der <a href="https://www.elastic.co/search-labs/blog/lexical-and-semantic-search-with-elasticsearch#lexical-search---sparse-retrieval">lexikalischen Suche</a> mit den Möglichkeiten der <a href="https://www.elastic.co/what-is/semantic-search">semantischen Suche</a> im Bereich der natürlichen Sprache kombiniert. Die praktische Anwendung gestaltet sich jedoch oft schwierig und erfordert häufig fundierte Kenntnisse über den Index sowie die Erstellung ausführlicher Abfragen mit komplexen Konfigurationen. In diesem Blogbeitrag werden wir untersuchen, wie das <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers#multi-field-query-format">Mehrfeld-Abfrageformat für lineare und RRF-Retriever die</a> hybride Suche vereinfacht und zugänglicher macht, häufige Probleme beseitigt und es Ihnen ermöglicht, ihre volle Leistungsfähigkeit leichter auszuschöpfen. Wir werden auch untersuchen, wie das Abfrageformat mit mehreren Feldern es Ihnen ermöglicht, hybride Suchanfragen durchzuführen, ohne vorher Kenntnisse über Ihren Index zu haben.</p><h2>Das Problem der Punktespanne</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3521a6558cd477ca/6a17f174445de94d3c4d0225/c8b49153c47d2cdc233c0d2e440db04711d48ca5-1600x1600.jpg" alt="" /><p>Um die Ausgangslage zu verdeutlichen, betrachten wir zunächst einen der Hauptgründe, warum die hybride Suche schwierig sein kann: die variierenden Bewertungsbereiche. Unser alter Bekannter <a href="https://www.elastic.co/elasticon/conf/2016/sf/improved-text-scoring-with-bm25">BM25</a> liefert unbegrenzte Ergebnisse. Mit anderen Worten: BM25 kann Werte generieren, die von nahe 0 bis (theoretisch) unendlich reichen. Im Gegensatz dazu liefern Abfragen gegen <code>dense_vector</code> -Felder Ergebnisse im Bereich zwischen 0 und 1. Erschwerend kommt hinzu, dass <code>semantic_text</code> den Feldtyp verschleiert, der zur Indizierung von Einbettungen verwendet wird. Daher ist es ohne detaillierte Kenntnisse über die Konfiguration Ihres Index und Inferenzendpunkts schwierig abzuschätzen, in welchem Bereich die Ergebnisse Ihrer Abfrage liegen werden. Dies stellt ein Problem dar, wenn versucht wird, lexikalische und semantische Suchergebnisse zu verschachteln, da die lexikalischen Ergebnisse Vorrang vor den semantischen haben können, selbst wenn die semantischen Ergebnisse relevanter sind. Die allgemein anerkannte Lösung für dieses Problem besteht darin, die Werte vor der Verschachtelung der Ergebnisse zu normalisieren. Elasticsearch bietet hierfür zwei Tools an: den <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers/linear-retriever">linearen</a> und <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers/rrf-retriever">den RRF-</a> Retriever.
</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt09ed6bf3d25066bd/6a17f1750b0bedbd70dd3686/264481268c8b6ac259e3c257b85431b513f16672-1077x586.png" alt="Vergleich der Suchergebnisse mit linearer/rrf-Funktion vs. ohne lineare/rrf-Funktion" /><p>Der <strong>RRF-</strong> Retriever wendet den <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/reciprocal-rank-fusion">RRF-Algorithmus</a> an, wobei der Dokumentenrang als Relevanzmaß verwendet und der Score verworfen wird. Da die Punktzahl nicht berücksichtigt wird, stellen Abweichungen im Punktzahlbereich kein Problem dar.</p><p>Der <strong>lineare</strong> Retriever verwendet eine lineare Kombination, um die endgültige Punktzahl eines Dokuments zu bestimmen. Dabei wird für jede einzelne Abfrage die Punktzahl der Komponenten des Dokuments ermittelt, normalisiert und anschließend summiert, um die Gesamtpunktzahl zu erhalten. Mathematisch lässt sich die Operation wie folgt ausdrücken:</p>Total Score = 𝚺(N(Sx))<p>Dabei ist <code>N</code> die Normalisierungsfunktion und SX die Punktzahl für die Anfrage X. Die Normalisierungsfunktion ist hierbei von zentraler Bedeutung, da sie die Punktzahl jeder Abfrage so transformiert, dass sie denselben Wertebereich verwendet. <a href="https://www.elastic.co/search-labs/blog/linear-retriever-hybrid-search">Hier</a> erfahren Sie mehr über den linearen Retriever.</p><h2>Aufgeschlüsselt</h2><p>Mit diesen Tools können Benutzer eine effektive Hybridsuche implementieren, dies erfordert jedoch gewisse Kenntnisse über ihren Index. Betrachten wir ein Beispiel mit dem linearen Retriever, bei dem wir einen Index mit zwei Feldern abfragen:</p>PUT linear_retriever_example
{
  "mappings": {
    "properties": {
      "semantic_text_field": { &lt;1&gt;
        "type": "semantic_text",
        "inference_id": ".multilingual-e5-small-elasticsearch"
      },
      "text_field": { &lt;2&gt;
        "type": "text"
      }
    }
  }
}<p>1. <code>semantic_text_field</code> ist ein <code>semantic_text</code> -Feld, das <a href="https://www.elastic.co/docs/explore-analyze/machine-learning/nlp/ml-nlp-e5">E5</a>, ein Text-Embedding-Modell, verwendet.</p><p>2. <code>text_field</code> ist ein Standard- <code>text</code> -Feld</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "retrievers": [
        {
          "retriever": {
            "standard": {
              "query": {
                "match": { &lt;1&gt;
                  "semantic_text_field": "foo"
                }
              }
            }
          },
          "normalizer": "minmax"
        },
        {
          "retriever": {
            "standard": {
              "query": {
                "match": {
                  "text_field": "foo"
                }
              }
            }
          },
          "normalizer": "minmax"
        }
      ]
    }
  }
}<p>1. Wir verwenden eine <code>match</code> -Abfrage für unser <code>semantic_text</code> -Feld, dessen <a href="https://www.elastic.co/search-labs/blog/semantic-search-match-knn-sparse-vector#we-made-match-happen-in-semantic-search!">Unterstützung wir in Elasticsearch 8.18/9.0 hinzugefügt haben.</a></p><p>
Bei der Erstellung der Abfrage müssen wir berücksichtigen, dass <code>semantic_text_field</code> ein Text-Embedding-Modell verwendet, sodass alle Abfragen darauf eine Punktzahl zwischen 0 und 1 generieren. Wir müssen außerdem wissen, dass <code>text_field</code> ein Standardfeld <code>text</code> ist und dass Abfragen darauf eine unbegrenzte Punktzahl erzeugen. Um ein Ergebnis-Set mit der richtigen Relevanz zu erstellen, müssen wir einen Retriever verwenden, der die Abfrage-Scores normalisiert, bevor er sie kombiniert. In diesem Beispiel verwenden wir den linearen Retriever mit <code>minmax</code> -Normalisierung, der den Score jeder Abfrage auf einen Wert zwischen 0 und 1 normalisiert.</p><p>Die Abfragekonstruktion in diesem Beispiel ist recht einfach, da nur zwei Felder beteiligt sind. Allerdings kann es sehr schnell kompliziert werden, wenn weitere Felder unterschiedlicher Art hinzugefügt werden. Dies zeigt, dass das Schreiben einer effektiven hybriden Suchanfrage oft ein tieferes Verständnis des abgefragten Index erfordert, damit die Punktzahlen der einzelnen Suchanfragen vor der Kombination richtig normalisiert werden. Dies stellt ein Hindernis für die breitere Akzeptanz der hybriden Suche dar.</p><h3>Abfragegruppierung</h3><p>Erweitern wir das Beispiel: Was wäre, wenn wir ein <code>text</code> -Feld und zwei <code>semantic_text</code> -Felder abfragen wollten? Wir könnten eine Abfrage wie diese erstellen:</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "retrievers": [
        {
          "retriever": {
            "standard": {
              "query": {
                "semantic": {
                  "field": "semantic_text_field_1",
                  "query": "foo"
                }
              }
            }
          },
          "normalizer": "minmax"
        },
        {
          "retriever": {
            "standard": {
              "query": {
                "semantic": {
                  "field": "semantic_text_field_2",
                  "query": "foo"
                }
              }
            }
          },
          "normalizer": "minmax"
        },
        {
          "retriever": {
            "standard": {
              "query": {
                "match": {
                  "text_field": "foo"
                }
              }
            }
          },
          "normalizer": "minmax"
        }
      ]
    }
  }
}<p>Das klingt auf den ersten Blick gut, aber es gibt ein potenzielles Problem. Die Treffer im Feld <code>semantic_text</code> machen nun ⅔ der Gesamtpunktzahl aus:</p>Total Score = N(semantic_text_field_1 score) + N(semantic_text_field_2 score) + N(text_field score)<p>Das ist wahrscheinlich nicht das, was Sie wollen, denn dadurch entsteht ein unausgewogenes Ergebnis. Die Auswirkungen sind in einem Beispiel wie diesem mit nur 3 Feldern möglicherweise nicht so deutlich erkennbar, aber es wird problematisch, wenn mehr Felder abgefragt werden. Beispielsweise enthalten die meisten Indizes weitaus mehr lexikalische als semantische Felder (d. h. <code>dense_vector</code>, <code>sparse_vector</code>, oder <code>semantic_text</code>). Was wäre, wenn wir einen Index mit 9 lexikalischen Feldern und 1 semantischen Feld nach dem oben genannten Muster abfragen würden? Die lexikalischen Übereinstimmungen würden 90 % der Punktzahl ausmachen und somit die Effektivität der semantischen Suche beeinträchtigen.</p><p>Eine gängige Methode, um diesem Problem zu begegnen, besteht darin, Anfragen in lexikalische und semantische Kategorien zu gruppieren und beide gleich zu gewichten. Dadurch wird verhindert, dass eine der beiden Kategorien die Gesamtpunktzahl dominiert.</p><p>Lasst uns das in die Praxis umsetzen. Wie sähe dieser Ansatz mit gruppierten Abfragen in diesem Beispiel bei Verwendung des linearen Retrievers aus?</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "retrievers": [
        {
          "retriever": {
            "linear": {
              "retrievers": [
                {
                  "retriever": {
                    "standard": {
                      "query": {
                        "semantic": {
                          "field": "semantic_text_field_1",
                          "query": "foo"
                        }
                      }
                    }
                  },
                  "normalizer": "minmax"
                },
                {
                  "retriever": {
                    "standard": {
                      "query": {
                        "semantic": {
                          "field": "semantic_text_field_2",
                          "query": "foo"
                        }
                      }
                    }
                  },
                  "normalizer": "minmax"
                }
              ]
            }
          },
          "normalizer": "minmax"
        },
        {
          "retriever": {
            "standard": {
              "query": {
                "match": {
                  "text_field": "foo"
                }
              }
            }
          },
          "normalizer": "minmax"
        }
      ]
    }
  }
}<p>Wow, das wird aber ausführlich! Möglicherweise mussten Sie sogar mehrmals auf- und abscrollen, um die gesamte Abfrage zu prüfen! Hier verwenden wir zwei Normalisierungsebenen, um die Abfragegruppen zu erstellen. Mathematisch lässt sich dies wie folgt ausdrücken:</p>Total Score = N(N(semantic_text_field_1 score) + N(semantic_text_field_2 score)) + N(text_field score)<p>Diese zweite Normalisierungsebene stellt sicher, dass die Anfragen an die Felder <code>semantic_text</code> und <code>text</code> gleich gewichtet werden. Beachten Sie, dass wir in diesem Beispiel die Normalisierung zweiter Ebene für <code>text_field</code> weglassen, da es nur ein lexikalisches Feld gibt, wodurch Sie sich <em>noch mehr</em> Ausführlichkeit ersparen.</p><p>Diese Abfragestruktur ist schon jetzt unhandlich, und wir fragen nur drei Felder ab. Je mehr Felder man abfragt, desto unübersichtlicher wird es, selbst für erfahrene Suchmaschinenexperten.</p><h2>Das Abfrageformat mit mehreren Feldern</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5d9007d279f0da29/6a17f17714d90c39cf79b6f5/dd04e1686076a574b717c1460acfe4eb79299208-1600x1600.jpg" alt="" /><p>Um das Ganze zu vereinfachen, haben wir das <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers#multi-field-query-format">Multi-Field-Abfrageformat</a> für die linearen und RRF-Retriever in Elasticsearch 8.19, 9.1 und <a href="https://www.elastic.co/cloud/serverless">Serverless</a> hinzugefügt. Sie können die gleiche Abfrage wie oben nun mit folgendem Befehl durchführen:</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "fields": [ "semantic_text_field_1", "semantic_text_field_2", "text_field" ],
      "query": "foo",
      "normalizer": "minmax"
    }
  }
}<p>Dadurch verkürzt sich die Abfrage von 55 Zeilen auf nur noch 9! Elasticsearch verwendet automatisch die Indexzuordnungen für:</p><ul><li><p>Ermitteln Sie den Typ jedes abgefragten Feldes.</p></li><li><p>Ordnen Sie jedes Feld einer lexikalischen oder semantischen Kategorie zu.</p></li><li><p>Jede Kategorie sollte im Endergebnis gleich gewichtet werden.</p></li></ul><p>Dies ermöglicht es jedem, eine effektive hybride Suchanfrage auszuführen, ohne Details über den Index oder die verwendeten Inferenzendpunkte kennen zu müssen.</p><p>Bei Verwendung von RRF kann das <code>normalizer</code> weggelassen werden, da der Rang als Indikator für die Relevanz dient:</p>GET rrf_retriever_example/_search
{
  "retriever": {
    "rrf": {
      "fields": [ "semantic_text_field_1", "semantic_text_field_2", "text_field" ],
      "query": "foo"
    }
  }
}<h2>Steigerung pro Spielfeld</h2><p>Bei Verwendung des linearen Retrievers können Sie eine Gewichtung pro Feld anwenden, um die Wichtigkeit von Übereinstimmungen in bestimmten Feldern anzupassen. Nehmen wir beispielsweise an, Sie fragen vier Felder ab: zwei <code>semantic_text</code> -Felder und zwei <code>text</code> -Felder:</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "fields": [ "semantic_text_field_1", "semantic_text_field_2", "text_field_1", "text_field_2" ],
      "query": "foo",
      "normalizer": "minmax"
    }
  }
}<p>Standardmäßig wird jedes Feld innerhalb seiner Gruppe (lexikalisch oder semantisch) gleich gewichtet. Die Punkteverteilung sieht wie folgt aus:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdc6e197e5ff7b68d/6a17f179505ac32834ad8c46/ba31c76189e3a1e5b1638437ccf0528aafec2598-1600x549.png" alt="Vergleich von Abfragegruppen und Feldwerten" /><p>Mit anderen Worten: Jedes Feld macht 25 % der Gesamtpunktzahl aus.</p><p>Mit der Syntax <code>field^boost</code> können wir jedem Feld einen feldbezogenen Boost hinzufügen. Wenden wir einen Boost von 2 auf <code>semantic_text_field_1</code> und <code>text_field_1</code> an:</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "fields": [ "semantic_text_field_1^2", "semantic_text_field_2", "text_field_1^2", "text_field_2" ]
      "query": "foo",
      "normalizer": "minmax"
    }
  }
}<p>Die Aufschlüsselung der Punkte sieht nun wie folgt aus:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltccc9ed7d6e865a5e/6a17f17abe6086a31d004882/de20e555d52f914bf483a048d056f54f4fece757-1600x549.png" alt="Feldgewichtung mit Referenz- und Hybridsuche geändert" /><p>Jede Abfragegruppe ist weiterhin gleich gewichtet, aber die Feldgewichtung innerhalb der Gruppen hat sich geändert:</p><ul><li><p><code>semantic_text_field_1</code> entspricht 66 % der Punktzahl der semantischen Abfragegruppe und 33 % der Gesamtpunktzahl.</p></li><li><p><code>text_field_1</code> macht 66 % der Punktzahl der lexikalischen Abfragegruppe und 33 % der Gesamtpunktzahl aus.</p></li></ul><p>ℹ️ Beachten Sie, dass sich die Gesamtpunktzahl nicht ändert, wenn ein Bonus pro Feld angewendet wird. Dies ist ein beabsichtigter Nebeneffekt der Score-Normalisierung, der sicherstellt, dass lexikalische und semantische Anfrage-Scores direkt miteinander vergleichbar bleiben.</p><p>ℹ️ Die feldbezogene Gewichtung kann auch mit dem RRF-Retriever in Elasticsearch 9.2+ verwendet werden.</p><h3>Wildcard-Auflösung</h3><p>Sie können das Platzhalterzeichen <code>*</code> im Parameter <code>fields</code> verwenden, um mehrere Felder abzugleichen. Um das obige Beispiel fortzuführen: Diese Abfrage ist funktional äquivalent zur expliziten Abfrage von s<code>emantic_text_field_1</code>, <code>semantic_text_field_2</code>, und <code>text_field_1</code> :</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "fields": [ "semantic_text_field_*", "*_field_1" ],
      "query": "foo",
      "normalizer": "minmax"
    }
  }
}<p>Interessanterweise passt das Muster <code>*_field_1</code> sowohl zu <code>text_field_1</code> als auch <code>semantic_text_field_1</code>. Dies wird automatisch gehandhabt; die Abfrage wird so ausgeführt, als ob jedes der Felder explizit abgefragt würde. Es ist auch in Ordnung, dass <code>semantic_text_field_1</code> beiden Mustern entspricht; alle Feldnamenübereinstimmungen werden vor der Abfrageausführung dedupliziert.</p><p>Sie können das Wildcard-Zeichen auf verschiedene Arten verwenden:</p><ul><li><p>Präfixübereinstimmung (z. B. <code>*_text_field</code>)</p></li><li><p>Inline-Matching (z. B. <code>semantic_*_field</code>)</p></li><li><p>Suffix-Matching (z. B. <code>semantic_text_field_*</code>)</p></li></ul><p>Sie können auch mehrere Platzhalter verwenden, um eine Kombination der oben genannten anzuwenden, z. B. <code>*_text_field_*</code>.</p><h3>Standardabfragefelder</h3><p>Das Abfrageformat mit mehreren Feldern ermöglicht es Ihnen auch, einen Index abzufragen, über den Sie nichts wissen. Wenn Sie den Parameter <code>fields</code> weglassen, werden alle Felder abgefragt, die durch die <a href="https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules">Indexeinstellung index.query.default_field</a> angegeben sind:</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "query": "foo",
      "normalizer": "minmax"
    }
  }
}<p>Standardmäßig ist <code>index.query.default_field</code> auf <code>*</code> gesetzt. Dieser Platzhalter wird auf jeden Feldtyp im Index aufgelöst, der Termabfragen unterstützt, was auf die meisten zutrifft. Die Ausnahmen sind:</p><ul><li><p><code>dense_vector</code> Felder</p></li><li><p><code>rank_vector</code> Felder</p></li><li><p>Geometrische Felder: <code>geo_point</code>, <code>shape</code></p></li></ul><p>Diese Funktionalität ist besonders nützlich, wenn Sie eine hybride Suchanfrage auf einem von einem Drittanbieter bereitgestellten Index durchführen möchten. Das Abfrageformat mit mehreren Feldern ermöglicht es Ihnen, auf einfache Weise eine passende Abfrage auszuführen. Lassen Sie einfach den Parameter <code>fields</code> weg, und alle relevanten Felder werden abgefragt.</p><h2>Fazit</h2><p>Das Problem der Bewertungsbereiche kann die Implementierung einer effektiven hybriden Suche zu einer echten Herausforderung machen, insbesondere wenn nur begrenzter Einblick in den abgefragten Index oder die verwendeten Inferenzendpunkte besteht. Das Mehrfeld-Abfrageformat für die linearen und RRF-Retriever mindert dieses Problem, indem es einen automatisierten, auf Abfragegruppierung basierenden hybriden Suchansatz in einer einfachen und zugänglichen API bündelt. Zusätzliche Funktionen wie die Gewichtung einzelner Felder, die Auflösung von Platzhaltern und die Verwendung von Standardabfragefeldern erweitern den Funktionsumfang und decken viele Anwendungsfälle ab.</p><h2>Probieren Sie heute noch das Abfrageformat mit mehreren Feldern aus.</h2><p>Sie können die linearen und RRF-Retriever mit dem Multi-Field-Query-Format in vollständig verwalteten Elasticsearch <a href="https://www.elastic.co/cloud/serverless">Serverless-</a> Projekten mit einer <a href="https://www.elastic.co/docs/deploy-manage/deploy/elastic-cloud/create-serverless-project">kostenlosen Testversion</a> ausprobieren. Es ist auch in Stack-Versionen ab 8.19 und 9.1 verfügbar.</p><p>Legen Sie in wenigen Minuten in Ihrer lokalen Umgebung mit einem einzigen Befehl los:</p>curl -fsSL https://elastic.co/start-local | sh<p></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/hybrid-search-multi-field-query-retrievers-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/hybrid-search-multi-field-query-retrievers-elasticsearch</guid>
    <category><![CDATA[Hybride Suche]]></category>
    <category><![CDATA[Relevanz]]></category>
    <dc:creator><![CDATA[Mike Pellegrini]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt89e066372c549595/6a17f17c3e9e457c38ba1583/4494f98ae3958bbdbc6171df9677fc4d65ec5640-1536x1024.png" length="0" type="image/png"/>
    <pubDate>Thu, 27 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Sie wissen schon, Kontext – Teil III: Die Leistungsfähigkeit der hybriden Suche im Kontext-Engineering]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie Kontext-Engineering und hybride Suche nutzen können, um die Genauigkeit der KI-Ausgabe mithilfe von Aggregationen, RBAC und Nicht-Inhaltssignalen zu verbessern.]]></description>
    <content:encoded><![CDATA[<p>Wir haben sowohl die hybride Suche (<a href="https://www.elastic.co/search-labs/blog/context-engineering-hybrid-search-evolution-agentic-ai">Teil I</a>) als auch das Kontext-Engineering (<a href="https://www.elastic.co/search-labs/blog/context-engineering-llm-evolution-agentic-ai">Teil II</a>) besprochen; nun wollen wir uns damit befassen, wie sie zusammenwirken, um den größtmöglichen Effekt bei der Bereitstellung zielgerichteten Kontexts für RAG- und agentenbasierte KI-Operationen zu erzielen.</p><h2>Die Suche ist nicht tot, sie hat sich nur verlagert.</h2><p>Wir haben also einen Wandel erlebt: von der primären Suche nach Kontext über ein Textfeld und der Verwendung der zurückgegebenen Informationen (des Kontexts), um die Antworten selbst zu konstruieren, hin zur Verwendung natürlicher Sprache, um einem Agenten mitzuteilen, was wir wollen, und lassen ihn die Antwort automatisch für uns recherchieren und zusammenstellen. Viele in der Tech-Welt verweisen auf diesen Wandel und verkünden, dass „Suche tot ist“ (nun ja, die SEO- und AdWords-Welt <a href="https://www.pewresearch.org/short-reads/2025/07/22/google-users-are-less-likely-to-click-on-links-when-an-ai-summary-appears-in-the-results/">verändert sich definitiv</a>: <a href="https://www.wired.com/story/goodbye-seo-hello-geo-brandlight-openai/">GEO,</a> irgendjemand?), aber die Suche ist für operative Abläufe immer noch absolut entscheidend – sie wird nur heute größtenteils im Verborgenen mithilfe von Tools durchgeführt.</p><p>Bisher waren Menschen die Hauptverantwortlichen für die Beurteilung der subjektiven Relevanz: Jeder Nutzer hatte seine eigenen Gründe für die Durchführung der Suche, und seine persönlichen Erfahrungen prägten die relative Genauigkeit der Ergebnisse. Wenn wir darauf vertrauen sollen, dass Agenten zu demselben (oder einem besseren) Schluss kommen können, zu dem wir gekommen wären, müssen wir sicherstellen, dass die Kontextinformationen, auf die sie Zugriff haben, so nah wie möglich an unserer subjektiven Absicht liegen. Wir müssen den Kontext, den wir LLMs bieten, auf dieses Ziel ausrichten!</p><h2>Kontextgenerierung mit hybrider Suchabfrage</h2><p>Zur Erinnerung an Teil I: Die Hybridsuche von Elastic kombiniert die Stärken der traditionellen schlüsselwortbasierten Suche (Syntaxflexibilität, Schlüsselwortgenauigkeit und Relevanzbewertung) mit dem semantischen Verständnis der Vektorähnlichkeitssuche und bietet mehrere Reranking-Techniken. Diese Synergie (eine treffendere Verwendung dieses Wortes wurde noch nie gefunden!) ermöglicht hochrelevante Ergebnisse mit Suchanfragen, die wesentlich differenzierter auf die Inhalte abzielen. Es geht nicht nur darum, dass man die subjektive Relevanz als <em>eine</em> der Abrufphasen anwenden kann; es geht vielmehr darum, dass der Abruf in der ersten Phase die Relevanzbewertung zusammen mit all diesen anderen Modi gleichzeitig beinhalten kann.</p><h3>Überragende Genauigkeit und Effizienz</h3><p>Die Verwendung einer Datenplattform, die verteilte Suche, Abfrage und Neubewertung als primäre Kontextabfrage-Engine ermöglicht, ist sehr sinnvoll. Sie können eine erweiterte Abfragesyntax verwenden, um die fehlende Komponente der subjektiven Absicht hinzuzufügen und Inhalte herauszufiltern, die vom Wert der zurückgegebenen Kontextinformationen ablenken oder diesen verfälschen könnten. Sie können aus den verfügbaren Syntaxoptionen auswählen oder Modalitäten zu einer einzigen Suche kombinieren, die auf jeden Datentyp auf die für ihn beste Weise abzielt, und diese dann mit Reranking kombinieren/neu anordnen. Sie können die Antwort so filtern, dass sie nur die gewünschten Felder/Werte enthält und überflüssige Daten fernhält. Im Dienste der Agenten ermöglicht diese Targeting-Flexibilität die Entwicklung von Tools, die äußerst präzise beim Abrufen von Kontextinformationen sind.</p><h3>Kontextverfeinerung (Aggregationen und nicht-inhaltliche Signale)</h3><p>Aggregationen können besonders nützlich sein, um den Inhalt zu gestalten, den ein Tool im Kontextfenster anzeigt. Aggregationen liefern naturgemäß numerisch basierte Fakten über die Struktur der zurückgegebenen Kontextdaten, was es LLMs erleichtert und genauer macht, darüber zu argumentieren. Da Aggregationen hierarchisch verschachtelt werden können, ist dies eine einfache Möglichkeit, dem LLM mehrstufige Details hinzuzufügen, um ein differenzierteres Verständnis zu erzeugen. Aggregationen können auch bei der Verwaltung der Kontextfenstergröße helfen – Sie können ein Abfrageergebnis von 100.000 Dokumenten leicht auf einige hundert Tokens aggregierter Erkenntnisse reduzieren.</p><p>Nicht-inhaltliche Signale sind die in Ihren Daten enthaltenen Indikatoren, die Ihnen ein umfassenderes Bild dessen vermitteln, was Sie betrachten; es handelt sich um zusätzliche Merkmale der Ergebnisse, wie beispielsweise Popularität, Aktualität, geografische Lage, Kategorien, Vielfalt der Anbieter oder Preisklassen. Diese Informationsschnipsel können für den Agenten hilfreich sein, um die Bedeutung des empfangenen Kontextes einzuschätzen. Einige einfache Beispiele veranschaulichen dies am besten:</p><ul><li><p><strong>Hervorhebung kürzlich veröffentlichter und beliebter Inhalte</strong> – Stellen Sie sich vor, Sie verfügen über eine Wissensdatenbank mit Artikeln. Sie möchten Artikel finden, die für die Suchanfrage eines Nutzers relevant sind, aber Sie möchten auch Artikel hervorheben, die sowohl aktuell sind als auch von anderen Nutzern als hilfreich empfunden wurden (z. B. eine hohe Anzahl von „Gefällt mir“-Angaben haben). In diesem Szenario können wir eine Hybridsuche verwenden, um relevante Artikel zu finden und sie dann anhand einer Kombination aus Veröffentlichungsdatum und Popularität neu zu ordnen.</p></li><li><p><strong>E-Commerce-Suche mit Umsatz- und Lagerbestandsanpassung</strong> – Im E-Commerce-Umfeld möchten Sie Ihren Kunden Produkte anzeigen, die zu ihrem Suchbegriff passen, aber Sie möchten auch Produkte bewerben, die sich gut verkaufen und auf Lager sind. Um Frustration bei den Kunden zu vermeiden, sollten Sie Produkte mit geringem Lagerbestand möglicherweise in der Rangfolge herabstufen.</p></li><li><p><strong>Priorisierung von schwerwiegenden Problemen in einem Bugtracker</strong> - Für ein Softwareentwicklungsteam ist es bei der Suche nach Problemen entscheidend, dass schwerwiegende, prioritäre und kürzlich aktualisierte Probleme zuerst angezeigt werden. Sie können nicht-signalgebende Kriterien wie „Kritikalität“ und „meistdiskutiert“ verwenden, um verschiedene Faktoren unabhängig voneinander zu gewichten und so sicherzustellen, dass die wichtigsten und am aktivsten diskutierten Themen ganz oben stehen.</p></li></ul><p>Diese und weitere Beispielabfragen finden Sie auf der zugehörigen <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/you-know-for-context/">Inhaltsseite</a> von Elasticsearch Labs.</p><h3>Sicherheitsdurchsetzung</h3><p>Ein entscheidender Vorteil der Nutzung einer suchbasierten Geschwindigkeitsschicht wie Elastic für Context Engineering ist ihr integriertes Sicherheitsframework. Die Plattform von Elastic stellt sicher, dass der Kontext, der an agentenbasierte und generative KI-Operationen geliefert wird, sensible, privat gehaltene Informationen durch granulare rollenbasierte Zugriffskontrolle (RBAC) und attributbasierte Zugriffskontrolle (ABAC) respektiert und schützt. Dies bedeutet, dass Anfragen nicht nur effizient bearbeitet werden, sondern dass die Ergebnisse auch nach den spezifischen Berechtigungen des Agenten oder des Benutzers, der die Anfrage initiiert, gefiltert werden.</p><p>Die Agenten werden als authentifizierter Benutzer ausgeführt, sodass die Sicherheit implizit durch die in die Plattform integrierten Sicherheitsfunktionen gewährleistet ist:</p><ul><li><p><strong>Feingranulare Berechtigungen:</strong> Definieren Sie den Zugriff auf Dokument-, Feld- oder sogar Begriffsebene und stellen Sie so sicher, dass KI-Agenten nur Daten erhalten, zu deren Einsicht sie berechtigt sind.</p></li><li><p><strong>Rollenbasierte Zugriffskontrolle (RBAC):</strong> Agenten oder Benutzern werden Rollen zugewiesen, wodurch ihnen basierend auf ihren definierten Verantwortlichkeiten Zugriff auf bestimmte Datensätze oder Funktionalitäten gewährt wird.</p></li><li><p><strong>Attributbasierte Zugriffskontrolle (ABAC):</strong> Implementieren Sie dynamische Zugriffsrichtlinien basierend auf Attributen der Daten, des Benutzers oder der Umgebung, wodurch eine hochgradig anpassungsfähige und kontextsensitive Sicherheit ermöglicht wird.</p></li><li><p><strong>Dokumentenebene-Sicherheit (DLS) und Feldebene-Sicherheit (FLS):</strong> Diese Funktionen gewährleisten, dass auch innerhalb eines abgerufenen Dokuments nur autorisierte Abschnitte sichtbar sind, wodurch die Offenlegung sensibler Informationen verhindert wird.</p></li><li><p><strong>Integration mit der Unternehmenssicherheit:</strong> Nahtlose Integration mit bestehenden Identitätsmanagementsystemen (wie LDAP, SAML, OIDC), um einheitliche Sicherheitsrichtlinien im gesamten Unternehmen durchzusetzen.</p></li></ul><p>Durch die direkte Integration dieser Sicherheitsmaßnahmen in den Kontextabrufmechanismus fungiert Elastic als sicherer Wächter, der sicherstellt, dass KI-Agenten innerhalb definierter Datengrenzen arbeiten, eine unbefugte Datenoffenlegung verhindert und die Einhaltung der Datenschutzbestimmungen gewährleistet. Dies ist von entscheidender Bedeutung für den Aufbau von Vertrauen in agentenbasierte KI-Systeme, die vertrauliche oder geschützte Informationen verarbeiten.</p><p>Als zusätzlichen Vorteil verringern Sie durch die Verwendung einer einheitlichen Datengeschwindigkeitsschicht über Ihren Unternehmensdatenquellen die unerwarteten Ad-hoc-Abfragelasten auf diese Repositories, die agentenbasierte Tools erzeugen würden. Sie erhalten einen zentralen Ort, um alles nahezu in Echtzeit zu durchsuchen, und einen Ort, um Sicherheits- und Governance-Kontrollen anzuwenden.</p><h2>Hybride suchbasierte Tools</h2><p>Es gibt einige Kernfunktionen (und <a href="https://www.elastic.co/blog/whats-new-elastic-9-2-0">ständig kommen neue hinzu</a>) der Elastic-Plattform, die das Streben nach Kontextentwicklung enorm beschleunigen. Das Wichtigste hierbei ist, dass die Plattform eine Vielzahl von Möglichkeiten bietet, um Ziele zu erreichen, und die Flexibilität besitzt, Methoden anzupassen, zu verändern und zu erweitern, wenn sich das KI-Ökosystem weiterentwickelt.</p><h3>Wir stellen Ihnen Agent Builder vor</h3><p>Elastic <a href="https://www.elastic.co/elasticsearch/agent-builder">Agent Builder</a> ist unser erster Ausflug in die Welt der agentenbasierten KI-Tools, die entwickelt wurden, um mit den Daten zu kommunizieren, die Sie bereits in Elastic speichern. Agent Builder bietet eine Chat-Oberfläche, mit der Benutzer ihre eigenen Agenten und Tools innerhalb von Kibana erstellen und verwalten können. Es verfügt über integrierte MCP- und A2A-Server, programmatische APIs und eine Reihe vorkonfigurierter Systemtools zum Abfragen und Erkunden von Elasticsearch-Indizes sowie zum Generieren von ES|QL-Abfragen aus natürlicher Sprache. Mit Agent Builder können Sie benutzerdefinierte Tools erstellen, die die an den Agenten zurückgegebenen Kontextdaten mithilfe einer ausdrucksstarken <a href="https://www.elastic.co/docs/reference/query-languages/esql">ES|QL-</a> Abfragesyntax gezielt ansprechen und formen.</p><p>Wie funktioniert die hybride Suche in ES|QL, fragen Sie? Die Kernfunktionalität wird durch die Kombination des Feldtyps <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/semantic-text">semantic_text</a> und der Befehle <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/fork">FORK</a>/<a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/fuse">FUSE</a> erreicht (FUSE verwendet standardmäßig <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/reciprocal-rank-fusion">RRF</a> , um die Ergebnisse der einzelnen Forks zusammenzuführen). Hier ein einfaches Beispiel für eine fiktive Produktsuche:</p>FROM products
| FORK
  (MATCH description "high performance gaming laptop" | EVAL search_type = "bm25"),
  (MATCH description_semantic "high performance gaming laptop" | EVAL search_type = "semantic")
| FUSE 
| LIMIT 20
| KEEP product_name, description, _score, search_type<p>Die <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/eval">EVAL-</a> Klausel, die in jedem der FORK-Zweige im obigen Beispiel enthalten ist, ist nicht unbedingt notwendig; sie dient lediglich dazu, zu veranschaulichen, wie Sie nachverfolgen können, aus welcher Suchmodalität ein bestimmtes Ergebnis zurückgegeben wurde.</p><h3>Suchvorlagen</h3><p>Angenommen, Sie möchten Ihre eigenen externen Agenten-Tools auf Ihre Elastic-Bereitstellung verweisen. Anstelle von ES|QL möchten Sie mehrstufige Retriever verwenden oder eine bereits entwickelte DSL-Syntax wiederverwenden und außerdem die Eingaben, die die Abfrage akzeptiert, die Syntax, die zur Ausführung der Suche verwendet wird, und die in der Ausgabe zurückgegebenen Felder steuern können. <a href="https://www.elastic.co/docs/solutions/search/search-templates">Suchvorlagen</a> ermöglichen es Benutzern, vordefinierte Strukturen für häufige Suchmuster festzulegen, wodurch die Effizienz und Konsistenz beim Abrufen von Daten verbessert wird. Dies ist besonders vorteilhaft für agentenbasierte Tools, die mit Such-APIs interagieren, da sie dazu beitragen, Boilerplate-Code zu standardisieren und eine schnellere Iteration der Suchlogik zu ermöglichen. Und falls Sie jemals einen dieser Faktoren anpassen müssen, aktualisieren Sie einfach die Suchvorlage und voilà, die Änderungen werden übernommen. Wenn Sie ein Beispiel für die Verwendung von Suchvorlagen mit agentenbasierten Tools suchen, schauen Sie sich den Blog von Elasticsearch Labs an: „<a href="https://www.elastic.co/search-labs/blog/mcp-intelligent-search">MCP für intelligente Suche</a> “. Dort wird eine Suchvorlage hinter einem Tool-Aufruf von einem externen MCP-Server verwendet.</p><h3>Integrierte Arbeitsabläufe (FTW!)</h3><p>Eine der größten Herausforderungen in unserer neuen Welt der agentenbasierten KI ist die nicht-deterministische Natur von semi-autonomen, selbstgesteuerten „denkenden“ Agenten. Kontextgestaltung ist eine entscheidende Disziplin für agentenbasierte KI: Es handelt sich um Techniken, die dazu beitragen, die möglichen Schlussfolgerungen, die unser Agent generieren kann, auf das einzugrenzen, was wir als Wahrheit kennen. Selbst bei einem hochpräzisen und relevanten Kontextfenster (wenn wir den Bereich numerischer Fakten verlassen) fehlt uns immer noch die Gewissheit, dass die Reaktion des Agenten vollständig wiederholbar und verlässlich ist.</p><p>Wenn Sie dieselbe Anfrage mehrmals an einen Agenten senden, können die Antworten <em>im Wesentlichen</em> gleich sein, wobei <em>sich lediglich die Antwort geringfügig</em> unterscheidet. Das ist in der Regel für einfache Abfragen ausreichend, vielleicht kaum wahrnehmbar, und wir können versuchen, die Ausgabe mithilfe von Kontextmanipulationstechniken zu gestalten. Doch je komplexer die Aufgaben werden, die wir unseren Agenten stellen, desto größer ist die Wahrscheinlichkeit, dass eine oder mehrere Teilaufgaben eine Abweichung hervorrufen, die das Endergebnis geringfügig verändert. Es wird wahrscheinlich noch schlimmer werden, wenn wir uns stärker auf die Kommunikation zwischen den Agenten verlassen, und diese Abweichungen werden sich summieren. Dies unterstreicht erneut die Notwendigkeit, dass die Werkzeuge, mit denen unsere Agenten interagieren, sehr flexibel und genau auf die jeweiligen Kontextdaten abstimmbar sein müssen und dass sie in einem erwarteten Ausgabeformat reagieren sollten. Dies deutet auch darauf hin, dass wir für viele Anwendungsfälle die Interaktion zwischen Agenten und Werkzeugen steuern müssen – hier kommen Workflows ins Spiel!</p><p>Elastic wird schon bald vollständig anpassbare Workflows in den Kern der Plattform integrieren. Diese Workflows werden in der Lage sein, bidirektional mit Agenten und Tools zu interagieren, sodass Workflows Agenten und Tools aufrufen können und Agenten und Tools Workflows aufrufen können. Die vollständige Integration dieser Funktionen in dieselbe Such-KI-Plattform, auf der sich all Ihre Daten befinden, wird einen grundlegenden Wandel bewirken; das Potenzial der Arbeitsabläufe ist äußerst spannend! Bald, schon sehr bald!</p><h3>Elastisch wie die einheitliche Speicherbank</h3><p>Da Elastic eine verteilte Datenplattform ist, die für die Suche in nahezu Echtzeit konzipiert wurde, übernimmt sie auf natürliche Weise die Langzeitgedächtnisfunktionen für agentenbasierte KI-Systeme. Mit der integrierten Chat-Funktion des Agent Builders bieten wir auch die Möglichkeit, das Kurzzeitgedächtnis und den Chatverlauf zu verfolgen und zu verwalten. Und weil die gesamte Plattform API-first ist, ist es extrem einfach, Elastic als Plattform zu nutzen, um die Kontextausgabe eines Tools zu speichern (und später darauf zurückgreifen zu können), die das Kontextfenster des Agenten überfordern könnte; diese Technik wird in Kontext-Engineering-Kreisen manchmal als „ <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents#:~:text=Agents%20can%20assemble%20understanding%20layer%20by%20layer%2C%20maintaining%20only%20what%27s%20necessary%20in%20working%20memory%20and%20leveraging%20note%2Dtaking%20strategies%20for%20additional%20persistence">Notizen-Making</a>“ bezeichnet.</p><p>Die Kombination von Kurzzeit- und Langzeitgedächtnis auf derselben Suchplattform bietet viele Vorteile: Stellen Sie sich vor, Sie könnten Chatverläufe und gespeicherte Kontextantworten als semantische Einflussfaktoren für zukünftige Chatinteraktionen nutzen, Bedrohungsanalysen durchführen oder persistente Datenprodukte erstellen, die automatisch aus häufig wiederholten Toolaufrufen generiert werden… Die Möglichkeiten sind endlos!</p><h2>Fazit</h2><p>Das Aufkommen großer Sprachmodelle hat die Art und Weise verändert, wie wir Inhalte abgleichen und wie wir unsere Daten analysieren. Wir bewegen uns rasant weg von unserer gegenwärtigen Welt, in der Menschen Recherche, Kontextbetrachtung und logisches Denken betreiben, um ihre eigenen Fragen zu beantworten, hin zu einer Welt, in der diese Schritte weitgehend durch agentenbasierte KI automatisiert werden. Damit wir den generierten Antworten vertrauen können, benötigen wir die Gewissheit, dass der Agent bei der Generierung seiner Antwort <em>alle</em> <em>relevanten</em> Informationen (einschließlich des Faktors der subjektiven Relevanz) berücksichtigt hat. Unsere primäre Methode, um agentenbasierte KI vertrauenswürdig zu machen, besteht darin, die Werkzeuge, die zusätzlichen Kontext abrufen, durch RAG- und Kontext-Engineering-Techniken zu verankern. Die Art und Weise, wie diese Werkzeuge den <em>anfänglichen Abruf</em> durchführen, kann jedoch entscheidend für die Genauigkeit der Antwort sein.</p><p>Die Elastic Search AI-Plattform bietet die Flexibilität und Vorteile der hybriden Suche sowie zahlreiche integrierte Funktionen, die agentenbasierte KI in Bezug auf Genauigkeit, Leistung und Skalierbarkeit unterstützen; mit anderen Worten: Elastic ist eine fantastische Plattform für verschiedene Aspekte des Kontext-Engineerings! Durch die Standardisierung des Kontextabrufs über eine Suchplattform vereinfachen wir die Funktionsweise von agentenbasierten Werkzeugen in vielerlei Hinsicht – und ähnlich dem Widerspruch „langsamer werden, um schneller zu werden“ bedeutet Einfachheit auf der Ebene der Kontextgenerierung eine schnellere und vertrauenswürdigere agentenbasierte KI.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/context-engineering-hybrid-search-agentic-ai-accuracy</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/context-engineering-hybrid-search-agentic-ai-accuracy</guid>
    <category><![CDATA[Hybride Suche]]></category>
    <category><![CDATA[Agentische KI]]></category>
    <dc:creator><![CDATA[Woody Walton]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt42a203a316f0e22e/6a170932b339d58ebc769f5f/b82ff25242e4229cc20b218d9cc91c60cfd680bc-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 20 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Sie wissen schon, Kontext – Teil I: Die Entwicklung von hybrider Suche und Kontextgestaltung]]></title>
    <description><![CDATA[Erfahren Sie, wie sich hybride Suche und Kontextgestaltung von lexikalischen Grundlagen weiterentwickelt haben, um die nächste Generation agentenbasierter KI-Workflows zu ermöglichen.]]></description>
    <content:encoded><![CDATA[<h2>Unsere brandneue agentische KI-Welt</h2><p>Wie viele von uns bin auch ich gleichermaßen begeistert und erstaunt über das Tempo, mit dem sich die Fähigkeiten der KI weiterentwickeln. Wir erlebten zum ersten Mal, wie große Sprachmodelle (LLMs) und die Vektorsuche uns in die semantische Revolution katapultierten, bei der wir nicht mehr mühsam mit Schlüsselwörtern herumsuchen mussten, um Dinge zu finden. Dann zeigten uns die LLMs neue Wege der Interaktion mit unseren Daten auf, indem sie Chat-Schnittstellen nutzten, um Anfragen in natürlicher Sprache in Antworten umzuwandeln, die riesige Wissensdatenbanken in leicht verständliche Zusammenfassungen destillierten. Wir jetzt (schon!) haben die Anfänge einer automatisierten LLM-gesteuerten Logik in Form von „agentischen KI“-Workflows, die eine eingehende Anfrage semantisch verstehen, über die zu unternehmenden Schritte nachdenken und dann aus den verfügbaren Werkzeugen auswählen können, um iterativ Aktionen auszuführen, um diese Ziele zu erreichen.</p><p>Das Versprechen agentenbasierter KI zwingt uns, uns von der primären Verwendung von „Prompt Engineering“ zur Gestaltung unserer generativen KI-Interaktionen hin zu einem Fokus darauf zu entwickeln, wie wir agentenbasierte Werkzeuge dabei unterstützen können, die relevantesten und effizientesten Zusatzinformationen zu erhalten, die das LLM bei der Generierung seiner Antworten berücksichtigen muss – „Context Engineering“ ist die nächste Herausforderung. Die hybride Suche ist mit Abstand das leistungsstärkste und flexibelste Mittel, um relevante Kontextinformationen zu finden, und die Search AI-Plattform von Elastic eröffnet völlig neue Möglichkeiten, Daten im Dienste des Context Engineering zu nutzen. In diesem Artikel werden wir aus zwei Blickwinkeln erörtern, wie LLMs die Welt der Informationswiedergewinnung verändert haben, und anschließend darauf eingehen, wie sie für bessere Ergebnisse zusammenarbeiten können. Es gibt noch viel zu besprechen…</p><h2>Teil I: Wie LLMs die Suche verändert haben</h2><p>Beginnen wir mit der Frage, wie LLMs die Art und Weise verändert haben, wie wir auf Informationen zugreifen und sie abrufen.</p><h3>Unser lexikalisches Erbe</h3><p>Wir alle leben schon seit langer Zeit in der etwas eingeschränkten Welt der lexikalischen Suche (ziemlich gut, so gut es eben geht). Die Suche ist das erste Werkzeug, zu dem wir greifen, wenn wir recherchieren oder ein neues Projekt beginnen, und bis vor kurzem lag es an uns, unsere Suchanfragen so zu formulieren, dass eine lexikalische Suchmaschine sie versteht. Die lexikalische Suche basiert auf dem Abgleich von Suchbegriffen mit Schlüsselwörtern in einem Dokumentenkorpus – unabhängig davon, ob der Inhalt unstrukturiert oder strukturiert ist. Damit eine lexikalische Suche ein Dokument als Treffer zurückgibt, muss dieses mit dem entsprechenden Schlüsselwort übereinstimmen (oder über ein kontrolliertes Vokabular wie eine Synonymliste oder ein Wörterbuch verfügen, um die konzeptionelle Verbindung für uns herzustellen).</p>POST my-index/_search
{
  "size": 10,
  "query": {
    "semantic": {
      "query": "machine learning applications",
      "field": "semantic-content-field"
    }
  }
}<p><em>Beispiel einer lexikalischen </em><a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-multi-match-query"></a><em> Mehrfachabfrage</em></p><p>Suchmaschinen haben zumindest die Möglichkeit, Treffer mit einer Relevanzbewertung zurückzugeben. Suchmaschinen bieten eine Fülle von Abfragesyntaxoptionen, um indizierte Daten effektiv anzusprechen, sowie integrierte Relevanzalgorithmen, die die Ergebnisse im Verhältnis zur Absicht der Abfragesyntax des Benutzers bewerten. Suchmaschinen profitieren von jahrzehntelangen Fortschritten bei Relevanz-Ranking-Algorithmen und sind dadurch eine effiziente Datenabrufplattform, die Ergebnisse liefern kann, die nach ihrer Relevanz für die Suchanfrage bewertet und sortiert sind. Datenbanken und andere Systeme, die SQL als ihre Hauptmethode zum Abrufen von Daten verwenden, sind hier im Nachteil: Es gibt kein Relevanzkonzept in einer Datenbankabfrage; sie können bestenfalls Ergebnisse alphabetisch oder numerisch sortieren. Die gute Nachricht ist, dass Sie mit diesen Schlüsselwörtern alle Treffer (Recall) erhalten, diese aber nicht unbedingt in einer hilfreichen Reihenfolge im Hinblick darauf, <em>warum</em> Sie danach gesucht haben (Präzision). Das ist ein wichtiger Punkt, wie wir gleich sehen werden…</p><h3>Betreten Sie den (semantischen) Drachen</h3><p>Das Potenzial von Vektordarstellungen von Informationen als Alternative zur Stichwortsuche wird schon seit <a href="https://www.elastic.co/search-labs/blog/introduction-to-vector-search">geraumer Zeit</a> erforscht. Vektoren bergen großes Potenzial, da sie uns aus dem rein schlüsselwortbasierten Modus des Inhaltsabgleichs herausführen – da Vektoren numerische Darstellungen von Begriffen und Gewichtungen sind, ermöglichen sie es, Konzepte mathematisch nahe beieinander zu bringen, basierend auf dem Verständnis eines Sprachmodells darüber, wie Begriffe im Trainingsbereich miteinander in Beziehung stehen. Die lange Verzögerung bei der allgemeinen Vektorsuche war darauf zurückzuführen, dass die Modelle größtenteils auf spezifische Domänen beschränkt waren; sie waren einfach nicht groß genug, um die vielen verschiedenen Konzepte, die ein Begriff in unterschiedlichen Kontexten repräsentieren könnte, ausreichend zu verstehen.</p><p>Erst mit dem Aufkommen der Large Language Models (LLMs) vor einigen Jahren, die in der Lage sind, mit viel größeren Datenmengen zu trainieren (unter Verwendung <a href="https://en.wikipedia.org/wiki/Transformer_(deep_learning_architecture)">von Transformatoren</a> und <a href="https://en.wikipedia.org/wiki/Attention_(machine_learning)">Aufmerksamkeit</a>), wurde die Vektorsuche praktikabel – die Größe und Tiefe der LLMs ermöglichten es Vektoren schließlich, genügend Nuancen zu speichern, um tatsächlich semantische Bedeutung zu erfassen. Dieser plötzliche Anstieg des Verständnisses ermöglichte es LLMs, nun eine große Anzahl von Funktionen der natürlichen Sprachverarbeitung (NLP) zu erfüllen, die zuvor gesperrt waren. Die vielleicht wirkungsvollste Funktion ist die Fähigkeit, aus dem Kontext dessen, was sich bisher in der Sequenz befindet, auf das wahrscheinlichste nächste Glied in einer Sequenz zu schließen. Inferenz ist der Prozess, der generativer KI ihre nahezu menschenähnliche Fähigkeit verleiht, Texte zu erzeugen. Der KI-generierte Text basiert auf dem Verständnis des LLM darüber, wie Begriffe in seinen Trainingsdaten miteinander in Beziehung stehen, und verwendet außerdem die Formulierung der Anfrage, um zwischen verschiedenen Kontexten, in denen die Begriffe vorkommen könnten, zu unterscheiden.</p><p>So magisch generative KI auch sein mag, es <em>gibt</em> Einschränkungen bei LLMs, die zu Fehlern in Qualität und Genauigkeit führen, die gemeinhin als Halluzinationen bezeichnet werden. Halluzinationen treten auf, wenn das LLM keinen Zugang zu den Informationen hat (oder nicht in den richtigen Kontext geführt wird), um seine Antwort auf die Wahrheit zu gründen. Stattdessen generiert es, um hilfreich zu sein, eine selbstsicher und plausibel klingende, aber erfundene Antwort. Ein Teil der Ursache liegt darin, dass LLMs zwar den Sprachgebrauch in großen Bereichen mit vielfältigen Informationen erlernen, das Training aber irgendwann beendet werden muss. Daher gibt es einen Zeitfaktor für ihr Verständnis – das heißt, das Modell kann nur das wissen, was bis zum Zeitpunkt des Trainingsstopps korrekt war. Ein weiterer Faktor für Halluzinationen ist, dass das Modell normalerweise keine Kenntnis von privat gespeicherten Daten hat (Daten, die nicht im öffentlichen Internet verfügbar sind), und das ist besonders bedeutsam, wenn diese Daten spezifische Begriffe und Nomenklatur enthalten.</p><h3>Vektordatenbanken</h3><p>LLMs vektorisieren Inhalte in ihren Modellraum mithilfe einer Technik namens Text Embedding. Dabei wird die semantische Bedeutung des Inhalts auf der Grundlage des erhaltenen Trainings in die Weltanschauung des Modells <a href="https://www.elastic.co/search-labs/blog/hybrid-search-multiple-embeddings">eingebettet</a> oder abgebildet. Zur Vorbereitung und Verarbeitung von Inhalten für die Einbettung sind einige Schritte erforderlich, darunter <a href="https://www.elastic.co/search-labs/blog/chunking-strategies-elasticsearch">Chunking</a> und Tokenisierung (sowie <a href="https://www.kaggle.com/code/danishmahdi/subword-tokenization-bpe-wordpiece-and-unigram">Subwort-Tokenisierung</a>). Das Ergebnis ist typischerweise eine Menge dichter Vektoren, die das Verständnis des Modells für die Bedeutung dieses Inhaltsabschnitts innerhalb seines Vektorraums darstellen. Chunking ist ein ungenaues Verfahren, das darauf abzielt, Inhalte an die Verarbeitungsbeschränkungen eines Modells zur Generierung von Einbettungen anzupassen und gleichzeitig verwandten Text mithilfe semantischer Konstrukte wie Satz- und Absatzindikatoren zu einem Chunk zusammenzufassen.</p><p>Die Notwendigkeit der Segmentierung kann zu einem gewissen semantischen Verlust in einem eingebetteten Dokument führen, da einzelne Segmente nicht vollständig mit anderen Segmenten aus demselben Dokument verknüpft sind. Die inhärente Undurchsichtigkeit neuronaler Netze kann diesen Verlust noch verschlimmern – ein LLM ist in Wahrheit eine „Black Box“, bei der die während des Trainings hergestellten Verbindungen zwischen Begriffen und Konzepten nicht deterministisch und für Menschen nicht interpretierbar sind. Dies führt zu Problemen mit der Erklärbarkeit, der Wiederholbarkeit, unbewussten Voreingenommenheit und möglicherweise zu einem Verlust an Vertrauen und Genauigkeit. Dennoch ist die Möglichkeit, Ideen semantisch zu verknüpfen und bei Suchanfragen nicht an bestimmte Schlüsselwörter gebunden zu sein, extrem wirkungsvoll:</p>POST my-index/_search 
{
  "size": 10, 
  "query": {
    "semantic": {
      "query": "machine learning applications",
      "field": "semantic-content-field"
    }
  }
} <p><em>Ein Beispiel für </em><a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-semantic-query"><em>eine semantische</em></a><em> Anfrage</em></p><p>Bei Vektordatenbanken gibt es noch einen weiteren Punkt zu beachten: Sie sind keine Suchmaschinen, sondern Datenbanken! Bei einer <a href="https://www.elastic.co/search-labs/blog/introduction-to-vector-search">Vektorähnlichkeitssuche</a> werden die Suchbegriffe kodiert, um einen Satz von (Einbettungs-)Koordinaten innerhalb des Vektorraums des Modells zu finden. Diese Koordinaten dienen dann als Zielscheibe, um die Dokumente zu finden, die die „nächsten Nachbarn“ der Zielscheibe sind – das heißt, der Rang eines Dokuments (oder seine Platzierung in den Ergebnissen) wird durch die berechnete <em>Ähnlichkeitsdistanz</em> der Koordinaten dieses Dokuments zu den Koordinaten der Anfrage bestimmt. In welche Richtung sollte die Rangfolge Vorrang haben, welcher der möglichen Kontexte entspricht am ehesten der Absicht des Nutzers? Das Bild, mit dem ich es vergleiche, ist eine Szene aus dem Film <a href="https://www.youtube.com/watch?v=x3h7xz558EY&amp;start=3&amp;end=86">Stargate</a>, in der wir die sechs Koordinatenpunkte haben, die sich schneiden, um uns das Ziel (die Zielscheibe) zu nennen, aber wir können es nicht erreichen, ohne das „7. Symbol“ zu kennen – die Koordinaten des Startpunkts, die die subjektive Absicht des Benutzers repräsentieren. Anstatt also die relative Rangfolge der Vektoren auf einer sich ständig erweiternden und undifferenzierten Sphäre der Ähnlichkeit zu basieren, können wir durch die Berücksichtigung der subjektiven Absicht der Anfrage mittels ausdrucksstarker Syntax und Relevanzbewertung so etwas wie einen <em>Zylinder</em> abgestufter subjektiver Relevanz erhalten.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb49ae330d3de1fc1/6a17053ee8fbce089639fb46/1ddfaae0c1496d08d7d30419e6d2aeaeacfc0ea2-1600x544.png" alt="Ein Zylinder abgestufter subjektiver Relevanz." /><p>Die Inferenzfähigkeiten eines LLM können zwar helfen, den wahrscheinlichsten Kontext <em>für</em> die Anfrage zu identifizieren, das Problem besteht jedoch darin, dass <em>ohne diese Unterstützung</em> die Koordinaten der eingehenden Anfrage <em>nur</em> anhand der Art und Weise bestimmt werden können, wie das Modell ursprünglich trainiert wurde.</p><p>In gewisser Hinsicht könnte man sagen, dass Vektorähnlichkeit das entgegengesetzte Extrem darstellt als eine strikte Stichwortübereinstimmung – ihre Stärke liegt in ihrer Fähigkeit, die Probleme der Begriffsabweichung zu überwinden, aber <a href="https://medium.com/data-science/vector-embeddings-are-lossy-heres-what-to-do-about-it-4f9a8ee58bb7">fast bis zum Exzess</a>: LLMs neigen dazu, verwandte Konzepte zu vereinheitlichen, anstatt zwischen ihnen zu unterscheiden. Die Vektorähnlichkeit verbessert unsere Fähigkeit, Inhalte semantisch abzugleichen, garantiert aber keine Präzision, da sie exakte Schlüsselwörter und spezifische Details übersehen kann, die vom Modell nicht ausreichend unterschieden werden. Die Vektorähnlichkeitssuche ist an sich schon leistungsstark, aber wir brauchen Möglichkeiten, die Ergebnisse, die wir aus einer Vektordatenbank abrufen, mit Ergebnissen anderer Abrufmethoden zu korrelieren.</p><h3>Neubewertungstechniken</h3><p>An dieser Stelle sei eine allgemeine Technik namens Reranking erwähnt, bei der die Ergebnismengen neu bewertet oder normalisiert werden, um eine einheitliche Rangfolge zu erhalten. Die Notwendigkeit einer Neubewertung könnte darauf zurückzuführen sein, dass Ergebnisse aus mehreren Quellen oder Abrufmethoden unterschiedliche Bewertungsmechanismen (oder gar keine, SQL!) haben, oder die Neubewertung könnte dazu dienen, die Ergebnisse aus nicht-semantischen Quellen semantisch an die Anfrage des Benutzers anzupassen. Das Reranking ist ein zweiter Schritt, bei dem es sich um eine Reihe von Ergebnissen handelt, die durch eine <em>erste Abrufmethode</em> (z. B. Anschließend werden SQL-, lexikalische und Vektorsuchen mit einer anderen Bewertungsmethode neu geordnet.</p><p>Es stehen verschiedene Ansätze zur Verfügung, darunter <a href="https://www.elastic.co/docs/solutions/search/ranking/learning-to-rank-ltr">Learning-To-Rank (LTR)</a> und <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/reciprocal-rank-fusion">Reciprocal Rank Fusion (RRF)</a> – LTR eignet sich, um Suchergebnisse zu erfassen (Likes, Bewertungen, Klicks usw.) und diese zu nutzen, um Ergebnisse zu bewerten und zu verstärken oder zu verzerren. RRF eignet sich perfekt zum Zusammenführen von Ergebnissen, die von verschiedenen Abfragemodalitäten zurückgegeben werden (z. B. lexikalische und Vektordatenbankrecherchen) werden zu einer einzigen Ergebnisliste zusammengeführt. Elastic bietet außerdem die Flexibilität, die Ergebnisse mithilfe <a href="https://www.elastic.co/search-labs/blog/linear-retriever-hybrid-search">linearer Neubewertungsmethoden</a> anzupassen.</p><p>Eine der effektivsten Reranking-Techniken ist jedoch <a href="https://www.elastic.co/docs/solutions/search/ranking/semantic-reranking">das semantische Reranking</a>, bei dem das semantische Verständnis eines LLM genutzt wird, um die Vektoreinbettungen sowohl der Anfrage als auch der Ergebnisse gemeinsam zu analysieren und anschließend eine Relevanzbewertung/Rescoring anzuwenden, um die endgültige Reihenfolge zu bestimmen. Für das semantische Reranking ist natürlich eine Verbindung zu einem Reranking-Modell erforderlich. Elasticsearch bietet eine <a href="https://www.elastic.co/docs/api/doc/elasticsearch/group/endpoint-inference">Inference API</a> , mit der Sie <strong>Rerank-</strong> Endpunkte erstellen können, die integrierte Modelle (<a href="https://www.elastic.co/docs/explore-analyze/machine-learning/nlp/ml-nlp-rerank">Elastic Rerank</a>), <a href="https://www.elastic.co/docs/reference/elasticsearch/clients/eland/machine-learning">importierte</a> Modelle von Drittanbietern oder extern gehostete Dienste wie <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-inference-put-cohere">Cohere</a> oder <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-inference-put-googlevertexai">Google Vertex AI nutzen</a>. Anschließend können Sie mithilfe der Abstraktionssyntax <a href="https://www.elastic.co/docs/solutions/search/retrievers-overview">der Retriever</a> -Abfrage ein Reranking durchführen:</p>POST my-index/_search 
{
  "size": 10,
  "retriever": {
    "text_similarity_reranker": {
      "retriever": {
        "rrf": {
          "retrievers": [
            {
              "standard": {
                "query": {
                  "multi_match": {
                    "query": "machine learning applications",
                    "fields": ["title", "content"]
                  }
                }
              }
            },
            {
              "knn": {
                "field": "semantic-content-field",
                "k": 10,
                "num_candidates": 100,
                "query_vector_builder": {
                  "text_embedding": {
                    "model_id": "my-text-embedding-model",
                    "model_text": "machine learning applications"
                  }
                }
              }
            }
          ],
          "rank_window_size": 50,
          "rank_constant": 20
        }
      }
    },
    "field": "content",
    "inference_id": "my-reranker",
    "inference_text": "machine learning applications",
    "rank_window_size": 20
  }
}<p><em>Ein Beispiel für eine mehrstufige Retriever-Neubewertungsoperation</em></p><p>Klingt super, oder? Wir können eine Neubewertung der Ergebnisse aus unterschiedlichen Quellen durchführen und so ein nahezu vollständiges semantisches Verständnis aller Inhaltsarten erreichen… Die semantische Neubewertung kann sowohl rechenintensiv als auch zeitaufwendig sein, weshalb sie nur bei einer begrenzten Anzahl von Ergebnissen praktikabel ist. Daher ist es wichtig, <em>wie</em> die ursprünglichen Ergebnisse abgerufen werden.</p><h3>Die Methode zur Kontextabfrage ist wichtig.</h3><p>Die subjektive Intention ist ein wichtiger Faktor bei der Bestimmung der Genauigkeit eines Ergebnisses und bei der Bewertung seiner Relevanz. Ohne die Möglichkeit, die Absicht des Benutzers bei der Durchführung der Abfrage zu berücksichtigen (ausgedrückt durch eine flexible Syntax oder durch eine Neubewertung in einer zweiten Stufe), können wir nur aus den bereits im Modellraum kodierten Kontexten auswählen. Um diesem Mangel an Kontext zu begegnen, setzen wir üblicherweise Techniken wie <a href="https://en.wikipedia.org/wiki/Retrieval-augmented_generation">Retrieval Augment Generation (RAG)</a> ein. Die Funktionsweise von RAG besteht darin, dass die Koordinaten der Abfrage effektiv verschoben werden, indem zusätzliche verwandte Begriffe aus einer Vorabfrage für kontextrelevante Daten einbezogen werden. Dadurch wird die Art und Weise, wie die Engine diesen zusätzlichen Kontext bereitstellt, und <em>ihre</em> anfängliche Methode zur Datenabfrage umso wichtiger für die Genauigkeit des Kontextes!</p><p>Lassen Sie uns die verschiedenen Methoden zur Kontextabfrage und deren Einfluss auf eine RAG-Operation betrachten:</p><ul><li><p><strong>Hybride Suchabrufe ohne Suchmaschine weisen immer noch einen Mangel an subjektiver Relevanz auf.</strong> Wenn die Plattform, die RAG bereitstellt, im Wesentlichen auf SQL basiert (was auf die meisten „Data Lake“-Plattformen zutrifft), fehlt ihr die Relevanzbewertung in der ersten Abrufphase. Viele Data-Lake-Plattformen bieten ihre eigene Version des hybriden Retrieval (nicht der Suche) an, wobei in der Regel Reranking-Techniken wie semantisches Reranking und RRF auf ihren SQL-basierten Retrieval- und Vektordatenbankergebnissen kombiniert werden. Eine einfache Sortierung reicht offensichtlich nicht für eine subjektive Rangfolge aus, aber selbst wenn sie als Grundlage für eine semantische Neubewertung in einem zweiten Schritt verwendet wird, wird SQL als erste Stufe der Abfrage problematisch, wenn die semantische Neubewertung nur auf den „Top k“ Treffern durchgeführt wird – ohne eine Möglichkeit, die Ergebnisse bei der Abfrage zu bewerten, welche Garantie haben wir, dass die <em>besten</em> Ergebnisse tatsächlich unter den Top-Ergebnissen enthalten sind?</p></li><li><p><strong>Vektorähnlichkeit allein reicht für RAG nicht aus</strong>. Das liegt eigentlich an einer Reihe von sich gegenseitig verstärkenden Problemen – es ist der Verlust beim Einbetten, zusammen mit naiven Chunking-Methoden, der Art und Weise, wie Ähnlichkeit berechnet wird, und der entscheidenden fehlenden Komponente der subjektiven Absicht. Eines der Hauptziele von RAG ist es, generative KI-Interaktionen auf objektiver Wahrheit zu gründen, um sowohl Halluzinationen zu verhindern als auch das LLM über private Informationen zu informieren, von denen es während des Trainings keine Kenntnis hatte. Wir können den durch RAG bereitgestellten zusätzlichen Kontext nutzen, um LLMs einzuschränken und anzuleiten, die Verbindungen und Details zu berücksichtigen, von denen wir wissen, dass sie für die Beantwortung der jeweiligen Frage am wichtigsten sind. Dazu müssen wir <em>sowohl</em> semantische als auch lexikalische Ansätze verwenden.</p></li><li><p><strong>Dateibasierte grep/regex RAG.</strong> Einige <a href="https://www.nicolasbustamante.com/p/the-rag-obituary-killed-by-agents">Kreise</a> im Universum der agentenbasierten KI plädieren für die Verwendung stark vergrößerter Kontextfenster, die über grep und reguläre Ausdrücke für RAG auf lokale Dateien zugreifen, anstatt externe Abrufplattformen zu nutzen. Die Idee dahinter ist, dass LLMs mit einem wesentlich größeren Kontextfenster in der Lage sein werden, konzeptionelle Verbindungen innerhalb ihres eigenen Denkraums herzustellen, anstatt sich auf fragmentierte Informationen und verschiedene Abrufmethoden/Plattformen zu verlassen, um relevante Informationen zu sammeln. Theoretisch ist es zwar richtig, dass ein ganzes Dokument ein umfassenderes Bild liefert als Dokumentsegmente, dies funktioniert jedoch nur in kleinen Datenbereichen (oder beispielsweise bei der Bereitstellung von Dateien für <a href="https://en.wikipedia.org/wiki/Vibe_coding">Vibecoding</a>), und selbst dann besteht die erste Abrufmethode in einem Scan aller Dokumente mit einer reinen Stichwortübereinstimmung.</p></li></ul><p><strong>Suche ist mehr als nur Abruf.</strong></p><p>Suchmaschinen sind speziell dafür entwickelt, Suchanfragen so schnell und flexibel wie möglich zu gestalten. Intern nutzen sie spezialisierte Datenstrukturen zum Speichern und Abrufen verschiedener Datentypen, die auf diese Datentypen zugeschnitten sind. Elasticsearch bietet optimiertes Speichern und Abfragen für praktisch alle Datentypen, einschließlich unstrukturierter/Volltext-Lexikalsuche (Match, Phrase, Proximity, Multi-Match), schneller Keyword-Suche (exakte Übereinstimmung) und Filterung, numerischer Bereiche, Datumsangaben, IP-Adressen und ist sehr flexibel in der Speicherung von Dokumentstrukturen (z. B. …). verschachtelte oder flache Dokumente). Elasticsearch ist außerdem eine native Vektordatenbank, die sowohl dünnbesetzte als auch dichte Vektortypen speichern und abfragen kann, und wir erforschen weiterhin innovative Wege (zum Beispiel <a href="https://www.elastic.co/search-labs/blog/better-binary-quantization-lucene-elasticsearch">Better Binary Quantization (BBQ)</a> &amp; <a href="https://www.elastic.co/search-labs/blog/diskbbq-elasticsearch-introduction">DiskBBQ</a>), um die Suchgenauigkeit zu erhalten und gleichzeitig die Geschwindigkeit, Skalierbarkeit und Kosten im Zusammenhang mit vektorisierten Inhalten zu verbessern. Die Elasticsearch-Plattform bietet zudem integrierte Datenstabilität und Hochverfügbarkeit und beinhaltet Funktionen für das Datenlebenszyklusmanagement wie <a href="https://www.elastic.co/docs/deploy-manage/tools/snapshot-and-restore/searchable-snapshots">Searchable Snapshots</a> , mit denen Sie selten genutzte oder langfristig aufzubewahrende Daten auf kostengünstigem Objektspeicher speichern können – und diese dennoch vollständig durchsuchbar sind.</p><h3>Die Hybridsuche vereint das Beste aus allen Welten.</h3><p><a href="https://www.elastic.co/what-is/hybrid-search">Hybride Suche</a> (nicht nur hybride Abfrage!) kombiniert die Stärken der traditionellen lexikalischen Suche mit dem semantischen Verständnis von LLMs und der Vektorähnlichkeitssuche. Diese Synergie ermöglicht es, bereits in der <em>Abrufphase</em> hochrelevante Ergebnisse durch die flexiblen Abfragesyntaxoptionen einer Suchmaschine zu erzielen: absichtsgesteuerte Syntaxoptionen und Relevanzbewertung, multimodaler Datenabruf, Filterung, Aggregation und Biasing. Mit Suchsyntax wie <a href="https://www.elastic.co/docs/reference/query-languages/esql">ES|QL</a> und mehrstufigen <a href="https://www.elastic.co/docs/solutions/search/retrievers-overview">Abrufern</a> können wir die traditionelle Suche flexibel mit semantischer Suche, Filtern und mehreren Reranking-Techniken in einer einzigen Anfrage kombinieren.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6ee9512910856ee3/6a17053fcdacbf2ea97d291e/f25180cb430414b99ae553d3b8eb161dbccea4d4-1920x1080.png" alt="Wie funktioniert die Hybridsuche?" /><p>Einer der größten Vorteile der hybriden Suche ist, dass Ihre Abfragen eine spezialisierte Syntax für mehrere verschiedene Datentypen gleichzeitig verwenden können. Diese unterschiedlichen Abfragesyntaxen können nicht nur zum <em>Auffinden</em> von Ergebnissen verwendet werden, sondern auch als Filter oder Aggregationen <em>der</em> Ergebnisse. Ein Beispiel hierfür ist <a href="https://www.elastic.co/docs/explore-analyze/geospatial-analysis">die Geodatenanalyse</a>, eine der häufigsten Abfragearten, die oft mit anderen Syntaxelementen kombiniert wird. Sie können beispielsweise Abfragen durchführen, um Ergebnisse zu erhalten, deren Geokoordinaten sich innerhalb einer bestimmten Entfernung von einem Punkt befinden, oder um Aggregationen Ihrer Ergebnisse nach Region anzufordern, oder um Aggregationen anzufordern, um Bewegungen in/aus einer Zone zu verfolgen und Warnungen auszugeben. Mit der Hybridsuche haben Sie die Flexibilität, Syntaxen zu kombinieren, um Ergebnisse so präzise wie möglich zu liefern und die Inhalte abzurufen, die Ihrem Kontext am nächsten kommen.</p><h2>Pause</h2><p>Dieser erste Teil erzählt die Geschichte, wie die Vektorsuche die Art und Weise verändert hat, wie wir Daten abrufen können, und bereitet den Boden für die Veränderungen, die LLMs an den Abfragemechanismen mit sich gebracht haben, mit denen wir mit Daten interagieren. Wir werden so tun, als hätten wir das in mehrere Teile aufteilen müssen, damit LLMs es verstehen können, ohne den Kontext zu verlieren… ;-) Erfahren wir mehr darüber, <em>warum das wichtig ist,</em> in <a href="https://www.elastic.co/search-labs/blog/context-engineering-llm-evolution-agentic-ai">Teil II: Agentische KI und die Notwendigkeit des Kontext-Engineerings</a>, und in Teil III kehren wir zu unserer Diskussion über die hybride Suche zurück.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/context-engineering-hybrid-search-evolution-agentic-ai</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/context-engineering-hybrid-search-evolution-agentic-ai</guid>
    <category><![CDATA[Hybride Suche]]></category>
    <category><![CDATA[Relevanz]]></category>
    <dc:creator><![CDATA[Woody Walton]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc49e39872984c8eb/6a1705410e2e49e42c419fd5/7e59a0671aa9ea32d68188a693936a66ebf48625-1000x628.png" length="0" type="image/png"/>
    <pubDate>Wed, 12 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Multimodale Suche nach Berggipfeln mit Elasticsearch und SigLIP-2 ]]></title>
    <description><![CDATA[Lernen Sie, wie Sie die multimodale Suche von Text zu Bild und von Bild zu Bild mithilfe von SigLIP-2-Einbettungen und der Elasticsearch kNN-Vektorsuche implementieren. Projektschwerpunkt: Auffinden von Fotos des Gipfels des Mount Ama Dablam während einer Everest-Trekkingtour.]]></description>
    <content:encoded><![CDATA[<p>Wollten Sie schon immer einmal Ihr Fotoalbum nach Bedeutung durchsuchen? Versuchen Sie Suchanfragen wie „Zeig mir meine Bilder, auf denen ich eine blaue Jacke trage und auf einer Bank sitze“, „Zeig mir Bilder vom Mount Everest“ oder „Sake und Sushi“. Schnapp dir eine Tasse Kaffee (oder dein Lieblingsgetränk) und lies weiter. In diesem Blog zeigen wir Ihnen, wie Sie eine multimodale hybride Suchanwendung erstellen. Multimodal bedeutet, dass die App verschiedene Arten von Eingaben verstehen und durchsuchen kann – Text, Bilder und Audio – und nicht nur Wörter. Hybrid bedeutet, dass Techniken wie Keyword-Matching, kNN-Vektorsuche und Geofencing kombiniert werden, um präzisere Ergebnisse zu liefern.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdfa1ec1ccd450e94/6a17da751d1b8308ee93e344/0ec6bbb45013846b59ee00d2bf73ee2182ee7392-1920x1080.gif" alt="Bibliothek mit Fotos verschiedener Berggipfel von der Mount-Everest-Wanderung." /><p>Um dies zu erreichen, verwenden wir Googles SigLIP-2, um Vektoreinbettungen sowohl für Bilder als auch für Texte zu generieren und diese in der Elasticsearch-Vektordatenbank zu speichern. Zum Zeitpunkt der Abfrage wandeln wir die Sucheingabe, Text oder Bild, in Einbettungen um und führen schnelle kNN-Vektorsuchen durch, um Ergebnisse abzurufen. Diese Konfiguration ermöglicht eine effiziente Text-zu-Bild- und Bild-zu-Bild-Suche. Eine Streamlit-Benutzeroberfläche erweckt dieses Projekt zum Leben, indem sie uns ein Frontend zur Verfügung stellt, mit dem wir nicht nur textbasiert nach passenden Fotos aus dem Album suchen und diese anzeigen können, sondern auch den Berggipfel auf dem hochgeladenen Bild identifizieren und weitere Fotos dieses Berges im Fotoalbum anzeigen können.
Wir beschreiben außerdem die Schritte, die wir zur Verbesserung der Suchgenauigkeit unternommen haben, und geben praktische Tipps und Tricks. Zur weiteren Erkundung stellen wir ein <a href="https://github.com/navneet83/multimodal-mountain-peak-search">GitHub-Repository</a> und ein <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/notebooks/multimodal_mountain_peak_search.ipynb">Colab-Notebook</a> zur Verfügung.</p><h2>Wie alles begann</h2><p>Dieser Blogbeitrag entstand auf Anregung eines 10-Jährigen, der mich bat, ihm alle Bilder des Mount Ama Dablam von meiner Everest-Basislager-Trekkingtour zu zeigen. Während wir das Fotoalbum durchsahen, wurde ich auch gebeten, mehrere andere Berggipfel zu identifizieren, von denen ich einige nicht benennen konnte.</p><p>Das brachte mich auf die Idee, dass dies ein unterhaltsames Computer-Vision-Projekt werden könnte. Was wir erreichen wollten:</p><ul><li><p>Finde Bilder eines Berggipfels anhand seines Namens</p></li><li><p>Errate den Namen des Berggipfels anhand eines Bildes und finde ähnliche Gipfel im Fotoalbum.</p></li><li><p>Konzeptabfragen zum Laufen bringen (<em>Person</em>, <em>Fluss</em>, <em>Gebetsfahnen</em> <em>usw.)</em></p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf82df9d7005fc3fe/6a17da78abe0f2e77bdfe8b9/e9d0d720a9b565d5b749bdc915068852d4f157ad-1200x1600.png" alt="Mount Ama Dablam " /><h2>Zusammenstellung des Dreamteams: SigLIP-2, Elasticsearch &amp; Streamlit</h2><p>Es wurde schnell klar, dass wir, um dies zu ermöglichen, sowohl den Text („Ama Dablam“) als auch die Bilder (Fotos aus meinem Album) in Vektoren umwandeln müssten, die sinnvoll verglichen werden können, d. h. im selben Vektorraum. Sobald wir das getan haben, besteht die Suche nur noch darin, „die nächstgelegenen Nachbarn zu finden“.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5f80b69a9d5bd28a/6a17da7a4b055ddd1243209e/20e6f8b7d4fa48414f407ec200adbe00ee28d517-1536x1024.png" alt="SigLIP-2, Elasticsearch &amp; Streamlit – ein Dreamteam." /><p>Um Bildeinbettungen zu generieren, verwenden wir einen mehrsprachigen<a href="https://huggingface.co/blog/vlms-2025"> Bild-Sprach-Encoder</a>, sodass ein Foto eines Berges und ein Ausdruck wie „Ama Dablam“ im selben Vektorraum landen.</p><p><a href="https://huggingface.co/blog/siglip2"><strong>SigLIP-2</strong></a>, das kürzlich von Google veröffentlicht wurde, passt hier gut hinein. Es kann Einbettungen ohne aufgabenspezifisches Training generieren (eine <strong>Zero-Shot</strong> -Einstellung) und eignet sich hervorragend für unseren Anwendungsfall: unbeschriftete Fotos und Gipfel mit unterschiedlichen Namen und Sprachen. Da es für die Zuordnung von Text zu Bild trainiert wurde, werden ein Bergbild von der Wanderung und eine kurze Texteingabeaufforderung als Einbettungen sehr ähnlich dargestellt, selbst wenn die Abfragesprache oder die Rechtschreibung variiert.</p><p>SigLIP-2 bietet ein gutes Verhältnis von Qualität zu Geschwindigkeit, unterstützt mehrere Eingangsauflösungen und läuft sowohl auf der CPU als auch auf der GPU. Der SigLIP-2 ist im Vergleich zu Vorgängermodellen wie dem ursprünglichen CLIP robuster für Außenaufnahmen. Während unserer Tests lieferte SigLIP-2 durchweg zuverlässige Ergebnisse. Es wird zudem sehr gut unterstützt, was es zur naheliegenden Wahl für dieses Projekt macht.</p><p>Als nächstes benötigen wir eine Vektordatenbank zum Speichern der Einbettungen und zur Durchführung der Power-Suche. Es sollte nicht nur die Cosinus-kNN-Suche über Bildeinbettungen unterstützen, sondern auch Geofencing und Textfilter in einer einzigen Abfrage anwenden. Elasticsearch passt hier gut: Es verarbeitet Vektoren (HNSW kNN auf dense_vector-Feldern) sehr gut, unterstützt die hybride Suche, die Text-, Vektor- und Geo-Abfragen kombiniert, und bietet standardmäßig Filter- und Sortierfunktionen. Es ist außerdem horizontal skalierbar, sodass man problemlos von einer Handvoll Fotos auf Tausende wachsen kann. Der offizielle <a href="https://www.elastic.co/docs/reference/elasticsearch/clients/python">Elasticsearch Python-Client</a> hält die Infrastruktur einfach und lässt sich nahtlos in das Projekt integrieren. Schließlich benötigen wir noch ein schlankes Frontend, in dem wir Suchanfragen eingeben und Ergebnisse anzeigen können. Für eine schnelle, Python-basierte Demo ist Streamlit hervorragend geeignet. Es bietet die grundlegenden Funktionen, die wir benötigen – Datei-Upload, ein responsives Bildraster und Dropdown-Menüs zum Sortieren und Geofencing. Es lässt sich leicht klonen und lokal ausführen und funktioniert auch in einem Colab-Notebook.</p><h2>Implementierung</h2><h3>Elasticsearch-Indexierungsdesign und Indexierungsstrategie</h3><p>Für dieses Projekt verwenden wir zwei Indizes: <code>peaks_catalog</code> und <code>photos</code>.</p><h4>Peaks_Katalogindex</h4><p>Dieser Index dient als kompakter Katalog markanter Berggipfel, die während der Everest-Basislager-Trekkingtour sichtbar sind. Jedes Dokument in diesem Index entspricht einem einzelnen Berggipfel, wie zum Beispiel dem Mount Everest. Für jedes Berggipfeldokument speichern wir Namen/Aliasse, optionale Breiten- und Längengradkoordinaten sowie einen einzelnen Prototypvektor, der durch die Kombination von SigLIP-2-Texteingabeaufforderungen (+ optionalen Referenzbildern) erstellt wird.</p><p><strong>Indexzuordnung:</strong></p><p>Feld</p><p>Typ</p><p>Beispiel</p><p>Zweck/Anmerkungen</p><p>Vektor-/Indexierung</p><p>Ausweis</p><p>Stichwort</p><p>ama-dablam</p><p>Stabiler Slug/ID</p><p>—</p><p>Namen</p><p>Text + Stichwort-Unterfeld</p><p>["Ama Dablam","Amadablam"]</p><p>Aliase / mehrsprachige Namen; names.raw für genaue Filter</p><p>—</p><p>Breitengrad</p><p>Geopunkt</p><p>{"lat":27.8617,"lon":86.8614}</p><p>GPS-Koordinaten des Gipfels als Kombination aus Breitengrad und Längengrad (optional)</p><p>—</p><p>elev_m</p><p>ganze Zahl</p><p>6812</p><p>Höhenangabe (optional)</p><p>—</p><p>text_embed</p><p>dense_vector</p><p>768</p><p>Kombinierter Prototyp (Aufforderungen und optional 1–3 Referenzbilder) für diesen Peak</p><p>index:true, similarity:"cosine", index_options:{type:"hnsw", m:16, ef_construction:128}</p><p>Dieser Index wird vor allem für Bild-zu-Bild-Suchen verwendet, beispielsweise zur Identifizierung von Berggipfeln anhand von Bildern. Wir verwenden diesen Index auch, um die Ergebnisse der Text-zu-Bild-Suche zu verbessern.</p><p>Zusammenfassend lässt sich sagen, dass die <code>peaks_catalog</code> die Frage „Welcher Berg ist das?“ in ein fokussiertes Nächste-Nachbar-Problem umwandelt und so das konzeptionelle Verständnis effektiv von der Komplexität der Bilddaten trennt.</p><p><strong>Indexierungsstrategie für den peaks_catalog-Index: </strong>Wir beginnen mit der Erstellung einer Liste der markantesten Gipfel, die während der EBC-Trekkingtour sichtbar sind. Für jeden Gipfel speichern wir seine geografische Position, seinen Namen, Synonyme und seine Höhe in einer <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/data/peaks.yaml">YAML-Datei</a>. Im nächsten Schritt wird für jeden Peak <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/embed_and_index_photos.py#L351">die Einbettung generiert</a> und im Feld <code>text_embed</code> gespeichert. Um robuste Einbettungen zu erzeugen, verwenden wir die folgende Technik:</p><ul><li><p>Erstellen Sie einen Textprototyp mit folgendem Werkzeug:</p><ul><li><p>Namen der Gipfel</p></li><li><p><a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/embed_and_index_photos.py#L301">Prompt-Ensemble</a> (Verwendung mehrerer unterschiedlicher Prompts, um dieselbe Frage zu beantworten), zum Beispiel:</p><ul><li><p>„Ein Naturfoto des Berggipfels {name} im Himalaya, Nepal“</p></li><li><p>„ {name} markanter Gipfel in der Khumbu-Region, alpine Landschaft“</p></li><li><p>„ {name} Berggipfel, Schnee, felsiger Grat“</p></li></ul></li><li><p>optionales <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/embed_and_index_photos.py#L333">Anti-Konzept</a> (sagt SigLIP-2, wonach nicht gematcht werden soll): einen kleinen Vektor für „Gemälde, Illustration, Poster, Karte, Logo“ abziehen, um eine Bevorzugung von echten Fotos zu erreichen.</p></li></ul></li><li><p>Optional <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/embed_and_index_photos.py#L388C13-L388C29">kann ein Bildprototyp erstellt werden,</a> falls Referenzbilder des Gipfels vorhanden sind.</p></li></ul><p>Anschließend <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/embed_and_index_photos.py#L392">verschmelzen wir den Text- und Bildprototyp</a> , um die endgültige Einbettung zu erzeugen. Abschließend wird das Dokument mit allen erforderlichen Feldern <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/embed_and_index_photos.py#L396">indexiert</a> :</p>def l2norm(v: np.ndarray) -&gt; np.ndarray:
    return v / (np.linalg.norm(v) + 1e-12)
def compute_blended_peak_vec(
        emb: Siglip2,
        names: List[str],
        peak_id: str,
        peaks_images_root: str,
        alpha_text: float = 0.5,
        max_images: int = 3,
) -&gt; Tuple[np.ndarray, int, int, List[str]]:
    """
    Build blended vector for a single peak.

    Returns:
      vec           : np.ndarray (L2-normalized)
      found_count   : number of reference images discovered
      used_count    : number of references used (&lt;= max_images)
      used_filenames: list of filenames used (for logging)
    """
    # 1) TEXT vector
    tv = embed_text_blend(emb, names)

    # 2) IMAGE refs: prefer folder by id; fallback to slug of the primary name
    root = Path(peaks_images_root)
    candidates = [root / peak_id]
    if names:
        candidates.append(root / slugify(names[0]))

    all_refs: List[Path] = []
    for c in candidates:
        if c.exists() and c.is_dir():
            all_refs = list_ref_images(c)
            if all_refs:
                break

    found = len(all_refs)
    used_list = all_refs[:max_images] if (max_images and found &gt; max_images) else all_refs
    used = len(used_list)

    img_v = embed_image_mean(emb, used_list) if used_list else None

    # 3) Blend TEXT and IMAGE vectors, clamp alpha to [0,1]
    a = max(0.0, min(1.0, float(alpha_text)))
    vec = l2norm(tv if img_v is None else (a * tv + (1.0 - a) * img_v)).astype("float32")
    return vec, found, used, [p.name for p in used_list]<p>Beispieldokument aus dem Index <code>peaks_catalog</code> :</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1219f5d0e39b512c/6a17da7c57726263161bcace/bc05fbd0c4f8d721d5170c28a3884a9eda80bb7d-1210x1132.png" alt="Ein Beispieldokument aus dem peaks_catalog-Index in Elasticsearch." /><h4>Fotoindex</h4><p>Dieser Hauptindex speichert detaillierte Informationen über alle Fotos im Album. Jedes Dokument stellt ein einzelnes Foto dar und enthält folgende Informationen:</p><ul><li><p>Relativer Pfad zum Foto im Fotoalbum. Dies kann verwendet werden, um das passende Bild anzuzeigen oder das Bild in die Suchoberfläche zu laden.</p></li><li><p>GPS- und Zeitinformationen des Bildes.</p></li><li><p>Dichter Vektor für die Bildkodierung, generiert durch SigLIP-2.</p></li><li><p><code>predicted_peaks</code> Das ermöglicht es uns, nach Gipfelnamen zu filtern.

<strong>Indexzuordnung</strong></p></li></ul><p>Feld</p><p>Typ</p><p>Beispiel</p><p>Zweck/Anmerkungen</p><p>Vektor-/Indexierung</p><p>Weg</p><p>Stichwort</p><p>data/images/IMG_1234.HEIC</p><p>Wie die Benutzeroberfläche das Miniaturbild/Vollbild öffnet</p><p>—</p><p>Bildausschnitt</p><p>dense_vector</p><p>768</p><p>SigLIP-2 Bildeinbettung</p><p>index:true, similarity:"cosine", index_options:{type:"hnsw", m:16, ef_construction:128}</p><p>vorhergesagte_Spitzen</p><p>Stichwort</p><p>["ama-dablam","pumori"]</p><p>Top-K-Vorhersagen zur Indexierungszeit (kostengünstiger UX-Filter / Facette)</p><p>—</p><p>GPS</p><p>Geopunkt</p><p>{"lat":27.96,"lon":86.83}</p><p>Aktiviert Geofilter</p><p>—</p><p>Schusszeit</p><p>date</p><p>2023-10-18T09:41:00Z</p><p>Aufnahmezeit: Sortieren/Filtern</p><p>—</p><p><strong>Indexierungsstrategie für den Fotoindex: </strong>Für jedes Foto im Album gehen wir wie folgt vor:
 Extrahieren Sie die Bildinformationen <code>shot_time</code> und <code>gps</code> <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/embed_and_index_photos.py#L526">aus den Bildmetadaten</a>.</p><ul><li><p><a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/embed_and_index_photos.py#L511">SigLIP-2 Bildeinbettung</a>: Das Bild wird durch das Modell geleitet und der Vektor anschließend L2-normalisiert. Speichere die Einbettung im Feld <code>clip_image</code> .</p></li><li><p><a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/embed_and_index_photos.py#L519">Die Peaks werden vorhergesagt</a> und im Feld <code>predicted_peaks</code> gespeichert. Dazu nehmen wir zunächst den im vorherigen Schritt erzeugten Bildvektor des Fotos und führen dann eine schnelle kNN-Suche im Feld text_embed im Index <code>peaks_catalog</code> durch. Wir behalten die obersten 3-4 Spitzen bei und ignorieren den Rest.</p></li><li><p>Wir berechnen das Feld <code>_id</code> , indem wir einen <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/embed_and_index_photos.py#L509">Hashwert</a> aus Bildname und Pfad erstellen. Dadurch wird sichergestellt, dass nach mehreren Durchläufen keine Duplikate entstehen.</p></li></ul><p>Sobald alle Felder für das Foto ermittelt wurden, werden die Fotodokumente mithilfe <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/embed_and_index_photos.py#L530">der Massenindizierung</a> stapelweise indexiert:</p>def bulk_index_photos(
        es: Elasticsearch,
        images_root: str,
        photos_index: str = "photos",
        peaks_index: str = "peaks_catalog",
        topk_predicted: int = 5,
        batch_size: int = 200,
        refresh: str = "false",
) -&gt; None:
    """Walk a folder of images, embed + enrich, and bulk index to Elasticsearch."""
    root = Path(images_root)
    if not root.exists():
        raise SystemExit(f"Images root not found: {images_root}")

    emb = Siglip2()
    batch: List[Dict[str, Any]] = []
    n_indexed = 0

    for p in iter_images(root):
        rel = relpath_within(root, p)
        _id = id_for_path(rel)

        # 1) Image embedding (and reuse it for predicted_peaks)
        try:
            with Image.open(p) as im:
                ivec = emb.image_vec(im.convert("RGB")).astype("float32")
        except (UnidentifiedImageError, OSError) as e:
            print(f"[skip] {rel} — cannot embed: {e}")
            continue

        # 2) Predict top-k peak names
        try:
            top_names = predict_peaks(es, ivec.tolist(), peaks_index=peaks_index, k=topk_predicted)
        except Exception as e:
            print(f"[warn] predict_peaks failed for {rel}: {e}")
            top_names = []

        # 3) EXIF enrichment (safe)
        gps = get_gps_decimal(str(p))
        shot = get_shot_time(str(p))

        # 4) Build doc and stage for bulk
        doc = {"path": rel, "clip_image": ivec.tolist(), "predicted_peaks": top_names}
        if gps:
            doc["gps"] = gps
        if shot:
            doc["shot_time"] = shot

        batch.append(
            {"_op_type": "index", "_index": photos_index, "_id": _id, "_source": doc}
        )

        # 5) Periodic flush
        if len(batch) &gt;= batch_size:
            helpers.bulk(es, batch, refresh=refresh)
            n_indexed += len(batch)
            print(f"[photos] indexed {n_indexed} (last: {rel})")
            batch.clear()

    # Final flush
    if batch:
        helpers.bulk(es, batch, refresh=refresh)
        n_indexed += len(batch)
        print(f"[photos] indexed {n_indexed} total.")

    print("[done] photos indexing")<p>Beispieldokument aus dem Fotoindex:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt744b7e6326937cfc/6a17da7e6df731d3040a0da8/1dc1406ac2a97440b6804838795b3c2205c4c6b2-1080x1234.png" alt="Ein Beispieldokument aus dem Fotoindex in Elasticsearch." /><p>Zusammenfassend lässt sich sagen, dass der Fotoindex ein schneller, filterbarer und kNN-fähiger Speicher aller Fotos im Album ist. Die Kartierung ist bewusst minimalistisch gehalten – gerade so strukturiert, dass die Ergebnisse schnell abgerufen, übersichtlich dargestellt und nach Raum und Zeit unterteilt werden können. Dieser Index dient beiden Suchanwendungsfällen. Das Python-Skript zur Erstellung beider Indizes finden Sie <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/create_indices.py">hier</a>.</p><p>Die untenstehende Visualisierung der Kibana-Karten zeigt Dokumente aus dem Fotoalbum als grüne Punkte und Berggipfel ab dem Index <code>peaks_catalog</code> als rote Dreiecke an, wobei die grünen Punkte gut mit dem Wanderweg zum Everest-Basislager übereinstimmen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb5bf016e8d9c3e84/6a17da80be608681f10045e6/1c75d0ed0ce53d28a94bf2f47a354e25581d2baf-1600x1402.png" alt="Eine Visualisierung in Kibana Maps, die Dokumente aus dem Fotoalbum als grüne Punkte und Berggipfel aus dem peaks_catalog-Index als rote Dreiecke darstellt, wobei die grünen Punkte gut mit dem Wanderweg zum Everest Base Camp übereinstimmen." /><h2>Suchanwendungsfälle</h2><p><strong>Namenssuche (Text-zu-Bild): Mit</strong> dieser Funktion können Benutzer mithilfe von Textanfragen Fotos von Berggipfeln (und sogar abstrakten Konzepten wie „Gebetsfahnen“) finden. Um dies zu erreichen, wird die Texteingabe mithilfe von SigLIP-2 <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/query_by_peak_name.py#L87C5-L87C20">in einen Textvektor umgewandelt</a> . Für eine robuste Textvektorgenerierung verwenden wir die gleiche Strategie wie für die Erstellung von Text-Embeddings im <code>peaks_catalog</code> -Index: <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/query_by_peak_name.py#L104">Kombination</a> der Texteingabe mit einem kleinen <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/query_by_peak_name.py#L100">Prompt-Ensemble</a>, Subtraktion eines minor<a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/query_by_peak_name.py#L103"> Anti-Concept-Vektors</a> und Anwendung <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/query_by_peak_name.py#L104">der L2-Normalisierung</a> zur Erzeugung des endgültigen Abfragevektors. Anschließend wird eine kNN- <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/query_by_peak_name.py#L140">Abfrage</a> auf dem Feld <code>photos.clip_image</code> ausgeführt, um die am besten übereinstimmenden Peaks auf Basis der Kosinusähnlichkeit zu ermitteln und so die ähnlichsten Bilder zu finden. Optional können die Suchergebnisse relevanter gestaltet werden, indem Geo- und <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/query_by_peak_name.py#L152">Datumsfilter</a> und/oder ein <code>photos.predicted_peaks</code> -Termfilter als Teil der Abfrage angewendet werden (siehe Abfragebeispiele unten). Dadurch werden ähnlich aussehende Gipfel ausgeschlossen, die auf der Wanderung gar nicht sichtbar sind.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9bb9abf5ce64fcbb/6a17da81e8fbce20db3a17da/b5fac28ffdbedb820505365ca07df125cd01b939-946x370.png" alt="Wie die multimodale Suche nach Namen (Text-zu-Bild) in Elasticsearch funktioniert." /><p><strong>Elasticsearch-Abfrage mit Geofilter:</strong></p>POST photos/_search
{
  "knn": {
    "field": "clip_image",
    "query_vector": [ ... ],
    "k": 60,
    "num_candidates": 2000
  },
  "query": {
    "bool": {
      "filter": [
        { "geo_bounding_box": { "gps": { "top_left": "...", "bottom_right": "..." } } }
      ]
    }
  },
  "_source": ["path","predicted_peaks","gps","shot_time"]
}

Response (first two documents):
{
 "hits": {
   "total": {
     "value": 56,
     "relation": "eq"
   },
   "max_score": 0.5779596,
   "hits": [
     {
       "_index": "photos",
       "_id": "d01da3a1141981486c3493f6053c79e92a788463",
       "_score": 0.5779596,
       "_source": {
         "path": "IMG_2738.HEIC",
         "predicted_peaks": [
           "Pumori",
           "Kyajo Ri",
           "Khumbila",
           "Nangkartshang",
           "Kongde Ri"
         ],
         "gps": {
           "lat": 27.97116388888889,
           "lon": 86.82331111111111
         },
         "shot_time": "2023-11-03T08:07:13"
       }
     },
     {
       "_index": "photos",
       "_id": "c79d251f07adc5efaedc53561110a7fd78e23914",
       "_score": 0.5766071,
       "_source": {
         "path": "IMG_2761.HEIC",
         "predicted_peaks": [
           "Kyajo Ri",
           "Makalu",
           "Baruntse",
           "Cho Oyu",
           "Khumbila"
         ],
         "gps": {
           "lat": 27.975558333333332,
           "lon": 86.82515
         },
         "shot_time": "2023-11-03T08:51:08"
       }
     }
}<p><strong>Bildsuche (Bild-zu-Bild): Mit</strong> dieser Funktion können wir einen Berg auf einem Bild identifizieren und weitere Bilder desselben Berges innerhalb des Fotoalbums finden. Beim Hochladen eines Bildes wird dieses vom SigLIP-2-Bildcodierer verarbeitet, um einen <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/identify_from_picture_find_similar_peaks.py#L228">Bildvektor</a> zu erzeugen. Anschließend wird eine <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/identify_from_picture_find_similar_peaks.py#L234">kNN-Suche</a> im Feld <code>peaks_catalog.text_embed</code> durchgeführt, um die am besten passenden Peaknamen zu identifizieren. Anschließend <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/identify_from_picture_find_similar_peaks.py#L257">wird aus diesen übereinstimmenden Peaknamen ein Textvektor generiert</a> und eine weitere <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/scripts/identify_from_picture_find_similar_peaks.py#L263">kNN-Suche</a> im Fotoindex durchgeführt, um entsprechende Bilder zu finden.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltab9d16333e2a9e69/6a17da827f6f155448c099cc/3a3d5635bee7a222b95529dd7f9fbee016381610-1226x550.png" alt="Wie die multimodale Bildersuche (Bild-zu-Bild) in Elasticsearch funktioniert." /><p><strong>Elasticsearch-Abfrage:</strong></p><p>Schritt 1: Finde die passenden Peaknamen</p>GET peaks_catalog/_search
{
 "knn": {
   "field": "text_embed",
   "query_vector": [...image-vector... ],
   "k": 3,
   "num_candidates": 500
 },
 "_source": [
   "id",
   "names",
   "latlon",
   "text_embed"
 ]
}


Response (first two documents):
{
 "took": 2,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 3,
     "relation": "eq"
   },
   "max_score": 0.58039916,
   "hits": [
     {
       "_index": "peaks_catalog",
       "_id": "pumori",
       "_score": 0.58039916,
       "_source": {
         "id": "pumori",
         "names": [
           "Pumori",
           "Pumo Ri"
         ],
         "latlon": {
           "lat": 28.01472,
           "lon": 86.82806
         },
         "text_embed": [
                  ... embeddings...
         ]
       }
     },
     {
       "_index": "peaks_catalog",
       "_id": "kyajo-ri",
       "_score": 0.57942784,
       "_source": {
         "id": "kyajo-ri",
         "names": [
           "Kyajo Ri",
           "Kyazo Ri"
         ],
         "latlon": {
           "lat": 27.909167,
           "lon": 86.673611
         },
         "text_embed": [
           ... embeddings...
         ]
       }
     }
   ]
 }
}<p>Schritt 2: Führen Sie eine Suche im Index <code>photos</code> durch, um die passenden Bilder zu finden (dieselbe Abfrage wie im Anwendungsfall der Text-zu-Bild-Suche):</p>POST photos/_search
{
 "knn": {
   "field": "clip_image",
   "query_vector": [ ...image-vector... ],
   "k": 30,
   "num_candidates": 2000
 },
 "_source": [
   "path",
   "gps",
   "shot_time",
   "predicted_peaks",
   "clip_image"
 ],
 "query": {
   "bool": {
     "filter": [
       {
         "term": {
           "predicted_peaks": "Pumori"
         }
       }
     ]
   }
 }
}


Response (first two documents):
{
 "hits": {
   "total": {
     "value": 56,
     "relation": "eq"
   },
   "max_score": 0.5779596,
   "hits": [
     {
       "_index": "photos",
       "_id": "d01da3a1141981486c3493f6053c79e92a788463",
       "_score": 0.5779596,
       "_source": {
         "path": "IMG_2738.HEIC",
         "predicted_peaks": [
           "Pumori",
           "Kyajo Ri",
           "Khumbila",
           "Nangkartshang",
           "Kongde Ri"
         ],
         "gps": {
           "lat": 27.97116388888889,
           "lon": 86.82331111111111
         },
         "shot_time": "2023-11-03T08:07:13"
       }
     },
     {
       "_index": "photos",
       "_id": "c79d251f07adc5efaedc53561110a7fd78e23914",
       "_score": 0.5766071,
       "_source": {
         "path": "IMG_2761.HEIC",
         "predicted_peaks": [
           "Kyajo Ri",
           "Makalu",
           "Baruntse",
           "Cho Oyu",
           "Khumbila"
         ],
         "gps": {
           "lat": 27.975558333333332,
           "lon": 86.82515
         },
         "shot_time": "2023-11-03T08:51:08"
       }
     }
}<h2>Streamlit-Benutzeroberfläche</h2><p>Um alles zusammenzuführen, haben wir eine einfache Streamlit-Benutzeroberfläche entwickelt, die es uns ermöglicht, beide Suchanwendungsfälle durchzuführen. In der linken Spalte wird eine scrollbare Liste von Gipfeln (aggregiert aus <code>photos.predicted_peaks</code>) mit Kontrollkästchen und einem Mini-Karten-/Geofilter angezeigt. Ganz oben befinden sich ein <strong>Suchfeld für den Namen</strong> und eine Schaltfläche zum Hochladen <strong>eines Fotos zur Identifizierung</strong> . Im mittleren Bereich befindet sich ein responsives Miniaturraster mit kNN-Werten, vorhergesagten Spitzenwerten und Erfassungszeiten. Jedes Bild enthält eine Schaltfläche <strong>„Bild anzeigen“</strong> für Vorschauen in voller Auflösung.</p><p><strong>Suche durch Hochladen eines Bildes:</strong> Wir prognostizieren den Peak und finden übereinstimmende Peaks aus dem Fotoalbum.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd1fb2b0304a310d2/6a17da8425daab7cda08a0fa/dca540cbf5279e6d6102c5a0c0351ddd4ac91cda-1600x1112.png" alt="Eine einfache, intuitive Benutzeroberfläche, die die multimodale Suche nach den Gipfeln des Mount Ama Dablam sowohl per Text-zu-Bild- als auch per Bild-zu-Bild-Suche ermöglicht." /><p><strong>Suche nach Text</strong>: Finde die passenden Höhepunkte im Album anhand des Textes</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt496c1ae8f7886320/6a17da86abe0f2da48dfe8bd/b1e8618db746cd49ea4962d3dc73031387b975dd-1600x1166.png" alt="Wie man in der Berggipfelbibliothek mithilfe der Textsuche nach einem Gipfel des Mount Everest sucht." /><h2>Fazit</h2><p>Was mit der Frage begann: <em>Können wir bitte die </em>Bilder<em><strong>von Ama Dablam</strong></em>sehen<em>?</em> entwickelte sich zu einem kleinen, funktionierenden <strong>multimodalen Suchsystem</strong> . Wir haben Rohdaten von Trekkingfotos aufgenommen, diese in <strong>SigLIP-2-Einbettungen</strong> umgewandelt und <strong>Elasticsearch</strong> verwendet, um ein schnelles <strong>kNN</strong> über Vektoren durchzuführen, sowie einfache Geo-/Zeitfilter, um die richtigen Bilder anhand ihrer <em>Bedeutung</em> anzuzeigen. Dabei haben wir die Belange mithilfe zweier Indizes getrennt: einem winzigen <code>peaks_catalog</code> Index von kombinierten Prototypen (zur Identifizierung) und einem skalierbaren <code>photos</code> Index von Bildvektoren und EXIF-Daten (zum Abruf). Es ist praktisch, reproduzierbar und leicht erweiterbar.</p><p>Falls Sie es feinabstimmen möchten, gibt es einige Einstellungen, mit denen Sie experimentieren können:</p><ul><li><p><strong>Einstellungen für die Abfragezeit:</strong> <code>k</code> (wie viele Nachbarn Sie zurückbekommen möchten) und <code>num_candidates</code> (wie breit die Suche vor der endgültigen Bewertung sein soll). Diese Einstellungen werden <a href="https://www.elastic.co/search-labs/blog/elasticsearch-knn-and-num-candidates-strategies">hier</a> im Blog besprochen.</p></li><li><p><strong>Indexzeiteinstellungen:</strong> <code>m</code> (Graphkonnektivität) und <code>ef_construction</code> (Genauigkeit der Build-Zeit vs. Speicher). Experimentieren Sie bei Abfragen auch mit <code>ef_search</code> – ein höherer Wert bedeutet in der Regel eine bessere Trefferquote, allerdings mit einem gewissen Nachteil bei der Latenz. Weitere Einzelheiten zu diesen Einstellungen finden Sie in <a href="https://www.elastic.co/search-labs/blog/hnsw-graph">diesem Blog</a> .</p></li></ul><p>Zukünftig werden native Modelle/Reranker für <strong>multimodale</strong> und <strong>mehrsprachige</strong> Suche in Kürze im Elastic-Ökosystem verfügbar sein. Dies dürfte die Bild-/Textsuche und das hybride Ranking von Haus aus noch weiter verbessern.<a href="https://ir.elastic.co/news/news-details/2025/Elastic-Completes-Acquisition-of-Jina-AI-a-Leader-in-Frontier-Models-for-Multimodal-and-Multilingual-Search/default.aspx?utm_source=chatgpt.com"> ir.elastic.co+1</a></p><p>Wenn Sie das selbst ausprobieren möchten:</p><ul><li><p><strong>GitHub-Repository:</strong> <a href="https://github.com/navneet83/multimodal-mountain-peak-search"><em>https://github.com/navneet83/multimodal-mountain-peak-search</em></a></p></li><li><p><strong>Colab-Schnellstartanleitung:</strong> <a href="https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/notebooks/multimodal_mountain_peak_search.ipynb">https://github.com/navneet83/multimodal-mountain-peak-search/blob/main/notebooks/multimodal_mountain_peak_search.ipynb</a></p></li></ul><p>Damit ist unsere Reise zu Ende, und es ist Zeit, zurückzufliegen. Ich hoffe, das war hilfreich, und falls etwas kaputtgeht (oder verbessert wird), würde ich gerne erfahren, was Sie geändert haben.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdce2fff1569d2a8b/6a17da894b055dd1f24320a2/d324d1e1472f1bfbd8f25747f57bdeeb9c7f16b2-1600x1200.png" alt="" />]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/multimodal-search-siglip-2-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/multimodal-search-siglip-2-elasticsearch</guid>
    <category><![CDATA[Vektordatenbank]]></category>
    <category><![CDATA[Hybride Suche]]></category>
    <category><![CDATA[KI]]></category>
    <category><![CDATA[Python]]></category>
    <dc:creator><![CDATA[Navneet Kumar]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltccb66279debb05f9/6a17da8b63baffe228741b15/ffcf93358a7c5dadcea82faf3de460bf060d003c-1600x1200.png" length="0" type="image/png"/>
    <pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Experimente zur Verbesserung von Agentic AI-Tools für Elasticsearch]]></title>
    <description><![CDATA[Erfahren Sie, wie wir die Arbeitsabläufe von KI-Agenten für Elasticsearch durch iterative Experimente verbessert haben, indem wir lineare Retriever, hybride Suche und semantic_text für eine skalierbare RAG-Optimierung kombiniert haben.]]></description>
    <content:encoded><![CDATA[<p>Wie heutzutage alle anderen setzen auch wir bei Elastic voll auf Chat, Agenten und RAG. In der Suchabteilung haben wir kürzlich an einem Agent Builder und einer Tool Registry gearbeitet, alles mit dem Ziel, die Interaktion mit Ihren Daten in Elasticsearch so einfach wie möglich zu gestalten.</p><p>Lesen Sie den <a href="https://www.elastic.co/search-labs/blog/ai-agentic-workflows-elastic-ai-agent-builder">Blogbeitrag „Building AI Agentic Workflows with Elasticsearch“,</a> um mehr über das Gesamtbild dieser Bemühungen zu erfahren, oder <a href="https://www.elastic.co/search-labs/blog/ai-agent-builder-elasticsearch">„Your First Elastic Agent: From a Single Query to an AI-Powered Chat“</a> für eine praxisorientiertere Einführung.</p><p>In diesem Blogbeitrag wollen wir uns jedoch etwas genauer mit einem der ersten Dinge befassen, die beim Starten eines Chats passieren, und Ihnen einige der kürzlich vorgenommenen Verbesserungen vorstellen.</p><h2>Was geschieht hier?</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1331b1043612efe3/6a17f115505ac3dc41ad8c3c/25a24055a166d7d6ba81d80aa35cb97163662e23-1600x443.png" alt="" /><p>Wenn Sie mit Ihren Elasticsearch-Daten interagieren, durchläuft unser standardmäßiger KI-Agent diesen Standardablauf:</p><ol><li><p>Überprüfen Sie die Eingabeaufforderung.</p></li><li><p>Ermitteln Sie, welcher Index wahrscheinlich die Antworten auf diese Frage enthält.</p></li><li><p>Erstelle eine Abfrage für diesen Index basierend auf der Eingabeaufforderung.</p></li><li><p>Durchsuchen Sie diesen Index mit dieser Suchanfrage.</p></li><li><p>Die Ergebnisse zusammenfassen.</p></li><li><p>Können die Ergebnisse die Fragestellung beantworten? Falls ja, antworten Sie bitte. Wenn nicht, wiederholen Sie den Vorgang, aber versuchen Sie etwas anderes.</p></li></ol><p>Das sollte nicht allzu neuartig aussehen – es ist einfach nur Retrieval Augmented Generation (RAG). Wie zu erwarten, hängt die Qualität Ihrer Antworten stark von der Relevanz Ihrer ersten Suchergebnisse ab. Während wir an der Verbesserung unserer Antwortqualität gearbeitet haben, haben wir den Abfragen, die wir in Schritt 3 generiert und in Schritt 4 ausgeführt haben, sehr große Aufmerksamkeit geschenkt. Und wir haben ein interessantes Muster festgestellt.</p><p>Oftmals lag es bei unseren ersten, „schlechten“ Antworten nicht daran, dass wir eine fehlerhafte Abfrage ausgeführt hatten. Das lag daran, dass <em>wir den falschen Index für die Abfrage ausgewählt hatten</em> . Die Schritte 3 und 4 waren normalerweise nicht unser Problem – es war Schritt 2.</p><h2>Was haben wir gemacht?</h2><p>Unsere erste Implementierung war einfach. Wir hatten ein Tool (namens index_explorer) entwickelt, das effektiv eine <code>_cat/indices</code> -Auflistung aller verfügbaren Indizes durchführt und anschließend den LLM auffordert, denjenigen dieser Indizes zu ermitteln, der am besten zur Nachricht/Frage/Aufforderung des Benutzers passt. Die <a href="https://github.com/elastic/kibana/blob/0cc78184957fcd12110dabae50353392ea937508/x-pack/platform/packages/shared/onechat/onechat-genai-utils/tools/index_explorer.ts#L98-L113">ursprüngliche Implementierung können Sie hier</a> einsehen.</p>You are an AI assistant for the Elasticsearch company.
based on a natural language query from the user, your task is to select up to ${limit} most relevant indices from a list of indices.

*The natural language query is:* ${nlQuery}

*List of indices:*
${indices.map((index) =&gt; `- ${index.index}`).join('\n')}

Based on those information, please return most relevant indices with your reasoning.
Remember, you should select at maximum ${limit} indices.<p>Wie gut funktionierte das? Wir waren uns nicht sicher! Wir hatten klare Beispiele, wo es <em>nicht</em> gut funktionierte, aber unsere eigentliche erste Herausforderung bestand darin, unseren aktuellen Zustand zu quantifizieren.</p><h2>Festlegung einer Ausgangsbasis</h2><h3>Es beginnt mit Daten</h3><p>Was wir brauchten, war ein Referenzdatensatz, um die Effektivität eines Tools bei der Auswahl des richtigen Index anhand einer Benutzereingabe und einer bereits vorhandenen Menge von Indizes zu messen. Und wir hatten keinen solchen Datensatz zur Hand. Also haben wir einen generiert.</p><p>Hinweis: Wir wissen, dass dies nicht die „Best Practice“ ist. Manchmal ist es aber besser, vorwärts zu gehen, als auf der Stelle zu treten. <a href="https://www.elastic.co/about/our-source-code#progress-perfection">Fortschritt, schlichte Perfektion</a>.</p><p>Wir haben mithilfe <a href="https://gist.github.com/seanstory/a08db2e149897da656db3a1ca72e17ac">dieser Eingabeaufforderung</a> Startindizes für verschiedene Domänen generiert. Anschließend generierten wir für jede generierte Domäne mithilfe<a href="https://gist.github.com/seanstory/a280a85d067e61bfeb5911bf2654e6e2"> dieser Eingabeaufforderung</a> einige weitere Indizes (Ziel war es, das LLM mit schwierigen Negativen und schwer zu klassifizierenden Beispielen zu verwirren). Anschließend haben wir jeden generierten Index und seine Beschreibungen manuell bearbeitet. Abschließend generierten wir mithilfe <a href="https://gist.github.com/seanstory/44291b666c05a383136f6e36bb9106fa">dieser Eingabeaufforderung</a> Testabfragen. Dies ergab Beispieldaten wie:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1bd9cd78154195e3/6a17f117dbb4fff7b5fb57d2/9d96d87e286eddbc012402b1ecccd57419a99253-1600x782.png" alt="" /><p>und Testfälle wie:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltadf30a0aeafd56ef/6a17f1192f4a5c160ffa89eb/4c2e9ad941d98d7e66033bbc08c9b8060ec19097-1600x797.png" alt="" /><h3>Anfertigung eines Testgeschirrs</h3><p>Der weitere Ablauf war von hier an sehr einfach. Entwerfen Sie ein Tool, das Folgendes kann:</p><ol><li><p>Erstellen Sie eine saubere Ausgangsbasis mit einem Elasticsearch-Zielcluster.</p></li><li><p>Erstelle alle im Zieldatensatz definierten Indizes.</p></li><li><p>Führen Sie für jedes Testszenario das Tool i<code>ndex_explorer</code> aus (praktischerweise verfügen wir über eine <a href="https://www.elastic.co/docs/api/doc/kibana/operation/operation-post-agent-builder-tools-execute">Execute Tool API</a>).</p></li><li><p>Vergleiche den Ergebnisindex mit dem erwarteten Index und speichere das Ergebnis.</p></li><li><p>Nachdem alle Testszenarien abgeschlossen sind, werden die Ergebnisse tabellarisch erfasst.</p></li></ol><h3>Laut einer Umfrage…</h3><p>Die ersten Ergebnisse waren wenig überraschend mittelmäßig.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt73367741359e258d/6a17f11a505ac39749ad8c40/9c10679bcd6291edfa2a9ba42e7dd922aa483f0b-1216x806.png" alt="" /><p>Insgesamt lag die Trefferquote bei der Identifizierung des richtigen Index bei 77,14 %. Und das war ein „Best-Case“-Szenario, in dem alle Indizes gute, semantisch aussagekräftige Namen haben. Jeder, der schon einmal `PUT test2/_doc/foo {...}` ausgeführt hat, weiß, dass die Indizes nicht immer aussagekräftige Namen haben.</p><p>Wir haben also einen Ausgangspunkt, und dieser zeigt, dass es noch viel Raum für Verbesserungen gibt. Nun war es Zeit für etwas Wissenschaft! 🧪</p><h2>Experimentieren</h2><h3>Hypothese 1: Kartierungen werden helfen</h3><p>Das Ziel hierbei ist es, einen Index zu identifizieren, der Daten enthält, die für die ursprüngliche Fragestellung relevant sind. Und der Teil eines Index, der die darin enthaltenen Daten am besten beschreibt, sind die <em>Indexzuordnungen</em>. Selbst ohne Stichproben aus dem Indexinhalt zu entnehmen, lässt die Tatsache, dass der Index ein Preisfeld vom Typ double besitzt, darauf schließen, dass die Daten etwas darstellen, das verkauft werden soll. Ein Autorenfeld vom Typ Text impliziert unstrukturierte Sprachdaten. Die Kombination der beiden Begriffe könnte darauf hindeuten, dass es sich bei den Daten um Bücher/Geschichten/Gedichte handelt. Allein aus der Kenntnis der Eigenschaften eines Index lassen sich viele semantische Hinweise ableiten. In einem lokalen Branch habe ich also unsere `.index_explorer`-Methode angepasst. Tool zum Senden der vollständigen Zuordnungen eines Index (samt Namen) an das LLM zur Entscheidungsfindung. </p><p>Das Ergebnis (aus den Kibana-Protokollen):</p>[2025-09-05T11:01:21.552-05:00][ERROR][plugins.onechat] Error: Error calling connector: event: error
data: {"error":{"code":"request_entity_too_large","message":"Received a content too large status code for request from inference entity id [.rainbow-sprinkles-elastic] status [413]","type":"error"}}


    at createInferenceProviderError (errors.ts:90:10)
    at convertUpstreamError (convert_upstream_error.ts:39:38)
    at handle_connector_response.ts:26:33
    at Observable.init [as _subscribe] (/Users/seanstory/Desktop/Dev/kibana/node_modules/rxjs/src/internal/observable/throwError.ts:123:68)...<p>Die ursprünglichen Entwickler des Tools hatten dies vorhergesehen. Während die Zuordnung eines Index eine wahre Fundgrube an Informationen darstellt, ist sie gleichzeitig ein ziemlich umfangreicher JSON-Block. Und in einem realistischen Szenario, in dem man zahlreiche Indizes vergleicht (unser Evaluierungsdatensatz definiert 20), summieren sich diese JSON-Blobs. Wir möchten dem LLM also mehr Kontext für seine Entscheidung geben als nur Indexnamen für alle Optionen, aber nicht so sehr die vollständigen Zuordnungen jeder einzelnen.</p><h3>Hypothese 2: „Vereinfachte“ Zuordnungen (Feldlisten) als Kompromiss</h3><p>Wir gingen von der Annahme aus, dass Indexersteller semantisch aussagekräftige Indexnamen verwenden würden. Was wäre, wenn wir diese Annahme auch auf Feldnamen ausdehnen würden? Unser vorheriges Experiment scheiterte, weil Mapping-JSON eine Menge überflüssiger Metadaten und Boilerplate-Code enthält.</p>     "description_text": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          },
          "copy_to": [
            "description_semantic"
          ]
        },<p>Der obige Block beispielsweise umfasst 236 Zeichen und definiert lediglich ein einzelnes Feld in einem Elasticsearch-Mapping. Die Zeichenkette „description_text“ hingegen umfasst nur 16 Zeichen. Das entspricht einer fast 15-fachen Erhöhung der Zeichenanzahl, ohne dass sich die semantische Aussagekraft dieses Feldes hinsichtlich der verfügbaren Daten sinnvoll verbessert. Was wäre, wenn wir Zuordnungen für alle Indizes abrufen, diese aber vor dem Senden an das LLM zu einer Liste ihrer Feldnamen „vereinfachen“ würden?</p><p>Wir haben es versucht.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta5eda7a79493ee81/6a17f11c9da390327fe46590/112c2f447c11f154b5082725cd49b51d0a3c8a65-1214x804.png" alt="" /><p>Das ist großartig! Durchweg Verbesserungen. Aber könnten wir es besser machen?</p><h3>Hypothese 3: Beschreibungen in der Mapping-Datei _meta</h3><p>Wenn schon Feldnamen ohne zusätzlichen Kontext einen so großen Sprung verursachen, wäre das Hinzufügen von substanziellem Kontext vermutlich noch besser! Es ist nicht unbedingt üblich, jedem Index eine Beschreibung beizufügen, aber es ist möglich, dem _meta-Objekt der Zuordnung Metadaten auf Indexebene jeglicher Art hinzuzufügen. Wir haben unsere generierten Indizes erneut aufgerufen und jedem Index in unserem Datensatz eine Beschreibung hinzugefügt. Solange die Beschreibungen nicht übermäßig lang sind, sollten sie weniger Tokens verwenden als die vollständige Zuordnung und einen deutlich besseren Einblick in die im Index enthaltenen Daten bieten. Unser Experiment bestätigte diese Hypothese.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt61b85cf40e0e6357/6a17f11dfbc5f82809491bbe/32d2692ad4479d0e52d8ee723dcc5710a6ec90f3-1208x806.png" alt="" /><p>Eine kleine Verbesserung, und wir liegen jetzt durchweg bei über 90 % Genauigkeit.</p><h3>Hypothese 4: Das Ganze ist größer als seine Teile</h3><p>Feldnamen haben unsere Ergebnisse verbessert. Die Beschreibungen verbesserten unsere Ergebnisse. Die Verwendung <em>von </em>Beschreibungen UND Feldnamen sollte also noch bessere Ergebnisse liefern, richtig?</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte6297c6aaf7db802/6a17f11e14d90c1bd779b6e6/114cbb408ff16b136251d2265416bd5270380fe5-1208x794.png" alt="" /><p>Die Daten ergaben „nein“ (keine Veränderung gegenüber dem vorherigen Experiment). Die vorherrschende Theorie hierbei war, dass, da die Beschreibungen von vornherein aus den Indexfeldern/Zuordnungen generiert wurden, zwischen diesen beiden Kontextelementen nicht genügend unterschiedliche Informationen vorhanden sind, um bei ihrer Kombination etwas „Neues“ hinzuzufügen. Darüber hinaus wird die Nutzlast, die wir für unsere 20 Testindizes senden, ziemlich groß. Der Gedankengang, dem wir bisher gefolgt sind, ist nicht skalierbar. Tatsächlich gibt es guten Grund zu der Annahme, dass keines unserer bisherigen Experimente auf Elasticsearch-Clustern funktionieren würde, bei denen Hunderte oder Tausende von Indizes zur Auswahl stehen. Ein Ansatz, der die Größe der an den LLM gesendeten Nachricht linear mit der Gesamtzahl der Indizes erhöht, dürfte wahrscheinlich keine allgemein anwendbare Strategie darstellen.</p><p>Was wir wirklich brauchen, ist ein Ansatz, der uns hilft, eine große Anzahl von Kandidaten auf die relevantesten Optionen zu reduzieren…</p><p>Wir haben es hier mit einem Suchproblem zu tun.</p><h3>Hypothese 5: Selektion durch semantische Suche</h3><p>Wenn der Name eines Indexes eine semantische Bedeutung hat, dann kann er als Vektor gespeichert und semantisch durchsucht werden.</p><p>Wenn die Feldnamen eines Index eine semantische Bedeutung haben, dann können sie als Vektoren gespeichert und semantisch durchsucht werden.</p><p>Wenn ein Index eine Beschreibung mit semantischer Bedeutung besitzt, kann auch diese als Vektor gespeichert und semantisch durchsucht werden.</p><p>Aktuell sind diese Informationen mit Elasticsearch-Indizes nicht durchsuchbar (vielleicht sollten wir das ändern!), aber es war relativ einfach, <a href="https://github.com/elastic/connectors/pull/3638"> etwas zusammenzubasteln</a> , das diese Lücke umgehen konnte. Mithilfe des Connector-Frameworks von Elastic habe ich einen Connector erstellt, der für jeden Index in einem Cluster ein Dokument ausgibt. Die Ausgabedokumente würden etwa so aussehen:</p> doc = {
                "_id": index_name,
                "index_name": index_name,
			"meta_description”: description,
"field_descriptions" = field_descriptions,
                "mapping": json.dumps(mapping),  
                "source_cluster": self.es_client.configured_host,
            }<p>Ich habe diese Dokumente in einen neuen Index verschoben, in dem ich die Zuordnung manuell wie folgt definiert habe:</p>{
   "mappings": {
       "properties": {
           "semantic_content": {
               "type": "semantic_text"
           },
           "index_name": {
               "type": "text",
               "copy_to": "semantic_content"
           },
           "mapping": {
               "type": "keyword",
               "copy_to": "semantic_content"
           },
           "source_cluster": {
               "type": "keyword"
           },
           "meta_description": {
               "type": "text",
               "copy_to": "semantic_content"
           },
           "field_descriptions": {
               "type": "text",
               "copy_to": "semantic_content"
           }
       }
   }
}<p>Dadurch entsteht ein einzelnes semantisches Inhaltsfeld, in dem alle anderen Felder mit semantischer Bedeutung zusammengefasst und indiziert werden. Die Suche in diesem Index wird trivial, mit lediglich:</p>GET indexed-indices/_search
{
 "query": {
   "semantic": {
     "field": "semantic_content",
     "query": "$query"
   }
 }
}<p>Das modifizierte <code>index_explorer</code> -Tool ist jetzt <em>wesentlich</em> schneller, da es keine Anfrage an ein LLM stellen muss, sondern stattdessen eine einzelne Einbettung für die gegebene Anfrage anfordern und eine effiziente Vektorsuche durchführen kann. Wenn wir den Spitzenreiter als unseren ausgewählten Index verwenden, erhalten wir folgende Ergebnisse:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc27c302e6bef0b23/6a17f120577262d2f21bccdc/06ef5d78040d064d3444793f636d527d9e19a869-1214x800.png" alt="" /><p>Dieser Ansatz ist skalierbar. Diese Vorgehensweise ist effizient. Dieser Ansatz ist aber kaum besser als unser Ausgangszustand. Das ist allerdings nicht überraschend; der Suchansatz ist hier unglaublich naiv. Da gibt es keine Nuancen. Es wird nicht anerkannt, dass der Name und die Beschreibung eines Index mehr Gewicht haben sollten als ein beliebiger Feldname, der im Index enthalten ist. Es besteht keine Möglichkeit, exakte lexikalische Übereinstimmungen gegenüber synonymen Übereinstimmungen zu gewichten. Allerdings müsste man für die Erstellung einer hochdifferenzierten Abfrage eine Menge Annahmen über die vorliegenden Daten treffen. Bis jetzt haben wir bereits einige große Annahmen darüber getroffen, dass Index- und Feldnamen eine semantische Bedeutung haben, aber wir müssten noch einen Schritt weiter gehen und anfangen anzunehmen, <em>wie viel</em> Bedeutung sie haben und wie sie zueinander in Beziehung stehen. Ohne dies zu tun, können wir wahrscheinlich nicht zuverlässig die beste Übereinstimmung als unser Top-Ergebnis identifizieren, sondern können eher sagen, dass die beste Übereinstimmung irgendwo unter den Top N Ergebnissen liegt. Wir benötigen etwas, das semantische Informationen in dem Kontext, in dem sie existieren, verarbeiten, mit einer anderen Entität vergleichen kann, die sich möglicherweise auf eine semantisch unterschiedliche Weise darstellt, und zwischen ihnen urteilen kann. Wie ein LLM.</p><h3>Hypothese 6: Reduktion der Kandidatenmenge</h3><p>Es gab noch einige weitere Experimente, die ich hier nur kurz erwähnen werde, aber der entscheidende Durchbruch bestand darin, den Wunsch aufzugeben, die beste Übereinstimmung ausschließlich anhand einer semantischen Suche auszuwählen, und stattdessen die semantische Suche als Filter zu nutzen, um irrelevante Indizes aus der Betrachtung des LLM auszusortieren. Wir kombinierten Linear Retrievers, Hybrid Search mit RRF und <code>semantic_text</code> für <a href="https://gist.github.com/seanstory/d704443120e20f6c844db10e30066860">unsere Suche</a> und beschränkten die Ergebnisse auf die Top 5 übereinstimmenden Indizes.</p><p>Anschließend haben wir für jede Übereinstimmung den Namen des Index, die Beschreibung und die Feldnamen zu einer Nachricht für das LLM hinzugefügt. Die Ergebnisse waren fantastisch:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7ac4cb8f7153fdf9/6a17f121af47b66d1dcde082/8fcabd78f591f90d6bc7c0e087d31317e4eef791-1206x804.png" alt="" /><p>Die höchste Genauigkeit, die je in einem Experiment erzielt wurde! Und weil bei diesem Ansatz die Nachrichtengröße nicht proportional zur Gesamtzahl der Indizes ansteigt, ist dieser Ansatz weitaus besser skalierbar.</p><h2>Ergebnisse</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8d66130d9fae6bea/6a17f123ddf97d7527910c19/04d630797213dbb8bf567da41d1cdd5c7b4586c9-1600x521.png" alt="" /><p>Das erste eindeutige Ergebnis war, dass unsere Ausgangslage verbessert werden <em>kann</em> . Dies erscheint im Nachhinein offensichtlich, aber bevor die Experimente begannen, gab es ernsthafte Diskussionen darüber, ob wir unser <code>index_explorer</code> -Tool ganz aufgeben und uns auf eine explizite Konfiguration durch den Benutzer verlassen sollten, um den Suchraum einzuschränken. Auch wenn dies nach wie vor eine praktikable und gültige Option darstellt, zeigt diese Studie, dass es vielversprechende Wege zur Automatisierung der Indexauswahl gibt, wenn solche Benutzereingaben nicht verfügbar sind.</p><p>Das nächste eindeutige Ergebnis war, dass das bloße Hinzufügen weiterer beschreibender Zeichen zur Lösung des Problems immer weniger Nutzen bringt. Vor dieser Studie hatten wir darüber diskutiert, ob wir in den Ausbau der Elasticsearch-Funktionalität zur Speicherung <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/mapping-field-meta">von Metadaten auf Feldebene</a> investieren sollten. Heute sind diese <code>meta</code> -Werte auf 50 Zeichen begrenzt, und es gab die Annahme, dass wir diesen Wert erhöhen müssten, um ein semantisches Verständnis unserer Felder zu erlangen. Dies ist eindeutig nicht der Fall, und das LLM scheint mit reinen Feldnamen recht gut zurechtzukommen. Wir werden dies möglicherweise später noch genauer untersuchen, aber es erscheint uns momentan nicht dringlich.</p><p>Umgekehrt hat dies deutlich gezeigt, wie wichtig „durchsuchbare“ Indexmetadaten sind. Für diese Experimente haben wir einen Index von Indizes gehackt. Aber das ist etwas, was wir untersuchen könnten, indem wir es direkt in Elasticsearch integrieren, APIs zur Verwaltung erstellen oder zumindest eine Konvention dafür festlegen. Wir werden unsere Optionen abwägen und intern diskutieren, also bleiben Sie gespannt.</p><p>Letztendlich hat diese Anstrengung den Wert darin bestätigt, uns Zeit für Experimente zu nehmen und datengestützte Entscheidungen zu treffen. Tatsächlich hat es uns geholfen, erneut zu bestätigen, dass unser Agent Builder-Produkt robuste, im Produkt integrierte Evaluierungsfunktionen benötigt. Wenn wir ein komplettes Test-Framework nur für ein Tool entwickeln müssen, das Indizes auswählt, benötigen unsere Kunden unbedingt Möglichkeiten, ihre kundenspezifischen Tools qualitativ zu bewerten, während sie iterative Anpassungen vornehmen.</p><p>Ich bin gespannt, was wir bauen werden, und ich hoffe, Sie auch!</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/ai-agent-builder-experiments-performance</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/ai-agent-builder-experiments-performance</guid>
    <category><![CDATA[Agentische KI]]></category>
    <category><![CDATA[Inside Elastic]]></category>
    <category><![CDATA[Hybride Suche]]></category>
    <dc:creator><![CDATA[Sean Story]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt68d11a4c7fd11d4c/6a17f1257b54f9b6598b39d4/42903c869e034674b30bb36013345aaa97f6608b-1184x864.png" length="0" type="image/png"/>
    <pubDate>Mon, 06 Oct 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Hybride Suche neu betrachtet: Einführung des linearen Retrievers in Elasticsearch!]]></title>
    <description><![CDATA[Entdecken Sie, wie der lineare Retriever die hybride Suche durch die Nutzung gewichteter Scores und MinMax-Normalisierung für präzisere und konsistentere Rangfolgen verbessert, und lernen Sie, wie Sie ihn verwenden.]]></description>
    <content:encoded><![CDATA[<p>In unserem <a href="https://www.elastic.co/de/search-labs/blog/elasticsearch-retrievers-ga-8.16.0">vorherigen Blogbeitrag</a> haben wir das von Grund auf neu gestaltete Retriever-Framework vorgestellt, das die Erstellung komplexer Ranking-Pipelines ermöglicht. Wir haben auch untersucht, wie der Reciprocal Rank Fusion (RRF)-Retriever eine hybride Suche ermöglicht, indem er Ergebnisse aus verschiedenen Abfragen zusammenführt. Obwohl RRF einfach zu implementieren ist, weist es eine bemerkenswerte Einschränkung auf: Es konzentriert sich ausschließlich auf relative Ränge und ignoriert tatsächliche Punktzahlen. Dies macht die Feinabstimmung und Optimierung zu einer Herausforderung.</p><h2>Lernen Sie den Linear Retriever kennen!</h2><p>In diesem Beitrag stellen wir den <a href="https://www.elastic.co/de/docs/solutions/search/retrievers-overview#retrievers-overview-types"><code>linear</code></a> <a href="https://www.elastic.co/de/docs/solutions/search/retrievers-overview#retrievers-overview-types">Retriever</a> vor, unsere neueste Ergänzung zur Unterstützung der Hybridsuche! Im Gegensatz zu <code>rrf</code> berechnet der <code>linear</code> -Retriever eine gewichtete Summe aller Abfragen, die mit einem Dokument übereinstimmen. Dieser Ansatz bewahrt die relative Bedeutung jedes Dokuments innerhalb eines Ergebnissatzes und ermöglicht gleichzeitig eine präzise Kontrolle über den Einfluss jeder Abfrage auf das Endergebnis. Dadurch bietet es eine intuitivere und flexiblere Möglichkeit zur Feinabstimmung der Hybridsuche.</p><p>Definieren eines linearen Retrievers, bei dem die endgültige Punktzahl wie folgt berechnet wird:</p><p>Es ist so einfach wie:</p>GET linear_retriever_blog/_search
{
   "retriever": {
       "linear": {
           "retrievers": [
               {
                   "retriever": {
                       "knn": {
                          ...
                        }
                    },
                   "weight": 5
               },
                  {
                   "retriever": {
                       "standard": {
                          ...
                        }
                    },
                   "weight": 1.5
               },


           ]
        }
     }
}<p>Merken Sie, wie einfach und intuitiv es ist? (und sehr ähnlich zu <code>rrf</code>!) Mit dieser Konfiguration können Sie genau steuern, wie viel jeder Abfragetyp zum endgültigen Ranking beiträgt, im Gegensatz zu <code>rrf</code>, das sich ausschließlich auf relative Ränge stützt.</p><p>Ein Vorbehalt bleibt bestehen: <code>knn</code> -Wertungen können je nach verwendeter Ähnlichkeitsmetrik streng begrenzt sein. Beispielsweise liegen die Werte bei der Kosinusähnlichkeit oder dem Skalarprodukt einheitsnormalisierter Vektoren immer im Bereich <code>[0, 1]</code> . Im Gegensatz dazu sind <code>bm25</code> -Werte weniger vorhersehbar und haben keine klar definierten Grenzen.</p><h2>Skalierung der Ergebnisse: kNN vs. BM25</h2><p>Eine Herausforderung bei der Hybridsuche besteht darin, dass verschiedene Retriever Ergebnisse auf unterschiedlichen Skalen liefern. Stellen Sie sich beispielsweise das folgende Szenario vor:</p><p>Abfrage A-Ergebnisse:</p><p></p><p>Dokument 1</p><p>doc2</p><p>doc3</p><p>doc4</p><p>knn</p><p>0,347</p><p>0,35</p><p>0,348</p><p>0,346</p><p>bm25</p><p>100</p><p>1,5</p><p>1</p><p>0,5</p><p>Abfrage B-Ergebnisse:</p><p></p><p>Dokument 1</p><p>doc2</p><p>doc3</p><p>doc4</p><p>knn</p><p>0,347</p><p>0,35</p><p>0,348</p><p>0,346</p><p>bm25</p><p>0,63</p><p>0,01</p><p>0,3</p><p>0,4</p><p>Sie können die Ungleichheit oben sehen: <code>kNN</code> -Wertungen liegen zwischen 0 und 1, während <code>bm25</code> -Wertungen stark variieren können. Dieser Unterschied macht es schwierig, statische optimale Gewichte für die Kombination der Ergebnisse festzulegen.</p><h2>Normalisierung zur Rettung: der MinMax-Normalisierer</h2><p>Um dieses Problem zu beheben, haben wir einen optionalen <code>minmax</code> -Normalisierer eingeführt, der die Punktzahlen unabhängig für jede Abfrage mithilfe der folgenden Formel auf den <code>[0, 1]</code> -Bereich skaliert:</p><p>Dadurch bleibt die relative Wichtigkeit jedes Dokuments innerhalb des Ergebnissatzes einer Abfrage erhalten, was die Kombination von Bewertungen verschiedener Abrufer erleichtert. Durch die Normalisierung ergeben sich folgende Werte:</p><p>Abfrage A-Ergebnisse:</p><p></p><p>Dokument 1</p><p>doc2</p><p>doc3</p><p>doc4</p><p>knn</p><p>0,347</p><p>0,35</p><p>0,348</p><p>0,346</p><p>bm25</p><p>1,00</p><p>0,01</p><p>0,005</p><p>0,000</p><p>Abfrage B-Ergebnisse:</p><p></p><p>Dokument 1</p><p>doc2</p><p>doc3</p><p>doc4</p><p>knn</p><p>0,347</p><p>0,35</p><p>0,348</p><p>0,346</p><p>bm25</p><p>1,00</p><p>0,000</p><p>0,465</p><p>0,645</p><p>Alle Punktzahlen liegen jetzt im Bereich <code>[0, 1]</code> und die Optimierung der gewichteten Summe ist viel einfacher, da wir jetzt die (im Verhältnis zur Abfrage) Wichtigkeit eines Ergebnisses anstelle seiner absoluten Punktzahl erfassen und die Konsistenz über alle Abfragen hinweg aufrechterhalten.</p><h2>Beispiel für einen linearen Retriever </h2><p>Sehen wir uns nun ein Beispiel an, um zu zeigen, wie das oben genannte aussieht und wie der <code>linear</code> -Retriever einige der Mängel von <code>rrf</code> behebt. RRF basiert ausschließlich auf relativen Rängen und berücksichtigt keine tatsächlichen Punkteunterschiede. Beispielsweise bei diesen Ergebnissen:</p><p></p><p>Dokument 1</p><p>doc2</p><p>doc3</p><p>doc4</p><p>knn</p><p>0,347</p><p>0,35</p><p>0,348</p><p>0,346</p><p>bm25</p><p>100</p><p>1,5</p><p>1</p><p>0,5</p><p>RRF-Score</p><p>0,03226</p><p>0,03252</p><p>0,03200</p><p>0,03125</p><p>rrf würde die Dokumente wie folgt einstufen:</p><p>Allerdings weist doc1 einen deutlich höheren <code>bm25</code> -Score als die anderen auf, den <code>rrf</code> nicht erfasst, da nur die relativen Ränge berücksichtigt werden. Der <code>linear</code> -Retriever berücksichtigt in Kombination mit der Normalisierung sowohl die Punktzahlen als auch ihre Unterschiede korrekt und erzeugt so eine aussagekräftigere Rangfolge:</p><p></p><p>Dokument 1</p><p>doc2</p><p>doc3</p><p>doc4</p><p>knn</p><p>0,347</p><p>0,35</p><p>0,348</p><p>0,346</p><p>bm25</p><p>1</p><p>0,01</p><p>0,005</p><p>0</p><p>Wie wir oben sehen können, wird das großartige Ranking von doc1 und <code>score</code> für <code>bm25</code> richtig berücksichtigt und in den endgültigen Ergebnissen widergespiegelt. Darüber hinaus liegen jetzt alle Ergebnisse im Bereich <code>[0, 1]</code> , sodass wir sie viel intuitiver vergleichen und kombinieren können (und sogar Offline-Optimierungsprozesse erstellen können).</p><h2>Alles zusammenfügen</h2><p>Um den <code>linear</code> -Retriever mit Normalisierung optimal zu nutzen, würde die Suchanfrage folgendermaßen aussehen:</p>GET linear_retriever_blog/_search
{
   "retriever": {
       "linear": {
           "retrievers": [
               {
                   "retriever": {
                       "knn": {
                          ...
                        }
                    },
                   "weight": 5
               },
                  {
                   "retriever": {
                       "standard": {
                          ...
                        }
                    },
                   "weight": 1.5,
                   "normalizer": "minmax"
               },


           ]
       }
   }
}<p>Dieser Ansatz kombiniert das Beste aus beiden Welten: Er behält die Flexibilität und intuitive Bewertung des <code>linear</code> -Retrievers bei und gewährleistet gleichzeitig eine konsistente Bewertungsskalierung mit MinMax-Normalisierung.</p><p>Wie alle unsere Retriever kann der <code>linear</code> -Retriever in jede Ebene eines hierarchischen Retrieverbaums integriert werden und bietet Unterstützung für Erklärbarkeit, Hervorhebung von Übereinstimmungen, Ausblenden von Feldern und mehr.</p><h2>Wann Sie sich für den Linear Retriever entscheiden sollten und warum das einen Unterschied macht</h2><p>Der <code>linear</code> -Retriever:</p><ul><li><p>Bewahrt die relative Bedeutung durch die Nutzung tatsächlicher Punktzahlen und nicht nur von Rängen.</p></li><li><p>Ermöglicht eine Feinabstimmung mit gewichteten Beiträgen aus verschiedenen Abfragen.</p></li><li><p>Verbessert die Konsistenz durch Normalisierung und macht die Hybridsuche robuster und vorhersehbarer.</p></li></ul><h2>Fazit</h2><p>Der <code>linear</code> -Retriever ist bereits auf Elasticsearch Serverless und den Versionen 8.18 und 9.0 verfügbar! Weitere Beispiele und Konfigurationsparameter finden Sie auch in unserer Dokumentation. Probieren Sie es aus und sehen Sie, wie es Ihr Hybridsucherlebnis verbessern kann – wir freuen uns auf Ihr Feedback. Viel Spaß beim Suchen!</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/linear-retriever-hybrid-search</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/linear-retriever-hybrid-search</guid>
    <category><![CDATA[Relevanz]]></category>
    <category><![CDATA[Hybride Suche]]></category>
    <dc:creator><![CDATA[Panagiotis Bailis]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte58a751cbcc1153d/6a17e3c76317305c4f585a10/7a07e27e3095463ff93b4cb7f8a0cf3b8e44eab0-1777x1000.png" length="0" type="image/png"/>
    <pubDate>Wed, 28 May 2025 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>