Azure AI Search: Deploying a Powerful AI-Powered Search Engine

Azure AI Search: KI-Suchmaschine aufbauen

Azure AI Search: Eine leistungsstarke KI-Suchmaschine aufbauen ist das praktische Ziel dieses Artikels: Unternehmensinhalte mit Microsoft Azure AI Search in eine durchsuchbare, gerankte und KI-fähige Wissensebene zu verwandeln.

Dieser Beitrag ist eine praxisnahe Anleitung, um mit Azure AI Search eine leistungsstarke KI-Suchmaschine aufzubauen. Von der Konfiguration des Indexers über das Einrichten des semantischen Rankings bis hin zur Vektorsuche – der hier beschriebene Workflow ist derselbe, den ich für den Aufbau produktionsreifer KI-Suche für reale Workloads nutze.

Azure AI Search ist zumindest meiner Erfahrung nach eine der leistungsstärksten Suchmaschinen. In Zeiten von KI und LLMs erlebt die früher eher langweilige Technologie der Suchmaschinen einen neuen Hype. In diesem Blogbeitrag führe ich dich durch das Bereitstellen und Konfigurieren von Azure AI Search und zeige dir, wie du damit deine Daten in eine hochgradig durchsuchbare, KI-gestützte Ressource verwandelst.

Azure AI Search ist ein Platform-as-a-Service-Angebot (PaaS) von Microsoft Azure. Es ermöglicht Organisationen, Suchindizes aus verschiedenen Datenquellen und Formaten zu erstellen, etwa aus SQL-Datenbanken, PDF-Dokumenten, PowerPoint-Dateien und mehr. Eines seiner herausragenden Merkmale ist die Vektorsuche, die mithilfe von KI Suchanfragen anhand ihrer Bedeutung statt nur anhand von Schlüsselwörtern besser versteht und zuordnet. Du kannst sogar Modelle wie text-embedding-ada-002 von Azure OpenAI oder neuere Versionen nutzen, um deine Suchfähigkeiten zu erweitern.

Den Dienst bereitstellen

Die Bereitstellung ist sehr unkompliziert. Folge diesen Schritten:

  • Öffne das Azure-Portal: Gib in der Suchleiste „Azure AI Search” ein und wähle es aus den Ergebnissen aus.
Azure AI Search: Eine leistungsstarke KI-gestützte Suchmaschine bereitstellen
  • Erstelle den Dienst: Klicke auf die Schaltfläche „+ Erstellen”. Wähle anschließend dein Abonnement, deine Ressourcengruppe und die Region aus und gib deiner Suchressource einen Namen.
  • Sicherheitsüberlegungen: Für Produktionsumgebungen ist es am besten, die Ressource abzusichern, indem du sie im selben Netzwerk wie deine Anwendung platzierst. Für dieses Tutorial überspringen wir diesen Schritt, für Produktionsbereitstellungen ist er jedoch empfehlenswert.
  • Überprüfen und Bereitstellen: Nachdem du deine Einstellungen überprüft hast, klicke auf „Überprüfen + Erstellen”, um die Ressource bereitzustellen.
Azure AI Search: Eine leistungsstarke KI-gestützte Suchmaschine bereitstellen

Das war der einfache Teil.

Deine Umgebung vorbereiten

Bevor du deinen Suchindex erstellst, sind einige Vorbereitungsschritte nötig:

1. Systemseitig zugewiesene verwaltete Identität aktivieren: Damit kann dein Suchdienst sicher auf andere Azure-Ressourcen zugreifen. Du aktivierst dies in den Identitätseinstellungen deiner Azure-AI-Search-Instanz.

Azure AI Search: Eine leistungsstarke KI-gestützte Suchmaschine bereitstellen

2. Blob Storage einrichten: Erstelle ein Blob-Storage-Konto und einen Container, um die zu indizierenden Daten zu speichern. Folge der Anleitung für Azure-Speicherkonten, um dies einzurichten.

3. Ein Embedding-Modell bereitstellen: Um die Vektorsuche zu nutzen, musst du ein Embedding-Modell bereitstellen. Erstelle zunächst eine Azure-OpenAI-Instanz. Nach der Bereitstellung gehst du in den Bereich „Deployments” und wählst das Modell text-embedding-ada-002 oder das neueste verfügbare Modell aus.

Azure AI Search: Eine leistungsstarke KI-gestützte Suchmaschine bereitstellen

Indem du die systemseitig zugewiesene verwaltete Identität aktivierst, kannst du deinem Suchdienst die Berechtigung zum Lesen aus deinem Blob Storage erteilen. Öffne das Blob-Storage-Konto, navigiere zu „Zugriffssteuerung” und weise der verwalteten Identität deines Suchdienstes die Rolle „Storage Blob Data Reader” zu.

Azure AI Search: Eine leistungsstarke KI-gestützte Suchmaschine bereitstellen
Azure AI Search: Eine leistungsstarke KI-gestützte Suchmaschine bereitstellen

Einen Index erstellen

Das Erstellen eines Index in Azure AI Search ist ein wesentlicher Schritt, um deine Daten durchsuchbar zu machen. Du kannst dies über die Weboberfläche erledigen:

1. Den Assistenten verwenden: Auf der Startseite deines Azure-AI-Search-Dienstes findest du einen Assistenten, der dich durch den Prozess der Indexerstellung führt. Klicke auf „Import and Vectorize Data”.

Azure AI Search: Eine leistungsstarke KI-gestützte Suchmaschine bereitstellen

2. Datenquelle auswählen: Wähle dein Blob-Storage-Konto und den Container aus, in dem die zu indizierenden Dateien gespeichert sind.
3. Authentifizieren: Wähle für die Authentifizierung „System-Assigned Identity”.

Azure AI Search: Eine leistungsstarke KI-gestützte Suchmaschine bereitstellen

4. Embedding-Modell hinzufügen: Wähle das zuvor erstellte Embedding-Modell aus.

Azure AI Search: Eine leistungsstarke KI-gestützte Suchmaschine bereitstellen

5. Zeitplan erstellen: Den Schritt „Enrich image” kannst du überspringen (falls du keine Bilder indizieren möchtest) und im Schritt „Advanced settings” einen Zeitplan für eine Aktualisierung auswählen.

Azure AI Search: Eine leistungsstarke KI-gestützte Suchmaschine bereitstellen

6. Überprüfen und Abschließen: Folge den Schritten des Assistenten, um deinen Index fertigzustellen.

Für fortgeschrittenere Umgebungen mit mehreren Stages ist es oft besser, diesen Prozess per Code zu automatisieren.

Mit Code automatisieren

Was ich dir zuvor gezeigt habe, funktioniert, ist aber nicht die optimale Lösung, wenn du dich in einer größeren Umgebung mit mehreren Stages bewegst und Reproduzierbarkeit eine wichtige Rolle spielt. Schauen wir uns an, wie du dasselbe per Code erledigst. Zunächst prüfen wir, welche API-Aufrufe du benötigst. Der erste dient dazu, die Datasource zu erstellen. Sehen wir uns ein Beispiel für eine Azure File Share an:

PUT
https://{SEARCHRESSOURCENAME}.windows.net/datasources/{DTASOURCENAME}?api-version=2024-05-01-Preview
{
    "name": "DATSOURCENAME",
    "description": "DESCRIPTIONOFTHEDATASOURCE",
    "type": "azurefile",
    "credentials": {
        "connectionString": "CONNECTIONSTRINGORTHERAUTH"
    },
    "container": {
        "name": "SHARENAME",
        "query": "QUERY"
    },
    "dataDeletionDetectionPolicy" : {
        "@odata.type" :"#Microsoft.Azure.Search.SoftDeleteColumnDeletionDetectionPolicy",
        "softDeleteColumnName" : "IsDeleted",
        "softDeleteMarkerValue" : "true"
    }
}

Dies ist ein kurzes Python-Skript, um das per Code zu erledigen:

import os
import requests

# Set up environment variables
azure_search_secret = os.getenv("AZURE_SEARCH_KEY")
azure_search_endpoint = "https://your-search-resource.search.windows.net"
file_share_connection_string = os.getenv("FILE_SHARE_CONNECTION_STRING")

# Define the data source
data_source_name = "ds-secret-intune-info"
datasource_url = f"{azure_search_endpoint}/datasources/{data_source_name}?api-version=2024-05-01-Preview"

body = {
    "name": data_source_name,
    "description": "It is very secret",
    "type": "azurefile",
    "credentials": {"connectionString": file_share_connection_string},
    "container": {"name": "intune", "query": "secret"},
    "dataDeletionDetectionPolicy": {
        "@odata.type": "#Microsoft.Azure.Search.SoftDeleteColumnDeletionDetectionPolicy",
        "softDeleteColumnName": "IsDeleted",
        "softDeleteMarkerValue": "true",
    },
}

# Send the request to create the data source
response = requests.put(
    datasource_url,
    json=body,
    timeout=1000,
    headers={"api-key": azure_search_secret, "Content-Type": "application/json"},
)

# Output the response
print(response.json())

Dieses Skript zeigt, wie sich das Erstellen einer Datenquelle automatisieren lässt. Derselbe Ansatz lässt sich anwenden, um Indizes, Indexer, Aliase und Skillsets zu erstellen. Die URLs für die einzelnen API-Endpunkte lauten wie folgt (der Body unterscheidet sich natürlich jeweils):

  • Index: f"{azure_search_endpoint}/indexes/{index_name}?api-version=2024-05-01-Preview"
  • Indexer: f"{azure_search_endpoint}/indexers/{indexer_name}?api-version=2024-05-01-Preview"
  • Skillset: f"{azure_search_endpoint}/skillsets/{skillset_name}?api-version=2024-05-01-Preview"
  • Alias: f"{azure_search_endpoint}/aliases/{alias_name}/reset?api-version=2024-05-01-Preview"

Diese Methode ist ideal für Umgebungen mit komplexen Workflows, in denen Konsistenz über mehrere Stages hinweg entscheidend ist.

Vektorsuche aktivieren

Die Vektorsuche ist ein Gamechanger für Anwendungen, die relevante und kontextbezogene Suchergebnisse liefern müssen. Anders als herkömmliche schlüsselwortbasierte Suchen versteht die Vektorsuche die semantische Bedeutung von Anfragen, indem sie KI-gestützte Embeddings nutzt. So funktioniert es:

  1. Embedding-Modelle: Azure AI Search lässt sich mit Modellen wie text-embedding-ada-002 integrieren, um deine Daten in Vektoren umzuwandeln. Diese Vektoren repräsentieren die Bedeutung hinter Wörtern und Phrasen und machen die Suchergebnisse dadurch genauer und kontextuell relevanter.
  2. Praktischer Anwendungsfall: Wenn du beispielsweise Dokumente zum Kundensupport indizierst, ermöglicht eine Vektorsuche es Nutzern, relevante Inhalte anhand ihrer Frage zu finden, selbst wenn die genaue Formulierung nicht mit den Dokumenten übereinstimmt.

Durch die Kombination von Azure AI Search mit der Vektorsuche kannst du in deinen Anwendungen ein deutlich reichhaltigeres und aussagekräftigeres Sucherlebnis bieten. Egal, ob du eine interne Wissensdatenbank oder ein kundenseitiges Suchtool betreibst – diese Funktion kann die Qualität deiner Ergebnisse erheblich verbessern.

Um dies zu aktivieren, benötigst du ein Skillset wie dieses:

{
  "name": "SKILLSETNAME",
  "description": "...": [
    {
      "@odata.type": "#Microsoft.Skills.Text.AzureOpenAIEmbeddingSkill",
      "name": "RANDOMNAME",
      "description": null,
      "context": "/document/pages/*",
      "resourceUri": "https://your-oai-resource.openai.azure.com",
      "deploymentId": "text-embedding-3-large",
      "apiKey": "APIKEY",
      "modelName": "experimental",
      "inputs": [
        {
          "name": "text",
          "source": "/document/pages/*"
        }
      ],
      "outputs": [
        {
          "name": "embedding",
          "targetName": "vector"
        }
      ],
      "authIdentity": null
    },
    {
      "@odata.type": "#Microsoft.Skills.Text.SplitSkill",
      "name": "RANDOMNAME",
      "description": "Split skill to chunk documents",
      "context": "/document",
      "defaultLanguageCode": "en",
      "textSplitMode": "pages",
      "maximumPageLength": 2000,
      "pageOverlapLength": 500,
      "maximumPagesToTake": 0,
      "inputs": [
        {
          "name": "text",
          "source": "/document/Description"
        }
      ],
      "outputs": [
        {
          "name": "textItems",
          "targetName": "pages"
        }
      ]
    }
  ],
  "cognitiveServices": null,
  "knowledgeStore": null,
  "indexProjections": {
    "selectors": [
      {
        "targetIndexName": "NAMEOFTHEINDEX",
        "parentKeyFieldName": "parent_id",
        "sourceContext": "/document/pages/*",
        "mappings": [
          {
            "name": "chunk",
            "source": "/document/pages/*",
            "inputs": []
          },
          {
            "name": "vector",
            "source": "/document/pages/*/vector",
            "inputs": []
          },

          ...ALL_OTHER_ATTRIBUTES...
        ]
      }
    ],
    "parameters": {
      "projectionMode": "skipIndexingParentDocuments"
    }
  },
  "encryptionKey": null
}

Im Index benötigst du dann die folgende Konfiguration:

{
  "name": "INDEXNAME",
  "defaultScoringProfile": "SCORINGNAME",
  "fields": [
    ...ALL_OTHER_ATTRIBUTES...
    {
      "name": "parent_id",
      "type": "Edm.String",
      "searchable": false,
      "filterable": true,
      "retrievable": true,
      "sortable": false,
      "facetable": true,
      "key": false,
      "indexAnalyzer": null,
      "searchAnalyzer": null,
      "analyzer": null,
      "normalizer": null,
      "dimensions": null,
      "vectorSearchProfile": null,
      "synonymMaps": []
    },
    {
      "name": "chunk",
      "type": "Edm.String",
      "searchable": true,
      "filterable": false,
      "retrievable": true,
      "sortable": true,
      "facetable": false,
      "key": false,
      "indexAnalyzer": null,
      "searchAnalyzer": null,
      "analyzer": null,
      "normalizer": null,
      "dimensions": null,
      "vectorSearchProfile": null,
      "synonymMaps": []
    },
    {
      "name": "vector",
      "type": "Collection(Edm.Single)",
      "searchable": true,
      "filterable": false,
      "retrievable": true,
      "sortable": false,
      "facetable": false,
      "key": false,
      "indexAnalyzer": null,
      "searchAnalyzer": null,
      "analyzer": null,
      "normalizer": null,
      "dimensions": 3072,
      "vectorSearchProfile": "vector-profile",  #Should be the same
      "synonymMaps": []
    }
  ],
  "scoringProfiles": [
    YOUR_SCORING_CONFIG
  ],
  "corsOptions": null,
  "suggesters": [],
  "analyzers": [],
  "normalizers": [],
  "tokenizers": [],
  "tokenFilters": [],
  "charFilters": [],
  "encryptionKey": null,
  "similarity": {
    "@odata.type": "#Microsoft.Azure.Search.BM25Similarity",
    "k1": null,
    "b": null
  },
  "semantic": {
    "defaultConfiguration": null,
    "configurations": [
      YOUR_SEMANTIC_SEARCH_CONFIG
    ]
  },
  "vectorSearch": {
    "algorithms": [
      {
        "name": "RANDOMNAME",
        "kind": "hnsw",
        "hnswParameters": {
          "metric": "cosine",
          "m": 4,
          "efConstruction": 400,
          "efSearch": 500
        },
        "exhaustiveKnnParameters": null
      }
    ],
    "profiles": [
      {
        "name": "vector-profile", #Should be the same
        "algorithm": "RANDOMNAME",
        "vectorizer": "RANDOMNAME"
      }
    ],
    "vectorizers": [
      {
        "name": "RANDOMNAME",
        "kind": "azureOpenAI",
        "azureOpenAIParameters": {
          "resourceUri": "https://your-oai-resource.openai.azure.com",
          "deploymentId": "text-embedding-3-large",
          "apiKey": "APIKEY",
          "modelName": "experimental"
        },
        "customWebApiParameters": null
      }
    ]
  }
}

Fazit

Azure AI Search ist ein vielseitiges Werkzeug, das dir fortschrittliche Suchfunktionen direkt zur Hand gibt. Mit Funktionen wie der Vektorsuche und der nahtlosen Integration in Azure-Dienste kannst du leistungsstarke, KI-gestützte Sucherlebnisse erstellen, die auf deine Daten zugeschnitten sind. Egal, ob du mit strukturierten oder unstrukturierten Daten arbeitest – Azure AI Search hilft dir dabei, neue Erkenntnisse zu gewinnen und die Suchrelevanz zu verbessern.

Auch wenn die anfängliche Einrichtung komplex erscheinen mag, vereinfacht der schrittweise Prozess die Bereitstellung, und mit der Möglichkeit, Aufgaben per Code zu automatisieren, wird das Skalieren deiner Suchlösung handhabbarer. Nutze die Leistung von Azure AI Search, um deine Suchfähigkeiten auf die nächste Stufe zu heben und in der sich wandelnden KI-Landschaft die Nase vorn zu behalten.

Viel Erfolg beim Suchen!
Jannik