Competenza API Web personalizzata in una pipeline di arricchimento di Azure AI Search

Note

Azure AI Search è disponibile tramite il portale di Azure, le API REST e Azure SDK. È inoltre alla base di Foundry IQ, il livello di conoscenza gestito che trasforma il contenuto aziendale in knowledge base riutilizzabili e con riconoscimento delle autorizzazioni per gli agenti nel portale di Microsoft Foundry.

Usare la competenza API Web personalizzata per estendere l'arricchimento tramite intelligenza artificiale chiamando un endpoint API Web che fornisce operazioni personalizzate. Analogamente alle competenze predefinite, una competenza dell'API Web personalizzata include input e output. A seconda degli input, l'API Web riceve un payload JSON quando viene eseguito l'indicizzatore e restituisce un payload JSON come risposta, insieme a un codice di stato di esito positivo. La risposta deve includere gli output specificati dalla competenza personalizzata. Qualsiasi altra risposta è considerata un errore e non vengono eseguiti arricchimenti. La struttura del payload JSON è descritta più avanti in questo documento.

La competenza API Web personalizzata viene usata anche nell'implementazione della funzionalità OpenAI di Azure Sui dati. Se Azure OpenAI è configurato per l'accesso in base al ruolo e si verificano 403 Forbidden errori durante la creazione dell'indice vettoriale, verificare che Azure AI Search abbia un'identità assegnata dal sistema ed eseguito come servizio attendibile in Azure OpenAI.

Note

L'indicizzatore esegue due tentativi per determinati codici di stato HTTP standard restituiti dall'API Web. Questi codici di stato HTTP sono:

  • 502 Bad Gateway
  • 503 Service Unavailable
  • 429 Too Many Requests

@odata.type

Microsoft.Skills.Custom.WebApiSkill

Parametri della competenza

I parametri fanno distinzione tra maiuscole e minuscole.

Nome del parametro Description
uri URI dell'API Web a cui verrà inviato il payload JSON. È consentito solo lo schema URI https. Quando si recupera il set di competenze con GET, il servizio restituisce il valore del ?code= parametro di query per ?code=<redacted> evitare l'esposizione delle chiavi di funzione. Per aggiornare la competenza senza modificare l'URI archiviato, impostare su uri<unchanged>.
authResourceId (Facoltativo) Stringa che, se impostata, indica che questa competenza deve usare un'identità gestita dal sistema nella connessione alla funzione o all'app che ospita il codice. Questa proprietà accetta un ID applicazione (client) o la registrazione dell'app in Microsoft Entra ID, in uno di questi formati: api://<appId>, <appId>/.default, api://<appId>/.default. Questo valore viene usato per definire l'ambito del token di autenticazione recuperato dall'indicizzatore e viene inviato insieme alla richiesta della competenza dell'API Web personalizzata alla funzione o all'app. L'impostazione di questa proprietà richiede che il servizio di ricerca sia configurato per l'identità gestita e che l'app per le funzioni di Azure sia configurata per l'accesso a Microsoft Entra. Per usare questo parametro, chiamare l'API con api-version=2023-10-01-Preview.
authIdentity (Facoltativo) Identità gestita dall'utente usata dal servizio di ricerca per la connessione alla funzione o all'app che ospita il codice. È possibile usare un'identità gestita dal sistema o dall'utente. Per usare un'identità gestita dal sistema, lasciare authIdentity vuoto.
httpMethod Metodo da usare per l'invio del payload. I metodi consentiti sono PUT o POST
httpHeaders Raccolta di coppie chiave-valore in cui le chiavi corrispondono ai nomi di intestazione e i valori rappresentano i valori di intestazione che sono inviati all'API Web insieme al payload. In questa raccolta è proibito l'uso delle intestazioni seguenti: Accept, Accept-Charset, Accept-Encoding, Content-Length, Content-Type, Cookie, Host, TE, Upgrade, Via. Quando si recupera il set di competenze con GET, il servizio restituisce <redacted> per tutti i valori di intestazione per impedire l'esposizione di credenziali, ad esempio token di connessione e chiavi API. Per aggiornare la competenza senza modificare i valori di intestazione archiviati, impostare ogni valore su <unchanged>. Il servizio ripristina il valore archiviato originale.
timeout (facoltativo) Se specificato, indica il timeout per il client HTTP che effettua la chiamata API. Il valore deve essere formattato come valore XSD "dayTimeDuration" (un subset limitato di un valore duration ISO 8601 ). Ad esempio, PT60S per 60 secondi. Se non impostato, viene scelto un valore predefinito di 30 secondi. Il timeout può essere impostato su un massimo di 230 secondi e un minimo di 1 secondo.
batchSize (Facoltativo) Indica quanti "record di dati" (vedere la struttura del payload JSON più avanti) vengono inviati per ogni chiamata API. Se non impostato, viene scelto un valore predefinito di 1000. Usare questo parametro per ottenere un compromesso appropriato tra la velocità effettiva di indicizzazione e il carico nell'API.
degreeOfParallelism (Facoltativo) Se specificato, indica il numero di chiamate effettuate dall'indicizzatore in parallelo all'endpoint specificato. È possibile diminuire questo valore se l'endpoint è in sovraccarico o aumentarlo se l'endpoint è in grado di gestire il carico. Se non è impostato, viene usato un valore predefinito pari a 5. degreeOfParallelism può essere impostato scegliendo un valore da 1 (minimo) a 10 (massimo).

Input delle competenze

Questa competenza non ha input predefiniti. Gli input sono costituiti da qualsiasi campo esistente o qualsiasi nodo nell'albero di arricchimento che si desidera passare alla competenza personalizzata.

Output delle competenze

Questa competenza non ha output predefiniti. Assicurarsi di definire un mapping dei campi di output nell'indicizzatore se l'output della competenza deve essere inviato a un campo nell'indice di ricerca.

Definizione di esempio

{
  "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
  "description": "A custom skill that can identify positions of different phrases in the source text",
  "uri": "https://contoso.count-things.com",
  "batchSize": 4,
  "context": "/document",
  "inputs": [
    {
      "name": "text",
      "source": "/document/content"
    },
    {
      "name": "language",
      "source": "/document/languageCode"
    },
    {
      "name": "phraseList",
      "source": "/document/keyphrases"
    }
  ],
  "outputs": [
    {
      "name": "hitPositions"
    }
  ]
}

Note

Quando si recupera un set di competenze usando GET, il servizio restituisce <redacted> per tutti i valori e ?code=<redacted> per qualsiasi httpHeaders?code= parametro di query in uri. Entrambi i valori impediscono l'esposizione delle credenziali ai chiamanti che hanno il ruolo collaboratore al servizio di ricerca, ma non al servizio esterno. Per aggiornare la competenza senza modificare i valori archiviati, passare <unchanged> per ogni campo interessato.

L'esempio seguente mostra una risposta GET per una competenza che usa l'autenticazione basata su intestazione e un URI della funzione Azure:

{
  "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
  "uri": "https://contoso.example.org/api?code=<redacted>",
  "httpMethod": "POST",
  "name": "myCustomSkill",
  "httpHeaders": {
    "Authorization": "<redacted>",
    "Ocp-Apim-Subscription-Key": "<redacted>"
  }
}

Per aggiornare questa competenza senza modificare i valori esistenti, usare <unchanged>:

{
  "uri": "<unchanged>",
  "httpHeaders": {
    "Authorization": "<unchanged>",
    "Ocp-Apim-Subscription-Key": "<unchanged>"
  }
}

Struttura JSON di input di esempio

Questa struttura JSON rappresenta il payload inviato all'API Web. Segue sempre questi vincoli:

  • L'entità di primo livello è denominata values ed è una matrice di oggetti. Il numero di questi oggetti è al massimo .batchSize

  • Ogni oggetto nella matrice values ha:

    • Proprietà recordId che è una stringa univoca , utilizzata per identificare il record.

    • Proprietà data che è un oggetto JSON. I campi della data proprietà corrispondono ai "nomi" specificati nella inputs sezione della definizione della competenza. I valori di tali campi provengono da source questi campi (che possono provenire da un campo nel documento o potenzialmente da un'altra competenza).

{
    "values": [
      {
        "recordId": "0",
        "data":
           {
             "text": "Este es un contrato en Inglés",
             "language": "es",
             "phraseList": ["Este", "Inglés"]
           }
      },
      {
        "recordId": "1",
        "data":
           {
             "text": "Hello world",
             "language": "en",
             "phraseList": ["Hi"]
           }
      },
      {
        "recordId": "2",
        "data":
           {
             "text": "Hello world, Hi world",
             "language": "en",
             "phraseList": ["world"]
           }
      },
      {
        "recordId": "3",
        "data":
           {
             "text": "Test",
             "language": "es",
             "phraseList": []
           }
      }
    ]
}

Struttura JSON di output di esempio

L'"output" corrisponde alla risposta restituita dall'API Web. L'API Web deve restituire solo un payload JSON verificato esaminando l'intestazione della risposta Content-Type, e deve soddisfare i vincoli seguenti:

  • Deve contenere un'entità di primo livello denominata values che deve essere una matrice di oggetti.

  • Il numero di oggetti nella matrice deve essere lo stesso degli oggetti inviati all'API Web.

  • Ogni oggetto deve avere:

    • Una proprietà recordId.

    • Una proprietà data, che è un oggetto in cui i campi sono arricchimenti corrispondenti ai "nomi" nell'output e il cui valore viene considerato l'arricchimento.

    • Una proprietà errors, una matrice che elenca eventuali errori rilevati che vengono aggiunti alla cronologia di esecuzione dell'indicizzatore. Questa proprietà è obbligatoria, ma può avere un valore null.

    • Una proprietà warnings, una matrice che elenca eventuali avvisi rilevati che vengono aggiunti alla cronologia di esecuzione dell'indicizzatore. Questa proprietà è obbligatoria, ma può avere un valore null.

  • L'ordinamento degli oggetti in values nella richiesta o nella risposta non è importante. Tuttavia, il valore recordId viene usato per la correlazione in modo che eventuali record nella risposta contenenti un recordId che non fa parte della richiesta originale all'API Web vengano rimossi.

{
    "values": [
        {
            "recordId": "3",
            "data": {
            },
            "errors": [
              {
                "message" : "'phraseList' should not be null or empty"
              }
            ],
            "warnings": null
        },
        {
            "recordId": "2",
            "data": {
                "hitPositions": [6, 16]
            },
            "errors": null,
            "warnings": null
        },
        {
            "recordId": "0",
            "data": {
                "hitPositions": [0, 23]
            },
            "errors": null,
            "warnings": null
        },
        {
            "recordId": "1",
            "data": {
                "hitPositions": []
            },
            "errors": null,
            "warnings": [
              {
                "message": "No occurrences of 'Hi' were found in the input text"
              }
            ]
        },
    ]
}

Casi di errore

Oltre all'API Web non disponibile o all'invio di codici di stato non riusciti, considerare i casi seguenti come errori:

  • Se l'API Web restituisce un codice di stato di esito positivo, ma la risposta indica che non application/jsonè , la risposta non è valida e non vengono eseguiti arricchimenti.

  • Se la matrice di risposta values contiene record non validi (ad esempio, mancanti o duplicati recordId), i record non validi non vengono arricchiti. Quando si sviluppano competenze personalizzate, attenersi al contratto di competenza dell'API Web. È possibile fare riferimento a questo esempio fornito nel repository Power skill che segue il contratto previsto.

Nei casi in cui l'API Web non è disponibile o restituisce un errore HTTP, la cronologia di esecuzione dell'indicizzatore include un errore descrittivo con tutti i dettagli disponibili sull'errore HTTP.

Vedere anche