<?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[Integrationen - 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[Integrationen - 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/integrations</link>
    </image>
    <link>https://www.elastic.co/de/search-labs/blog/category/integrations</link>
    <atom:link href="https://www.elastic.co/de/search-labs/rss/category/integrations.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[de]]></language>
    <lastBuildDate>Mon, 28 Sep 2026 16:26:15 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Kibana Dashboards API: Ein stabiler Vertrag für jeden Panel-Typ, vor GA von über 50 Teams getestet]]></title>
    <description><![CDATA[Kibana-Dashboards als Code verwalten: Änderungen in Git einchecken, umgebungsübergreifend bereitstellen und Deployments mit der Kibana-API und Terraform automatisieren.]]></description>
    <content:encoded><![CDATA[<p>Die<a href="https://dashboardsapispec.kibana.dev/dashboards#tag/Dashboards"> Kibana-Dashboard- und Visualisierungs-APIs</a> sind in Elastic 9.5 produktionsbereit, über alle Abonnementstufen hinweg verfügbar und mit vollständiger Abwärtskompatibilität. Definieren Sie Ihre Dashboards als JSON, übertragen Sie sie in Git und stellen Sie sie anschließend mithilfe von CI/CD-Pipelines (Continuous Integration und Continuous Deployment),<a href="https://registry.terraform.io/providers/elastic/elasticstack/latest/docs/resources/kibana_dashboard"> Terraform</a> oder anderen Tools, die Sie bereits einsetzen, in verschiedenen Umgebungen bereit. Über 50 Teams testeten die API während<a href="https://www.elastic.co/search-labs/blog/kibana-dashboards-as-code-terraform-api"> der technischen Vorschau in Version 9.4</a>, einige setzen sie bereits in der Produktion ein. In Version 9.5 werden außerdem neue Endpunkte (in der technischen Vorschau) für <a href="https://dashboardsapispec.kibana.dev/tags.html">Tags</a> hinzugefügt, wobei die Endpunkte für die Bedienfelder <a href="https://dashboardsapispec.kibana.dev/markdowns.html">Markdown</a> und <a href="https://dashboardsapispec.kibana.dev/links.html#tag/Links">Links</a> bereits in Elastic Cloud Serverless verfügbar sind und in Version 9.6 eingeführt werden.</p><h2>Was Abwärtskompatibilität für die Kibana-Dashboards API bedeutet</h2><p>Während der technischen Vorschau kann sich die API-Struktur zwischen den Releases ändern.[1] Diese Zeiten sind vorbei. Allgemeine Verfügbarkeit (General Availability, GA) bedeutet:</p><ul><li><p><strong>Vollständige Abwärtskompatibilität.</strong> Im Laufe der Zeit werden neue Felder und Paneltypen hinzugefügt, aber bestehende Felder und Verhaltensweisen bleiben unverändert. Alle zukünftigen kompatibilitätsbrechenden Änderungen würden sehr sorgfältig geprüft und nur in einer neuen Haupt-Stack-Version eingeführt.</p></li><li><p><strong>Produktionsbereit mit voller Unterstützung.</strong> Die API bietet die vollständigen Support-Garantien von Elastic. Sie können es bedenkenlos in Produktionsumgebungen für automatisierte Deployments, Umgebungs-Promotion und programmatisches Dashboard-Management verwenden.</p></li></ul><h2>Neue Kibana-API-Endpoints für die Panels „Tags“, „Markdown“ und „Links“</h2><p>Elastic 9.5 führt außerdem einen neuen eigenständigen Endpoint für <a href="https://dashboardsapispec.kibana.dev/tags.html"><strong>Tags</strong></a> ein, der es ermöglicht, Dashboards zu kategorisieren und zu filtern. Sie können diese nun programmatisch über dedizierte CRUD-Endpoints verwalten, was die Organisation von Dashboards in großem Umfang über verschiedene Umgebungen hinweg vereinfacht.	</p><p>Neue Endpoints für die <a href="https://dashboardsapispec.kibana.dev/markdowns.html"><strong>Markdown</strong></a>- und <a href="https://dashboardsapispec.kibana.dev/links.html#tag/Links"><strong>Links</strong></a>-Bedienfelder sind ab sofort in Serverless verfügbar und werden in der nächsten Stack-Version (9.6) implementiert.</p><h2>Welche Panel-Typen unterstützt die Kibana-Dashboards-API?</h2><p>Die Dashboards-API unterstützt alle <em>By-Value</em>-Panels in Version 9.5 (d. h. diejenigen, die direkt in einem Dashboard definiert wurden, im Gegensatz zu Bibliotheks-Panels, die zur Wiederverwendung gespeichert wurden). Jeder unterstützte Paneltyp verfügt über ein typisiertes, validiertes Schema.</p><p><strong>Panel-Typ</strong></p><p><strong>Status</strong></p><p>XY-Diagramme</p><p>Ja</p><p>Metriken</p><p>Ja</p><p>Kreisdiagramm</p><p>Ja</p><p>Messgerät</p><p>Ja</p><p>Heatmap</p><p>Ja</p><p>Datentabellen</p><p>Ja</p><p>Treemap</p><p>Ja</p><p>Discover Sitzungen</p><p>Ja</p><p>Steuerungen</p><p>Ja</p><p>Markdown</p><p>Ja</p><p>Links</p><p>Ja</p><p>ML-Panels</p><p>Ja</p><p>Observability-Panels</p><p>Ja</p><p>Maps</p><p>Demnächst verfügbar</p><p>Vega</p><p>Demnächst verfügbar</p><h2>Wie man Kibana-Dashboards als Code verwaltet</h2><p>Die Dashboards-API ermöglicht einen vollständigen „Dashboards-as-Code“-Workflow: Exportieren Sie ein Dashboard als sauberes, vergleichbares JSON, übertragen Sie es als maßgebliche Quelle in Git, überprüfen Sie Änderungen in Pull-Anfragen und stellen Sie dieselbe Definition in den Umgebungen Entwicklung, Staging und Produktion bereit. Sobald ein Dashboard als Code verwaltet wird, ist Git als einzige Quelle der Wahrheit zu behandeln: Änderungen, die direkt in der Benutzeroberfläche vorgenommen werden, werden beim nächsten Bereitstellen überschrieben.</p><p>Die größte Herausforderung beim Verschieben eines Dashboards zwischen Bereichen, Clustern oder Phasen besteht darin, dass Dashboards auf Objekte wie Datenansichten und Bibliotheksvisualisierungen anhand ihrer ID verweisen. Da diese IDs automatisch generiert werden und sich je nach Umgebung unterscheiden, kann ein aus einer Umgebung exportiertes Dashboard auf Objekte verweisen, die in einer anderen Umgebung nicht vorhanden sind. Es gibt drei Möglichkeiten, dies zu handhaben, hier aufgelistet von der am stärksten automatisierten bis zur am wenigsten automatisierten:</p><ul><li><p><strong>Benutzen Sie Terraform.</strong> Der <a href="https://registry.terraform.io/providers/elastic/elasticstack/latest/docs/resources/kibana_dashboard">Elastic Stack Terraform Provider</a> verfolgt jede Ressource und ordnet IDs pro Umgebung automatisch zu, sodass die Referenzen konsistent bleiben, wenn Sie ein Dashboard von der Entwicklung bis zur Produktion überführen.</p></li><li><p><strong>Nach Wert definieren </strong><a href="https://www.elastic.co/docs/explore-analyze/visualize/esorql"><strong>Elasticsearch Abfragesprache (ES|QL)-Panels</strong></a><strong>.</strong> Die portabelste Methode zum Erstellen eines Panels besteht darin, dessen Visualisierung mit ES|QL direkt im Dashboard zu definieren. Eine <a href="https://www.elastic.co/docs/explore-analyze/query-filter/languages/esql-kibana">ES|QL</a>-Abfrage liest aus den von Ihnen genannten Indizes, sodass das Panel keine externen Referenzen auf Data view oder Bibliotheksobjekte enthält. Das Ergebnis ist ein vollständig autarkes, portables Dashboard.</p></li><li><p><strong>Weisen Sie passende IDs zu.</strong> Wenn Sie auf gespeicherte Objekte wie Data View oder Bibliotheksvisualisierungen verweisen, erstellen Sie diese mit einer ausgewählten ID mittels PUT (upsert) anstatt mit POST (das automatisch eine ID generiert). Verwenden Sie für Menschen lesbare IDs, wie beispielsweise „logs-prod“, damit diese in verschiedenen Umgebungen leicht wiederverwendet und erkannt werden können.</p></li></ul><p>Eine ausführliche Anleitung zu diesen Portabilitätsmustern und dem vollständigen Dashboards-as-Code-Workflow finden Sie in der Dokumentation <a href="https://www.elastic.co/docs/explore-analyze/dashboards/manage-dashboards-as-code#dashboards-as-code-portability">Dashboards als Code verwalten.</a></p><h3>Erstellen Sie ein Kibana-Dashboard mit der Dashboards-API mithilfe von PUT</h3><p>Hier ein kurzes Beispiel zur Erstellung eines Dashboards mit einem Metrikbereich. Dabei wird PUT anstelle von POST verwendet, um eine benutzerdefinierte ID anhand des Dashboard-Namens (service-health-overview) zuzuweisen. Dieselbe Logik funktioniert auch für die Erstellung eigenständiger Visualisierungen, die in der Bibliothek gespeichert werden.</p>PUT kbn:/api/dashboards/service-health-overview
{
  "title": "Service health overview",
  "description": "Key service metrics — managed via API",
  "tags": [
    "production",
    "sre-team"
  ],
  "panels": [
    {
      "type": "vis",
      "grid": {
        "x": 0,
        "y": 0,
        "w": 12,
        "h": 8
      },
      "config": {
        "title": "Error rate (5xx)",
        "type": "metric",
        "data_source": {
          "type": "esql",
          "query": "FROM logs-* | WHERE http.response.status_code &gt;= 500 | STATS error_rate=count(*) BY host.name"
        },
        "metrics": [
          {
            "type": "primary",
            "column": "count"
          }
        ]
      }
    }
  ]
}<h2>Kibana Dashboards API-Roadmap: Maps, Vega und eigenständige Endpoints</h2><p>Wir erweitern aktiv die API-Schnittstelle. Als nächstes folgt die Unterstützung für Maps und Vega-Panels, wobei typisierte Schemas dafür hinzugefügt werden. Wir entwickeln außerdem eigenständige CRUD-Endpunkte für Discover-Sitzungen (zusätzlich zu ihrer bestehenden Unterstützung als Dashboard-Panels), Vega, Maps und Annotations, die vom Dashboard-Lebenszyklus entkoppelt sind.</p><p>Für die vollständigen Schema-Definitionen besuchen Sie die <a href="https://dashboardsapispec.kibana.dev/dashboards#tag/Dashboards">Dashboards API-Dokumentation</a>. Für Terraform-Nutzer unterstützt der <a href="https://registry.terraform.io/providers/elastic/elasticstack/latest/docs/resources/kibana_dashboard">Elastic Stack Terraform-Provider</a> die GA Dashboards API.</p><h2>Anmerkung</h2><ol><li><p>Die Kern-Endpoints sind gegenüber der technischen Vorschau unverändert. Wenn Sie Integrationen für 9.4 erstellt haben, funktionieren sie in 9.5. Die einzigen kompatibilitätsbrechenden Änderungen sind zwei geringfügige, die sich auf die Formate für Dashboard-Auflistungen und Dauereinheiten auswirken und <a href="https://www.elastic.co/docs/release-notes/kibana/breaking-changes">hier dokumentiert sind</a>.</p></li></ol>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/dashboards-as-code-kibana-api</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/dashboards-as-code-kibana-api</guid>
    <category><![CDATA[Kibana]]></category>
    <category><![CDATA[Entwicklererfahrung]]></category>
    <category><![CDATA[Integrationen]]></category>
    <dc:creator><![CDATA[Teresa Alvarez Soler]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8ed7e33de291f255/6a730619c8b7ac02b251f9d3/image1.png" length="0" type="image/png"/>
    <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[On-Prem in weniger als 5 Minuten: Jina-Einbettungsmodelle jetzt für On-Prem-Deployment verfügbar]]></title>
    <description><![CDATA[Alle 28 Jina AI-Modelle, einschließlich Rerankern, als sofort bereitstellbare Docker-Container, ohne Telemetrie und ohne Lizenzserver. Drop-in-kompatibel mit den APIs von OpenAI, Cohere, Voyage AI und Elastic Inference Service.]]></description>
    <content:encoded><![CDATA[<p>Alle 28 Einbettungs- und Reranking-Modelle von Jina AI werden nun als vollständig offline nutzbare Docker-Container für das On-Prem-Deployment bereitgestellt, darunter <a href="https://www.elastic.co/de/search-labs/blog/jina-embeddings-v5-omni-all-media-one-index">jina-embeddings-v5-omni</a><a href="https://www.elastic.co/de/search-labs/blog/jina-embeddings-v5-omni-all-media-one-index"> </a>sowie <a href="https://www.elastic.co/de/search-labs/tutorials/jina-tutorial/jina-reranker-v3">jina-reranker-v3</a>. Laden Sie ein Modell herunter, übertragen Sie es auf ein lokales Air-Gap- oder durch eine Firewall geschütztes System und schon wird die lokale Inferenz in weniger als fünf Minuten ausgeführt. Die Container sind komplett eigenständig und weisen keine externen Verbindungen auf. Es erfolgt kein Aufruf von Hugging Face oder einer anderen Modell-Registrierungsstelle. Zudem gibt es weder einen Lizenzserver noch Telemetrie- oder Logging-Endpoints. In regulierten Branchen, bei Anforderungen an die Datensouveränität oder in Umgebungen, in denen der Internetzugang unzuverlässig oder gar nicht verfügbar ist, entfällt dadurch die Abhängigkeit von KI-Diensten von Drittanbietern. Jina On-Prem unterstützt die Schemata von Elastic Inference Service (EIS), OpenAI, Cohere, Voyage AI und Gemini API, sodass bestehende Anwendungen ohne Codeänderungen funktionieren.</p><p>Die leistungsstärksten KI-Modelle werden auf externen Cloud-Installationen mit Zugriff über eine Web-API ausgeführt, was bedeutet, dass Sie Ihrem KI-Dienstanbieter in Bezug auf Sicherheit, Verfügbarkeit und stabile Preise vertrauen müssen. Sie können die berechtigten Anforderungen an Zuverlässigkeit, Datenschutz, überschaubare Kosten und eine gute Data Governance nicht ohne Weiteres mit dem Einsatz von KI in Einklang bringen, die immer leistungsfähiger, ausgefeilter und ressourcenintensiver wird.</p><p>Regierungsvorschriften, Gerichtsurteile und geschäftliche Erwägungen, die im Interesse Dritter getroffen wurden, haben in jüngster Zeit dazu geführt, dass der Zugang zu bestimmten Diensten eingeschränkt wurde. Und selbst wenn ein Wechsel zu anderen Diensten möglich ist, sind KI-Modelle keine Komponenten, die sich einfach nach Belieben austauschen lassen. Anwendungen, die semantische Einbettungen nutzen, sind darauf angewiesen, zum Zeitpunkt der Abfrage Zugriff auf dieselben Modelle wie zum Zeitpunkt der Daten-Ingestion zu erhalten. Den Zugriff auf das Einbettungsmodell zu verlieren bedeutet, dass Ihr Suchsystem zum Stillstand kommt.</p><p>KI-Preismodelle verstärken dieses Risiko noch. Die jüngsten Finanzberichte großer KI-Anbieter geben den Kunden guten Grund zur Sorge vor möglichen Preiserhöhungen. Die Abhängigkeit von Produkten mit unvorhersehbaren Kosten erhöht das Risiko kapitalintensiver KI-Investitionen, die möglicherweise keine eindeutigen Renditen erzielen.</p><p>Jina On-Prem ist die Antwort von Elastic auf diese Herausforderungen.</p><h2>Wer benötigt On-Prem-KI?</h2><p>Lokales Hosting und die direkte Kontrolle über Ihre KI-Modelle unterstützen eine Vielzahl technischer Anforderungen, Branchenvorgaben und geschäftlicher Interessen.</p><p>Durch eine lokale Installation sinken zwar die Kosten für Ihre KI-Dienstanbieter, allerdings fallen die Kosten für die Hardware und einen zuverlässigen Zugang nun zu Lasten Ihres Unternehmens. Je nach Nutzungsumfang kann es durchaus günstiger sein. Doch es gibt noch weitere dringende Gründe, die für den Betrieb einer eigenen KI sprechen. Sollte eines der unten beschriebenen Probleme auf Ihr Unternehmen zutreffen, sollten Sie eine lokale KI-Lösung wie Jina On-Prem in Betracht ziehen. Diese Liste erhebt keinen Anspruch auf Vollständigkeit.</p><p>Anwendungsfall</p><p>Warum On-Prem</p><p>Beispiel</p><p>Air-Gap/Hohe Sicherheit</p><p>Keine ausgehende Datenübertragung; vollständige Netzwerkisolierung</p><p>Verteidigung, Nachrichtendienste, geheime Forschung</p><p>Einhaltung gesetzlicher Vorschriften</p><p>Datensouveränität; keine grenzüberschreitende Übermittlung oder Weitergabe an Dritte</p><p>Gesundheitswesen (Health Insurance Portability and Accountability Act [HIPAA]), Finanzwesen, EU-Unternehmen (Datenschutz-Grundverordnung [DSGVO])</p><p>Latenzkritisch</p><p>Keine Netzwerkabhängigkeit; keine Toleranz gegenüber Verbindungsausfällen</p><p>Robotik, Edge Computing, Fahrzeuge, Schiffe</p><p>Planbarkeit der Kosten</p><p>Feste Infrastrukturkosten vs. Preise pro Token mit ungewissen zukünftigen Preisen</p><p>Kontinuierliche Inferenz-Workloads mit hohem Volumen</p><p>Haftungsbeschränkung</p><p>Keine Offenlegung von Daten Dritter; Wahrung des Anwaltsgeheimnisses und der Sorgfaltspflicht</p><p>Anwaltskanzleien, Behörden</p><h3>Warum Air-Gap- und firewallgeschützte Systeme On-Prem-KI benötigen</h3><p>Air-Gap- und durch eine Firewall geschützte Systeme können keine externen KI-APIs verwenden. Jina On-Prem wird vollständig innerhalb Ihrer Infrastruktur ohne ausgehende Verbindungen ausgeführt.</p><p>Für Unternehmen, die besonders sensible Daten verwalten, sind Sicherheits- und Datenschutzaspekte von größter Bedeutung. Es nützt wenig, in den Schutz Ihrer sensiblen Daten zu investieren, wenn Sie diese umgehend an einen externen Dritten weitergeben, der möglicherweise über unzureichende Sicherheitsvorkehrungen verfügt oder den Auflagen einer ausländischen Regierung unterliegt.</p><p>Mitarbeiter in Unternehmen, die mit sensiblen Daten umgehen, erhalten oft Schulungen zum sicheren Umgang mit Daten. Diese sind jedoch nicht sehr wirksam, wenn alle Mitarbeiter Webbrowser nutzen, die während der Bearbeitung dieser Daten möglicherweise auf beliebige Seiten im Internet zugreifen können. Die Isolierung ist die wirksamste verfügbare Sicherheitsmaßnahme, sei es durch ein Air Gap oder durch sehr restriktive Firewalls, doch dadurch wird die Nutzung externer Dienste jeglicher Art erschwert.</p><h3>On-Prem-KI für latenzempfindliche Systeme und Systeme mit hoher Verfügbarkeit</h3><p>Software as a Service und Cloud Computing stellen einen Kompromiss zwischen den Kosten für die Bereitstellung leicht zugänglicher, zuverlässiger Dienste auf den eigenen Computern und der Auslagerung dieser Problematik an Dritte dar. Allerdings sind sie mit schwankenden Latenzzeiten, Ausfällen und einem völligen Kontrollverlust verbunden, wenn etwas schiefgeht. KI-Dienste bilden da keine Ausnahme. Wenn Ihr Suchsystem offline geht, sobald Sie keinen Zugriff mehr auf Ihr Einbettungsmodell haben, scheint es möglicherweise kein guter Kompromiss mehr zu sein.</p><p>Darüber hinaus birgt der Einsatz externer KI stets Risiken, die sich nicht ohne Weiteres vorhersehen oder verwalten lassen. Der Internetzugang und die Netzwerklatenz können sich ohne Vorwarnung verschlechtern, beispielsweise aufgrund politischer Ereignisse, schlechten Wetters oder weil Schiffe mit ihren Ankern über Unterwasser-Glasfaserkabel schleifen. Regierungen können Exportverbote verhängen, um den Zugriff auf KI-Modelle schlagartig zu unterbinden – und das haben sie in jüngster Zeit auch getan. KI-Dienstanbieter nehmen Modelle gelegentlich aus dem Angebot, um Sie zu einem Wechsel auf neuere Modelle zu bewegen. Die Flexibilität und die kontrollierten Kosten externer Dienste müssen gegen die Risiken einer Abhängigkeit abgewogen werden.</p><h3>On-Prem-KI für die Compliance mit der DSGVO, HIPAA und Datensouveränität</h3><p>Unternehmen, die personenbezogene Daten erheben, unterliegen immer strengeren Vorschriften, die sich oft von Rechtsraum zu Rechtsraum unterscheiden und widersprüchliche Anforderungen enthalten können. Insbesondere sehen die <a href="https://www.hhs.gov/hipaa/for-professionals/privacy/laws-regulations/index.html">HIPAA-Vorschriften</a> sehr strenge Datenschutzbestimmungen für amerikanische Gesundheitsdienstleister vor. Zudem verlangen strenge allgemeine Datenschutzgesetze in <a href="https://laws-lois.justice.gc.ca/eng/acts/p-8.6/">Kanada</a>, der <a href="https://gdpr-info.eu/">Europäischen Union</a> sowie <a href="https://www.japaneselawtranslation.go.jp/en/laws/view/4241">vielen asiatischen Ländern</a> von allen Unternehmen, die personenbezogene Daten verarbeiten, einen sicheren Umgang mit diesen Daten sowie eine Beschränkung der Weitergabe dieser Daten an Dritte oder in andere Länder. Diese Vorschriften könnten sogar für ausländische Unternehmen Verpflichtungen mit sich bringen, sofern sie Kunden in diesen Ländern haben. Finanzinstitute unterliegen häufig noch strengeren Vorschriften und tragen dieselbe direkte Verantwortung für die Informationssicherheit wie beim Schutz vor anderen Formen krimineller Aktivitäten.</p><p>Die Einhaltung gesetzlicher Vorschriften kann mit KI-Diensten von Drittanbietern unvereinbar sein, insbesondere wenn ihre Nutzung eine grenzüberschreitende Datenübertragung beinhaltet.</p><p>Zudem zeigen die jüngsten Ereignisse, dass Vorschriften, die den physischen Standort von Datenspeichern einschränken, nicht unbedingt einen verlässlichen Schutz bieten, wenn internationale Cloud-Anbieter dem Druck ausländischer Regierungen ausgesetzt sind. Lokale Gesetze können sich je nach Rechtsraum widersprechen, was eine lokale Datenspeicherung und -verarbeitung erforderlich und die Nutzung von Diensten Dritter unmöglich macht. In einigen Fällen ist die einzige Lösung eine vollständige interne Abwicklung aller Prozesse, einschließlich Ihrer KI-Systeme.</p><h3>KI-Haftungsrisiken durch die Datenübertragung von Drittanbietern</h3><p>Datenschutzgesetze und anerkannte Sorgfaltspflichten im Umgang mit sensiblen Daten haben regelmäßig haftungsrechtliche Konsequenzen, die mitunter sehr schwerwiegend sein können. Sie können für den Umgang mit Ihren Daten durch Drittanbieter haftbar gemacht werden. Zwar bieten Gerichte und rechtliche Verfahren unter Umständen einen gewissen nachträglichen Schutz vor unsicheren Dienstanbietern, doch stehen diese Rechtsmittel gegenüber Akteuren der nationalen Sicherheit, Strafverfolgungsbehörden oder kriminellen Hackern weder zur Verfügung noch sind sie im Allgemeinen wirksam.</p><p>Bei Regierungen gab es bereits Fälle, in denen grenzüberschreitend tätige Cloud-Dienstanbieter sensible staatliche Informationen an ausländische Akteure weitergegeben haben.</p><p>Aber selbst wenn Sie sich keine Sorgen um ausländische Regierungen oder Hacker machen und Ihre externen KI-Dienstanbieter selbst sicher sind, kann allein die Tatsache, dass sie extern sind, Haftungsrisiken mit sich bringen.</p><p>So genießen beispielsweise in den meisten Ländern die Kommunikation zwischen Rechtsanwälten und ihren Mandanten einen besonderen rechtlichen Schutz, und Anwaltskanzleien unterliegen strengen Haftungsvorschriften bei der Aufzeichnung oder Speicherung dieser Informationen. In den Vereinigten Staaten ist dieses „Anwaltsgeheimnis“ so bekannt, dass es sogar eine zentrale Rolle in Film- und Fernsehhandlungen spielt. Eine Möglichkeit, diese Privilegien zu verlieren, besteht jedoch darin, Informationen an jemanden weiterzugeben, der diese Privilegien nicht besitzt, und die jüngsten Entwicklungen deuten darauf hin, dass externe KI-Dienstanbieter unter diese Kategorie fallen könnten.</p><p>Zumindest in den Vereinigten Staaten ist es möglich, dass bereits die bloße Nutzung von KI-Diensten von Drittanbietern über eine Internet-API – wie beispielsweise die Einbindung von Modellen, die Indizierungsdienste bereitstellen – gegen wichtige Vertraulichkeitsvorschriften verstoßen könnte. Eine Anwaltskanzlei könnte allein aufgrund der Nutzung extern gehosteter Software verklagt, disziplinarisch belangt oder aus der Anwaltskammer ausgeschlossen werden, selbst wenn keine Sicherheitsverletzung vorliegt.</p><h3>On-Prem-KI für Offline-, Edge- und physisch isolierte Systeme</h3><p>Computersysteme werden nicht nur aus Sicherheitsgründen isoliert. Beispielsweise dürfen sich fahrende Fahrzeuge bei keiner ihrer wesentlichen Funktionen auf einen Internetzugang verlassen. Schiffe und Flugzeuge verfügen über sehr umfangreiche Bordcomputersysteme, die ohne Internetverbindung funktionieren müssen und daher keine externen KI-Dienste nutzen können. Offshore-Plattformen, abgelegene Anlagen in unberührten Naturgebieten, Computerdienste in der Arktis, der Antarktis und auf kleinen Inseln ohne ausreichende physische Anbindung an globale Netzwerke sind allesamt Beispiele für Einrichtungen, die davon profitieren, alle benötigten Dienste lokal zu hosten. Da die Bedeutung der KI in der Unternehmens-IT zunimmt, wird es immer wichtiger, diese Einschränkungen anzugehen.</p><p>Neue Anwendungen der KI in physischen Systemen (Robotik und andere Anwendungsfälle, die räumlich begrenzt sind oder auf die Außenwelt ausgerichtet sind, wie Logistikmanagementsysteme oder sogar Supermarktkassen) sind zwar möglicherweise mit dem globalen Internet verbunden, tolerieren jedoch weder Verbindungsausfälle noch plötzliche Latenzspitzen. Wenn sie für ihren Betrieb auf ein KI-System angewiesen sind, muss dieses KI-System so lokal und zuverlässig wie möglich sein.</p><h2>Wer braucht keine On-Prem-KI?</h2><p>Remote-Softwaredienste und externe KI bieten durchaus Vorteile. Für den Betrieb von KI-Modellen sind unter Umständen teure, stromfressende Prozessoren erforderlich, die bekanntermaßen nur eine kurze Lebensdauer haben. Der Zugang zu hochwertiger Hardware ist derzeit aufgrund von Marktfaktoren und externen wirtschaftlichen Schocks besonders schwierig. Unter diesen Umständen kann es sinnvoll sein, für die Nutzung einer externen API pro Token zu bezahlen, anstatt die hohen Investitionskosten für eine lokale KI zu tragen.</p><p>Externe APIs sind für gelegentliche Nutzer am sinnvollsten. Wenn Sie KI-Modelle in erster Linie zur Batch-Verarbeitung von Daten für Analysezwecke nutzen und nicht zum Betreiben eines Suchsystems, das ständig online sein muss, macht es wenig Sinn, in kapitalintensive Hardware und lokale Installationen zu investieren.</p><p>Darüber hinaus kann die Nutzung von KI-Diensten, die sich in derselben Cloud-Infrastruktur befinden, ein besseres Preis-Leistungs-Verhältnis bieten als das Deployment eines eigenen lizenzierten KI-Modells, wenn Ihre Datenverarbeitung bereits cloudbasiert ist, beispielsweise bei einer E-Commerce-Website, die aus Gründen der Zuverlässigkeit und Erreichbarkeit in der Cloud gehostet wird. Sie sind ohnehin schon von Ihrem Cloud-Dienstanbieter abhängig, daher stellt die Abhängigkeit von seinen KI-Diensten kein großes zusätzliches Risiko dar.</p><p>Wenn Ihr Anwendungsfall dieser Beschreibung entspricht, stehen Ihnen Jina AI-Modelle auf <a href="https://www.elastic.co/docs/explore-analyze/elastic-inference/eis">EIS</a>, im <a href="https://aws.amazon.com/marketplace/seller-profile?id=seller-stch2ludm6vgy">AWS Marketplace</a> und auf der <a href="https://console.cloud.google.com/marketplace/browse?q=jina">Google Cloud Platform</a> speziell für Ihre Anforderungen zur Verfügung.</p><p>Die folgende Tabelle fasst die wichtigsten Faktoren zusammen. Ihre Antwort hängt von Ihren Daten, Ihrer Infrastruktur und Ihrem Nutzungsmuster ab.</p><p>Faktor</p><p>On-Prem bevorzugt</p><p>Cloud-API bevorzugt</p><p>Nutzungsmuster</p><p>Kontinuierliche oder Inferenz mit hohem Volumen</p><p>Intermittierende oder Batch-Verarbeitung</p><p>Datensensibilität</p><p>Reguliert, souverän oder klassifiziert</p><p>Keine grenzüberschreitenden oder durch Dritte auferlegten Einschränkungen</p><p>Netzwerkumgebung</p><p>Air-Gap, durch Firewall geschützt oder unzuverlässig</p><p>Stabiles, stets verfügbares Internet</p><p>Bestehende Infrastruktur</p><p>Im Besitz von GPU-Hardware oder Möglichkeit zur Beschaffung</p><p>Bereits in der Cloud mit KI-Colocation gehostet</p><p>Kostenmodell</p><p>Feste Hardware + Lizenz; vorhersehbare Kosten beim Skalieren</p><p>Pro Token; geringere Vorabkosten, variable langfristige Kosten</p><p>Latenztoleranz</p><p>Keine (Robotik, Edge, Echtzeit)</p><p>Netzwerkvariabilität ist akzeptabel</p><p>Operative Verantwortung</p><p>Ihr Team verwaltet die Hardware und Verfügbarkeit</p><p>Der Anbieter verwaltet die Hardware und die Updates; Sie verwalten die Integration</p><p>Sie müssen die Kosten und den Nutzen unter Berücksichtigung Ihrer individuellen Umstände und Anwendungsfälle abwägen und dabei die im vorigen Abschnitt hervorgehobenen Punkte berücksichtigen, die auf Sie zutreffen. Die Kosten-Nutzen-Analyse wird sich im Laufe der Zeit zweifellos ändern. Wir können die Zukunft der KI-Branche oder die Hardwarepreise nicht einmal kurzfristig vorhersagen.</p><h2>Einführung von Jina On-Prem</h2><p>Für Nutzer, die von lokalen KI-Diensten profitieren können, führen wir <a href="https://github.com/jina-ai/jina-on-prem/wiki/">Jina On-Prem</a> ein, ein vollständig eigenständiges Installationspaket für die leistungsstarken Modelle von Jina AI.</p><p>Die Modelle von Jina AI erreichen die gleiche Genauigkeit wie Einbettungsmodelle, die <a href="https://mteb-leaderboard.hf.space/benchmark/MTEB(Multilingual%2C%20v2)">ein Vielfaches ihrer Größe haben</a>, und senken dabei die Rechenkosten, den Speicherbedarf und die Hardwareanforderungen. Dadurch sind sie eine ideale Wahl für Nutzer, die ihre KI On-Prem betreiben möchten oder müssen. Kommerzielle Lizenzen sind mit skalierbaren, preislich gestaffelten Lösungen für Anwendungsfälle aller Größen verfügbar.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt190865fb3ebde472/6a6a33d0065b162508701ff9/02559ceca556a26c53eb703ae87d421452b27251-1374x1400.png" alt="MMTEB Multilingual v2 leaderboard showing Jina AI embedding model rankings: jina-embeddings-v5-omni-small and jina-embeddings-v5-text-small ranked 13th, jina-embeddings-v5-omni-nano and jina-embeddings-v5-text-nano ranked 19th, competing against models from Microsoft, Google, Tencent, NVIDIA and Qwen" /><h3>Welche API-Schemata unterstützt Jina On-Prem?</h3><ul><li><p>Erhältlich als vollständige Sammlung von Abhängigkeiten für die lokale Installation oder als <a href="https://www.docker.com/">Docker-Container</a>, den Sie innerhalb weniger Minuten installieren und ausführen können.</p></li><li><p>Jina-On-Prem-Installationen <em>rufen</em> keine externen Systeme auf.</p><ul><li><p>Es erfolgt kein Aufruf des Hugging Face Hub oder einer Modellregistrierung (HF_HUB_OFFLINE=1 und TRANSFORMERS_OFFLINE=1 sind fest integriert).</p></li><li><p>Es gibt keinen Lizenzserver.</p></li><li><p>Es gibt keine Telemetrie- oder Logging-Endpoints.</p></li></ul></li><li><p>Unterstützt sowohl CPU- als auch GPU-Hardware mit automatischer GPU-Erkennung.</p></li><li><p>Alle 28 verfügbaren Jina-AI-Modelle, einschließlich der neuesten multimodalen Einbettungsmodelle <a href="https://www.elastic.co/de/search-labs/blog/jina-embeddings-v5-omni-all-media-one-index">jina-embeddings-v5-omni</a> und <a href="https://www.elastic.co/de/search-labs/tutorials/jina-tutorial/jina-reranker-v3">jina-reranker-v3</a>.</p></li><li><p>Zugriff über gängige KI-API-Schemata: <a href="https://jina.ai/api-dashboard">Jina API</a>, OpenAI, Cohere, Voyage AI und Gemini. Jina On-Prem ist eine sofort einsatzbereite Lösung für Anwendungen, die auf diesen Schemata basieren.</p></li><li><p>Drop-in-Ersatz für Modelle, die über den <a href="https://www.elastic.co/docs/explore-analyze/elastic-inference/eis">EIS</a> bereitgestellt werden. Jina On-Prem lässt sich direkt in <a href="https://www.elastic.co/de/blog/deploy-elastic-air-gapped-disconnected-environments">Elastic-Deployments mit Air-Gap</a> integrieren.</p></li></ul><h2>Hardwareanforderungen für Jina AI-On-Prem-Modelle</h2><p>Die Hardwareanforderungen variieren je nach Jina-Modell. Die folgende Tabelle zeigt die Empfehlungen für die neuesten Modelle unter Verwendung von GPU-Einstellungen. Sie benötigen keine leistungsstärkere GPU als eine NVIDIA L4, allerdings wird für die v5-Einbettungsmodelle eine A100 empfohlen. Unser neuestes Einbettungsmodell erfordert derzeit mindestens 8 GB VRAM.</p><p>Modell</p><p>Mindest-VRAM</p><p>Empfohlene GPU</p><p>jina-embeddings-v5-text-nano</p><p>2 GB</p><p>T4 / L4</p><p>jina-embeddings-v5-text-small</p><p>3 GB</p><p>L4 / A10G</p><p>jina-embeddings-v5-omni-small</p><p>8 GB</p><p>L4 / A10G / A100</p><p>jina-reranker-v3</p><p>3 GB</p><p>L4</p><p>jina-clip-v2</p><p>4 GB</p><p>L4</p><p>jina-code-embeddings-1.5b</p><p>4 GB</p><p>L4</p><p>ReaderLM-v2</p><p>4 GB</p><p>L4</p><p>Wenn Sie mehr als ein Modell gleichzeitig verwenden, steigen die VRAM-Anforderungen. Weitere Informationen finden Sie auf der Seite <a href="https://github.com/jina-ai/jina-on-prem/wiki/Sizing-And-Hardware">Größen und Hardware</a>.</p><h2>So installieren Sie Jina On-Prem mit Docker</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt20265d09e2d8d0f4/6a6a33d1065b162105701ffd/ada9881af407168298b1940f8537ad71a5411c89-1999x1200.png" alt="" /><p>Der schnellste Weg für den Einstieg ist die <a href="https://www.docker.com/get-started/">Installation von Docker</a> (sofern noch nicht geschehen) und das Befolgen der Anweisungen auf der Seite <a href="https://github.com/jina-ai/jina-on-prem/wiki/QuickStart">Jina On-Prem Quick Start</a>.</p><p>Für alle 28 Jina-Modelle stehen vorkonfigurierte Docker-Container zur Verfügung. Laden Sie ein Modell herunter und übertragen Sie es auf Ihr Installationsziel – schon können Sie Jina-AI-Modelle in weniger als fünf Minuten ausführen.</p><p>Für multimodale oder benutzerdefinierte Builds oder zum Herunterladen des vollständigen Abhängigkeitssatzes für die Installation außerhalb eines Containers befolgen Sie bitte die Schritte, die in der <a href="https://github.com/jina-ai/jina-on-prem/wiki/Bundling-Guide">Bundling-Anleitung</a> beschrieben sind.</p><p>Ihre Jina-On-Prem-Installation unterstützt alle Jina-API- und EIS-Funktionen sowie die Generierung von Einbettungen über die APIs von OpenAI, Cohere, Voyage AI und Gemini, sodass sie sich über Standardschnittstellen in bereits vorhandene Anwendungen integrieren lässt. Weitere Informationen finden Sie in der <a href="https://github.com/jina-ai/jina-on-prem/wiki/API-Reference">API-Dokumentation</a>.</p><p>Jina-Modelle, einschließlich der mit Jina On-Prem installierten Modelle, sind unter verschiedenen Lizenzbedingungen erhältlich, wobei die neuesten Modelle für die nichtkommerzielle Nutzung unter einer <a href="https://creativecommons.org/licenses/by-nc/4.0/deed.en">CC BY-NC 4.0</a>-Lizenz kostenlos zur Verfügung stehen. Für die Lizenzierung von Jina On-Prem für die kommerzielle Nutzung wenden Sie sich bitte an <a href="https://www.elastic.co/de/contact">Elastic Sales</a>.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/on-prem-ai-jina-embedding-models</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/on-prem-ai-jina-embedding-models</guid>
    <category><![CDATA[Jina AI]]></category>
    <category><![CDATA[Integrationen]]></category>
    <dc:creator><![CDATA[Scott Martens]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt17731ab0c6ec66f6/6a6a33d140a4941014ca5c9a/09bc6dac4e6a86c7877f8ed78d68f5d581aeffa9-1999x1200.png" length="0" type="image/png"/>
    <pubDate>Thu, 23 Jul 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Mehr Power für Elasticsearch: native Prometheus-API-Unterstützung hinzufügen]]></title>
    <description><![CDATA[Elasticsearch kann direkt von Prometheus-kompatiblen Clients über native PromQL-, Discovery- und Metadaten-Endpunkte abgefragt werden. Senden Sie Daten an Elasticsearch mit Prometheus Remote Write.]]></description>
    <content:encoded><![CDATA[<p>Richten Sie einen beliebigen Prometheus-kompatiblen Client auf Elasticsearch aus und führen Sie PromQL direkt gegen Ihre vorhandenen Metriken aus. Elasticsearch fügt als technische Vorschau native Prometheus-Abfrage-, Erkennungs- und Metadaten-Endpunkte hinzu, die mit Metriken arbeiten, die über Prometheus Remote Write, OpenTelemetry oder die Bulk-API aufgenommen werden. Die API läuft auf den Zeitreihendatenströmen (TSDS) von Elasticsearch, sodass keine separate Prometheus-spezifische Speicherschicht erforderlich ist.</p><p>Dieser Beitrag erklärt, wie die Abfrage-, Discovery- und Metadaten-Endpunkte auf der früheren Ingest- und Abfragearbeit aufbauen, um diese API-Oberfläche zu formen. In Begleitbeiträgen werden einzelne Aspekte näher beleuchtet:</p><ul><li><p><a href="https://www.elastic.co/observability-labs/blog/elasticsearch-supports-promql">Native PromQL-Unterstützung in ES|QL</a> beschreibt, wie PromQL-Abfragen in ES|QL-Ausführungspläne übersetzt werden.</p></li><li><p><a href="https://www.elastic.co/observability-labs/blog/prometheus-remote-write-elasticsearch">Prometheus-Metriken mit Remote Write an Elasticsearch versenden</a> behandelt die Einrichtung der Ingestion.</p></li><li><p><a href="https://www.elastic.co/observability-labs/blog/prometheus-remote-write-elasticsearch-architecture">So funktioniert die Prometheus Remote Write Ingestion in Elasticsearch</a> behandelt die internen Abläufe von Remote Write.</p></li></ul><p>Dieses Projekt läuft noch. In den folgenden Abschnitten wird aufgeführt, was derzeit unterstützt wird und welche Teile sich noch in der Entwicklung befinden.</p><h2>Die API-Oberfläche</h2><p>Heute fällt die Prometheus-kompatible API-Oberfläche in drei Gruppen.</p><h3>Abfrage-Endpoints</h3><p>Die Abfrage-Endpoints ermöglichen Prometheus-kompatiblen Clients die Auswertung von PromQL-Ausdrücken:</p><ul><li><p><code>GET /_prometheus/api/v1/query_range</code> wertet einen PromQL-Ausdruck über ein Zeitfenster aus (Matrix-Ergebnisse).</p></li><li><p><code>GET /_prometheus/api/v1/query</code> wertet zu einem einzelnen Zeitpunkt aus (Vektor-Ergebnisse). Derzeit als Kurzbereichsabfrage implementiert, die die letzte Stichprobe zurückgibt.</p></li></ul><p>Aktuell wird nur GET als Abfrage-Endpoint unterstützt. Einige Clients verwenden standardmäßig POST, so dass Sie sie möglicherweise auf GET umstellen müssen. Die Prometheus POST-Konvention verwendet <code>application/x-www-form-urlencoded</code>-Bodies, die von der HTTP-Schicht von Elasticsearch als CSRF-Schutzmaßnahme abgelehnt werden, bevor die Anfrage überhaupt den Handler erreicht.</p><p>Den vollständigen PromQL-Abdeckungsstatus finden Sie im <a href="https://www.elastic.co/observability-labs/blog/elasticsearch-supports-promql">Begleitbeitrag zu PromQL in ES|QL</a>.</p><h3>Metadaten-Endpoints</h3><p>Die Metadaten-Endpoints liefern die Discovery-Informationen, die Kunden für Autovervollständigung, Variablen-Dropdowns und das Durchsuchen von Metriken benötigen.</p><p>Die Endpunkte für Serien, Labels und Labelwerte akzeptieren alle <code>match[]</code>-Selektoren und einen Zeitbereich (<code>start</code>/<code>end</code>). Der Parameter <code>match[]</code> nimmt einen Prometheus-Serienselektor wie <code>http_requests_total{job="api"}</code> entgegen und beschränkt die Reaktion auf passende Zeitreihen. Dadurch bleiben die Reaktionen auf Clustern mit einer großen Anzahl von Metriken schnell und relevant. Zum Beispiel:</p>GET /_prometheus/api/v1/series?match[]=http_requests_total{job="api"}GET /_prometheus/api/v1/labels?match[]=http_requests_totalGET /_prometheus/api/v1/label/instance/values?match[]=http_requests_total{job="api"}<p>Die erste gibt alle Serien für <code>http_requests_total</code> zurück, wobei <code>job="api"</code> gilt, zusammen mit ihren vollständigen Label-Sets. Die zweite gibt nur die Label-Namen zurück, die in der <code>http_requests_total</code>-Serie existieren. Die dritte gibt nur die <code>instance</code> Werte zurück, die in übereinstimmenden Reihen vorkommen.</p><p><code>GET /_prometheus/api/v1/metadata</code> ist anders: Pro Metrik werden nur Typ und Einheit zurückgegeben, optional gefiltert nach Namen über einen <code>metric</code>-Parameter.</p>GET /_prometheus/api/v1/metadata?metric=http_requests_total<p><code>match[]</code>-Selektoren oder ein Zeitbereich werden nicht akzeptiert. In Prometheus werden Metadaten von aktiven Scrape-Zielen gesammelt (die Zeilen <code>HELP</code>, <code>TYPE</code> und <code>UNIT</code>, die sie anzeigen), sodass die Reaktion keinen Datenscan beinhaltet. Elasticsearch verfügt über keinen dedizierten Metadatenspeicher dieser Art, daher ermittelt die aktuelle Implementierung Metrik-Metadaten, indem sie Zeitreihendaten der letzten 24 Stunden durchsucht. Dadurch bleibt die Abfrage schnell, ohne dass ein vollständiger Indexscan erforderlich ist. Diese 24-Stunden-Rückschau ist derzeit fest vorgegeben: Die Prometheus-Metadaten-API stellt keine <code>start</code>- oder <code>end</code>-Parameter zur Verfügung, die Elasticsearch verwenden könnte, um sie für den Nutzer anpassbar zu machen.</p><p>Wie die Metadaten-Endpunkte im Hintergrund funktionieren, einschließlich der Befehle <code>TS_INFO</code> und <code>METRICS_INFO</code>, auf denen sie basieren, wird <a href="https://www.elastic.co/search-labs/blog//elasticsearch-native-prometheus-api#ts-info-and-metrics-info">im Folgenden</a> erläutert.</p><h3>Index-Vorfilterung</h3><p>Alle Abfrage- und Metadaten-Endpoints akzeptieren ein optionales <code>{index}</code>-Pfadsegment nach <code>/_prometheus/</code>:</p>GET /_prometheus/metrics-prod-*/api/v1/query_range?query=up&amp;start=...&amp;end=...<p>Dies schränkt ein, gegen welche Elasticsearch-Indizes die Abfrage ausgeführt wird, bevor mit der Auswertung des Ausdrucks begonnen wird. In Clustern mit vielen Datenströmen, die sich über Teams oder Umgebungen erstrecken, verhindert dies das Durchsuchen irrelevanter Indizes und kann die Latenz bei Abfragen erheblich verringern. Sie können pro Indexmuster separate Datenquellen konfigurieren, um Teams gezielten Zugriff auf ihre eigenen Metriken zu gewähren.</p><h3>Eine Anmerkung zum Remote Write</h3><p>Für die Ingestion stellt Elasticsearch auch den standardmäßigen Prometheus Remote Write-Endpoint bereit:</p><ul><li><p><code>POST /_prometheus/api/v1/write</code> nimmt Zeitreihen über das Prometheus Remote Write v1-Protokoll auf. v2 wird noch nicht unterstützt.</p></li></ul><p>Remote Write schreibt in die bestehenden Zeitreihendatenströme (TSDS) von Elasticsearch und nicht in eine separate, Prometheus-spezifische Speicherschicht. Prometheus-Labels werden zu TSDS-Dimensionen, und Metriknamen werden zu Feldern im Index-Mapping. Der <a href="https://www.elastic.co/observability-labs/blog/prometheus-remote-write-elasticsearch-architecture">Beitrag zur Architektur von Remote Write</a> behandelt das vollständige Mapping im Detail, einschließlich der Ableitung von Metriktypen und der Speicherung von Labels mit einem <code>labels.</code>-Präfix.</p><h3>So funktionierts</h3><p>Im Hintergrund funktionieren alle Endpoints auf die gleiche Weise: Sie parsen die eingehenden HTTP-Parameter, erstellen einen ES|QL-Abfrageplan, führen ihn für Zeitreihendatenströme aus und konvertieren das spaltenorientierte Ergebnis zurück in das von Prometheus-Clients erwartete JSON-Format.</p><h2>TS_INFO und METRICS_INFO</h2><p>Die Metadaten-Endppoints müssen Fragen beantworten wie „Welche Labels existieren?“ oder „Welche Metriktypen sind definiert?“, und das über potenziell Millionen von Zeitreihen hinweg, ohne jeden einzelnen Datenpunkt zu prüfen.</p><p>Intern beantworten die Prometheus-Metadaten-Endpoints diese Fragen, indem sie ES|QL-Pläne um zwei neue Verarbeitungsbefehle erstellen: <code>METRICS_INFO</code> und <code>TS_INFO</code>. Sie müssen diese Befehle nicht direkt verwenden, um die Prometheus-API zu nutzen, doch sie bilden die Kernausführungsprimitive hinter den Metadatenantworten. Beide funktionieren, indem sie nur ein Dokument pro Zeitreihe aufrufen, um dessen Metadaten zu extrahieren, anstatt alle Stichproben zu scannen. Das bedeutet, dass sich ihre Kosten proportional zur Anzahl der einzelnen Zeitreihen und nicht zur Anzahl der Datenpunkte verhalten.</p><p><code>METRICS_INFO</code> gibt eine Zeile pro eindeutiger Metrik mit ihrem Namen, Typ, Einheit und zugehörigen Dimensionsfeldern zurück. <code>TS_INFO</code> ist detaillierter: eine Zeile pro Kombination aus Metrik und Zeitreihe, einschließlich der tatsächlichen Dimensionswerte als JSON-Objekt.</p><p>Ein eigener Blogbeitrag zu <code>TS_INFO</code> und <code>METRICS_INFO</code> folgt in Kürze. Er behandelt das zweiphasige Ausführungsmodell, wie sie skaliert werden und wie sie direkt in ES|QL-Abfragen außerhalb der Prometheus-API verwendet werden können.</p><h3>So werden sie von den Metadaten-Endpoints verwendet</h3><p>Jeder Metadaten-Endpoint konstruiert einen ES|QL-Plan mit einem dieser Befehle im Kern.</p><p><code>/api/v1/labels</code> und <code>/api/v1/series</code> verwenden <code>TS_INFO</code>, da sie detaillierte Daten pro Zeitreihe benötigen (welche Labels existieren, welche Dimensionswerte jede Reihe identifizieren). <code>/api/v1/metadata</code> und <code>/api/v1/label/__name__/values</code> verwenden <code>METRICS_INFO</code>, da sie nur Informationen pro Metrik benötigen (Metriknamen, Typen, Einheiten).</p><p><code>/api/v1/label/{name}/values</code> Für reguläre Labels (alles außer <code>__name__</code>) wird keiner der beiden Befehle verwendet. Reguläre Labels wie <code>job</code> oder <code>instance</code> sind tatsächliche Dimensionsfelder im Index, sodass der Endpoint sie direkt mit einer Gruppenaggregation abfragen kann. Wenn <code>match[]</code> Selektoren bereitgestellt werden, werden sie in eine <code>WHERE</code>-Klausel übersetzt, die die Zeitreihen filtert, bevor die Aggregation ausgeführt wird.</p><p>Das <code>__name__</code>-Label erfordert eine andere Strategie, da es nicht immer als Dimensionsfeld vorhanden ist. Prometheus Remote Write speichert <code>labels.__name__</code>, aber Metriken, die über andere Pfade (OpenTelemetry, die Bulk-API) aufgenommen werden, enthalten es nicht. Der metrische Name ist im Feldnamen selbst kodiert (z. B. <code>metrics.http_requests_total</code>). Sie könnten sich die Index-Mappings ansehen, um die Feldnamen aufzulisten, aber Mappings allein geben keinen Aufschluss darüber, welche Metrik welche Dimensionen aufweist, und sie lassen sich nicht nach Labelwerten aus einem <code>match[]</code>-Selektor filtern. <code>METRICS_INFO</code> kann beides: Es zählt Metriknamen über Indizes auf, während es Upstream-Filter <code>WHERE</code> berücksichtigt.</p><p>In allen Fällen übernimmt die API-Ebene die Rückübersetzung in die Prometheus-Konventionen: indem sie die Speicherpräfixe <code>labels.</code> und <code>metrics.</code> entfernt und <code>__name__</code> für Nicht-Prometheus-Metriken ergänzt, denen ein solches Präfix fehlt.</p><h2>Fazit</h2><p>Das Ergebnis: Jeder Prometheus-kompatible Client kann Elasticsearch-Metriken über bereits verstehende Endpunkte abfragen und erkunden. Remote Write-Metriken, OpenTelemetry-Metriken und Metriken, die über andere Pfade indiziert werden, werden alle über dieselbe API angezeigt, die von denselben TSDS-Indizes unterstützt wird.</p><p>Alle hier erwähnten Prometheus-APIs sind heute als technische Vorschau in Elasticsearch Serverless verfügbar. Für selbstverwaltete Cluster und Elastic Cloud Hosted Deployments, verfügbar als technische Vorschau in Elasticsearch 9.4, mit Ausnahme von <code>GET /_prometheus/api/v1/metadata</code>. Um lokal zu experimentieren, verwenden Sie <a href="https://www.elastic.co/docs/deploy-manage/deploy/self-managed/local-development-installation-quickstart">start-local</a>.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-native-prometheus-api</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-native-prometheus-api</guid>
    <category><![CDATA[Integrationen]]></category>
    <dc:creator><![CDATA[Felix Barnsteiner]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt12b4e100d5bbb7f0/6a16f7a22b835ff747f4afdd/c7b333bd73e8a1f4e18486b2d692ba742788dcfd-1376x768.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Erstellung eines Elasticsearch MCP-Servers mit TypeScript]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie mit TypeScript und Claude Desktop einen Elasticsearch MCP-Server erstellen.]]></description>
    <content:encoded><![CDATA[<p>Bei der Arbeit mit großen Wissensdatenbanken in Elasticsearch ist das Finden von Informationen nur die halbe Miete. Entwickler müssen häufig Ergebnisse aus mehreren Dokumenten zusammenführen, Zusammenfassungen erstellen und Antworten bis zu ihren Quellen zurückverfolgen. Um dies zu erreichen, bietet das Modellkontextprotokoll (MCP) eine standardisierte Möglichkeit, Elasticsearch mit LLM-gestützten Anwendungen zu verbinden. Während Elastic offizielle Lösungen anbietet, wie den Elastic Agent Builder (der unter anderem einen <a href="https://www.elastic.co/docs/solutions/search/agent-builder/mcp-server">MCP-Endpoint</a> zu seinen Features zählt), ermöglicht die Entwicklung eines benutzerdefinierten MCP-Servers die volle Kontrolle über die Suchlogik, die Ergebnisformatierung und die Art und Weise, wie abgerufene Inhalte an ein LLM zur Synthese, Zusammenfassung und Zitierung weitergegeben werden.</p><p>In diesem Artikel untersuchen wir die Vorteile der Entwicklung eines benutzerdefinierten Elasticsearch MCP-Servers und zeigen, wie man einen in TypeScript erstellt, der Elasticsearch mit LLM-gestützten Anwendungen verbindet.</p><h2>Warum einen benutzerdefinierten Elasticsearch MCP-Server entwickeln?</h2><p>Elastic bietet einige Alternativen für <a href="https://www.elastic.co/docs/solutions/search/mcp">MCP-Server</a>:</p><ul><li><p><a href="https://www.elastic.co/docs/solutions/search/agent-builder/mcp-server">Elastic Agent Builder MCP-Server für Elasticsearch 9.2+</a></p></li><li><p><a href="https://github.com/elastic/mcp-server-elasticsearch?tab=readme-ov-file#elasticsearch-mcp-server">Elasticsearch MCP-Server für ältere Versionen (Python)</a></p></li></ul><p>Wenn Sie mehr Kontrolle darüber benötigen, wie Ihr MCP-Server mit Elasticsearch interagiert, bietet Ihnen die Entwicklung eines eigenen benutzerdefinierten Servers die nötige Flexibilität, um ihn genau an Ihre Bedürfnisse anzupassen. Zum Beispiel ist der MCP-Endpoint von Agent Builder auf Elasticsearch Query Language (ES|QL) Abfragen beschränkt, während ein benutzerdefinierter Server die Verwendung des vollständigen Abfrage-DSL ermöglicht. Sie erhalten außerdem die Kontrolle über die Formatierung der Ergebnisse, bevor sie an das LLM weitergeleitet werden, und können zusätzliche Verarbeitungsschritte integrieren, wie die OpenAI-gestützte Zusammenfassung, die wir in dieses Tutorial implementieren.</p><p>Am Ende dieses Artikels verfügen Sie über einen MCP-Server in TypeScript, der in einem Elasticsearch-Index gespeicherte Informationen durchsucht, zusammenfasst und Zitate bereitstellt. Wir verwenden Elasticsearch für den Abruf, das <code>gpt-4o-mini</code>-Modell von OpenAI zur Zusammenfassung und Erzeugung von Zitaten sowie Claude Desktop als MCP-Client und Benutzeroberfläche, um Nutzeranfragen zu empfangen und darauf zu reagieren. Das Endergebnis ist ein interner Wissensassistent, der Entwicklern dabei hilft, Best Practices in der technischen Dokumentation ihres Unternehmens zu entdecken und zu synthetisieren.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltad9133cb083ad352/6a170c19b0367d411e72bd5b/ec5771a874cf9740d4cac6888622cbe8cd6aede7-1999x1133.png" alt="Erstellen eines Elastic MCP-Servers mit TypeScript und Claude Desktop." /><h2>Voraussetzungen:</h2><ul><li><p>Node.js 20+</p></li><li><p>Elasticsearch</p></li><li><p>OpenAI-API-Schlüssel</p></li><li><p>Claude Desktop</p></li></ul><h3>Was ist MCP?</h3><p><a href="https://www.elastic.co/what-is/mcp">MCP</a> ist ein offener Standard, der von <a href="https://www.anthropic.com/news/model-context-protocol">Anthropic</a> entwickelt wurde und sichere, bidirektionale Verbindungen zwischen LLMs und externen Systemen wie Elasticsearch ermöglicht. Mehr über den aktuellen Stand von MCP können Sie in <a href="https://www.elastic.co/search-labs/blog/mcp-current-state">diesem Artikel</a> lesen.</p><p>Die MCP-Landschaft <a href="https://www.elastic.co/search-labs/blog/mcp-current-state#mcp-project-updates:-transport,-elicitation,-and-structured-tooling">entwickelt sich täglich weiter</a>, wobei Server für eine Vielzahl von Anwendungsfällen zur Verfügung stehen. In diesem Artikel zeigen wir Ihnen außerdem, wie einfach es ist, Ihren eigenen benutzerdefinierten MCP-Server zu entwickeln.</p><h3>MCP-Clients</h3><p>Es gibt eine lange <a href="https://modelcontextprotocol.io/clients">Liste verfügbarer MCP-Clients</a>, von denen jeder seine eigenen Eigenschaften und Einschränkungen hat. Aufgrund seiner Einfachheit und Beliebtheit verwenden wir <a href="https://claude.ai/download">Claude Desktop</a> als unseren MCP-Client. Er dient als Chat-Schnittstelle, auf der Nutzer Fragen in natürlicher Sprache stellen können, und ruft automatisch die von unserem MCP-Server bereitgestellten Tools auf, um Dokumente zu durchsuchen und Zusammenfassungen zu erstellen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt06fd7a02042094e1/6a170c1b14b2700024e3c651/66eb0b11473347b6cf2d85718251eeac38d6249d-1999x1491.png" alt="Claude 4.5 Sonnet Seite mit dem Vermerk: „Zeit für Kaffee und Claude? Wie kann ich Ihnen weiterhelfen?“" /><h2>Erstellen eines Elasticsearch MCP-Servers</h2><p>Mit dem <a href="https://github.com/modelcontextprotocol/typescript-sdk">TypeScript SDK</a> können wir einfach einen Server erstellen, der versteht, wie er unsere Elasticsearch-Daten basierend auf einer Nutzereingabe abfragt.</p><p>In diesem Artikel werden die folgenden Schritte zur Integration des Elasticsearch MCP-Servers mit dem Claude Desktop-Client beschrieben:</p><ol><li><p><a href="https://www.elastic.co/search-labs/blog/elastic-mcp-server-typescript-claude#configure-mcp-server-for-elasticsearch">MCP-Server für Elasticsearch konfigurieren.</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/elastic-mcp-server-typescript-claude#load-the-mcp-server-into-claude-desktop">MCP-Server in Claude Desktop laden.</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/elastic-mcp-server-typescript-claude#test-it-out">Probieren Sie es aus.</a></p></li></ol><h3>MCP-Server für Elasticsearch konfigurieren</h3><p>Zunächst initialisieren wir eine Node-Anwendung:</p>npm init -y<p>Dadurch wird eine <code>package.json</code>-Datei erstellt, wodurch wir damit beginnen können, die notwendigen Abhängigkeiten für diese Anwendung zu installieren.</p>npm install @elastic/elasticsearch @modelcontextprotocol/sdk openai zod &amp;&amp; npm install --save-dev ts-node @types/node typescript<ul><li><p><strong>@elastic/elasticsearch</strong> verschafft Ihnen Zugriff auf die Node.js-Bibliothek von Elasticsearch.</p></li><li><p><strong>@modelcontextprotocol/SDK</strong> stellt die Kerntools bereit, um einen MCP-Server zu erstellen und zu verwalten, Tools zu registrieren und die Kommunikation mit MCP-Clients zu übernehmen.</p></li><li><p><strong>OpenAI</strong> ermöglicht die Interaktion mit OpenAI-Modellen, um Zusammenfassungen oder Antworten in natürlicher Sprache zu generieren.</p></li><li><p><a href="https://zod.dev/"><strong>ZOD</strong></a>sorgt dafür, strukturierte Schemata für Eingangs- und Ausgangsdaten in jedem Tool zu definieren und zu validieren.</p></li></ul><p><code>ts-node</code>Während der Entwicklung werden <code>@types/node</code> und <code>typescript</code> verwendet, um den Code zu schreiben und die Skripte zu kompilieren.</p><h4>Datensatz einrichten</h4><p>Um die Daten bereitzustellen, die Claude Desktop über unseren MCP-Server abfragen kann, verwenden wir einen simulierten <a href="https://github.com/Delacrobix/typescript-elasticsearch-mcp/blob/main/dataset.json">internen Wissensdatenbank-Datensatz</a>. So sieht ein Dokument aus diesem Datensatz aus:</p>{
    "id": 5,
    "title": "Logging Standards for Microservices",
    "content": "Consistent logging across microservices helps with debugging and tracing. Use structured JSON logs and include request IDs and timestamps. Avoid logging sensitive information. Centralize logs in Elasticsearch or a similar system. Configure log rotation to prevent storage issues and ensure logs are searchable for at least 30 days.",
    "tags": ["logging", "microservices", "standards"]
}<p>Für die Aufnahme der Daten haben wir ein Skript vorbereitet, das einen Index in Elasticsearch erstellt und den Datensatz darin lädt. Sie finden es <a href="https://github.com/Delacrobix/typescript-elasticsearch-mcp/blob/main/setup.ts">hier</a>.</p><h4>MCP-Server</h4><p>Erstellen Sie eine Datei mit dem Namen <a href="https://github.com/Delacrobix/typescript-elasticsearch-mcp/blob/main/index.ts"><code>index.ts</code></a> und fügen Sie den folgenden Code hinzu, um die Abhängigkeiten zu importieren und Umgebungsvariablen zu verarbeiten:</p>// index.ts
import { z } from "zod";
import { Client } from "@elastic/elasticsearch";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import OpenAI from "openai";

const ELASTICSEARCH_ENDPOINT =
  process.env.ELASTICSEARCH_ENDPOINT ?? "http://localhost:9200";
const ELASTICSEARCH_API_KEY = process.env.ELASTICSEARCH_API_KEY ?? "";
const OPENAI_API_KEY = process.env.OPENAI_API_KEY ?? "";
const INDEX = "documents";<p>Außerdem initialisieren wir die Clients, um Elasticsearch- und OpenAI-Aufrufe zu bewältigen:</p>const openai = new OpenAI({
  apiKey: OPENAI_API_KEY,
});

const _client = new Client({
  node: ELASTICSEARCH_ENDPOINT,
  auth: {
    apiKey: ELASTICSEARCH_API_KEY,
  },
});<p>Um unsere Implementierung robuster zu machen und einen strukturierten Eingang und Ausgang zu gewährleisten, definieren wir Schemata mit <a href="https://zod.dev/"><code>zod</code></a>. Dadurch können wir Daten zur Laufzeit validieren, Fehler frühzeitig abfangen und die Tool-Reaktionen einfacher programmatisch verarbeiten.</p>const DocumentSchema = z.object({
  id: z.number(),
  title: z.string(),
  content: z.string(),
  tags: z.array(z.string()),
});

const SearchResultSchema = z.object({
  id: z.number(),
  title: z.string(),
  content: z.string(),
  tags: z.array(z.string()),
  score: z.number(),
});

type Document = z.infer&lt;typeof DocumentSchema&gt;;
type SearchResult = z.infer&lt;typeof SearchResultSchema&gt;;<p>Erfahren Sie <a href="https://www.elastic.co/search-labs/blog/structured-outputs-elasticsearch-guide">hier</a> mehr über strukturierte Ausgänge.</p><p>Nun initialisieren wir den MCP-Server:</p>const server = new McpServer({
  name: "Elasticsearch RAG MCP",
  description:
    "A RAG server using Elasticsearch. Provides tools for document search, result summarization, and source citation.",
  version: "1.0.0",
});<h4>Definition der MCP-Tools</h4><p>Wenn alles konfiguriert ist, können wir mit dem Schreiben der Tools beginnen, die von unserem MCP-Server bereitgestellt werden. Dieser Server stellt zwei Tools bereit:</p><ul><li><p><strong><code>search_docs</code></strong><strong>: </strong>Sucht nach Dokumenten in Elasticsearch mittels Volltextsuche.</p></li><li><p><strong><code>summarize_and_cite</code></strong><strong>:</strong> Fasst Informationen aus zuvor abgerufenen Dokumenten zusammen und synthetisiert sie, um eine Nutzerfrage zu beantworten. Dieses Tool fügt außerdem Zitate hinzu, die auf die Quelldokumente verweisen.</p></li></ul><p>Zusammen bilden diese Tools einen einfachen Workflow zum Abrufen und Zusammenfassen, bei dem ein Tool relevante Dokumente abruft und das andere diese Dokumente verwendet, um eine zusammengefasste, zitierte Reaktion zu generieren.</p><h4>Reaktionsformat des Tools</h4><p>Jedes Tool kann beliebige Eingangsparameter akzeptieren, muss aber mit folgender Struktur antworten:</p><ul><li><p><strong>Inhalt:</strong> Dies ist die Reaktion des Tools im unstrukturierten Format. Dieses Feld wird in der Regel verwendet, um Text, Bilder, Audio, Links oder Einbettungen zurückzugeben. In dieser Anwendung dient es dazu, formatierten Text mit den Informationen zurückzugeben, die von den Tools generiert wurden.</p></li><li><p><strong>structuredContent: </strong>Dies ist eine optionale Rückgabe, die verwendet wird, um die Ergebnisse der einzelnen Tools in einem strukturierten Format bereitzustellen. Dies ist für programmatische Zwecke nützlich. Zwar wird es in diesem MCP-Server nicht verwendet, es kann jedoch von Nutzen sein, wenn Sie andere Tools entwickeln oder die Ergebnisse programmatisch verarbeiten möchten.</p></li></ul><p>Vor diesem Hintergrund betrachten wir nun jedes Tool im Detail.</p><h4>Tool „Search_docs“</h4><p>Dieses Tool führt eine <a href="https://www.elastic.co/docs/solutions/search/full-text">Volltextsuche</a> im Elasticsearch-Index durch, um die relevantesten Dokumente basierend auf der Nutzeranfrage abzurufen. Es hebt die wichtigsten Treffer hervor und bietet einen schnellen Überblick mit Relevanzbewertungen.</p>server.registerTool(
  "search_docs",
  {
    title: "Search Documents",
    description:
      "Search for documents in Elasticsearch using full-text search. Returns the most relevant documents with their content, title, tags, and relevance score.",
    inputSchema: {
      query: z
        .string()
        .describe("The search query terms to find relevant documents"),
      max_results: z
        .number()
        .optional()
        .default(5)
        .describe("Maximum number of results to return"),
    },
    outputSchema: {
      results: z.array(SearchResultSchema),
      total: z.number(),
    },
  },
  async ({ query, max_results }) =&gt; {
    if (!query) {
      return {
        content: [
          {
            type: "text",
            text: "Query parameter is required",
          },
        ],
        isError: true,
      };
    }

    try {
      const response = await _client.search({
        index: INDEX,
        size: max_results,
        query: {
          bool: {
            must: [
              {
                multi_match: {
                  query: query,
                  fields: ["title^2", "content", "tags"],
                  fuzziness: "AUTO",
                },
              },
            ],
            should: [
              {
                match_phrase: {
                  title: {
                    query: query,
                    boost: 2,
                  },
                },
              },
            ],
          },
        },
        highlight: {
          fields: {
            title: {},
            content: {},
          },
        },
      });

      const results: SearchResult[] = response.hits.hits.map((hit: any) =&gt; {
        const source = hit._source as Document;

        return {
          id: source.id,
          title: source.title,
          content: source.content,
          tags: source.tags,
          score: hit._score ?? 0,
        };
      });

      const contentText = results
        .map(
          (r, i) =&gt;
            `[${i + 1}] ${r.title} (score: ${r.score.toFixed(
              2,
            )})\n${r.content.substring(0, 200)}...`,
        )
        .join("\n\n");

      const totalHits =
        typeof response.hits.total === "number"
          ? response.hits.total
          : (response.hits.total?.value ?? 0);

      return {
        content: [
          {
            type: "text",
            text: `Found ${results.length} relevant documents:\n\n${contentText}`,
          },
        ],
        structuredContent: {
          results: results,
          total: totalHits,
        },
      };
    } catch (error: any) {
      console.log("Error during search:", error);

      return {
        content: [
          {
            type: "text",
            text: `Error searching documents: ${error.message}`,
          },
        ],
        isError: true,
      };
    }
  }
);<p><em>Wir konfigurieren </em><a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-fuzzy-query"><em><code>fuzziness</code></em></a><em><code>: “AUTO”</code></em><em> so, dass eine variable Tippfehlertoleranz basierend auf der Länge des analysierten Tokens besteht. Wir legen außerdem </em><em><code>title^2</code></em><em> fest, um die Bewertung der Dokumente zu erhöhen, bei denen die Übereinstimmung im Feld „Titel“ erfolgt.</em></p><h4>Tool „summarize_and_cite“</h4><p>Dieses Tool erstellt eine Zusammenfassung auf Basis von Dokumenten, die bei der vorherigen Suche ermittelt wurden. Es verwendet das <code>gpt-4o-mini</code>-Modell von OpenAI, um die relevantesten Informationen zur Beantwortung der Nutzerfragen zu synthetisieren und Antworten zu liefern, die direkt aus den Suchergebnissen abgeleitet werden. Neben der Zusammenfassung werden auch Metadaten für Zitate zu den verwendeten Quelldokumenten zurückgegeben.</p>server.registerTool(
  "summarize_and_cite",
  {
    title: "Summarize and Cite",
    description:
      "Summarize the provided search results to answer a question and return citation metadata for the sources used.",
    inputSchema: {
      results: z
        .array(SearchResultSchema)
        .describe("Array of search results from search_docs"),
      question: z.string().describe("The question to answer"),
      max_length: z
        .number()
        .optional()
        .default(500)
        .describe("Maximum length of the summary in characters"),
      max_docs: z
        .number()
        .optional()
        .default(5)
        .describe("Maximum number of documents to include in the context"),
    },
    outputSchema: {
      summary: z.string(),
      sources_used: z.number(),
      citations: z.array(
        z.object({
          id: z.number(),
          title: z.string(),
          tags: z.array(z.string()),
          relevance_score: z.number(),
        })
      ),
    },
  },
  async ({ results, question, max_length, max_docs }) =&gt; {
    if (!results || results.length === 0 || !question) {
      return {
        content: [
          {
            type: "text",
            text: "Both results and question parameters are required, and results must not be empty",
          },
        ],
        isError: true,
      };
    }

    try {
      const used = results.slice(0, max_docs);

      const context = used
        .map(
          (r: SearchResult, i: number) =&gt;
            `[Document ${i + 1}: ${r.title}]\\n${r.content}`
        )
        .join("\n\n---\n\n");

      // Generate summary with OpenAI
      const completion = await openai.chat.completions.create({
        model: "gpt-4o-mini",
        messages: [
          {
            role: "system",
            content:
              "You are a helpful assistant that answers questions based on provided documents. Synthesize information from the documents to answer the user's question accurately and concisely. If the documents don't contain relevant information, say so.",
          },
          {
            role: "user",
            content: `Question: ${question}\\n\\nRelevant Documents:\\n${context}`,
          },
        ],
        max_tokens: Math.min(Math.ceil(max_length / 4), 1000),
        temperature: 0.3,
      });

      const summaryText =
        completion.choices[0]?.message?.content ?? "No summary generated.";

      const citations = used.map((r: SearchResult) =&gt; ({
        id: r.id,
        title: r.title,
        tags: r.tags,
        relevance_score: r.score,
      }));

      const citationText = citations
        .map(
          (c: any, i: number) =&gt;
            `[${i + 1}] ID: ${c.id}, Title: "${c.title}", Tags: ${c.tags.join(
              ", ",
            )}, Score: ${c.relevance_score.toFixed(2)}`,
        )
        .join("\n");

      const combinedText = `Summary:\\n\\n${summaryText}\\n\\nSources used (${citations.length}):\\n\\n${citationText}`;

      return {
        content: [
          {
            type: "text",
            text: combinedText,
          },
        ],
        structuredContent: {
          summary: summaryText,
          sources_used: citations.length,
          citations: citations,
        },
      };
    } catch (error: any) {
      return {
        content: [
          {
            type: "text",
            text: `Error generating summary and citations: ${error.message}`,
          },
        ],
        isError: true,
      };
    }
  }
);<p>Zu guter Letzt starten wir den Server mithilfe von <a href="https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#stdio">stdio</a>. Das bedeutet, dass der MCP-Client mit unserem Server kommuniziert, indem er seine standardmäßigen Eingangs- und Ausgangsstreams liest und schreibt. stdio ist die einfachste Transportoption und funktioniert gut für lokale MCP-Server, die vom Client als Unterprozesse gestartet werden. Fügen Sie den folgenden Code am Ende der Datei hinzu:</p>const transport = new StdioServerTransport();
server.connect(transport);<p>Kompilieren Sie das Projekt jetzt mit folgendem Befehl:</p>npx tsc index.ts --target ES2022 --module node16 --moduleResolution node16 --outDir ./dist --strict --esModuleInterop<p>Dadurch wird ein Ordner <code>dist</code> erstellt und darin eine Datei <code>index.js</code>.</p><h3>Laden Sie den MCP-Server in Claude Desktop</h3><p>Folgen Sie <a href="https://modelcontextprotocol.io/docs/develop/connect-local-servers">dieser Anleitung</a>, um den MCP-Server mit Claude Desktop zu konfigurieren. In der Konfigurationsdatei von Claude müssen die folgenden Werte festgelegt werden:</p>{
  "mcpServers": {
    "elasticsearch-rag-mcp": {
      "command": "node",
      "args": [   "/Users/user-name/app-dir/dist/index.js"
      ],
      "env": {
        "ELASTICSEARCH_ENDPOINT": "your-endpoint-here",
        "ELASTICSEARCH_API_KEY": "your-api-key-here",
        "OPENAI_API_KEY": "your-openai-key-here"
      }
    }
  }
}<p>Der Wert <code>args</code> sollte auf die kompilierte Datei im Ordner <code>dist</code> verweisen. Außerdem müssen Sie die Umgebungsvariablen in der Konfigurationsdatei mit genau den gleichen Namen festlegen, die im Code definiert sind.</p><h3>Probieren Sie es aus</h3><p>Klicken Sie vor der Ausführung jedes Tools auf <strong>Search and Tools</strong>, um sicherzustellen, dass die Tools aktiviert sind. Hier können Sie außerdem alle Funktionen aktivieren oder deaktivieren:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt395a7337021f9820/6a170c1c67045bb74d45c228/172981c2a54adabc70d5819013c3007670935605-1999x1002.png" alt="Claude 4.5 Sonnet Seite mit dem Vermerk: „Guten Tag Jeff. Wie kann ich Ihnen weiterhelfen?“" /><p>Zum Schluss testen wir den MCP-Server über den Claude Desktop-Chat und beginnen, Fragen zu stellen:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf4ac458dc0206271/6a170c1e66c4f91328f8c072/03654c0f8c53c714f801fba8b25747071179209b-1999x1353.png" alt="Nutzersuchanfrage im Claude Desktop-Chat nach Dokumenten über Authentifizierungsmethoden und RBAC sowie Reaktionen von Claude." /><p>Für die Frage „<strong>Suche nach Dokumenten zu Authentifizierungsmethoden und RBAC</strong>“ wird das <code>search_docs</code>-Tool ausgeführt und liefert folgende Ergebnisse:</p>Most Relevant Documents:
Access Control and Role Management (highest relevance) - This document covers role-based access control (RBAC) principles, including ensuring users only have necessary permissions, regular auditing of user roles, revoking inactive accounts, and implementing just-in-time access for sensitive operations.
User Authentication with OAuth 2.0 - This document explains OAuth 2.0 authentication, which enables secure delegated access without credential sharing. It covers configuring identity providers, token management with limited scope and lifetime, and secure storage of refresh tokens.
Container Security Guidelines - While primarily about container security, this document touches on access control aspects like running containers as non-root users and avoiding embedded credentials.
Incident Response Playbook - This mentions role assignment during incidents (incident commander, communications lead, etc.), which relates to access control in emergency scenarios.
Logging Standards for Microservices - This document includes guidance on avoiding logging sensitive information, which is relevant to authentication security.<p>Die Reaktion lautet: „Großartig! Ich habe 5 relevante Dokumente über Authentifizierungsmethoden und RBAC gefunden. Folgendes wurde gefunden:“</p><p>Der Toolaufruf gibt die Quelldokumente als Teil seiner Reaktionnutzlast zurück, die später zur Erstellung von Zitaten verwendet werden.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbaf48a9468770ce2/6a170c21509168bffee1bb14/25ff4c7e9563d99752f95540dafdc7fd211a66e3-800x530.gif" alt="Claude 4.5 Sonett Seite mit Reaktionen zum Durchscrollen, die die fünf relevanten Dokumente zu Authentifizierungsmethoden und RBAC enthalten." /><p>Es ist auch möglich, mehrere Tools in einer einzigen Interaktion zu verketten. In diesem Fall analysiert Claude Desktop die Frage des Nutzers und stellt fest, dass zunächst <code>search_docs</code> aufgerufen werden muss, um relevante Dokumente abzurufen, und dass diese Ergebnisse anschließend an <code>summarize_and_cite</code> übergeben werden müssen, um die endgültige Antwort zu generieren, ohne dass dafür separate Prompts vom Nutzer erforderlich sind:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta46ff45274e64192/6a170c230c4857a91501aac1/e6a8a46acb4236e77058f18bcd2f0737b5882c05-1999x1101.png" alt="Claude Desktop-Chat mit dem Hinweis „Jeff ist zurück“ und einer neuen Nutzerfrage: „Was sind die wichtigsten Empfehlungen zur Verbesserung der Authentifizierung und Zugriffskontrolle in unseren Systemen? Referenzen einbeziehen.“" /><p>In diesem Fall haben wir für die Abfrage „<strong>Was sind die wichtigsten Empfehlungen zur Verbesserung der Authentifizierung und Zugriffssteuerung in unseren Systemen? Referenzen einbeziehen.</strong>“ folgende Ergebnisse erzielt:</p>Based on the documentation, here are the main recommendations to improve authentication and access control across your systems:

Key Recommendations

1. Implement Role-Based Access Control (RBAC)
Ensure users have only the permissions necessary for their job functions. This principle of least privilege minimizes security risks by limiting access to what's truly needed. [1]

2. Regular Access Audits
Conduct regular audits of user roles and promptly revoke access for inactive accounts. This helps prevent unauthorized access from dormant or compromised accounts. [1]

3. Just-in-Time (JIT) Access
Implement just-in-time access for sensitive operations, where permissions are granted only when needed and for a limited duration. This reduces the attack surface by minimizing standing privileges. [1]

4. OAuth 2.0 for Secure Authentication
Use OAuth 2.0 to enable secure delegated access without sharing user credentials. This protocol allows third-party applications to access resources on behalf of users without exposing passwords. [2]

5. Token Security and Management
Configure your identity provider to issue tokens with limited scope and lifetime

Store refresh tokens securely
Validate access tokens consistently to maintain security [2]
References

Access Control and Role Management (Tags: security, access-control)
User Authentication with OAuth 2.0 (Tags: authentication, oauth)
These recommendations work together to create a defense-in-depth approach, where multiple security layers protect your systems from unauthorized access.<p>Wie im vorherigen Schritt können wir die Reaktion jedes Tools auf diese Frage einsehen:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8f633c518e708a99/6a170c25ab7f082991db9ed6/cb606d356b2f7d5e4878a5eff71bc881869ac0ee-800x585.gif" alt="Claude Desktop-Chatseite mit Text zum Durchscrollen, der die Reaktion jedes Tools auf die Frage enthält: „Was sind die wichtigsten Empfehlungen zur Verbesserung der Authentifizierung und Zugriffskontrolle in unseren Systemen? Referenzen einbeziehen.“" /><p><em>Hinweis: Wenn ein Untermenü erscheint, in dem gefragt wird, ob Sie die Nutzung jedes Tools genehmigen möchten, wählen Sie </em><em><strong>Immer erlauben</strong></em><em> oder </em><em><strong>Einmal erlauben</strong></em><em>.</em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6627ee0bff1862df/6a170c266f7f040f6f91488c/aea942ba9b0037526ea215bec65690f1a5c3099c-1522x250.png" alt="Claude Desktop bietet Nutzern die Auswahl der Optionen „Immer zulassen“ und „Einmal zulassen“." /><h2>Fazit</h2><p>MCP-Server stellen einen bedeutenden Schritt zur Standardisierung von LLM-Tools für lokale und entfernte Anwendungen dar. Die vollständige Kompatibilität ist zwar noch in Bearbeitung, wir verzeichnen jedoch große Fortschritte in diese Richtung.</p><p>In diesem Artikel haben wir gelernt, wie man einen benutzerdefinierten MCP-Server in TypeScript entwickelt, der Elasticsearch mit LLM-gestützten Anwendungen verbindet. Unser Server stellt zwei Tools bereit: <code>search_docs</code> zum Abrufen relevanter Dokumente mittels Abfrage-DSL und <code>summarize_and_cite</code> zur Erstellung von Zusammenfassungen mit Zitaten über OpenAI-Modelle und Claude Desktop als Client-Benutzeroberfläche.</p><p>Die Zukunft der Kompatibilität zwischen verschiedenen Client- und Server-Anbietern sieht vielversprechend aus. Zu den nächsten Schritten gehört die Erweiterung des Funktionsumfangs und die Erhöhung der Flexibilität Ihres Agenten. Es gibt einen praktischen <a href="https://www.elastic.co/search-labs/blog/llm-functions-elasticsearch-intelligent-query">Artikel</a> dazu, wie Sie Ihre Abfragen mithilfe von Suchvorlagen für mehr Präzision und Flexibilität parametrisieren können.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elastic-mcp-server-typescript-claude</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elastic-mcp-server-typescript-claude</guid>
    <category><![CDATA[Agentische KI]]></category>
    <category><![CDATA[Integrationen]]></category>
    <dc:creator><![CDATA[Jeffrey Rengifo]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5600198cb47666a5/6a170c28509168ce3ae1bb18/0bb24c05fff391f42070c2883182ea6fe9cb9680-1280x720.png" length="0" type="image/png"/>
    <pubDate>Fri, 27 Mar 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Die Verwendung der Elasticsearch Inference API zusammen mit Hugging Face-Modellen]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie Elasticsearch mithilfe von Inferenz-Endpoints mit Hugging Face Modellen verbinden und ein mehrsprachiges Blog-Empfehlungssystem mit semantischer Suche und Chat-Abschlüssen erstellen.]]></description>
    <content:encoded><![CDATA[<p>In den letzten Aktualisierungen hat Elasticsearch eine native Integration eingeführt, um sich mit Modellen zu verbinden, die auf dem <a href="https://endpoints.huggingface.co/">Hugging Face Inference Service</a> gehostet werden. In diesem Beitrag erfahren Sie, wie Sie diese Integration konfigurieren und über einfache API-Aufrufe mithilfe eines großen Sprachmodells (LLM) Inferenzen durchführen können. Wir verwenden <a href="https://huggingface.co/HuggingFaceTB/SmolLM3-3B">SmolLM3-3B</a>, ein leichtes Allzweckmodell mit einem ausgewogenen Gleichgewicht zwischen Ressourcenverbrauch und Antwortqualität.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9094997548bd70f8/6a170d6a839dfa0ad6dcff54/7ddadf1976421a860a7d62087239adb9150d808b-1999x1388.png" alt="Punktdiagramm mit mehreren kleinen Sprachmodellen, aufgetragen nach Modellgröße (in Milliarden von Parametern) auf der x-Achse und Gewinnrate (in Prozent) auf der y-Achse. SmolLM3‑3B erscheint nahe an der Spitze des Effizienztrends, mit einer höheren Gewinnrate als andere Modelle ähnlicher Größe." /><h2>Voraussetzungen</h2><ul><li><p><strong>Elasticsearch 9.3 oder Elastic Cloud Serverless: </strong>Sie können ein Cloud-Deployment erstellen, indem Sie <a href="https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud">diese Anweisungen</a> befolgen, oder stattdessen den <a href="https://www.elastic.co/docs/deploy-manage/deploy/self-managed/local-development-installation-quickstart#local-dev-quick-start"><code>start-local</code></a> Quickstart verwenden.</p></li><li><p><strong>Python 3.12: </strong>Laden Sie Python <a href="https://www.python.org/">hier</a> herunter.</p></li><li><p><strong>Hugging Face </strong><a href="https://huggingface.co/docs/hub/en/security-tokens">Zugriffstoken</a>.</p></li></ul><h2>Chat-Abschlüsse unter Verwendung eines Inferenz-Endpoints von Hugging Face</h2><p>Zuerst erstellen wir ein praktisches Beispiel, das Elasticsearch mit einem Hugging Face <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-inference-put">Inferenz-Endpoint</a> verbindet, um KI-gestützte Empfehlungen aus einer Reihe von Blogbeiträgen zu generieren. Für die Wissensdatenbank der App verwenden wir einen Datensatz mit Blogartikeln des Unternehmens, der wertvolle, aber oft schwer zugängliche Informationen enthält.</p><p>Bei diesem Endpoint ruft die <a href="https://www.elastic.co/docs/solutions/search/semantic-search">semantische Suche</a> die relevantesten Artikel für eine gegebene Abfrage ab, und ein Hugging Face LLM generiert kurze, kontextuelle Empfehlungen basierend auf diesen Ergebnissen.</p><p>Verschaffen wir uns einen groben Überblick über den Informationsfluss, den wir entwickeln werden:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf217b7b7db4e1e6c/6a170d6ca929cf8022ae0a3b/1dfbc2323438feaaa42e13ab242dd1f7166f74aa-1200x676.png" alt="Flussdiagramm, das einen Elasticsearch-Index zeigt, der semantische Suchergebnisse an einen Inferenz-Endpoint weiterleitet, der Artikelempfehlungen zurückgibt." /><p>In diesem Artikel testen wir die Fähigkeit von <strong>SmolLM3-3B</strong> undkombinieren seine kompakte Größe mit einer starken mehrsprachigen Argumentations- und Tool-Aufruffunktion. Basierend auf einer Suchabfrage senden wir alle passenden Inhalte (auf Englisch und Spanisch) an das LLM, um eine Liste empfohlener Artikel mit einer individuell erstellten Beschreibung basierend auf der Suchanfrage und den Ergebnissen zu erstellen.</p><p>So könnte die Benutzeroberfläche einer Artikelseite mit einem System zur Generierung von KI-Empfehlungen aussehen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt20e69b9a06fecd65/6a170d6e839dfa6f97dcff58/8d3b86b212f28ff279f2da67a33e6134039f0e4e-1999x949.png" alt="Benutzeroberfläche einer Artikelseite mit einem KI-gestützten Empfehlungssystem und drei Beispielen mit englischem Text sowie englischen oder spanischen Titeln." /><p>Sie können die vollständige Implementierung dieser Anwendung im verlinkten <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/elasticsearch-inference-api-and-hugging-face/notebook.ipynb">Notizbuch</a> finden.</p><h3>Konfiguration der Elasticsearch Inferenz-Endpoints</h3><p>Um den Elasticsearch <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-inference-put-hugging-face">Hugging Face Inferenz-Endpoint</a> zu verwenden, benötigen wir zwei wichtige Elemente: einen Hugging Face API-Schlüssel und eine ausgeführte Hugging Face Endpoint-URL. Dies sollte so aussehen:</p>PUT _inference/chat_completions/hugging-face-smollm3-3b
{
    "service": "hugging_face",
    "service_settings": {
        "api_key": "hugging-face-access-token", 
        "url": "url-endpoint" 
    }
}<p>Der Hugging Face Inferenz-Endpoint in Elasticsearch unterstützt verschiedene Aufgabentypen: <code>text_embedding</code>, <code>completion</code>, <code>chat_completion</code> und <code>rerank</code>. In diesem Blogbeitrag verwenden wir <code>chat_completion</code>, weil das Modell Gesprächsempfehlungen basierend auf den Suchergebnissen und einem Systemprompt generieren kann. Dieser Endpoint ermöglicht es uns, Chatabschlüsse direkt von Elasticsearch aus auf einfache Weise mit der Elasticsearch-API durchzuführen:</p>POST _inference/chat_completion/hugging-face-smollm3-3b/_stream
{
  "messages": [
      { "role": "user", "content": "&lt;user prompt&gt;" }
  ]
}<p>Dies dient als Kern der Anwendung, der den Prompt und die Suchergebnisse empfängt, die durch das Modell laufen werden. Nachdem die Theorie geklärt ist, können wir mit der Implementierung der Anwendung beginnen.</p><h4>Einrichten des ​​Inferenz-Endpoints auf Hugging Face</h4><p>Um das Hugging Face Modell bereitzustellen, werden wir <a href="https://huggingface.co/inference-endpoints/dedicated">Hugging Face One-Click-Deployments</a> verwenden, einen einfachen und schnellen Service für die Bereitstellung von Modell-Endpoints. Beachten Sie bitte, dass es sich um einen kostenpflichtigen Service handelt, durch dessen Nutzung zusätzliche Kosten entstehen können. In diesem Schritt wird die Modellinstanz erstellt, die zur Generierung der Empfehlungen für die Artikel verwendet wird.</p><p>Sie können ein Modell aus dem Ein-Klick-Katalog aussuchen:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta7bdfa43d6766324/6a170d6fb339d59e5476a039/b816e9fba1fe172687bf58f5143fb1f838c1077f-549x331.png" alt="Ansicht der Schnittstelle eines Modellkatalogs, der auf „smoll3“ gefiltert ist, mit einem Modell namens „smollm3‑3b“, das Textgenerierung, vLLM, GPU 1× Nvidia L4 und einen angegebenen Preis von 0,80 $ aufweist, sowie einem Hinweis, die Suche auf alle Hugging Face Modelle auszuweiten." /><p>Wählen Sie das <strong>SmolLM3-3B</strong> Modell:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdb0a2e6ffd7deb20/6a170d710c48574b7401aafc/610d3aba0429f3666c2df3616d513eb6a4397c0c-502x478.png" alt="Schnittstelle zum Erstellen eines Endpoints für das SmolLM3‑3B-Modell mit dem Modellnamen, dem Hinweis „verified by Hugging Face“, einem Feld für den Endpointnamen, Kosten von 0,80 $ pro Stunde und laufendem Replikat, einer cURL-Option und einer Schaltfläche „Create Endpoint“." /><p>Hier können Sie die URL des Hugging Face Endpoints abrufen:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt25714021711ed6ff/6a170d72c1e8a54853f88336/025094ddb2cfbd1f0f216a5ec4e119b0f4fa2c42-646x328.png" alt="Dashboard-Ansicht eines Hugging Face Inferenz-Endpoints mit dem Namen „smollm3‑3b‑pnz“, die den grünen Status „Running“, ein aktives Replikat, null Anfragen in der letzten Stunde, Navigationstabs und die angezeigte Endpoint-URL zeigt." /><p>Wie in der <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-inference-put-hugging-face">Dokumentation zu den Hugging Face Inferenz-Endpunkten</a> von Elasticsearch erwähnt, erfordert die Textgenerierung ein Modell, das mit der OpenAI-API kompatibel ist. Aus diesem Grund müssen wir den <code>/v1/chat/completions</code>-Subpfad an die Hugging Face Endpoint-URL anhängen. Das Ergebnis sieht wie folgt aus:</p>https://j2g31h0futopfkli.us-east-1.aws.endpoints.huggingface.cloud/v1/chat/completions<p>Mit dieser Voraussetzung können wir mit dem Codieren in einem Python-Notebook beginnen.</p><h4>API-Schlüssel für Hugging Face generieren</h4><p>Erstellen Sie ein <a href="https://huggingface.co/join">Hugging Face Konto</a> und erhalten Sie ein API-Token, indem Sie <a href="https://huggingface.co/docs/hub/en/security-tokens#user-access-tokens">diesen Anweisungen</a> folgen. Man kann zwischen drei Token-Typen wählen: <em>detailliert</em> (empfohlen für die Produktion, da es nur Zugriff auf bestimmte Ressourcen bietet); <em>Lesezugriff</em> (schreibgeschützt); oder <em>Schreibzugriff</em> (für Lese- und Schreibzugriff). Für dieses Tutorial ist ein Lesezugriffstoken ausreichend, da wir nur den Inferenz-Endpoint aufrufen müssen. Speichern Sie diesen Code für den nächsten Schritt.</p><h4>Einrichten des Elasticsearch Inferenz-Endpoints</h4><p>Zunächst legen wir einen Elasticsearch-Python-Client fest:</p>os.environ["ELASTICSEARCH_API_KEY"] = "your-elasticsearch-api-key"
os.environ["ELASTICSEARCH_URL"] = "https://xxxx.us-central1.gcp.cloud.es.io:443"

es_client = Elasticsearch(
    os.environ["ELASTICSEARCH_URL"], api_key=os.environ["ELASTICSEARCH_API_KEY"]
)<p>Danach erstellen wir einen Elasticsearch Inferenz-Endpoint, der das Hugging Face Modell verwendet. Dieser Endpoint ermöglicht es uns, Reaktionen zu generieren, die auf den Blogbeiträgen und dem an das Modell übergebenen Prompt basieren.</p>INFERENCE_ENDPOINT_ID = "smollm3-3b-pnz"

os.environ["HUGGING_FACE_INFERENCE_ENDPOINT_URL"] = (
 "https://j2g31h0futopfkli.us-east-1.aws.endpoints.huggingface.cloud/v1/chat/completions"
)
os.environ["HUGGING_FACE_API_KEY"] = "hf_xxxxx"

resp = es_client.inference.put(
        task_type="chat_completion",
        inference_id=INFERENCE_ENDPOINT_ID,
        body={
            "service": "hugging_face",
            "service_settings": {
                "api_key": os.environ["HUGGING_FACE_API_KEY"],
                "url": os.environ["HUGGING_FACE_INFERENCE_ENDPOINT_URL"],
            },
        },
    )<h3>Datensatz</h3><p>Der Datensatz enthält die <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/elasticsearch-inference-api-and-hugging-face/dataset.json">Blogbeiträge</a>, die abgefragt werden, und repräsentiert einen mehrsprachigen Inhaltssatz, der im gesamten Workflow verwendet wird:</p>// Articles dataset document example: 
{
    "id": "6",
    "title": "Complete guide to the new API: Endpoints and examples",
    "author": "Tomas Hernandez",
    "date": "2025-11-06",
    "category": "tutorial",
    "content": "This guide describes in detail all endpoints of the new API v2. It includes code examples in Python, JavaScript, and cURL for each endpoint. We cover authentication, resource creation, queries, updates, and deletion. We also explain error handling, rate limiting, and best practices. Complete documentation is available on our developer portal."
  }<h4>Elasticsearch-Mappings</h4><p>Mit dem definierten Datensatz müssen wir ein Datenschema erstellen, das der Struktur des Blogbeitrags entspricht. Die folgenden <a href="https://www.elastic.co/docs/manage-data/data-store/mapping">Index-Mappings</a> werden verwendet, um die Daten in Elasticsearch zu speichern:</p>INDEX_NAME = "blog-posts"

mapping = {
    "mappings": {
        "properties": {
            "id": {"type": "keyword"},
            "title": {
                "type": "object",
                "properties": {
                    "original": {
                        "type": "text",
                        "copy_to": "semantic_field",
                        "fields": {"keyword": {"type": "keyword"}},
                    },
                    "translated_title": {
                        "type": "text",
                        "fields": {"keyword": {"type": "keyword"}},
                    },
                },
            },
            "author": {"type": "keyword", "copy_to": "semantic_field"},
            "category": {"type": "keyword", "copy_to": "semantic_field"},
            "content": {"type": "text", "copy_to": "semantic_field"},
            "date": {"type": "date"},
            "semantic_field": {"type": "semantic_text"},
        }
    }
}


es_client.indices.create(index=INDEX_NAME, body=mapping)<p>Hier können wir klar erkennen, wie die Daten strukturiert sind. Wir werden die semantische Suche verwenden, um Ergebnisse basierend auf natürlicher Sprache abzurufen, zusammen mit der <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/copy-to"><code>copy_to</code></a>-Eigenschaft, um den Feldinhalt in das <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/semantic-text"><code>semantic_text</code></a>-Feld zu kopieren. Zusätzlich enthält das <code>title</code>-Feld zwei Unterfelder: Das <code>original</code>-Unterfeld speichert den Titel entweder auf Englisch oder Spanisch, abhängig von der Originalsprache des Artikels, und das <code>translated_title</code>-Unterfeld ist nur für spanische Artikel vorhanden und enthält die englische Übersetzung des Originaltitels.</p><h3>Ingestieren von Daten</h3><p>Der folgende Code-Schnipsel überträgt den Datensatz des Blogbeitrags in Elasticsearch mithilfe der <a href="https://www.elastic.co/docs/reference/elasticsearch/clients/javascript/bulk_examples">Bulk-API</a>:</p>def build_data(json_file, index_name):
    with open(json_file, "r") as f:
        data = json.load(f)

    for doc in data:
        action = {"_index": index_name, "_source": doc}
        yield action


try:
    success, failed = helpers.bulk(
        es_client,
        build_data("dataset.json", INDEX_NAME),
    )
    print(f"{success} documents indexed successfully")

    if failed:
        print(f"Errors: {failed}")
except Exception as e:
    print(f"Error: {str(e)}")<p>Nun, da wir die Artikel in Elasticsearch aufgenommen haben, müssen wir eine Funktion erstellen, die nach dem Feld <code>semantic_text</code> sucht:</p>def perform_semantic_search(query_text, index_name=INDEX_NAME, size=5):
    try:
        query = {
            "query": {
                "match": {
                    "semantic_field": {
                        "query": query_text,
                    }
                }
            },
            "size": size,
        }

        response = es_client.search(index=index_name, body=query)
        hits = response["hits"]["hits"]

        return hits
    except Exception as e:
        print(f"Semantic search error: {str(e)}")
        return []<p>Wir benötigen außerdem eine Funktion, die den Endpoint aufruft. In diesem Fall rufen wir den Endpoint mit dem <strong><code>chat_completion</code></strong>Aufgabentyp auf, um Streaming-Antworten zu erhalten:</p>def stream_chat_completion(messages: list, inference_id: str = INFERENCE_ENDPOINT_ID):
    url = f"{ELASTICSEARCH_URL}/_inference/chat_completion/{inference_id}/_stream"
    payload = {"messages": messages}
    headers = {
        "Authorization": f"ApiKey {ELASTICSEARCH_API_KEY}",
        "Content-Type": "application/json",
    }

    try:
        response = requests.post(url, json=payload, headers=headers, stream=True)
        response.raise_for_status()

        for line in response.iter_lines(decode_unicode=True):
            if line:
                line = line.strip()

                if line.startswith("event:"):
                    continue

                if line.startswith("data: "):
                    data_content = line[6:]

                    if not data_content.strip() or data_content.strip() == "[DONE]":
                        continue

                    try:
                        chunk_data = json.loads(data_content)

                        if "choices" in chunk_data and len(chunk_data["choices"]) &gt; 0:
                            choice = chunk_data["choices"][0]
                            if "delta" in choice and "content" in choice["delta"]:
                                content = choice["delta"]["content"]
                                if content:
                                    yield content

                    except json.JSONDecodeError as json_err:
                        print(f"\nJSON decode error: {json_err}")
                        print(f"Problematic data: {data_content}")
                        continue

    except requests.exceptions.RequestException as e:
        yield f"Error: {str(e)}"<p>Nun können wir eine Funktion schreiben, die die semantische Suchfunktion, den <code>chat_completions</code> Inferenz-Endpoint und den Empfehlungs-Endoint aufruft, um die Daten zu generieren, die in den Karten angezeigt werden:</p>def recommend_articles(search_query, index_name=INDEX_NAME, max_articles=5):
    print(f"\n{'='*80}")
    print(f"🔍 Search Query: {search_query}")
    print(f"{'='*80}\n")

    articles = perform_semantic_search(search_query, index_name, size=max_articles)

    if not articles:
        print("❌ No relevant articles found.")
        return None, None

    print(f"✅ Found {len(articles)} relevant articles\n")

    # Build context with found articles
    context = "Available blog articles:\n\n"
    for i, article in enumerate(articles, 1):
        source = article.get("_source", article)
        context += f"Article {i}:\n"
        context += f"- Title: {source.get('title', 'N/A')}\n"
        context += f"- Author: {source.get('author', 'N/A')}\n"
        context += f"- Category: {source.get('category', 'N/A')}\n"
        context += f"- Date: {source.get('date', 'N/A')}\n"
        context += f"- Content: {source.get('content', 'N/A')}\n\n"

    system_prompt = """You are an expert content curator that recommends blog articles.

    Write recommendations in a conversational style starting with phrases like:
    - "If you're interested in [topic], this article..."
    - "This post complements your search with..."
    - "For those looking into [topic], this article provides..."


    FORMAT REQUIREMENTS:
    - Return ONLY a JSON array
    - Each element must have EXACTLY these three fields: "article_number", "title", "recommendation"
    - If the original title is in spanish, use the "translated_title" subfield in the "title" field

    Keep each recommendation concise (2-3 sentences max) and focused on VALUE to the reader.

    EXAMPLE OF CORRECT FORMAT:
    [
        {"article_number": 1, "title": "Article title in english", "recommendation": "If you are interested in [topic], this article provides..."},
        {"article_number": 2, "title": "Article title in english", "recommendation": " for those looking into [topic], this article provides..."}
    ]

    Return ONLY the JSON array following this exact structure."""

    user_prompt = f"""Search query: "{search_query}"

    Generate recommendations for the following articles: {context}
    """

    messages = [
        {"role": "system", "content": "/no_think"},
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": user_prompt},
    ]

    # LLM generation
    print(f"{'='*80}")
    print("🤖 Generating personalized recommendations...\n")

    full_response = ""

    for chunk in stream_chat_completion(messages):
        print(chunk, end="", flush=True)
        full_response += chunk

    return context, articles, full_response<p>Abschließend müssen wir die Informationen extrahieren und formatieren, um sie zu drucken:</p>def display_recommendation_cards(articles, recommendations_text):
    print("\n" + "=" * 100)
    print("📇 RECOMMENDED ARTICLES".center(100))
    print("=" * 100 + "\n")

    # Parse JSON recommendations - clean tags and extract JSON
    recommendations_list = []
    try:

        # Clean up &lt;think&gt; tags
        cleaned_text = re.sub(
            r"&lt;think&gt;.*?&lt;/think&gt;", "", recommendations_text, flags=re.DOTALL
        )
        # Remove markdown code blocks ( ... ``` or ``` ... ```)
        cleaned_text = re.sub(r"```(?:json)?", "", cleaned_text)
        cleaned_text = cleaned_text.strip()

        parsed = json.loads(cleaned_text)

        # Extract recommendations from list format
        for item in parsed:
            article_number = item.get("article_number")
            title = item.get("title", "")
            rec_text = item.get("recommendation", "")

            if article_number and rec_text:
                recommendations_list.append(
                    {
                        "article_number": article_number,
                        "title": title,
                        "recommendation": rec_text,
                    }
                )
    except json.JSONDecodeError as e:
        print(f"⚠️  Could not parse recommendations as JSON: {e}")
        return

    for i, article in enumerate(articles, 1):
        source = article.get("_source", article)

        # Card border
        print("┌" + "─" * 98 + "┐")

        # Find recommendation and title for this article number
        recommendation = None
        title = None
        for rec in recommendations_list:
            if rec.get("article_number") == i:
                recommendation = rec.get("recommendation")
                title = rec.get("title")
                break

        # Print title
        title_lines = textwrap.wrap(f"📌 {title}", width=94)
        for line in title_lines:
            print(f"│  {line}".ljust(99) + "│")

        # Card border
        print("├" + "─" * 98 + "┤")

        # Print recommendation
        if recommendation:
            recommendation_lines = textwrap.wrap(recommendation, width=94)
            for line in recommendation_lines:
                print(f"│  {line}".ljust(99) + "│")

        # Card bottom
        print("└" + "─" * 98 + "┘")<p>Wir führen einen Test durch, indem wir eine Frage zu den Sicherheitsblogbeiträgen stellen:</p>search_query = "Security and vulnerabilities"

context, articles, recommendations = recommend_articles(search_query)

print("\nElasticsearch context:\n", context)

# Display visual cards
display_recommendation_cards(articles, recommendations)<p>Hier sehen wir die vom Workflow in der Konsole generierten Karten:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4aa221a08a51aeb3/6a170d7460084be1413c45d6/730d35212594bb3db30447c3ea7e2a92857287b7-1999x1515.png" alt="Abschnitt mit dem Titel „Recommended Articles“ zeigt fünf zusammengefasste Artikel an, darunter Themen zu einer Schwachstelle im Authentifizierungssystem, Migrationsrisiken, Leistungs- und Authentifizierungsverbesserungen der REST API v2, Änderungen im Benachrichtigungssystem und eine vollständige Anleitung zur neuen API." /><p>Die vollständigen Ergebnisse, einschließlich aller Treffer und der LLM-Reaktion, können Sie in <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/elasticsearch-inference-api-and-hugging-face/results.md">dieser Datei</a> sehen.</p><p>Wir bitten um Artikel zum Thema: „Sicherheit und Schwachstellen“. Diese Frage wird als Suchabfrage gegen die in Elasticsearch gespeicherten Dokumente verwendet. Die abgerufenen Ergebnisse werden dann an das Modell weitergegeben, das basierend auf ihrem Inhalt Empfehlungen generiert. Wie wir sehen können, hat das Modell gute Arbeit geleistet und einen ansprechenden kurzen Text erstellt, der den Leser zum Anklicken motivieren kann.</p><h2>Fazit</h2><p>Dieses Beispiel zeigt, wie Elasticsearch und Hugging Face kombiniert werden können, um ein schnelles und effizientes zentrales System für KI-Anwendungen zu schaffen. Dieser Ansatz reduziert den manuellen Aufwand und bietet dank des umfangreichen Modellkatalogs von Hugging Face mehr Flexibilität. Insbesondere die Verwendung von SmolLM3-3B zeigt, wie kompakte, mehrsprachige Modelle in Kombination mit semantischer Suche weiterhin sinnvolles Schlussfolgern und Content-Generierung liefern können. Zusammen bieten diese Tools eine skalierbare und effektive Grundlage für die Entwicklung intelligenter Inhaltsanalysen und mehrsprachiger Anwendungen.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/hugging-face-elasticsearch-inference-api</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/hugging-face-elasticsearch-inference-api</guid>
    <category><![CDATA[Agentische KI]]></category>
    <category><![CDATA[Integrationen]]></category>
    <dc:creator><![CDATA[Jeffrey Rengifo]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5f961af4cb26ec97/6a170d767d8d6790c770e790/1417d6ff033712206c9bd4bcc22074ee3437ce96-1999x1125.png" length="0" type="image/png"/>
    <pubDate>Mon, 23 Mar 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Die Gemini CLI-Erweiterung für Elasticsearch mit Tools und Fähigkeiten]]></title>
    <description><![CDATA[Wir stellen die Erweiterung von Elastic für Googles Gemini CLI vor, mit der Elasticsearch-Daten in Entwickler- und agentischen Workflows gesucht, abgerufen und analysiert werden können.
]]></description>
    <content:encoded><![CDATA[<p>Wir freuen uns, die Veröffentlichung unserer Elastic-Erweiterung für Googles Gemini CLI ankündigen zu können, mit der Sie die volle Leistungsfähigkeit von <a href="https://www.elastic.co/elasticsearch">Elasticsearch</a> und <a href="https://www.elastic.co/elasticsearch/agent-builder">Elastic Agent Builder</a> direkt in Ihren KI-Entwicklungsworkflow einbringen können. Diese Erweiterung bietet auch mehrere kürzlich entwickelte Agentenfähigkeiten für die Interaktion mit Elasticsearch.</p><p>Die Erweiterung ist <a href="https://github.com/elastic/gemini-cli-elasticsearch">hier</a> als Open-Source-Projekt verfügbar.</p><h2>Was ist Gemini CLI, und wie installieren Sie sie?</h2><p><a href="https://geminicli.com/">Gemini CLI</a> ist ein Open-Source-KI-Agent, der Googles Gemini-Modelle direkt in die Befehlszeile bringt. Er ermöglicht Entwicklern, über das Terminal mit KI zu interagieren, um Aufgaben wie das Generieren von Code, das Bearbeiten von Dateien, das Ausführen von Shell-Befehlen und das Abrufen von Informationen aus dem Web durchzuführen.</p><p>Im Gegensatz zu typischen Chat-Schnittstellen integriert sich die Gemini CLI in Ihre lokale Entwicklungsumgebung. Das bedeutet, dass sie den Projektkontext versteht, Dateien ändert, Builds oder Tests ausführt und Workflows direkt im Terminal automatisiert. Dies macht sie besonders nützlich für Entwickler, Site Reliability Engineers (SREs) und Engineers, die KI-gestütztes Codieren und Automatisierung wünschen, ohne ihren Befehlszeilen-Workflow zu verlassen.</p><p>Gemini CLI kann mit mehreren Paketmanagern installiert werden. Die gängigste Methode ist die Installation über npm:</p>npm install -g @google/gemini-cli<p>Wenn Sie sich über alternative Installationsmöglichkeiten informieren möchten, lesen Sie die <a href="https://geminicli.com/docs/get-started/installation/">offizielle Installationsseite</a>.</p><p>Starten Sie die CLI nach der Installation durch Ausführen des folgenden Befehls:</p>gemini<p>Sie sehen einen Bildschirm, wie in Abbildung 1 dargestellt:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4ff43abe550941b4/6a17072ba29299fc2ad00fa4/6dfcec4a77b3dc83bf0d974417bf2e211abb1f4f-876x468.png" alt="Ein Screenshot der Gemini CLI." /><h2>Elasticsearch konfigurieren</h2><p>Wir benötigen eine laufende Elasticsearch-Instanz. Wenn Sie den Model Context Protocol (MCP)-Server verwenden möchten, benötigen Sie zudem Kibana 9.3+. Für die Nutzung der unten beschriebenen Elasticsearch Query Language (ES|QL)-Fähigkeit (<code>esql</code>) ist Kibana nicht erforderlich.</p><p>Sie können eine kostenlose Testversion auf <a href="https://www.elastic.co/cloud">Elastic Cloud</a> aktivieren oder es lokal mit dem <a href="https://github.com/elastic/start-local"><code>start-local</code></a>-Skript installieren:</p>curl -fsSL https://elastic.co/start-local | sh<p>Dadurch werden Elasticsearch und Kibana auf Ihrem Computer installiert und ein API-Schlüssel generiert, den Sie für die Konfiguration von Gemini CLI verwenden können.</p><p>Der API-Schlüssel wird als Ausgabe des vorherigen Befehls angezeigt und in einer <strong>.env</strong>-Datei im Ordner <strong><code>elastic-start-local</code></strong> gespeichert.</p><p>Wenn Sie Elasticsearch lokal (zum Beispiel <code>start-local</code>), und Elastic Agent Builder mit MCP verwenden möchten, müssen Sie auch ein Large Language Model (LLM) verbinden. Lesen Sie <a href="https://www.elastic.co/docs/explore-analyze/ai-features/llm-guides/llm-connectors">diese Dokumentationsseite</a>, um sich über die verschiedenen Optionen zu informieren.</p><p>Wenn Sie Elastic Cloud (oder serverless) verwenden, verfügen Sie bereits über eine vorgefertigte LLM-Verbindung.</p><h2>Installieren Sie die Elasticsearch-Erweiterung</h2><p>Sie können die Elasticsearch-Erweiterung für Gemini CLI mit folgendem Befehl installieren:</p>gemini extensions install https://github.com/elastic/gemini-cli-elasticsearch<p>Sie können überprüfen, ob die Erweiterungen erfolgreich installiert wurden, indem Sie Gemini öffnen und den folgenden Befehl ausführen:</p>/extensions list<p>Die Elasticsearch-Erweiterung sollte verfügbar sein.</p><p>Wenn Sie die MCP-Integration verwenden möchten, müssen Sie die Elasticsearch-Version 9.3 oder höher installiert haben. Sie benötigen die URL Ihres MCP-Servers aus <a href="https://www.elastic.co/kibana">Kibana</a>:</p><ul><li><p>Sie erhalten Ihre MCP-Server-URL unter Agenten &gt; Alle Tools anzeigen &gt; MCP verwalten &gt; MCP-Server-URL kopieren.</p></li><li><p>Die URL wird so aussehen: https://your-kibana-instance/api/agent_builder/mcp</p></li></ul><p>Sie benötigen die URL des Elasticsearch-Endpoints. Dies wird üblicherweise oben auf der Kibana Elasticsearch-Seite angezeigt. Wenn Sie Elasticsearch mit <code>start-local</code> ausführen, ist der Endpoint bereits im Schlüssel <code>ES_LOCAL_URL</code> in der .env-Datei <code>start-local</code> hinterlegt.</p><p>Sie benötigen auch einen API-Schlüssel. Wenn Sie Elasticsearch mit <code>start-local</code> ausführen, ist der <code>ES_LOCAL_API_KEY</code> in der .env-Datei <code>start-local</code> hinterlegt. Andernfalls können Sie einen API-Schlüssel über die Kibana-Schnittstelle erstellen, wie <a href="https://www.elastic.co/docs/deploy-manage/api-keys/elasticsearch-api-keys">hier</a> beschrieben:</p><ul><li><p>In Kibana: Stack Management &gt; Sicherheit &gt; API-Schlüssel &gt; API-Schlüssel erstellen.</p></li><li><p>Wir empfehlen, nur die Leserechte für den API-Schlüssel festzulegen und so die <a href="https://www.elastic.co/docs/explore-analyze/ai-features/agent-builder/permissions#grant-access-with-roles">hier</a> beschriebene Berechtigung <code>feature_agentBuilder.read</code> zu aktivieren.</p></li><li><p>Kopieren Sie den codierten API-Schlüsselwert.</p></li></ul><p>Stellen Sie die erforderlichen Umgebungsvariablen in Ihrer Shell ein:</p>export ELASTIC_URL="your-elasticsearch-url"
export ELASTIC_MCP_URL="your-elasticsearch-mcp-url"
export ELASTIC_API_KEY="your-encoded-api-key"<h2>Installieren Sie den Beispieldatensatz</h2><p>Sie können den Datensatz für <strong>E-Commerce-Bestellungen </strong>, der von Kibana verfügbar ist, installieren. Sie enthält einen einzigen Index mit dem Namen <strong><code>kibana_sample_data_ecommerce</code></strong>, der Informationen für 4.675 Bestellungen von einer E-Commerce-Website enthält. Für jede Bestellung haben wir folgende Informationen:</p><ul><li><p>Kundeninformationen (Name, Ausweis, Geburtsdatum, E-Mail-Adresse und mehr)</p></li><li><p>Bestelldatum</p></li><li><p>Bestell-ID</p></li><li><p>Produkte (Liste aller Produkte mit Preis, Menge, ID, Kategorie, Rabatt und weiteren Details)</p></li><li><p>SKU</p></li><li><p>Gesamtpreis (ohne Steuern, mit Steuern)</p></li><li><p>Gesamtmenge</p></li><li><p>Geoinformationen (Stadt, Land, Kontinent, Ort, Region)</p></li></ul><p>Um die Beispieldaten zu installieren, öffnen Sie die Seite <strong>Integrationen</strong> in Kibana (suchen Sie in der Suchleiste oben nach „Integration") und installieren Sie die <strong>Beispieldaten</strong>. Weitere Einzelheiten finden Sie in der Dokumentation <a href="https://www.elastic.co/docs/explore-analyze/#gs-get-data-into-kibana">hier</a>.</p><p>Ziel dieses Artikels ist es, zu zeigen, wie einfach es ist, die Gemini CLI so zu konfigurieren, dass sie mit Elasticsearch verbunden ist und mit dem Index <strong><code>kibana_sample_data_ecommerce</code></strong> interagiert.</p><h2>Verwendung des Elasticsearch MCP</h2><p>Sie können die Verbindung mit folgendem Befehl in Gemini überprüfen:</p>/mcp list<p>Sie sollten sehen, dass <strong><code>elastic-agent-builder</code></strong> aktiviert ist, wie in Abbildung 2 dargestellt:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt52b85e7255360f3b/6a17072da929cf33d3ae08f5/1508423bc1d1bc3c04a1cb01e2d59495a3516ed1-1465x844.png" alt="Der `elastic-agent-builder` MCP-Server mit der Liste der Tools." /><p>Elasticsearch bietet eine Reihe von Standardtools. Sehen Sie sich die Beschreibung <a href="https://www.elastic.co/docs/explore-analyze/ai-features/agent-builder/tools/builtin-tools-reference">hier</a> an.</p><p>Mithilfe dieser Tools können Sie mit Elasticsearch interagieren und Fragen stellen wie:</p><ul><li><p><code>Give me the list of all the indexes available in Elasticsearch.</code></p></li><li><p><code>How many customers are based in the USA in the kibana_sample_data_ecommerce index of Elasticsearch?</code></p></li></ul><p>Je nach Frage wird Gemini eines oder mehrere der verfügbaren Tools verwenden, um sie zu beantworten.</p><h2>Die /elastic-Befehle</h2><p>In der Elasticsearch-Erweiterung für Gemini CLI haben wir auch<strong><code>/elastic</code></strong>-Befehlehinzugefügt.</p><p>Wenn Sie den Befehl <strong><code>/help</code></strong> ausführen, werden Ihnen alle verfügbaren <code>/elastic</code>-Optionen angezeigt (Abbildung 3):</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt741c7451ecab10d2/6a17072ea6c2b9ccd6e79643/5b2a0727ce7a04354878dd048253d3f4d062324b-1983x230.png" alt="Die verfügbaren „/elastic“-Befehle." /><p>Diese Befehle können nützlich sein, wenn Sie ein bestimmtes Tool des <code>elastic-agent-builder</code>-MCP-Servers direkt ausführen möchten. Beispielsweise können Sie mit dem folgenden Befehl das Mapping von <code>kibana_sample_data_ecommerce</code> abrufen:</p>/elastic:get-mapping kibana_sample_data_ecommerce<p>Diese Befehle sind im Wesentlichen Abkürzungen für das Ausführen spezifischer Tools, anstatt sich auf das Gemini-Modell zu verlassen, um zu bestimmen, welches Tool aufgerufen werden sollte.</p><h2>Verwendung der Elasticsearch-Fähigkeiten</h2><p>Diese Erweiterung beinhaltet außerdem eine <a href="https://github.com/elastic/gemini-cli-elasticsearch/tree/main/skills/esql">agentische Fähigkeit für ES|QL</a>, die in Elasticsearch verfügbare <a href="https://www.elastic.co/docs/explore-analyze/discover/try-esql">Elasticsearch Query Language</a>. <a href="https://agentskills.io/home">Agentische Fähigkeiten</a> stellen ein offenes Format dar, das KI-Coding-Agenten wie Gemini CLI individuelle Anweisungen für bestimmte Aufgaben gibt. Sie verwenden ein Konzept namens <em>Progressive Disclosure</em> (progressive Offenlegung), was bedeutet, dass der anfänglichen Systemaufforderung nur eine kurze Beschreibung der Fähigkeit hinzugefügt wird. Wenn Sie den Agenten bitten, eine Aufgabe auszuführen, wie etwa eine Abfrage an Elasticsearch, passt er die Anfrage an die relevante Fähigkeit an und lädt dynamisch die detaillierten Anweisungen. Dies ist eine effiziente Methode, um Token-Budgets zu verwalten und der KI genau den Kontext bereitzustellen, den sie benötigt.</p><p>Die <strong><code>esql</code></strong>-<strong>Fähigkeit</strong> ist so konzipiert, dass Gemini CLI ES|QL-Abfragen direkt in Ihrem Cluster schreiben und ausführen kann. ES|QL ist eine leistungsstarke Abfragesprache, die die Datenexploration, die Log-Analyse und die Aggregationen sehr intuitiv macht. Wenn diese Fähigkeit aktiviert ist, müssen Sie nicht nach der ES|QL-Syntax suchen; Sie können der Gemini CLI einfach Fragen zu Ihren Daten in natürlicher Sprache stellen, und der Agent kümmert sich um den Rest.</p><p>Die Ausführung erfolgt mit einfachen <a href="https://curl.se/">curl</a>-Befehlen, die in einem Terminal ausgeführt werden. Dies ist möglich, da Elasticsearch eine umfangreiche Sammlung von REST APIs bereitstellt, die sich problemlos in jede beliebige Architektur integrieren lassen.</p><p><strong>Was die </strong><strong><code>esql</code></strong><strong> Fähigkeit bietet:</strong></p><ul><li><p><strong>Erkennung von Indizes und Schemata:</strong> Der Agent kann die integrierten Tools der Fähigkeit nutzen, um verfügbare Indizes aufzulisten und Feld-Mappings abzurufen. Bevor der Agent beispielsweise eine Abfrage für die E-Commerce-Datensätze schreibt, kann er eine Schema-Prüfung für <strong><code>kibana_sample_data_ecommerce</code></strong> ausführen, um die verfügbaren Felder wie <strong><code>taxful_total_price</code></strong> oder <strong><code>category</code></strong> zu ermitteln.</p></li><li><p><strong>Nahtlose Übersetzung natürlicher Sprache:</strong> Diese Fähigkeit bietet dem Agenten mehr als nur ein einfaches Nachschlagewerk; sie liefert eine konkrete Anleitung zur Interpretation der Nutzerabsicht. Wenn Sie Anfragen in natürlicher Sprache eingeben, wie „Zeige durchschnittliche Reaktionszeit gruppiert nach Service“, nutzt der Agent die in der Fähigkeit integrierte Mustererkennung, um Ihre Worte sofort in die richtigen ES|QL-Aggregationen, Filter und Befehle umzuwandeln.</p></li><li><p><strong>Selbstkorrektur:</strong> Wenn eine Abfrage fehlschlägt (zum Beispiel wegen eines Typfehlers oder eines Syntaxfehlers), gibt die Fähigkeit die generierte Abfrage zusammen mit der genauen Elasticsearch-Fehlermeldung zurück, sodass der Agent die Abfrage sofort beheben und erneut ausführen kann, ohne dass Sie eingreifen müssen.</p></li></ul><p>Da die <code>esql</code>-Fähigkeit auch als Tool auf dem <code>elastic-agent-builder</code>-MCP-Server verfügbar ist, müssen wir diesen Server vorübergehend deaktivieren. Sie können sie mit dem folgendem Befehl deaktivieren:</p>/mcp disable elastic-agent-builder<p>Dann können Sie einfach einen Befehl wie diesen in Ihre Gemini CLI eingeben:</p>Find the top 5 product categories by total sales revenue in the kibana_sample_data_ecommerce index<p>Der Agent wird:</p><ul><li><p>Die Notwendigkeit der <code>esql</code>-Fähigkeit erkennen</p></li><li><p>Überprüfen Sie das Schema von <strong><code>kibana_sample_data_ecommerce</code></strong>.</p></li><li><p>Eine ES|QL-Abfrage erstellen wie: <code>FROM kibana_sample_data_ecommerce | STATS total_revenue = SUM(taxful_total_price) BY category.keyword | SORT total_revenue DESC | LIMIT 5</code></p></li><li><p>Die Abfrage über die Elasticsearch-API ausführen</p></li><li><p>Das Ergebnis Ihnen direkt im Terminal anzeigen</p></li></ul><p>Hier haben wir ein Beispiel für die Antwort von Gemini auf die vorherige Eingabe aufgeführt:</p>───────────────────────────────────────────────────────────
&gt; Find the top 5 product categories by total sales revenue in the kibana_sample_data_ecommerce index   ───────────────────────────────────────────────────────────
✓  Activate Skill "esql": Interact with Elasticsearch using ES|QL and curl. Use when querying, managing indices,  …
Skill esql activated. Resources loaded from /home/user/.gemini/extensions/elasticsearch/skills/esql: 
Showing up to 200 items (files + folders).                                                                     /home/user/.gemini/extensions/elasticsearch/skills/esql/                                                            ├───SKILL.md 
└───references/
├───esql-reference.md 
├───generation-tips.md 
└───query-patterns.md

✦ I will start by exploring the mapping of the kibana_sample_data_ecommerce index to identify the fields for product category and sales revenue. Then, I will construct and execute an ES|QL query to determine the top 5 product categories by total sales revenue.

✓  Shell curl -s "${ELASTIC_URL%/}/kibana_sample_data_ecommerce/_mapping" -H "Authorization: ApiKey $(printenv ELAS…                                                                                                                       {  
   "kibana_sample_data_ecommerce": { 
     "mappings": { 
       "properties": {
         "category": { 
           "type": "text", 
           "fields": {
             "keyword": {
               "type": "keyword"
             }
           }
         }, 
         "currency": {
           "type": "keyword"
         }, 

✦ Okay, I have the mapping. The category is products.category.keyword and sales revenue is taxful_total_price. I'll now execute the ES|QL query to get the top 5 categories by revenue.

✓  Shell curl -s -X POST "${ELASTIC_URL%/}/_query" \  -H "Authorization: ApiKey $(printenv ELASTIC_API_KEY)" \  -H …
{ 
   "took": 62,
   "is_partial": false, 
   "completion_time_in_millis": 1772805644164,
   "documents_found": 4675,
   "values_loaded": 12084, 
   "start_time_in_millis": 1772805644102, 
   "expiration_time_in_millis": 1773237644087,  
   "columns": [ 
     { 
       "name": "total_revenue",    
       "type": "double"  
     }, 
     {   
       "name": "products.category.keyword",

✦ The query for top 5 product categories by revenue was successful. I'll format the returned JSON values into a   user-friendly list.

 ✓  Shell 
                             
 Top 5 product categories by total sales revenue: 
 1. Men's Clothing: 149393.91
 2. Women's Clothing: 135099.91
 3. Women's Shoes: 105479.17
 4. Men's Shoes: 91797.92
 5. Women's Accessories: 60830.31 

✦ I've found the answer; now I'll format it for clarity.

 ✓  Shell 

 Here are the top 5 product categories by total sales revenue:                                                        
                                                                      
 | Rank | Category              | Total Revenue | 
 |------|-----------------------|---------------| 
 | 1    | Men's Clothing        | 149,393.91    |
 | 2    | Women's Clothing      | 135,099.91    |
 | 3    | Women's Shoes         | 105,479.17    |
 | 4    | Men's Shoes           | 91,797.92     | 
 | 5    | Women's Accessories   | 60,830.31     | 

✦ I've formatted and presented the answer. I'm finished.
 ───────────────────────────────────────────────────────────<p>Es ist interessant festzustellen, wie das Gemini-Modell die endgültige Antwort generiert, indem es alle Schritte zeigt, die es dabei durchläuft. Hier können Sie deutlich den Einfluss der Fähigkeit auf den Denkprozess des Modells erkennen. Wenn das Modell zum ersten Mal erkennt, dass es eine Fähigkeit verwenden oder einen Shell-Befehl ausführen muss, erfragt es die Genehmigung mithilfe des Human-in-the-Loop-Ansatzes.</p><p>Durch die Übernahme der aufwendigen Aufgaben der Schemaerkennung, Abfragegenerierung und -ausführung ermöglicht Ihnen die <code>esql</code>-Fähigkeit, sich voll und ganz auf die Antworten zu konzentrieren, anstatt auf die Mechanismen ihrer Ermittlung. Sie erhalten die Daten, die Sie benötigen, richtig formatiert und direkt in Ihrem Terminal, ohne jemals eine einzige Zeile Syntax zu schreiben oder zu einer anderen Anwendung zu wechseln.</p><h2>Fazit</h2><p>In diesem Artikel haben wir die kürzlich veröffentlichte Elasticsearch-Erweiterung für die Gemini CLI vorgestellt. Mit dieser Erweiterung können Sie über Gemini und den von Elastic Agent Builder bereitgestellten Elasticsearch-MCP-Server, der ab Version 9.3.0 verfügbar ist, sowie über den Befehl <code>/elastic</code> mit Ihrer Elasticsearch-Instanz interagieren.</p><p>Darüber hinaus enthält die Erweiterung auch eine <code>esql</code>-Fähigkeit, die die Anfrage eines Nutzers von der natürlichen Sprache in eine ES|QL-Abfrage umwandelt. Diese Fähigkeit kann besonders nützlich sein, wenn der MCP-Server nicht genutzt werden kann, da die zugrundeliegende Kommunikation durch einfache Curl-Befehle in einem Terminal gesteuert wird. Elasticsearch bietet eine umfangreiche Auswahl an REST APIs, die leicht in jedes Projekt integriert werden können. Dies ist besonders nützlich bei der Entwicklung von agentischen KI-Anwendungen.</p><p>Weitere Informationen zu unserer Gemini CLI-Erweiterung finden Sie <a href="https://github.com/elastic/gemini-cli-elasticsearch">hier</a> im Projekt-Repository.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/gemini-cli-extension-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/gemini-cli-extension-elasticsearch</guid>
    <category><![CDATA[Integrationen]]></category>
    <category><![CDATA[Agentische KI]]></category>
    <dc:creator><![CDATA[Walter Rafelsberger,Enrico Zimuel]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4ff43abe550941b4/6a17072ba29299fc2ad00fa4/6dfcec4a77b3dc83bf0d974417bf2e211abb1f4f-876x468.png" length="0" type="image/png"/>
    <pubDate>Tue, 17 Mar 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Eine Einführung in Jina-Modelle, ihre Funktionalität und ihre Einsatzmöglichkeiten in Elasticsearch]]></title>
    <description><![CDATA[Entdecken Sie multimodale Einbettungen von Jina, Reranker v3 und semantische Einbettungsmodelle und erfahren Sie, wie Sie diese nativ in Elasticsearch verwenden können.]]></description>
    <content:encoded><![CDATA[<p>Jina by Elastic bietet Suchgrundlagenmodelle für Anwendungen und die Automatisierung von Geschäftsprozessen. Diese Modelle bieten Kernfunktionen für den Einsatz von KI in Elasticsearch-Anwendungen und innovativen KI-Projekten.</p><p>Jina-Modelle lassen sich in drei Hauptkategorien einteilen, die zur Unterstützung der Informationsverarbeitung, Organisation und den Informationsabruf entwickelt wurden:</p><ul><li><p>Semantische Einbettungsmodelle</p></li><li><p>Reranking-Modelle</p></li><li><p>Kleine generative Sprachmodelle</p></li></ul><h2>Semantische Einbettungsmodelle</h2><p>Die Idee hinter semantischen Einbettungen ist, dass ein KI-Modell lernen kann, Aspekte der Bedeutung seiner Eingaben in Bezug auf die Geometrie hochdimensionaler Räume darzustellen.</p><p>Sie können sich eine semantische Einbettung als einen Punkt (technisch gesehen einen <em>Vektor</em>) in einem hochdimensionalen Raum vorstellen. Ein Einbettungsmodell ist ein neuronales Netz, das digitale Daten als Eingabe aufnimmt (potenziell alles, aber meist Text oder Bild) und die Position eines entsprechenden hochdimensionalen Punktes als numerische Koordinaten ausgibt. Wenn das Modell seine Aufgabe gut erfüllt, ist der Abstand zwischen zwei semantischen Einbettungen proportional dazu, wie sehr ihre entsprechenden digitalen Objekte dieselbe Bedeutung haben.</p><p>Um zu verstehen, wie wichtig das für Suchanwendungen ist, stellen Sie sich eine Einbettung für das Wort „dog“ und eine für das Wort „cat“ als Punkte im Raum vor:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbad74e5d8292a60e/6a17db73abe0f2114edfe8d2/802cf9bbcb82180d3fc91009f9f62027eee8f031-615x615.png" alt="" /><p>Ein gutes Einbettungsmodell sollte eine Einbettung für das Wort „feline“ generieren, die viel näher an „cat“ als an „dog“ liegt, und „canine“ sollte eine Einbettung haben, die viel näher an „dog“ als an „cat“ liegt, weil diese Wörter fast dasselbe bedeuten:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdb2b25691801a881/6a17db747b54f946d28b37a5/bce49daf9a31b8fb7ce1c6ef7ae4e8117a4e8b33-615x615.png" alt="" /><p>Wenn ein Modell mehrsprachig ist, würden wir dasselbe für Übersetzungen von „cat“ und „dog“ erwarten:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt976ba40be7776449/6a17db75be6086c2bd0045f2/ce4d030385324526cbd7539140e0e634d939371c-615x615.png" alt="" /><p>Einbettungsmodelle übersetzen Ähnlichkeiten oder Unterschiede in der Bedeutung zwischen Dingen in räumliche Beziehungen zwischen Einbettungen. Die Bilder oben haben nur zwei Dimensionen, sodass Sie sie auf einem Bildschirm sehen können, aber das Einbetten von Modellen erzeugt Vektoren mit Dutzenden bis Tausenden von Dimensionen. Dies ermöglicht es ihnen, die Feinheiten der Bedeutung ganzer Texte zu kodieren, indem sie einen Punkt in einem Raum mit Hunderten oder Tausenden von Dimensionen für Dokumente mit Tausenden von Wörtern oder mehr zuweisen.</p><h2>Multimodale Einbettungen</h2><p>Multimodale Modelle erweitern das Konzept der semantischen Einbettung auf andere Dinge als Texte, insbesondere auf Bilder. Wir würden erwarten, dass eine Einbettung für ein Bild nahe an einer Einbettung einer getreuen Beschreibung des Bildes liegt:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt66dc8895485734ec/6a17db77b1e11318d279f155/1ac6aef5b1423e5fe4853e8a547a74e66b0885c2-615x615.png" alt="" /><p>Semantische Einbettungen haben viele Einsatzmöglichkeiten. Unter anderem können Sie sie verwenden, um effiziente Klassifikatoren zu erstellen, Clustering durchzuführen und eine Vielzahl von Aufgaben zu erledigen, wie z. B. die Deduplizierung von Daten und die Untersuchung der Datendiversität. Beides ist wichtig für Big-Data-Anwendungen, bei denen mit zu vielen Daten gearbeitet wird, um sie manuell zu verwalten.</p><p>Die größte direkte Anwendung von Einbettungen ist der Informationsabruf. Elasticsearch kann Abrufobjekte mit Einbettungen als Schlüssel speichern. Abfragen werden in Einbettungsvektoren umgewandelt, und eine Suche gibt die gespeicherten Objekte zurück, deren Schlüssel den Abfrage-Einbettungen am nächsten sind.</p><p>Bei der traditionellen <em>vektorbasierten Suche</em> (manchmal auch als <em>Sparse Vector Retrieval</em> bezeichnet) werden Vektoren verwendet, die auf Wörtern oder Metadaten in Dokumenten und Anfragen basieren. <em>Die einbettungsbasierte Suche</em> (auch bekannt als <em>Dense Vector Retrieval</em>) verwendet hingegen KI-bewertete Bedeutungen anstelle von Wörtern. Dadurch sind sie im Allgemeinen wesentlich flexibler und genauer als herkömmliche Suchmethoden.</p><h2>Matryoshka-Darstellungslernen</h2><p>Die Anzahl der Dimensionen, die eine Einbettung hat, und die Präzision der darin enthaltenen Zahlen haben erhebliche Auswirkungen auf die Leistung. Äußerst hochdimensionale Räume und extrem hochpräzise Zahlen können sehr detaillierte und komplexe Informationen darstellen, erfordern aber größere KI-Modelle, deren Training und Nutzung teurer sind. Die erzeugten Vektoren benötigen mehr Speicherplatz, und es braucht mehr Rechenzyklen, um die Abstände zwischen ihnen zu berechnen. Bei der Verwendung semantischer Einbettungsmodelle müssen wichtige Kompromisse zwischen Präzision und Ressourcenverbrauch eingegangen werden.</p><p>Um die Flexibilität für die Nutzer zu maximieren, werden Jina-Modelle mit einer Technik namens <a href="https://arxiv.org/abs/2205.13147">Matryoshka Representation Learning</a> trainiert. Dies führt dazu, dass die Modelle die wichtigsten semantischen Unterscheidungen in die ersten Dimensionen des Einbettungsvektors vorladen, sodass man die höheren Dimensionen einfach abschneiden und trotzdem eine gute Leistung erzielen kann.</p><p>In der Praxis bedeutet das, dass Nutzer von Jina-Modellen wählen können, wie viele Dimensionen ihre Einbettungen haben sollen. Die Wahl von weniger Dimensionen verringert die Präzision, der Leistungsverlust ist jedoch gering. Bei den meisten Aufgaben sinken die Leistungskennzahlen für Jina-Modelle um 1 bis 2 %, wenn man die Einbettungsgröße um 50 % reduziert, bis hin zu einer Reduzierung um etwa 95 %.</p><h2>Asymmetrischer Informationsabruf</h2><p>Semantische Ähnlichkeit wird normalerweise symmetrisch gemessen. Der Wert, den man beim Vergleich von „cat“ mit „dog“ erhält, ist derselbe wie der Wert, den man beim Vergleich von „dog“ mit „cat“ erhält. Bei der Verwendung von Einbettungen für den Informationsabruf funktionieren diese jedoch besser, wenn man die Symmetrie aufhebt und Anfragen anders kodiert als die zu kodierenden Objekte.</p><p>Das liegt an der Art, wie wir Einbettungsmodelle trainieren. Die Trainingsdaten enthalten Instanzen der gleichen Elemente, wie z. B. Wörter, in vielen verschiedenen Kontexten. Die Modelle lernen die Semantik, indem sie die kontextuellen Ähnlichkeiten und Unterschiede zwischen den Elementen vergleichen.</p><p>So könnten wir beispielsweise feststellen, dass das Wort „animal“ nicht in sehr vielen der gleichen Kontexte wie „cat“ oder „dog“ vorkommt, und daher ist die Einbettung für „animal“ möglicherweise nicht besonders nahe an der von „cat“ oder „dog“:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf219074e18a6290a/6a17db78be6086cf060045f6/9a33163405af6c71ee7f4ba8ebc86af39e295a69-615x615.png" alt="" /><p>Dies macht es unwahrscheinlicher, dass eine Abfrage nach „animal“ Dokumente über Katzen und Hunde zurückgibt – das Gegenteil unseres Ziels. Deshalb kodieren wir „Tier“ anders, wenn es sich um eine Suchanfrage handelt, als wenn es ein Ziel für den Informationsabruf ist:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt33438b4964001467/6a17db79b1e113101c79f159/363992d4f0affba7937c0c8a9f82c9a531fcd3ba-615x615.png" alt="" /><p><em>Asymmetrischer Informationsabruf</em> bedeutet, ein anderes Modell für Abfragen zu verwenden oder ein Einbettungsmodell speziell zu trainieren, um Dinge auf eine bestimmte Weise zu kodieren, wenn sie für den Abruf gespeichert sind, und Abfragen auf eine andere Weise zu kodieren.</p><h2>Multivektor-Einbettungen</h2><p>Einzelne Einbettungen sind gut für die Informationsabfrage, da sie in das grundlegende Framework einer indizierten Datenbank passen: Wir speichern Objekte für die Abfrage mit einem einzelnen Einbettungsvektor als deren Abfrageschlüssel. Wenn Nutzer den Dokumentenspeicher abfragen, werden ihre Abfragen in Einbettungsvektoren übersetzt und die Dokumente, deren Schlüssel der Abfrage-Einbettung am nächsten sind (im hochdimensionalen Einbettungsraum), werden als Kandidatenmatches abgerufen.</p><p>Multivektor-Einbettungen funktionieren etwas anders. Anstatt einen Vektor mit fester Länge zu erzeugen, um eine Abfrage und ein ganzes gespeichertes Objekt darzustellen, erzeugen sie eine Folge von Einbettungen, die kleinere Teile davon repräsentieren. Die einzelnen Teile sind typischerweise Tokens oder Wörter für Texte und Bildkacheln für visuelle Daten. Diese Einbettungen spiegeln die Bedeutung des Teils in seinem Kontext wider.</p><p>Betrachten wir zum Beispiel die folgenden Sätze:</p><ul><li><p>Sie hatte ein Herz aus Gold.</p></li><li><p>Sie hatte einen Herzenswandel.</p></li><li><p>Sie hatte einen Herzinfarkt.</p></li></ul><p>Oberflächlich betrachtet sehen sie sehr ähnlich aus, aber ein Multivektor-Modell würde wahrscheinlich sehr unterschiedliche Einbettungen für jede Instanz von „Herz“ generieren, was darstellt, wie jede im Kontext des gesamten Satzes etwas anderes bedeutet:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5c81f089771e6029/6a17db7b7f6f157601c099ec/a33e60c8d8ee3d312bca8375ca2a8b0a0cd40ba9-615x615.png" alt="" /><p>Der Vergleich zweier Objekte anhand ihrer Multivektor-Einbettungen beinhaltet oft die Messung ihres Chamfer-Abstands: der Vergleich jedes Teils einer Multivektor-Einbettung mit jedem Teil einer anderen und die Summierung der minimalen Abstände zwischen ihnen. Andere Systeme, einschließlich des unten beschriebenen Jina Rerankers, geben sie in ein KI-Modell ein, das speziell für die Bewertung ihrer Ähnlichkeit trainiert wurde. Beide Ansätze haben in der Regel eine höhere Präzision als der Vergleich von Einzeleinbettungen, da Einbettungen mit mehreren Vektoren viel detailliertere Informationen enthalten als solche mit einem Vektor.</p><p>Allerdings eignen sich Multivektor-Einbettungen nicht gut zum Indexieren. Sie werden häufig bei Neubewertungsaufgaben verwendet, wie im nächsten Abschnitt für das Modell <code>jina-colbert-v2</code> beschrieben.</p><h2>Jina-Einbettungsmodelle</h2><h3>Jina-Einbettungen – v4</h3><p><a href="https://jina.ai/news/jina-embeddings-v4-universal-embeddings-for-multimodal-multilingual-retrieval/"><strong>jina-embeddings-v4</strong></a> ist ein 3,8 Milliarden (3,8x10⁹) Parameter umfassendes mehrsprachiges und multimodales Einbettungsmodell, das Bilder und Texte in einer Vielzahl weit verbreiteter Sprachen unterstützt. Es verwendet eine neuartige Architektur, um visuelle Kenntnisse und Sprachkenntnisse zu nutzen, um die Leistung bei beiden Aufgaben zu verbessern, sodass es beim Abrufen von Bildern und insbesondere beim <a href="https://huggingface.co/tasks/visual-document-retrieval">visuellen Abrufen von Dokumenten</a> hervorragende Leistungen erbringt. Das bedeutet, dass es Bilder wie Diagramme, Dias, Karten, Screenshots, Seitenscans und Diagramme verarbeitet – gängige Bildtypen, oft mit wichtigem eingebettetem Text, die außerhalb des Bereichs von Computer-Vision-Modellen fallen, die auf Bildern realer Szenen trainiert sind.</p><p>Wir haben dieses Modell mithilfe kompakter <a href="https://huggingface.co/docs/peft/en/package_reference/lora">Low-Rank Adaptation (LoRA)-Adapter</a> für verschiedene Aufgaben optimiert. Dadurch können wir ein einzelnes Modell trainieren, um sich auf mehrere Aufgaben zu spezialisieren, ohne bei einer davon die Leistung zu beeinträchtigen – mit minimalen zusätzlichen Kosten für Speicher oder Verarbeitung.</p><p>Zu den wichtigsten Funktionen gehören:</p><ul><li><p>Spitzenleistung beim visuellen Dokumentenabruf sowie eine mehrsprachige Text- und Bildverarbeitungsleistung, die deutlich größere Modelle übertrifft.</p></li><li><p>Unterstützung für große Eingabekontextgrößen: 32.768 Tokens entsprechen ungefähr 80 Seiten doppeltzeiligem englischen Text, und 20 Megapixel entsprechen einem Bild von 4.500 x 4.500 Pixeln.</p></li><li><p>Vom Nutzer ausgewählte Einbettungsgrößen, von maximal 2048 Dimensionen bis zu 128 Dimensionen. Wir haben empirisch festgestellt, dass die Leistung unterhalb dieser Schwelle dramatisch abnimmt.</p></li><li><p>Unterstützung für sowohl einzelne Einbettungen als auch Multivektor-Einbettungen. Für Texte besteht die Multivektor-Ausgabe aus einer 128-dimensionalen Einbettung für jedes Eingabetoken. Für Bilder erzeugt es eine 128-dimensionale Einbettung für jede 28x28 Pixel große Kachel, die zur Abdeckung des Bildes benötigt wird.</p></li><li><p>Optimierung für asymmetrischen Datenabruf mittels eines Paares von LoRA-Adaptern, die speziell für diesen Zweck trainiert wurden.</p></li><li><p>Ein LoRA-Adapter, optimiert für die Berechnung semantischer Ähnlichkeit.</p></li><li><p>Spezielle Unterstützung für Programmiersprachen und IT-Frameworks, ebenfalls über einen LoRA-Adapter.</p></li></ul><p>Wir haben <code>jina-embeddings-v4</code> als allgemeines Mehrzweckwerkzeug für eine breite Palette gängiger Such-, Sprachverarbeitungs- und KI-Analyseaufgaben entwickelt. Es handelt sich im Verhältnis zu seinen Fähigkeiten um ein relativ kleines Modell, dessen Bereitstellung jedoch erhebliche Ressourcen erfordert und das sich am besten für die Nutzung über eine Cloud-API oder in einer Umgebung mit hohem Datenaufkommen eignet.</p><h3>Jina-Einbettungen – v3</h3><p><a href="https://jina.ai/news/jina-embeddings-v3-a-frontier-multilingual-embedding-model/"><strong>jina-embeddings-v3</strong></a> ist ein kompaktes, leistungsstarkes, mehrsprachiges, ausschließlich textbasiertes Einbettungsmodell mit weniger als 600 Millionen Parametern. Es unterstützt bis zu 8192 Texteingabetoken und liefert Einzelvektor-Einbettungen mit vom Nutzer gewählten Größen von einem Standard von 1024 Dimensionen bis zu 64 als Ausgabe.</p><p>Wir haben <code>jina-embeddings-v3</code> für eine Vielzahl von Textaufgaben trainiert – nicht nur für den Informationsabruf und die semantische Ähnlichkeit, sondern auch für Klassifikationsaufgaben wie die Sentiment-Analyse und Inhaltsmoderation sowie für Clustering-Aufgaben wie die Nachrichtenaggregation und -empfehlung. Wie <code>jina-embeddings-v4</code> bietet auch dieses Modell LoRA-Adapter, die auf die folgenden Nutzungskategorien spezialisiert sind:</p><ul><li><p>Asymmetrischer Informationsabruf</p></li><li><p>Semantische Ähnlichkeit</p></li><li><p>Klassifizierung</p></li><li><p>Clustering</p></li></ul><p><code>jina-embeddings-v3</code> ist ein deutlich kleineres Modell als <code>jina-embeddings-v4</code> mit einer deutlich reduzierten Eingabekontextgröße, aber es ist günstiger in der Nutzung. Dennoch bietet es eine sehr wettbewerbsfähige Leistung, wenn auch nur für Texte, und ist für viele Anwendungsfälle eine bessere Wahl.</p><h3>Jina Code-Einbettungen</h3><p>Die spezialisierten Code-Einbettungsmodelle von Jina – <a href="https://jina.ai/models/jina-code-embeddings-1.5b"><strong>jina-code-embeddings (0.5b und 1.5b)</strong></a> – unterstützen 15 Programmierschemata und Frameworks sowie englischsprachige Texte aus dem Bereich Informatik und Informationstechnologie. Es handelt sich um kompakte Modelle mit einer halben Milliarde (0,5x10⁹) bzw. eineinhalb Milliarden (1,5x10⁹) Parametern. Beide Modelle unterstützen Eingabekontextgrößen von bis zu 32.768 Token und ermöglichen es den Nutzern, ihre Ausgabe-Einbettungsgrößen auszuwählen, von 896 bis 64 Dimensionen für das kleinere Modell und 1536 bis 128 für das größere.</p><p>Diese Modelle unterstützen asymmetrische Abrufe für fünf aufgabenspezifische Spezialisierungen, wobei <a href="https://arxiv.org/abs/2101.00190">Präfixabstimmung</a> statt LoRA-Adapter verwendet wird:</p><ul><li><p><strong>Code zu Code.</strong> Ähnlichen Code in verschiedenen Programmiersprachen abrufen. Dies wird für die Code-Ausrichtung, Code-Deduplizierung sowie die Unterstützung von Portierung und Refactoring verwendet.</p></li><li><p><strong>Natürliche Sprache zu Code.</strong> Abrufen von Code, um Abfragen, Kommentare, Beschreibungen und Dokumentation in natürlicher Sprache abzugleichen.</p></li><li><p><strong>Code zu natürlicher Sprache. </strong>Vergleichen des Codes mit der Dokumentation oder anderen Texten in natürlicher Sprache.</p></li><li><p><strong>Code-zu-Code-Vervollständigung.</strong> Vorschlag von relevantem Code, um bestehenden Code zu ergänzen oder zu verbessern.</p></li><li><p><strong>Technische Fragen und Antworten.</strong> Identifizierung von Antworten in natürlicher Sprache auf Fragen zu Informationstechnologien, ideal geeignet für Anwendungsfälle im technischen Support.</p></li></ul><p>Diese Modelle bieten eine überlegene Leistung für Aufgaben, die Computerdokumentation und Programmiermaterialien erfordern, bei relativ geringen Rechenkosten. Sie eignen sich hervorragend für die Integration in Entwicklungsumgebungen und Code-Assistenten.</p><h3>Jina ColBERT v2</h3><p><a href="https://jina.ai/models/jina-colbert-v2"><strong>jina-colbert-v2</strong></a> ist ein Multivektor-Texteinbettungsmodell mit 560 Millionen Parametern. Es ist mehrsprachig, mit Materialien in 89 Sprachen trainiert und unterstützt variable Einbettungsgrößen sowie asymmetrischen Informationsabruf.</p><p>Wie bereits erwähnt, sind Multivektor-Einbettungen schlecht für das Indexieren geeignet, aber sehr nützlich, um die Genauigkeit von Ergebnissen anderer Suchstrategien zu erhöhen. <strong>Mit jina-colbert-v2können Sie Multivektor-Einbettungen im Voraus berechnen und sie dann verwenden, um Abrufkandidaten zur Abfragezeit neu zu ordnen.</strong> Dieser Ansatz ist weniger präzise als die Verwendung eines der Reranking-Modelle im nächsten Abschnitt, aber viel effizienter, da er nur den Vergleich gespeicherter Multivektor-Einbettungen beinhaltet, anstatt das gesamte KI-Modell für jede Abfrage und jedes Kandidatenmatch aufzurufen. Es eignet sich ideal für Anwendungsfälle, in denen die Latenz und der Rechenaufwand durch die Nutzung von Reranking-Modellen zu groß sind oder die Anzahl der Kandidaten zum Vergleich zu groß für das Reranking von Modellen ist.</p><p>Dieses Modell gibt eine Folge von Einbettungen aus – eine pro Eingabetoken – und Nutzer können Token-Einbettungen aus 128-, 96- oder 64-dimensionalen Einbettungen auswählen. Kandidaten-Textmatches sind auf 8.192 Token begrenzt. Abfragen werden asymmetrisch kodiert, daher müssen Nutzer angeben, ob ein Text eine Abfrage oder ein Kandidatenmatch ist, und die Abfragen auf 32 Token begrenzen.</p><h3>Jina CLIP v2</h3><p><a href="https://jina.ai/news/jina-clip-v2-multilingual-multimodal-embeddings-for-text-and-images/"><strong>jina-clip-v2</strong></a> ist ein multimodales Einbettungsmodell mit 900 Millionen Parametern, das so trainiert wurde, dass Texte und Bilder Einbettungen erzeugen, die nahe beieinander liegen, wenn der Text den Inhalt des Bildes beschreibt. Es dient in erster Linie zum Abrufen von Bildern auf der Grundlage von Textabfragen, ist aber auch ein leistungsstarkes reines Textmodell, das die Nutzerkosten senkt, da Sie keine separaten Modelle für Text-zu-Text- und Text-zu-Bild-Abfragen benötigen.</p><p>Dieses Modell unterstützt einen Texteingabekontext von 8.192 Tokens, und Bilder werden vor der Einbettung auf 512x512 Pixel skaliert.</p><p>CLIP-Architekturen („Contrastive Language-Image Pretraining“) sind einfach zu trainieren und zu bedienen und können sehr kompakte Modelle erzeugen, aber sie haben einige grundlegende Einschränkungen. Sie können ihr Wissen aus einem Medium nicht nutzen, um ihre Leistung in einem anderen zu verbessern. Sie können nicht ein Medium nutzen, um ihre Leistung in einem anderen zu verbessern. Obwohl das System also wissen mag, dass die Wörter „dog“ und „cat“ in ihrer Bedeutung näher beieinander liegen als jedes von ihnen bei „car“, weiß es nicht unbedingt, dass ein Bild von einem Hund und ein Bild von einer Katze enger miteinander verwandt sind als jedes von ihnen bei einem Bild von einem Auto.</p><p>Sie leiden auch unter der sogenannten <em>Modalitätslücke</em>: Die Einbettung eines Textes über Hunde ist wahrscheinlich näher an der Einbettung eines Textes über Katzen als an der Einbettung eines Bildes von Hunden. Aufgrund dieser Einschränkung empfehlen wir, CLIP entweder als Text-zu-Bild-Abfragemodell oder als reines Textmodell zu verwenden, jedoch nicht beide in einer einzigen Abfrage zu vermischen.</p><h2>Reranking-Modelle</h2><p>Reranking-Modelle nehmen ein oder mehrere Kandidatenmatches zusammen mit einer Abfrage als Eingabe für das Modell und vergleichen sie direkt, wodurch deutlich präzisere Übereinstimmungen entstehen.</p><p>Grundsätzlich könnte man einen Reranker direkt für die Informationsabfrage verwenden, indem man jede Abfrage mit jedem gespeicherten Dokument vergleicht, dies wäre jedoch sehr rechenintensiv und für alle außer den kleinsten Sammlungen unpraktisch. Daher werden Reranker tendenziell zur Bewertung relativ kurzer Listen von Kandidatenmatches verwendet, die mit anderen Mitteln gefunden wurden, wie z. B. durch einbettungsbasierte Suche oder andere Algorithmen für den Informationsabruf. Reranking-Modelle eignen sich ideal für hybride und föderierte Suchverfahren, bei denen eine Suche bedeuten kann, dass Anfragen an separate Suchsysteme mit unterschiedlichen Datensätzen gesendet werden, die jeweils unterschiedliche Ergebnisse liefern. Sie sind sehr gut darin, vielfältige Ergebnisse zu einem einzigen, hochwertigen Ergebnis zu vereinen.</p><p>Die auf Einbettungen basierende Suche kann eine große Herausforderung darstellen, da sie eine Neuindizierung aller gespeicherten Daten erfordert und die Erwartungen der Nutzer an die Ergebnisse verändert. Wenn Sie einen Reranker zu einem bestehenden Suchschema hinzufügen, können Sie viele der Vorteile von KI nutzen, ohne Ihre gesamte Suchlösung neu zu entwickeln.</p><h2>Jina-Reranker-Modelle</h2><h3>Jina Reranker m0</h3><p><a href="https://jina.ai/models/jina-reranker-m0/"><strong>jina-reranker-m0</strong></a> ist ein multimodaler Reranker mit 2,4 Milliarden (2,4x10⁹) Parametern, der Textanfragen und Kandidatenmatches aus Texten und/oder Bildern unterstützt. Es ist das führende Modell für die visuelle Dokumentensuche und somit eine ideale Lösung für Sammlungen von PDFs, Scans von Texten, Screenshots und anderen computergenerierten oder modifizierten Bildern, die Text oder andere semistrukturierte Informationen enthalten, sowie für gemischte Daten, die aus Textdokumenten und Bildern bestehen.</p><p>Dieses Modell nimmt eine einzelne Abfrage und einen Kandidatenmatch entgegen und gibt einen Score zurück. Wenn dieselbe Abfrage mit verschiedenen Kandidaten verwendet wird, sind die Scores vergleichbar und können zur Rangfolge herangezogen werden. Es unterstützt eine gesamte Eingabegröße von bis zu 10.240 Tokens, einschließlich des Anfragetextes und des Kandidatentextes oder -bildes. Jede 28x28 Pixel große Kachel, die zum Abdecken eines Bildes benötigt wird, zählt als Token zur Berechnung der Eingabegröße.</p><h3>Jina Reranker v3</h3><p><a href="https://jina.ai/models/jina-reranker-v3/"><strong>jina-reranker-v3</strong></a> ist ein Text-Reranker mit 600 Millionen Parametern und modernster Leistung für Modelle vergleichbarer Größe. Im Gegensatz zu <code>jina-reranker-m0</code> nimmt er eine einzelne Abfrage und eine Liste von bis zu 64 Kandidatenübereinstimmungen und gibt die Rangfolge zurück. Es hat einen Eingabekontext von 131.000 Token, einschließlich der Abfrage und aller Textkandidaten.</p><h3>Jina Reranker v2</h3><p><a href="https://jina.ai/models/jina-reranker-v2"><strong>jina-reranker-v2-base-multilingual</strong></a> ist ein äußerst kompakter, universeller Reranker mit zusätzlichen Features, die Funktionsaufrufe und SQL-Abfragen unterstützen. Mit weniger als 300 Millionen Parametern bietet er ein schnelles, effizientes und genaues mehrsprachiges Text-Reranking mit zusätzlicher Unterstützung für die Auswahl von SQL-Tabellen und externen Funktionen, die Textabfragen entsprechen, wodurch es sich für agentenbasierte Anwendungsfälle eignet.</p><h2>Kleine generative Sprachmodelle</h2><p>Generative Sprachmodelle sind Modelle wie ChatGPT von OpenAI, Google Gemini und Claude von Anthropic, die Text- oder Multimedia-Eingaben aufnehmen und mit Textausgaben antworten. Es gibt keine klar definierte Grenze, die <em>große</em> Sprachmodelle (LLMs) von <em>kleinen</em> Sprachmodellen (SLMs) unterscheidet, aber die praktischen Probleme bei der Entwicklung, dem Betrieb und der Nutzung von Top-LLMs sind wohlbekannt. Die bekanntesten werden nicht öffentlich verbreitet, daher können wir ihre Größe nur schätzen, aber es wird erwartet, dass ChatGPT, Gemini und Claude im Bereich von 1 bis 3 Billionen (1–3x10¹²) Parametern liegen.</p><p>Das Ausführen dieser Modelle – selbst wenn sie öffentlich verfügbar sind – geht weit über den Umfang herkömmlicher Hardware hinaus und erfordert die fortschrittlichsten Chips, die in riesigen parallelen Arrays angeordnet sind. Der Zugriff auf LLMs ist über kostenpflichtige APIs möglich, dies verursacht jedoch erhebliche Kosten, führt zu einer hohen Latenz und lässt sich nur schwer mit den Anforderungen an Datenschutz, digitale Souveränität und Cloud-Repatriierung vereinbaren. Außerdem können die Kosten für das Training und die Anpassung von Modellen dieser Größe beträchtlich sein.</p><p>Aus diesem Grund wurde viel Forschung in die Entwicklung kleinerer Modelle gesteckt, die vielleicht nicht alle Fähigkeiten der größten LLMs haben, aber bestimmte Aufgaben genauso gut erledigen können, und das zu geringeren Kosten. Unternehmen setzen Software in der Regel ein, um spezifische Probleme zu lösen, und KI-Software bildet da keine Ausnahme. Daher sind SLM-basierte Lösungen oft LLM-basierten Lösungen vorzuziehen. Sie können üblicherweise auf Standardhardware laufen, sind schneller, verbrauchen weniger Energie und lassen sich viel leichter anpassen.</p><p>Das SLM-Angebot von Jina wächst, da wir uns darauf konzentrieren, wie wir KI am besten in praktische Suchlösungen integrieren können.</p><h2>Jina SLMs</h2><h3>ReaderLM v2</h3><p><a href="https://jina.ai/models/ReaderLM-v2"><strong>ReaderLM-v2</strong></a> ist ein generatives Sprachmodell, das HTML gemäß benutzerdefinierten JSON-Schemata und natürlichen Sprachanweisungen in Markdown oder JSON umwandelt.</p><p>Datenvorverarbeitung und -normalisierung sind ein wesentlicher Bestandteil der Entwicklung guter Suchlösungen für digitale Daten, aber reale Daten, insbesondere webbasierte Informationen, sind oft chaotisch, und einfache Umwandlungsstrategien erweisen sich häufig als sehr zerbrechlich. Stattdessen bietet <code>ReaderLM-v2</code> eine intelligente KI-Modelllösung, die das Chaos eines DOM-Tree-Dumps einer Webseite verstehen und nützliche Elemente robust identifizieren kann.</p><p>Mit 1,5 Milliarden (1,5x10⁹) Parametern ist es drei Größenordnungen kompakter als modernste LLMs, leistet aber bei dieser einen engen Aufgabe auf Augenhöhe.</p><h3>Jina VLM</h3><p><a href="https://jina.ai/models/jina-vlm"><strong>jina-vlm</strong></a> ist ein generatives Sprachmodell mit 2,4 Milliarden (2,4x10⁹) Parametern, das darauf trainiert wurde, natürlichsprachliche Fragen zu Bildern zu beantworten. Es bietet eine sehr starke Unterstützung für die visuelle Dokumentenanalyse, d. h. für die Beantwortung von Fragen zu Scans, Screenshots, Folien, Diagrammen und ähnlichen nicht natürlichen Bilddaten.</p><p>Zum Beispiel:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt124b9932e01dcd40/6a17db7d4202291eca29f4bc/adfa1420d079ca4fd5582eef4349b1265b378e76-950x500.png" alt="" /><p>Es ist auch sehr gut darin, Text in Bildern zu lesen:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1a862a9c9a0e42ce/6a17db7fb1e1133a2979f15d/ea3956e7ad86f8e171841cab2c28c8b3498da1d4-1002x500.png" alt="" /><p>Die wahre Stärke von <code>jina-vlm</code> liegt jedoch im Verständnis des Inhalts von informativen und von Menschen erstellten Bildern:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt761cf621ea32e4ae/6a17db8163baff7730741b26/f68606f9d2d99e2cd616d4ff81db3574dc4e26a5-1020x700.png" alt="" /><p>Oder:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4df4d31e574df7e3/6a17db82e3179134e02d56e9/297e85e7e78f296388a02301e1e08fed70827423-1000x500.png" alt="" /><p><code>jina-vlm</code> ist gut geeignet für die automatische Generierung von Bildunterschriften, Produktbeschreibungen, Alternativtexten für Bilder und Barrierefreiheitsanwendungen für Sehbehinderte. Es schafft zudem Möglichkeiten für RAG-Systeme („Retrieval-Augmented-Generation“), visuelle Informationen zu verwenden, und für KI-Agenten, Bilder ohne menschliche Unterstützung zu verarbeiten.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/jina-models-elasticsearch-guide</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/jina-models-elasticsearch-guide</guid>
    <category><![CDATA[Integrationen]]></category>
    <category><![CDATA[Jina AI]]></category>
    <dc:creator><![CDATA[Scott Martens]]></dc:creator>
    <pubDate>Thu, 01 Jan 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Erstellung eines Wissensagenten mit semantischem Recall unter Verwendung von Mastra und Elasticsearch]]></title>
    <description><![CDATA[Lernen Sie, wie Sie einen Wissensagenten mit semantischer Erinnerung unter Verwendung von Mastra und Elasticsearch als Vektorspeicher für Gedächtnis und Informationsabruf erstellen.]]></description>
    <content:encoded><![CDATA[<p><a href="https://www.elastic.co/search-labs/blog/context-engineering-overview">Kontextentwicklung</a> gewinnt zunehmend an Bedeutung beim Aufbau zuverlässiger KI-Agenten und -Architekturen. Je besser die Modelle werden, desto weniger hängen ihre Effektivität und Zuverlässigkeit von den Trainingsdaten ab, sondern vielmehr davon, wie gut sie im richtigen Kontext verankert sind. Agenten, die die relevantesten Informationen zum richtigen Zeitpunkt abrufen und anwenden können, liefern mit viel höherer Wahrscheinlichkeit genaue und verlässliche Ergebnisse.</p><p>In diesem Blogbeitrag verwenden wir <a href="https://mastra.ai/">Mastra</a> , um einen Wissensagenten zu entwickeln, der sich merkt, was Benutzer sagen, und relevante Informationen später abrufen kann. Als Speicher- und Abruf-Backend nutzen wir Elasticsearch. Dieses Konzept lässt sich problemlos auf reale Anwendungsfälle übertragen. Man denke beispielsweise an Supportmitarbeiter, die sich an frühere Gespräche und Lösungen erinnern können, sodass sie ihre Antworten auf bestimmte Benutzer zuschneiden oder Lösungen schneller auf Basis des vorherigen Kontextes präsentieren können.</p><p>Folgen Sie dieser Anleitung, um zu sehen, wie Sie es Schritt für Schritt bauen können. Falls Sie nicht weiterkommen oder einfach nur ein fertiges Beispiel ausführen möchten, schauen Sie sich das Repository <a href="https://github.com/jdarmada/getting-started-mastra-elastic/tree/main">hier</a> an.</p><h2>Was ist Mastra?</h2><p>Mastra ist ein Open-Source-TypeScript-Framework zum Erstellen von KI-Agenten mit austauschbaren Teilen für Schlussfolgerungen, Speicher und Werkzeuge. Die <a href="https://mastra.ai/docs/memory/semantic-recall">semantische Abruffunktion</a> ermöglicht es Agenten, vergangene Interaktionen zu erinnern und abzurufen, indem Nachrichten als Einbettungen in einer Vektordatenbank gespeichert werden. Dies ermöglicht es den Agenten, den Gesprächskontext und die Kontinuität langfristig aufrechtzuerhalten. Elasticsearch ist ein hervorragender Vektorspeicher, um diese Funktion zu ermöglichen, da er eine effiziente dichte Vektorsuche unterstützt. Wenn der semantische Abruf ausgelöst wird, ruft der Agent relevante vergangene Nachrichten in das Kontextfenster des Modells ab, sodass das Modell diesen abgerufenen Kontext als Grundlage für seine Schlussfolgerungen und Antworten nutzen kann.</p><h2>Was Sie für den Einstieg benötigen</h2><ul><li><p>Node v18+</p></li><li><p>Elasticsearch (Version 8.15 oder neuer)</p></li><li><p>Elasticsearch API-Schlüssel</p></li><li><p><a href="https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key">OpenAI API-Schlüssel</a></p></li></ul><p>Hinweis: Sie benötigen dies, da die Demo den OpenAI-Provider verwendet. Mastra unterstützt jedoch auch andere KI-SDKs und Community-Modell-Provider, sodass Sie ihn je nach Ihrer Konfiguration problemlos austauschen können.</p><h2>Aufbau eines Mastra-Projekts</h2><p>Wir werden die integrierte CLI von Mastra verwenden, um das Grundgerüst für unser Projekt bereitzustellen. Führen Sie folgenden Befehl aus:</p>npm create mastra@latest<p>Sie erhalten eine Reihe von Eingabeaufforderungen, beginnend mit:</p><p>1. Gib deinem Projekt einen Namen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt87f941f654d03827/6a16f7af67045b214d45bfa1/2b9fe559e0276140dd539e24f916a73c60870405-620x84.png" alt="Benennen einer Eingabeaufforderung in der Mastra-App" /><p>2. Wir können diese Standardeinstellung beibehalten; Sie können dieses Feld gerne leer lassen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7dbb3d4f27435cac/6a16f7b0cdacbf29497d27de/e04729eb03bce8499e973e18c28642402340d0e5-852x68.png" alt="Mastra mitteilen, wo die Prompt-Dateien gespeichert werden sollen" /><p>3. Für dieses Projekt verwenden wir ein von OpenAI bereitgestelltes Modell.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1f654f6cb9397e94/6a16f7b2964cea899a08b942/a86596a469a71bdf8bd99cbaf528d0f0cf7272c0-436x222.png" alt="Auswahl eines von OpenAI in Mastra bereitgestellten Modells" /><p>4. Wählen Sie die Option „Jetzt überspringen“, da wir alle unsere Umgebungsvariablen in einer `.env`-Datei speichern, die wir in einem späteren Schritt konfigurieren werden.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltff106117521a3519/6a16f7b3c1e8a5031af880d8/02b19ccc34af0bdacf52fd94b519d036540ca2e6-426x114.png" alt="Die OpenAI-Schlüsselabfrage wird vorerst übersprungen." /><p>5. Diese Option können wir auch überspringen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcda7d9c51c3878d7/6a16f7b450916809dbe1b892/b3fe63d19d270bc2e0de1dd92033bf8b26750819-990x208.png" alt="" /><p>Sobald dieser Initialisierungsprozess abgeschlossen ist, können wir zum nächsten Schritt übergehen.</p><h3>Abhängigkeiten installieren</h3><p>Als Nächstes müssen wir einige Abhängigkeiten installieren:</p>npm install ai @ai-sdk/openai @elastic/elasticsearch dotenv<ul><li><p><code>ai</code> - Core AI SDK-Paket, das Werkzeuge zur Verwaltung von KI-Modellen, Eingabeaufforderungen und Arbeitsabläufen in JavaScript/TypeScript bereitstellt. Mastra basiert auf dem <a href="https://ai-sdk.dev/">AI SDK</a> von Vercel, daher benötigen wir diese Abhängigkeit, um Modellinteraktionen mit Ihrem Agenten zu ermöglichen.</p></li><li><p><code>@ai-sdk/openai</code> - Plugin, das das AI SDK mit OpenAI-Modellen (wie GPT-4, GPT-4o usw.) verbindet und API-Aufrufe mit Ihrem OpenAI-API-Schlüssel ermöglicht.</p></li><li><p><code>@elastic/elasticsearch</code> - <a href="https://www.elastic.co/docs/reference/elasticsearch/clients/javascript">Offizieller Elasticsearch-Client für Node.js</a>, Wird verwendet, um eine Verbindung zu Ihrer Elastic Cloud oder Ihrem lokalen Cluster für Indizierungs-, Such- und Vektoroperationen herzustellen.</p></li><li><p><code>dotenv</code> Lädt Umgebungsvariablen aus einer .env-Datei Datei in process.env, ermöglicht das sichere Einfügen von Anmeldeinformationen wie API-Schlüsseln und Elasticsearch-Endpunkten.</p></li></ul><h3>Konfiguration von Umgebungsvariablen</h3><p>Erstellen Sie eine <code>.env</code> -Datei in Ihrem Projektstammverzeichnis, falls dort noch keine vorhanden ist. Alternativ können Sie das von mir im <a href="https://github.com/jdarmada/getting-started-mastra-elastic/blob/main/.env.example">Repository</a> bereitgestellte Beispiel <code>.env</code> kopieren und umbenennen. In dieser Datei können wir die folgenden Variablen hinzufügen:</p>ELASTICSEARCH_ENDPOINT="your-endpoint-here"
ELASTICSEARCH_API_KEY="your-key-here"
OPENAI_API_KEY="your-key-here"<p>Damit ist die grundlegende Einrichtung abgeschlossen. Von hier aus können Sie bereits mit dem Erstellen und Orchestrieren von Agenten beginnen. Wir gehen noch einen Schritt weiter und fügen Elasticsearch als Speicher- und Vektorsuchschicht hinzu.</p><h2>Elasticsearch als Vektorspeicher hinzufügen</h2><p>Erstellen Sie einen neuen Ordner namens <code>stores</code> und fügen Sie darin diese <a href="https://github.com/jdarmada/getting-started-mastra-elastic/blob/main/src/mastra/stores/elastic-store.ts">Datei</a> ein. Bevor Mastra und Elastic eine offizielle Elasticsearch-Vektorspeicherintegration veröffentlichten, teilte <a href="https://github.com/abhiaiyer91">Abhi Aiyer</a>(CTO von Mastra) diese frühe Prototypklasse mit dem Namen <code>ElasticVector</code>. Vereinfacht gesagt verbindet es die Speicherabstraktion von Mastra mit den dichten Vektorfunktionen von Elasticsearch, sodass Entwickler Elasticsearch als Vektordatenbank für ihre Agenten verwenden können.</p><p>Werfen wir einen genaueren Blick auf die wichtigen Aspekte der Integration:</p><h3>Aufnahme des Elasticsearch-Clients</h3><p>Dieser Abschnitt definiert die Klasse <code>ElasticVector</code> und richtet die Elasticsearch-Clientverbindung mit Unterstützung für Standard- und serverlose Bereitstellungen ein.</p>export interface ElasticVectorConfig extends ClientOptions {
    /**
     * Explicitly specify if connecting to Elasticsearch Serverless.
     * If not provided, will be auto-detected on first use.
     */
    isServerless?: boolean;
    
    /**
     * Maximum documents to count accurately when describing indices.
     * Higher values provide accurate counts but may impact performance on large indices.
     * 
     * @default 10000
     */
    maxCountAccuracy?: number;
}

export class ElasticVector extends MastraVector {
    private client: Client;
    private isServerless: boolean | undefined;
    private deploymentChecked: boolean = false;
    private readonly maxCountAccuracy: number;

    constructor(config: ElasticVectorConfig) {
        super();
        this.client = new Client(config);
        this.isServerless = config.isServerless;
        this.maxCountAccuracy = config.maxCountAccuracy ?? 10000;
    }
}<ul><li><p><code>ElasticVectorConfig extends ClientOptions</code>Dadurch wird eine neue Konfigurationsschnittstelle erstellt, die alle Elasticsearch-Clientoptionen (wie <code>node</code>, <code>auth</code>, <code>requestTimeout</code>) erbt und unsere benutzerdefinierten Eigenschaften hinzufügt. Das bedeutet, dass Benutzer jede gültige Elasticsearch-Konfiguration zusammen mit unseren serverlosen Optionen übergeben können.</p></li><li><p><code>extends MastraVector</code>Dies ermöglicht es <code>ElasticVector</code> von Mastras Basisklasse <code>MastraVector</code> zu erben, die eine gemeinsame Schnittstelle darstellt, der alle Vektorspeicherintegrationen entsprechen. Dadurch wird sichergestellt, dass sich Elasticsearch aus Sicht des Agenten wie jedes andere Mastra-Vektor-Backend verhält.</p></li><li><p><code>private client: Client</code>Dies ist eine private Eigenschaft, die eine Instanz des Elasticsearch JavaScript-Clients enthält. Dadurch kann die Klasse direkt mit Ihrem Cluster kommunizieren.</p></li><li><p><code>isServerless</code> und <code>deploymentChecked</code>: Diese Eigenschaften arbeiten zusammen, um zu erkennen und zwischenzuspeichern, ob wir mit einer serverlosen oder einer Standard-Elasticsearch-Bereitstellung verbunden sind. Diese Erkennung erfolgt automatisch bei der ersten Nutzung oder kann explizit konfiguriert werden.</p></li><li><p><code>constructor(config: ClientOptions)</code>Dieser Konstruktor nimmt ein Konfigurationsobjekt entgegen (das Ihre Elasticsearch-Zugangsdaten und optionale Serverless-Einstellungen enthält) und verwendet es, um den Client in der Zeile <code>this.client = new Client(config)</code> zu initialisieren.</p></li><li><p><code>super()</code>: Dadurch wird der Basiskonstruktor von Mastra aufgerufen, sodass Logging, Validierungshilfsmechanismen und andere interne Hooks geerbt werden.</p></li></ul><p>Zu diesem Zeitpunkt weiß Mastra, dass es einen neuen Vektor-Shop namens gibt. <code>ElasticVector</code></p><h3>Erkennung des Bereitstellungstyps</h3><p>Vor dem Erstellen von Indizes erkennt der Adapter automatisch, ob Sie Elasticsearch Standard oder Elasticsearch Serverless verwenden. Dies ist wichtig, da serverlose Bereitstellungen keine manuelle Shard-Konfiguration zulassen.</p>private async detectServerless(): Promise&lt;boolean&gt; {
    // Return cached result if already detected
    if (this.deploymentChecked) {
        return this.isServerless ?? false;
    }

    // Use explicit configuration if provided
    if (this.isServerless !== undefined) {
        this.deploymentChecked = true;
        this.logger?.info(
            `Using explicit deployment type: ${this.isServerless ? 'Serverless' : 'Standard'}`
        );
        return this.isServerless;
    }

    try {
        const info = await this.client.info();
        
        // Primary detection: build flavor (most reliable)
        const isBuildFlavorServerless = info.version?.build_flavor === 'serverless';
        
        // Secondary detection: tagline (fallback)
        const isTaglineServerless = info.tagline?.toLowerCase().includes('serverless') ?? false;
        
        this.isServerless = isBuildFlavorServerless || isTaglineServerless;
        this.deploymentChecked = true;
        
        this.logger?.info(
            `Auto-detected ${this.isServerless ? 'Serverless' : 'Standard'} Elasticsearch deployment`,
            { 
                buildFlavor: info.version?.build_flavor, 
                version: info.version?.number,
                detectionMethod: isBuildFlavorServerless ? 'build_flavor' : 'tagline'
            }
        );
        
        return this.isServerless;
    } catch (error) {
        this.logger?.warn(
            'Could not auto-detect deployment type, assuming Standard Elasticsearch. ' +
            'Set isServerless: true explicitly in config if using Serverless.',
            { error: error instanceof Error ? error.message : String(error) }
        );
        this.isServerless = false;
        this.deploymentChecked = true;
        return false;
    }
}<p>Was passiert:</p><ul><li><p>Zuerst wird geprüft, ob Sie <code>isServerless</code> explizit in der Konfiguration festgelegt haben (überspringt die automatische Erkennung).</p></li><li><p>Ruft die <code>info()</code> -API von Elasticsearch auf, um Clusterinformationen zu erhalten.</p></li><li><p>Prüft den Wert <code>build_flavor field</code> (serverlose Bereitstellungen geben <code>serverless</code> zurück)</p></li><li><p>Falls die Build-Variante nicht verfügbar ist, wird auf die Überprüfung des Slogans zurückgegriffen.</p></li><li><p>Speichert das Ergebnis im Cache, um wiederholte API-Aufrufe zu vermeiden.</p></li><li><p>Wird standardmäßig die Bereitstellung durchgeführt, wenn die Erkennung fehlschlägt.</p></li></ul><p> Anwendungsbeispiel:</p>// Option 1: Auto-detect (recommended)
const vector = new ElasticVector({
    node: 'https://your-cluster.es.cloud',
    auth: { apiKey: 'your-api-key' }
});
// Detection happens automatically on first index operation

// Option 2: Explicit configuration (faster startup)
const vector = new ElasticVector({
    node: 'https://your-serverless.es.cloud',
    auth: { apiKey: 'your-api-key' },
    isServerless: true  // Skips auto-detection
});<h3>Erstellen des „Speichers“ in Elasticsearch</h3><p>Die folgende Funktion richtet einen Elasticsearch-Index zum Speichern von Einbettungen ein. Es wird geprüft, ob der Index bereits existiert. Andernfalls wird eine solche mit der unten stehenden Zuordnung erstellt, die ein <code>dense_vector</code> -Feld zum Speichern von Einbettungen und benutzerdefinierten Ähnlichkeitsmetriken enthält.</p><p>Einige Dinge sind zu beachten:</p><ul><li><p>Der Parameter <code>dimension</code> gibt die Länge des jeweiligen Einbettungsvektors an und hängt davon ab, welches Einbettungsmodell Sie verwenden. In unserem Fall generieren wir Einbettungen mithilfe des <code>text-embedding-3-small</code> -Modells von OpenAI, das Vektoren der Größe <code>1536</code> ausgibt. Dies werden wir als Standardwert verwenden.</p></li><li><p>Die in der folgenden Zuordnung verwendete Variable <code>similarity</code> wird durch die Hilfsfunktion c<code>onst similarity = this.mapMetricToSimilarity(metric)</code> definiert, welche den Wert für den Parameter <code>metric</code> entgegennimmt und ihn in ein Elasticsearch-kompatibles Schlüsselwort für die gewählte Distanzmetrik umwandelt.</p><ul><li><p>Zum Beispiel: Mastra verwendet allgemeine Begriffe für Vektorähnlichkeit wie <code>cosine</code>, <code>euclidean</code>, und <code>dotproduct</code>. Würden wir die Metrik <code>euclidean</code> direkt in das Elasticsearch-Mapping einfügen, würde dies einen Fehler auslösen, da Elasticsearch erwartet, dass das Schlüsselwort <code>l2_norm</code> die euklidische Distanz repräsentiert.</p></li></ul></li><li><p>Serverless-Kompatibilität: Der Code lässt Shard- und Replikateinstellungen für serverlose Bereitstellungen automatisch aus, da diese von Elasticsearch Serverless automatisch verwaltet werden.</p></li></ul>async createIndex(params: CreateIndexParams): Promise&lt;void&gt; {
    const { indexName, dimension = 1536, metric = 'cosine' } = params;

    try {
        const exists = await this.client.indices.exists({ index: indexName });

        if (exists) {
            try {
                await this.validateExistingIndex(indexName, dimension, metric);
                this.logger?.info(`Index "${indexName}" already exists and is valid`);
                return;
            } catch (validationError) {
                throw new Error(
                    `Index "${indexName}" exists but does not match the required configuration: ${
                        validationError instanceof Error ? validationError.message : String(validationError)
                    }`
                );
            }
        }

        const isServerless = await this.detectServerless();
        const similarity = this.mapMetricToSimilarity(metric);

        const indexConfig: any = {
            index: indexName,
            mappings: {
                properties: {
                    vector: {
                        type: 'dense_vector',
                        dims: dimension,
                        index: true,
                        similarity: similarity,
                    },
                    metadata: {
                        type: 'object',
                        enabled: true,
                        dynamic: true, // Allows flexible metadata structures
                    },
                },
            },
        };

        // Only configure shards/replicas for non-serverless deployments
        // Serverless manages infrastructure automatically
        if (!isServerless) {
            indexConfig.settings = {
                number_of_shards: 1,
                number_of_replicas: 0, // Increase for production HA deployments
            };
        }

        await this.client.indices.create(indexConfig);

        this.logger?.info(
            `Created ${isServerless ? 'Serverless' : 'Standard'} Elasticsearch index "${indexName}"`,
            { dimension, metric, similarity }
        );
    } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        this.logger?.error(`Failed to create index "${indexName}": ${errorMessage}`);
        throw new Error(`Failed to create index "${indexName}": ${errorMessage}`);
    }
}<h3>Speichern einer neuen Erinnerung oder Notiz nach einer Interaktion</h3><p>Diese Funktion nimmt die nach jeder Interaktion neu generierten Einbettungen zusammen mit den Metadaten entgegen und fügt sie anschließend mithilfe der <code>bulk</code> -API von Elastic in den Index ein oder aktualisiert sie. Die <code>bulk</code> API bündelt mehrere Schreibvorgänge in einer einzigen Anfrage; diese Verbesserung unserer Indexierungsleistung stellt sicher, dass Aktualisierungen effizient bleiben, während der Speicher unseres Agenten immer größer wird.</p>async upsert(params: UpsertVectorParams): Promise&lt;string[]&gt; {
    const { indexName, vectors, metadata = [], ids } = params;

    try {
        // Generate unique IDs if not provided
        const vectorIds = ids || vectors.map((_, i) =&gt; 
            `vec_${Date.now()}_${i}_${Math.random().toString(36).substr(2, 9)}`
        );

        const operations = vectors.flatMap((vec, index) =&gt; [
            { index: { _index: indexName, _id: vectorIds[index] } },
            {
                vector: vec,
                metadata: metadata[index] || {},
            },
        ]);

        const response = await this.client.bulk({
            refresh: true,
            operations,
        });

        if (response.errors) {
            const erroredItems = response.items.filter((item: any) =&gt; item.index?.error);
            const erroredIds = erroredItems.map((item: any) =&gt; item.index?._id);
            const errorDetails = erroredItems.slice(0, 3).map((item: any) =&gt; ({
                id: item.index?._id,
                error: item.index?.error?.reason || item.index?.error,
                type: item.index?.error?.type
            }));
            
            const errorMessage = `Failed to upsert ${erroredIds.length}/${vectors.length} vectors`;
            console.error(`${errorMessage}. Sample errors:`, JSON.stringify(errorDetails, null, 2));
            this.logger?.error(errorMessage, { 
                failedCount: erroredIds.length, 
                totalCount: vectors.length,
                sampleErrors: errorDetails 
            });
            
            // Still return successfully inserted IDs
            const successfulIds = vectorIds.filter((id, idx) =&gt; 
                !erroredIds.includes(id)
            );
            
            if (successfulIds.length === 0) {
                throw new Error(`${errorMessage}. All operations failed. See logs for details.`);
            }
            
            return successfulIds;
        }

        this.logger?.info(`Successfully upserted ${vectors.length} vectors to "${indexName}"`);
        return vectorIds;
    } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        this.logger?.error(`Failed to upsert vectors to "${indexName}": ${errorMessage}`);
        throw new Error(`Failed to upsert vectors to "${indexName}": ${errorMessage}`);
    }
}<h3>Abfrage ähnlicher Vektoren für semantische Wiedererkennung</h3><p>Diese Funktion ist der Kern des semantischen Recall-Features. Der Agent verwendet eine Vektorsuche, um ähnliche gespeicherte Einbettungen in unserem Index zu finden.</p>async query(params: QueryVectorParams&lt;any&gt;): Promise&lt;QueryResult[]&gt; {
    const { indexName, queryVector, topK = 10, filter, includeVector = false } = params;

    try {
        const knnQuery: any = {
            field: 'vector',
            query_vector: queryVector,
            k: topK,
            num_candidates: Math.max(topK * 10, 100), // Search more candidates for better recall
        };

        // Apply metadata filters if provided
        if (filter) {
            knnQuery.filter = this.buildElasticFilter(filter);
        }

        const sourceFields = ['metadata'];
        if (includeVector) {
            sourceFields.push('vector');
        }

        const response = await this.client.search({
            index: indexName,
            knn: knnQuery,
            size: topK,
            _source: sourceFields,
        });

        const results = response.hits.hits.map((hit: any) =&gt; ({
            id: hit._id,
            score: hit._score || 0,
            metadata: hit._source?.metadata || {},
            vector: includeVector ? hit._source?.vector : undefined,
        }));

        this.logger?.debug(`Query returned ${results.length} results from "${indexName}"`);
        return results;
    } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        this.logger?.error(`Failed to query vectors from "${indexName}": ${errorMessage}`);
        throw new Error(`Failed to query vectors from "${indexName}": ${errorMessage}`);
    }
}<p>Unter der Haube:</p><ul><li><p>Führt eine <a href="https://www.elastic.co/docs/solutions/search/vector/knn">kNN-</a> Abfrage (k-nächste Nachbarn) mit Hilfe der <code>knn</code> -API in Elasticsearch aus.</p></li><li><p>Gibt die K ähnlichsten Vektoren zum Eingabeabfragevektor zurück.</p></li><li><p>Optional können Metadatenfilter angewendet werden, um die Ergebnisse einzugrenzen (z. B. nur innerhalb einer bestimmten Kategorie oder eines bestimmten Zeitraums zu suchen).</p></li><li><p>Gibt strukturierte Ergebnisse zurück, einschließlich der Dokument-ID, des Ähnlichkeitswerts und der gespeicherten Metadaten.</p></li></ul><h2>Erstellung des Wissensagenten</h2><p>Nachdem wir nun die Verbindung zwischen Mastra und Elasticsearch durch die <code>ElasticVector</code> -Integration kennengelernt haben, erstellen wir den Knowledge Agent selbst.</p><p>Erstellen Sie im Ordner <code>agents</code> eine Datei namens <code>knowledge-agent.ts</code>. Wir können damit beginnen, unsere Umgebungsvariablen zu verbinden und den Elasticsearch-Client zu initialisieren.</p>import { Agent } from '@mastra/core/agent';
import { Memory } from '@mastra/memory';
import { openai } from '@ai-sdk/openai';
import { Client } from '@elastic/elasticsearch';
import { ElasticVector } from '../stores/elastic-store';
import dotenv from "dotenv";

dotenv.config();

const ELASTICSEARCH_ENDPOINT = process.env.ELASTICSEARCH_ENDPOINT;
const ELASTICSEARCH_API_KEY = process.env.ELASTICSEARCH_API_KEY;

//Error check for undefined credentials
if (!ELASTICSEARCH_ENDPOINT || !ELASTICSEARCH_API_KEY) {
  throw new Error('Missing Elasticsearch credentials');
}

//Check to see if a connection can be established
const testClient = new Client({
  node: ELASTICSEARCH_ENDPOINT,
  auth: { 
    apiKey: ELASTICSEARCH_API_KEY 
  },
});

try {
  await testClient.ping();
  console.log('Connected to Elasticsearch successfully');
} catch (error: unknown) {
  if (error instanceof Error) {
    console.error('Failed to connect to Elasticsearch:', error.message);
  } else {
    console.error('Failed to connect to Elasticsearch:', error);
  }
  process.exit(1);
}
//Initialize the Elasticsearch vector store
const vectorStore = new ElasticVector({
  node: ELASTICSEARCH_ENDPOINT,
  auth: {
    apiKey: ELASTICSEARCH_API_KEY,
  },
//Optional: Explicitly set to true if using Elasticsearch Serverless to skip auto-detection and improve startup time
//isServerless: true,
});<p>Hier, wir:</p><ul><li><p>Verwenden Sie <code>dotenv</code> um unsere Variablen aus unserer <code>.env</code> -Datei zu laden.</p></li><li><p>Prüfen Sie, ob die Elasticsearch-Zugangsdaten korrekt eingefügt werden, dann können wir eine erfolgreiche Verbindung zum Client herstellen.</p></li><li><p>Übergeben Sie den Elasticsearch-Endpunkt und den API-Schlüssel an den <code>ElasticVector</code> -Konstruktor, um eine Instanz unseres zuvor definierten Vektorspeichers zu erstellen.</p></li><li><p>Optional können Sie <code>isServerless: true</code> angeben, wenn Sie Elasticsearch Serverless verwenden. Dadurch wird der automatische Erkennungsschritt übersprungen und die Startzeit verkürzt. Wird dieser Parameter weggelassen, erkennt der Adapter Ihren Bereitstellungstyp bei der ersten Verwendung automatisch.</p></li></ul><p>Als nächstes können wir den Agenten mithilfe der Klasse <code>Agent</code> von Mastra definieren.</p>export const knowledgeAgent = new Agent({
    name: 'KnowledgeAgent',
    instructions: 'You are a helpful knowledge assistant.',
    model: openai('gpt-4o'),
    memory: new Memory({

        vector: vectorStore,

        //embedder used to create embeddings for each message
        embedder: 'openai/text-embedding-3-small',

        //set semantic recall options
        options: {
            semanticRecall: {
                topK: 3, // retrieve 3 similar messages
                messageRange: 2, // include 2 messages before/after each match
                scope: 'resource',
            },
        },
    }),
});<p>Folgende Felder können wir definieren:</p><ul><li><p><code>name</code> und <code>instructions</code>: Gib ihr eine Identität und eine primäre Funktion.</p></li><li><p><code>model</code>Wir verwenden OpenAIs <code>gpt-4o</code> über das <code>@ai-sdk/openai</code> -Paket.</p></li><li><p><code>memory</code>:</p><ul><li><p><code>vector</code>: Verweist auf unseren Elasticsearch-Speicher, sodass Einbettungen dort gespeichert und abgerufen werden.</p></li><li><p><code>embedder</code>Welches Modell soll zur Generierung von Einbettungen verwendet werden?</p></li><li><p><code>semanticRecall</code> Die Optionen bestimmen, wie der Rückruf funktioniert:</p><ul><li><p><code>topK</code>: Wie viele semantisch ähnliche Nachrichten sollen abgerufen werden?</p></li><li><p><code>messageRange</code>: Wie viel vom Gespräch soll bei jedem Spielzug einbezogen werden?</p></li><li><p><code>scope</code>: Definiert die Speichergrenze.</p></li></ul></li></ul></li></ul><p>Fast fertig. Wir müssen diesen neu erstellten Agenten lediglich zu unserer Mastra-Konfiguration hinzufügen. Importieren Sie in der Datei mit dem Namen <a href="http://index.ts/"><code>index.ts</code></a> den Wissensagenten und fügen Sie ihn in das Feld <code>agents</code> ein.</p>export const mastra = new Mastra({
  agents: { knowledgeAgent },
  storage: new LibSQLStore({
    // stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
    url: ":memory:",
  }),
  logger: new PinoLogger({
    name: 'Mastra',
    level: 'info',
  }),
  telemetry: {
    // Telemetry is deprecated and will be removed in the Nov 4th release
    enabled: false, 
  },
  observability: {
    // Enables DefaultExporter and CloudExporter for AI tracing
    default: { enabled: true }, 
  },
});<p>Zu den weiteren Bereichen gehören:</p><ul><li><p><code>storage</code>Dies ist Mastras interner Datenspeicher für Laufzeitverlauf, Observability-Metriken, Scores und Caches. Weitere Informationen zu Mastra-Speicherlösungen finden Sie <a href="https://mastra.ai/docs/server-db/storage">hier</a>.</p></li><li><p><code>logger</code>Mastra verwendet <a href="https://github.com/pinojs/pino">Pino</a>, einen leichtgewichtigen, strukturierten JSON-Logger. Es erfasst Ereignisse wie Agentenstart und -stopp, Toolaufrufe und -ergebnisse, Fehler und LLM-Reaktionszeiten.</p></li><li><p><code>observability</code>: Steuert die KI-Verfolgung und die Sichtbarkeit der Ausführung von Agenten. Es verfolgt:</p><ul><li><p>Beginn/Ende jedes Denkschritts.</p></li><li><p>Welches Modell oder Werkzeug wurde verwendet?</p></li><li><p>Ein- und Ausgänge.</p></li><li><p>Bewertungen und Beurteilungen</p></li></ul></li></ul><h3>Testen des Agenten mit Mastra Studio</h3><p>Glückwunsch! Wenn Sie es bis hierher geschafft haben, sind Sie bereit, diesen Agenten auszuführen und seine semantischen Erinnerungsfähigkeiten zu testen. Zum Glück bietet Mastra eine integrierte Chat-Benutzeroberfläche, sodass wir keine eigene entwickeln müssen.</p><p>Um den Mastra-Entwicklungsserver zu starten, öffnen Sie ein Terminal und führen Sie folgenden Befehl aus:</p>npm run dev<p>Nach der ersten Bündelung und dem Start des Servers sollte Ihnen eine Adresse für den Playground bereitgestellt werden.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte5f857fddc74ffc9/6a16f7b6a6c2b995d5e794c0/8b045f70008d26aec4d2e6b59d61085555b9c5b2-686x116.png" alt="Serveradresse für Playground" /><p>Fügen Sie diese Adresse in Ihren Browser ein, und Sie gelangen zum Mastra Studio.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc7fdda6ce46ce068/6a16f7b7b0367d4f7672bacf/69bc80fe8486edd9e0cf91d87b39f465aeb23111-1600x438.png" alt="Einfügen der Playground-Adresse, um auf Mastra Studio zuzugreifen" /><p>Wählen Sie die Option für <code>knowledgeAgent</code> und legen Sie los.</p><p>Um schnell zu prüfen, ob alles richtig verkabelt ist, geben Sie ihm beispielsweise folgende Information: „Das Team gab bekannt, dass die Umsatzentwicklung im Oktober um 12 % gestiegen ist, hauptsächlich aufgrund von Vertragsverlängerungen im Unternehmensbereich.“ Der nächste Schritt besteht darin, die Kundenansprache auf mittelständische Unternehmen auszuweiten.“ Starten Sie anschließend einen neuen Chat und stellen Sie eine Frage wie: „Auf welches Kundensegment sollten wir uns als Nächstes konzentrieren?“ Der Wissensagent sollte in der Lage sein, die Informationen aus dem ersten Chat abzurufen. Sie sollten eine Antwort wie diese sehen:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfec3266e81a7213b/6a16f7b92b835f6f70f4afe2/da8ebddad89874023ed440a8f1ad2cb04ed043f4-1070x288.png" alt="Chatten mit einem Wissensagenten in Mastra Studio – der Agent kann Informationen abrufen" /><p>Eine solche Antwort bedeutet, dass der Agent unsere vorherige Nachricht erfolgreich als Einbettungen in Elasticsearch gespeichert und später mithilfe der Vektorsuche abgerufen hat.</p><h3>Überprüfung des Langzeitspeichers des Agenten</h3><p>Wechseln Sie im Mastra Studio zur Registerkarte <code>memory</code> in der Konfiguration Ihres Agenten. So können Sie sehen, was Ihr Agent im Laufe der Zeit gelernt hat. Jede Nachricht, Antwort und Interaktion, die in Elasticsearch eingebettet und gespeichert wird, wird Teil dieses Langzeitgedächtnisses. Sie können vergangene Interaktionen semantisch durchsuchen, um schnell erinnerte Informationen oder Kontexte wiederzufinden, die der Agent zuvor gelernt hat. Dies ist im Wesentlichen derselbe Mechanismus, den der Agent beim semantischen Abruf verwendet, aber hier können Sie ihn direkt untersuchen. In unserem unten stehenden Beispiel suchen wir nach dem Begriff „Vertrieb“ und erhalten jede Interaktion zurück, die etwas mit Vertrieb zu tun hat.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte428134d7bf2a43a/6a16f7bbb0367d185872bad3/3decaa0c332d288c5ae0b11c25f592c7d50c2f0f-1104x1320.png" alt="Wie man den Langzeitspeicher von Wissensagenten untersucht" /><h2>Fazit</h2><p>Durch die Verbindung von Mastra und Elasticsearch können wir unseren Agenten Speicher zur Verfügung stellen, was eine wichtige Ebene im Kontext-Engineering darstellt. Mithilfe des semantischen Abrufs können Agenten im Laufe der Zeit Kontext aufbauen und ihre Antworten auf dem basieren, was sie gelernt haben. Das bedeutet genauere, zuverlässigere und natürlichere Interaktionen.</p><p>Diese frühe Integration ist nur der Ausgangspunkt. Das gleiche Prinzip kann hier Support-Mitarbeitern ermöglichen, die sich an frühere Tickets erinnern, internen Bots, die relevante Dokumente abrufen, oder KI-Assistenten, die sich mitten im Gespräch an Kundendetails erinnern können. Wir arbeiten außerdem an einer offiziellen Mastra-Integration, wodurch diese Verbindung in naher Zukunft noch nahtloser wird.</p><p>Wir sind gespannt, was Sie als Nächstes entwickeln werden. Probieren Sie es aus, erkunden Sie <a href="https://mastra.ai/">Mastra</a> und seine Speicherfunktionen und teilen Sie Ihre Entdeckungen gerne mit der Community.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/knowledge-agent-semantic-recall-mastra-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/knowledge-agent-semantic-recall-mastra-elasticsearch</guid>
    <category><![CDATA[Agentische KI]]></category>
    <category><![CDATA[Entwicklererfahrung]]></category>
    <category><![CDATA[Integrationen]]></category>
    <dc:creator><![CDATA[JD Armada]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt09afdbff05603865/6a16f7bd839dfabbf2dcfcb5/b8d51c2726d5573385c9246a7821d12ade4f1b0e-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 06 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>