Delen via


Vectoropslag in Azure AI Search

Azure AI Search biedt vectoropslag en configuraties voor vectorzoekopdrachten en hybride zoekopdrachten. Ondersteuning wordt geïmplementeerd op veldniveau, wat betekent dat u vector- en nietvectorvelden in hetzelfde zoeklichaam kunt combineren.

Vectoren worden opgeslagen in een zoekindex. Gebruik de CREATE Index REST API of een equivalente Azure SDK-methode om het vectorarchief te maken.

Overwegingen voor vectoropslag zijn onder andere de volgende punten:

  • Ontwerp een schema dat past bij uw use-case op basis van het beoogde vectorinhalingspatroon.
  • Maak een schatting van de indexgrootte en controleer de capaciteit van de zoekservice.
  • Een vectorarchief beheren
  • Een vectorarchief beveiligen

Patronen voor het ophalen van vectoren

In Azure AI Search zijn er twee patronen voor het werken met zoekresultaten.

  • Generatief zoeken. Taalmodellen formuleren een antwoord op de query van de gebruiker met behulp van gegevens uit Azure AI Search. Dit patroon bevat een indelingslaag om prompts te coördineren en context te onderhouden. In dit patroon worden zoekresultaten ingevoerd in promptstromen, ontvangen door chatmodellen zoals GPT en Text-Davinci. Deze benadering is gebaseerd op de RAG-architectuur (Retrieval Augmented Generation), waarbij de zoekindex de grondgegevens levert.

  • Klassieke zoekopdracht met behulp van een zoekbalk, queryinvoertekenreeks en weergegeven resultaten. De zoekmachine accepteert en voert de vectorquery uit, formuleert een antwoord en u geeft deze resultaten weer in een client-app. In Azure AI Search worden resultaten geretourneerd in een afgevlakte rijset en kunt u kiezen welke velden u wilt opnemen in zoekresultaten. Omdat er geen chatmodel is, wordt verwacht dat u het vectorarchief (zoekindex) zou vullen met niet-vectorinhoud die door mensen kan worden gelezen in uw antwoord. Hoewel de zoekmachine overeenkomt met vectoren, moet u niet-vectorwaarden gebruiken om de zoekresultaten te vullen. Vectorquery's en hybride query's hebben betrekking op de typen queryaanvragen die u kunt formuleren voor klassieke zoekscenario's.

Uw indexschema moet overeenkomen met uw primaire use case. In de volgende sectie ziet u de verschillen in veldsamenstelling voor oplossingen die zijn gebouwd voor generatieve AI of klassieke zoekopdrachten.

Schema van een vectorarchief

Een indexschema voor een vectorarchief vereist een naam, een sleutelveld (tekenreeks), een of meer vectorvelden en een vectorconfiguratie. Niet-ctorvelden worden aanbevolen voor hybride query's of voor het retourneren van letterlijke leesbare inhoud die niet door een taalmodel hoeft te lopen. Zie Een vectorarchief maken voor instructies over vectorconfiguratie.

Basisvectorveldconfiguratie

Vectorvelden worden onderscheiden door hun gegevenstype en vectorspecifieke eigenschappen. Hier ziet u hoe een vectorveld eruitziet in een veldenverzameling:

{
    "name": "content_vector",
    "type": "Collection(Edm.Single)",
    "searchable": true,
    "retrievable": true,
    "dimensions": 1536,
    "vectorSearchProfile": "my-vector-profile"
}

Vectorvelden zijn van het type Collection(Edm.Single).

Vectorvelden moeten doorzoekbaar en ophaalbaar zijn, maar ze kunnen niet worden gefilterd, facetabel of sorteerbaar zijn, of analyses, normalizers of synoniementoewijzingen hebben.

Vectorvelden moeten zijn dimensions ingesteld op het aantal insluitingen dat door het insluitingsmodel wordt gegenereerd. Met tekst-insluiten-ada-002 worden bijvoorbeeld 1536 insluitingen gegenereerd voor elk stuk tekst.

Vectorvelden worden geïndexeerd met behulp van algoritmen die worden aangegeven door een vectorzoekprofiel, dat elders in de index is gedefinieerd en dus niet wordt weergegeven in het voorbeeld. Zie de configuratie van vectorzoekopdrachten voor meer informatie.

Verzameling velden voor basisvectorworkloads

Vectorarchieven vereisen meer velden naast vectorvelden. Een sleutelveld ("id" in dit voorbeeld) is bijvoorbeeld een indexvereiste.

"name": "example-basic-vector-idx",
"fields": [
  { "name": "id", "type": "Edm.String", "searchable": false, "filterable": true, "retrievable": true, "key": true },
  { "name": "content_vector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "dimensions": 1536, "vectorSearchProfile": null },
  { "name": "content", "type": "Edm.String", "searchable": true, "retrievable": true, "analyzer": null },
  { "name": "metadata", "type": "Edm.String", "searchable": true, "filterable": true, "retrievable": true, "sortable": true, "facetable": true }
]

Andere velden, zoals het "content" veld, bieden het leesbare equivalent van het "content_vector" veld. Als u taalmodellen uitsluitend gebruikt voor antwoordformulering, kunt u niet-ctorinhoudsvelden weglaten, maar oplossingen die zoekresultaten rechtstreeks naar client-apps pushen, moeten niet-ctorinhoud hebben.

Metagegevensvelden zijn handig voor filters, met name als metagegevens oorsprongsinformatie over het brondocument bevatten. U kunt niet rechtstreeks filteren op een vectorveld, maar u kunt prefilter- of postfiltermodi instellen om te filteren voor of na de uitvoering van vectorquery's.

Schema gegenereerd door de wizard Gegevens importeren en vectoriseren

We raden de wizard Gegevens importeren en vectoriseren aan voor evaluatie en proof-of-concept-tests. De wizard genereert het voorbeeldschema in deze sectie.

De vooroordelen van dit schema zijn dat zoekdocumenten zijn gebouwd rond gegevenssegmenten. Als een taalmodel het antwoord formuleert, zoals gebruikelijk is voor RAG-apps, wilt u een schema dat is ontworpen rond gegevenssegmenten.

Gegevenssegmentering is nodig om binnen de invoerlimieten van taalmodellen te blijven, maar het verbetert ook de nauwkeurigheid van zoekopdrachten in overeenkomsten wanneer query's kunnen worden vergeleken met kleinere segmenten inhoud die uit meerdere bovenliggende documenten zijn opgehaald. Als u semantische rangschikking gebruikt, heeft de semantische rangschikking ook tokenlimieten, die gemakkelijker worden bereikt als gegevenssegmentering deel uitmaakt van uw benadering.

In het volgende voorbeeld is er voor elk zoekdocument één segment-id, segment, titel en vectorveld. De chunkID en de bovenliggende id worden ingevuld door de wizard, met behulp van base 64-codering van blobmetagegevens (pad). Chunk en titel zijn afgeleid van blob-inhoud en blobnaam. Alleen het vectorveld wordt volledig gegenereerd. Dit is de gevectoriseerde versie van het segmentveld. Insluitingen worden gegenereerd door een Azure OpenAI-insluitingsmodel aan te roepen dat u opgeeft.

"name": "example-index-from-import-wizard",
"fields": [
  {"name": "chunk_id",  "type": "Edm.String", "key": true, "searchable": true, "filterable": true, "retrievable": true, "sortable": true, "facetable": true, "analyzer": "keyword"},
  { "name": "parent_id", "type": "Edm.String", "searchable": true, "filterable": true, "retrievable": true, "sortable": true},
  { "name": "chunk", "type": "Edm.String", "searchable": true, "filterable": false, "retrievable": true, "sortable": false},
  { "name": "title", "type": "Edm.String", "searchable": true, "filterable": true, "retrievable": true, "sortable": false},
  { "name": "vector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "dimensions": 1536, "vectorSearchProfile": "vector-1707768500058-profile"}
]

Schema voor RAG- en chat-apps

Als u opslag ontwerpt voor generatieve zoekopdrachten, kunt u afzonderlijke indexen maken voor de statische inhoud die u hebt geïndexeerd en gevectoriseerd, en een tweede index voor gesprekken die kunnen worden gebruikt in promptstromen. De volgende indexen worden gemaakt op basis van de accelerator chat-with-your-data-solution-accelerator.

Schermopname van de indexen die door de accelerator zijn gemaakt.

Velden uit de chatindex die ondersteuning bieden voor generatieve zoekervaring:

"name": "example-index-from-accelerator",
"fields": [
  { "name": "id", "type": "Edm.String", "searchable": false, "filterable": true, "retrievable": true },
  { "name": "content", "type": "Edm.String", "searchable": true, "filterable": false, "retrievable": true },
  { "name": "content_vector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "dimensions": 1536, "vectorSearchProfile": "my-vector-profile"},
  { "name": "metadata", "type": "Edm.String", "searchable": true, "filterable": false, "retrievable": true },
  { "name": "title", "type": "Edm.String", "searchable": true, "filterable": true, "retrievable": true, "facetable": true },
  { "name": "source", "type": "Edm.String", "searchable": true, "filterable": true, "retrievable": true  },
  { "name": "chunk", "type": "Edm.Int32", "searchable": false, "filterable": true, "retrievable": true },
  { "name": "offset", "type": "Edm.Int32", "searchable": false, "filterable": true, "retrievable": true }
]

Velden uit de gesprekkenindex die indeling en chatgeschiedenis ondersteunt:

"fields": [
    { "name": "id", "type": "Edm.String", "key": true, "searchable": false, "filterable": true, "retrievable": true, "sortable": false, "facetable": false },
    { "name": "conversation_id", "type": "Edm.String", "searchable": false, "filterable": true, "retrievable": true, "sortable": false, "facetable": true },
    { "name": "content", "type": "Edm.String", "searchable": true, "filterable": false, "retrievable": true },
    { "name": "content_vector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "dimensions": 1536, "vectorSearchProfile": "default-profile" },
    { "name": "metadata", "type": "Edm.String", "searchable": true, "filterable": false, "retrievable": true },
    { "name": "type", "type": "Edm.String", "searchable": false, "filterable": true, "retrievable": true, "sortable": false, "facetable": true },
    { "name": "user_id", "type": "Edm.String", "searchable": false, "filterable": true, "retrievable": true, "sortable": false, "facetable": true },
    { "name": "sources", "type": "Collection(Edm.String)", "searchable": false, "filterable": true, "retrievable": true, "sortable": false, "facetable": true },
    { "name": "created_at", "type": "Edm.DateTimeOffset", "searchable": false, "filterable": true, "retrievable": true },
    { "name": "updated_at", "type": "Edm.DateTimeOffset", "searchable": false, "filterable": true, "retrievable": true }
]

Hier volgt een schermopname met zoekresultaten in Search Explorer voor de gespreksindex. De zoekscore is 1,00 omdat de zoekopdracht niet is gekwalificeerd. Let op de velden die bestaan ter ondersteuning van indeling en promptstromen. Een gespreks-id identificeert een specifieke chat. "type" geeft aan of de inhoud afkomstig is van de gebruiker of de assistent. Datums worden gebruikt om chats uit de geschiedenis te verouderen.

Schermopname van Search Explorer met resultaten van een index die is ontworpen voor RAG-apps.

Fysieke structuur en grootte

In Azure AI Search is de fysieke structuur van een index grotendeels een interne implementatie. U kunt het schema openen, inhoud laden en er query's op uitvoeren, de grootte ervan bewaken en capaciteit beheren, maar de clusters zelf (omgekeerde en vectorindexen) en andere bestanden en mappen) worden intern beheerd door Microsoft.

De grootte en inhoud van een index worden bepaald door:

  • Hoeveelheid en samenstelling van uw documenten
  • Kenmerken voor afzonderlijke velden. Er is bijvoorbeeld meer opslagruimte vereist voor filterbare velden.
  • Indexconfiguratie, inclusief vectorconfiguratie die aangeeft hoe de interne navigatiestructuren worden gemaakt op basis van of u HNSW of een uitgebreide KNN kiest voor overeenkomsten zoeken.

Azure AI Search legt limieten op voor vectoropslag, waarmee u een evenwichtig en stabiel systeem voor alle workloads kunt onderhouden. Om u te helpen onder de limieten te blijven, wordt vectorgebruik afzonderlijk in Azure Portal bijgehouden en gerapporteerd, en programmatisch via service- en indexstatistieken.

In de volgende schermopname ziet u een S1-service die is geconfigureerd met één partitie en één replica. Deze specifieke service heeft 24 kleine indexen, met gemiddeld één vectorveld, elk veld dat bestaat uit 1536 insluitingen. Op de tweede tegel ziet u het quotum en het gebruik voor vectorindexen. Een vectorindex is een interne gegevensstructuur die wordt gemaakt voor elk vectorveld. Als zodanig is opslag voor vectorindexen altijd een fractie van de opslag die door de index wordt gebruikt. Andere niet-ctorvelden en gegevensstructuren verbruiken de rest.

Schermopname van gebruikstegels met opslag, vectorindex en indexaantal.

Vectorindexlimieten en schattingen worden behandeld in een ander artikel, maar twee punten om vooraf te benadrukken, is dat de maximale opslag verschilt per servicelaag en ook wanneer de zoekservice is gemaakt. Nieuwere services met dezelfde laag hebben aanzienlijk meer capaciteit voor vectorindexen. Voer om deze redenen de volgende acties uit:

  • Controleer de implementatiedatum van uw zoekservice. Als deze vóór 3 april 2024 is gemaakt, kunt u overwegen een nieuwe zoekservice te maken voor een grotere capaciteit.

  • Kies een schaalbare laag als u schommelingen in vectoropslagvereisten verwacht. De Basic-laag is vastgezet op één partitie op oudere zoekservices. Overweeg Standard 1 (S1) en hoger voor meer flexibiliteit en snellere prestaties, of maak een nieuwe zoekservice die gebruikmaakt van hogere limieten en meer partities in elke nillable laag.

Basisbewerkingen en interactie

In deze sectie worden vectorruntimebewerkingen geïntroduceerd, waaronder het maken van verbinding met en het beveiligen van één index.

Notitie

Houd er bij het beheren van een index rekening mee dat er geen portal- of API-ondersteuning is voor het verplaatsen of kopiëren van een index. In plaats daarvan verwijzen klanten doorgaans hun toepassingsimplementatieoplossing naar een andere zoekservice (als ze dezelfde indexnaam gebruiken) of passen ze de naam aan om een kopie te maken op de huidige zoekservice en bouw deze vervolgens.

Continu beschikbaar

Een index is onmiddellijk beschikbaar voor query's zodra het eerste document is geïndexeerd, maar is pas volledig operationeel als alle documenten zijn geïndexeerd. Intern wordt een index verdeeld over partities en wordt uitgevoerd op replica's. De fysieke index wordt intern beheerd. De logische index wordt door u beheerd.

Een index is continu beschikbaar, zonder de mogelijkheid om deze te onderbreken of offline te halen. Omdat het is ontworpen voor continue werking, vindt elke update van de inhoud of toevoegingen aan de index zelf in realtime plaats. Als gevolg hiervan kunnen query's tijdelijk onvolledige resultaten retourneren als een aanvraag samenvalt met een documentupdate.

U ziet dat querycontinuïteit bestaat voor documentbewerkingen (vernieuwen of verwijderen) en voor wijzigingen die geen invloed hebben op de bestaande structuur en integriteit van de huidige index (zoals het toevoegen van nieuwe velden). Als u structurele updates moet uitvoeren (bestaande velden wijzigen), worden deze meestal beheerd met behulp van een werkstroom voor neerzetten en opnieuw opbouwen in een ontwikkelomgeving of door een nieuwe versie van de index in de productieservice te maken.

Om te voorkomen dat een index opnieuw wordt opgebouwd, kiezen sommige klanten die kleine wijzigingen aanbrengen ervoor om een veld 'versie' te maken door een nieuw veld te maken dat naast een eerdere versie wordt gebruikt. Na verloop van tijd leidt dit tot zwevende inhoud in de vorm van verouderde velden of verouderde aangepaste analysedefinities, met name in een productieindex die duur is om te repliceren. U kunt deze problemen oplossen bij geplande updates van de index als onderdeel van het levenscyclusbeheer van de index.

Eindpuntverbinding

Alle vectorindexerings- en queryaanvragen richten zich op een index. Eindpunten zijn meestal een van de volgende:

Eindpunt Verbinding maken ion en toegangsbeheer
<your-service>.search.windows.net/indexes Is gericht op de verzameling indexen. Wordt gebruikt bij het maken, weergeven of verwijderen van een index. Beheer rechten zijn vereist voor deze bewerkingen, beschikbaar via beheerder API-sleutels of de rol Inzender voor zoeken.
<your-service>.search.windows.net/indexes/<your-index>/docs Is gericht op het verzamelen van documenten van één index. Wordt gebruikt bij het uitvoeren van query's op een index of gegevensvernieuwing. Voor query's zijn leesrechten voldoende en beschikbaar via query-API-sleutels of een rol van gegevenslezer. Voor het vernieuwen van gegevens zijn beheerdersrechten vereist.
  1. Zorg ervoor dat u over machtigingen of een API-toegangssleutel beschikt. Tenzij u een query uitvoert op een bestaande index, hebt u beheerdersrechten of een roltoewijzing inzender nodig om inhoud in een zoekservice te beheren en weer te geven.

  2. Begin met Azure Portal. De persoon die de zoekservice heeft gemaakt, kan de zoekservice bekijken en beheren, inclusief het verlenen van toegang tot anderen via de pagina Toegangsbeheer (IAM ).

  3. Ga verder met andere clients voor programmatische toegang. We raden de quickstarts en voorbeelden aan voor de eerste stappen:

Beveiligde toegang tot vectorgegevens

Azure AI Search implementeert gegevensversleuteling, privéverbindingen voor scenario's zonder internet en roltoewijzingen voor beveiligde toegang via Microsoft Entra-id. Het volledige scala aan bedrijfsbeveiligingsfuncties wordt beschreven in Beveiliging in Azure AI Search.

Vectorarchieven beheren

Azure biedt een bewakingsplatform met diagnostische logboekregistratie en waarschuwingen. We raden de volgende aanbevolen procedures aan:

Zie ook