在 Azure AI 搜尋服務擴充管線中自訂 Web API 技能

Note

Azure AI 搜尋服務 可透過 Azure 入口網站、REST API 及 Azure SDK 取得。 它同時也是 Foundry IQ 的基礎,這是一個管理式知識層,能將企業內容轉化為可重複使用、權限感知的知識庫,供 Microsoft Foundry 入口網站中的代理使用。

利用 自訂 Web API 技能,呼叫提供自訂操作的 Web API 端點,來擴展 AI 豐富化。 像內建技能一樣, 自訂網頁 API 技能也有輸入和輸出。 根據輸入,當索引器執行時,你的 Web API 會收到一個 JSON payload,並以回應回傳一個 JSON payload 以及成功狀態碼。 回應必須包含你自訂技能指定的輸出。 任何其他的回應會被視為錯誤,並且不會執行任何擴充。 JSON 有效載荷的結構將在本文件後面說明。

自訂網頁 API 技能也用於 Azure OpenAI 的「你的資料」功能實作。 如果 Azure OpenAI 設定為基於角色的存取,且建立向量索引時出現403 Forbidden錯誤,請確認 Azure AI 搜尋服務 是否有系統指派的身份,且在 Azure OpenAI 上作為受信任服務執行。

Note

針對從 Web API 傳回的特定標準 HTTP 狀態碼,索引子會重試兩次。 這些 HTTP 狀態碼為:

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

@odata.type

Microsoft.Skills.Custom.WebApiSkill

技能參數

參數區分大小寫。

參數名稱 Description
uri JSON 承載會傳送的目標 Web API URI。 僅允許 https URI 配置。 當你用 GET 取得技能集時,服務會回傳 ?code= 查詢參數值 ?code=<redacted> ,以防止函式鍵外洩。 要更新技能而不更改儲存的 URI,請設 uri 為 <unchanged>。
authResourceId (可選)一個字串,當設定時表示此技能應該在連接承載該程式碼的函式或應用程式時使用系統管理身份。 此屬性可將應用程式(用戶端)ID 或應用程式在 Microsoft Entra ID 中註冊,格式為 api://<appId>、 <appId>/.default、 或 api://<appId>/.default。 此值用於設定索引器取得的認證權杖範圍,並隨自訂 Web API 技能請求一同傳送至函式或應用程式。 設定此屬性需要您的搜尋服務已針對受控身分識別進行設定,而且您的 Azure 函數應用程式已針對 Microsoft Entra 登入進行設定。 要使用此參數,請呼叫 API api-version=2023-10-01-preview ,並啟用或之後。 關於如何選擇正確數值,請參見 「了解數 authResourceId 值」。
authIdentity (選擇性) 搜尋服務用來連線至裝載程式碼之函式或應用程式的使用者受控識別。 您可以使用系統或使用者受控的識別。 若要使用系統受控識別,請保留 authIdentity 空白。
httpMethod 傳送承載時使用的方法。 允許的方法為 PUT 和 POST
httpHeaders 機碼值組的集合,其中機碼代表標頭名稱,而值代表將與承載一起傳送至 Web API 的標頭值。 下列標頭禁止加入此集合:Accept、Accept-Charset、Accept-Encoding、Content-Length、Content-Type、Cookie、Host、TE, Upgrade、Via。 當你用 GET 取得技能組時,服務會回傳 <redacted> 所有標頭值,以防止憑證(如承載憑證和 API 金鑰)被揭露。 若要更新技能而不更改儲存的標頭值,請將每個值設為 <unchanged>。 該服務會恢復原始儲存值。
timeout (選擇性) 指定時,表示進行 API 呼叫的 http 用戶端逾時。 其必須格式化為 XSD "dayTimeDuration" 值 ( ISO 8601 持續時間 值的受限子集)。 例如,PT60S 為 60 秒。 如果沒有設定,則選擇的預設值為 30 秒。 逾時最高可設定為 230 秒,最低 1 秒。
batchSize (選用) 指出每個 API 呼叫會傳送多少「資料記錄」(請參閱下面的 JSON 承載結構)。 如果未設定,則選擇的預設值為 1000。 利用這個參數在索引吞吐量與 API 負載之間取得適當的權衡。
degreeOfParallelism (選用) 指定時,指示索引子與您所提供的端點平行進行的呼叫數。 如果您的端點因壓力而失敗,則可以減少此值,或者,如果您的端點可以處理負載,則請增加此值。 若未設定,將會使用預設值 0.5。 degreeOfParallelism 最高可以設定為 10,最低為 1。

了解其 authResourceId 價值

當自訂 Web API 技能使用管理身份驗證時,Azure AI 搜尋服務 會取得 Microsoft Entra 存取權杖並發送至自訂技能端點。 該 authResourceId 屬性指定了請求令牌的資源識別碼,也稱為受眾或應用程式 ID URI。 該值必須符合目標應用程式在代幣驗證時的期望。 否則,驗證失敗且回應 401 Unauthorized 不佳。

這個 authResourceId 數值代表承載你自訂技能的應用程式。 它不是你的搜尋服務或索引器的網址。

下表顯示常見格式:

目標應用程式 authResourceId 數值
Microsoft Entra 受保護網頁應用程式 api://<application-client-id>
以自訂應用程式 ID URI 配置的應用程式 自訂應用程式識別碼 URI,例如 api://contoso-customskill
Azure Function protected by Microsoft Entra ID 為功能應用程式的應用程式註冊所設定的應用程式 ID URI,例如 api://contoso-funcapp

此屬性接受帶有及不帶 .default 範圍後綴的格式。 用 api://<appId> 來直接比對應用程式 ID 的 URI。 如果你加上 .default 後綴,例如 api://<appId>/.default,存取權杖的 aud 主張會包含沒有後綴的基礎應用程式 ID URI。

關於如何設定Microsoft Entra Azure函式認證及設定 authResourceId的步驟,請參見「使用搜尋服務管理身份連接 Azure 函式應用程式」。

範例:Microsoft Entra ID 保護的 Azure 函數

在此範例中,Azure AI 搜尋服務 為指定的authResourceId受眾取得存取權杖,並在呼叫自訂技能端點時包含該令牌。

{
  "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
  "uri": "https://contoso-function.azurewebsites.net/api/enrich",
  "authResourceId": "api://contoso-customskill"
}

技能輸入

此技能沒有預設輸入。 輸入是任何現有欄位,或您想要傳遞至自訂技能之擴充樹狀結構中的任何節點。

技能產出

此技能沒有預設輸出。 如果技能的輸出應該傳送至搜尋索引中的欄位,則請務必在索引子中定義輸出欄位對應。

範例定義

{
  "@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

當你使用 GET 取得技能組時,服務會回傳<redacted>所有httpHeaders值以及 ?code=<redacted>?code= .uri 這兩個值都防止持有搜尋服務貢獻者角色但外部服務無角色的來電者暴露憑證。 要更新技能而不改變儲存的值,請對每個受影響欄位都傳遞 <unchanged> 。

以下範例展示了一項技能的 GET 回應,該技能使用基於標頭的認證與 Azure 函式 URI:

{
  "@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>"
  }
}

要在不更改現有值的情況下更新此技能,請使用 <unchanged>:

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

範例輸入 JSON 結構

這個 JSON 結構代表你傳送給 Web API 的有效載荷。 它一律會遵循下列這些條件約束:

  • 最上層的實體稱為 values,且是物件的陣列。 這些物件的數量最多 batchSize為 。

  • values 陣列中的每個物件都具有:

    • 一個 recordId 唯一 字串的 屬性,用來識別該紀錄。

    • 一個 data 屬性是 JSON 物件。 屬性的 data 欄位會對應至技能定義區 inputs 段中指定的「名稱」。 這些欄位的數值來自這些欄位中的 ( source 可以是文件中的某個欄位,或可能是其他技能)。

{
    "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": []
           }
      }
    ]
}

範例輸出 JSON 結構

「輸出」對應至從您的 Web API 傳回的回應。 Web API 應該只傳回 JSON 承載 (透過查看 Content-Type 回應標頭進行驗證),並且應該滿足下列限制式:

  • 應該有一個名為 values 的最上層實體,它應該是物件陣列。

  • 陣列中的物件數目應該與傳送至 Web API 的物件數目相同。

  • 每個物件都應該有:

    • recordId 屬性。

    • data 屬性,它是一個物件,其中的欄位是與 output 中的「名稱」相符的擴充,其值會被視為擴充。

    • errors 屬性,一個會新增至索引子執行歷程記錄中的陣列,其中列出發生的任何錯誤。 此屬性是必要的,但可以具有 null 值。

    • warnings 屬性,一個會新增至索引子執行歷程記錄中的陣列,其中列出發生的任何警告。 此屬性是必要的,但可以具有 null 值。

  • 要求或回應中 values 內的物件順序並不重要。 不過,recordId 用於相互關聯,因此包含 recordId (不是 Web API 的原始要求的一部分) 的回應中的任何記錄都會捨棄。

{
    "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"
              }
            ]
        },
    ]
}

錯誤案例

除了你的 Web API 無法使用或傳送不成功的狀態碼外,以下情況也可視為錯誤:

  • 如果 Web API 回傳成功狀態碼,但回應顯示未 application/json成功,則回應無效且未進行任何豐富化。

  • 如果回應 values 陣列包含無效紀錄(例如缺失或重複 recordId),這些無效紀錄不會被豐富。 在開發自訂技能時,請遵守 Web API 技能合約。 您可以參考此範例,其提供於遵循預期合約的 Power Skill 存放庫。

當 Web API 無法使用或回傳 HTTP 錯誤時,索引器的執行歷史會包含一個友善錯誤,並包含所有可用的 HTTP 錯誤細節。

管理身份驗證的安全考量

當使用管理身份驗證搭配自訂 Web API 技能時,Azure AI 搜尋服務 會取得 Microsoft Entra 存取權杖,用於指定的應用程式authResourceId,並將該憑證包含在發送給該uri端點的請求中。 所uri參考的端點通常是你的 Azure Function、Azure App 服務、Azure API 管理 端點,或其他受 Microsoft Entra 保護的應用程式。 你負責配置並維護端點與應用程式 authResourceId之間的關係。

無論驗證方式為何,自訂技能輸入可能包含客戶提供文件的數值,或是從這些文件衍生出的數值。 把所有自訂技能輸入都當作不可信。 Azure AI 搜尋服務 會將技能組中設定的輸入轉發到你的端點,且不會解讀、驗證或限制其內容以供自訂實作使用。

在使用文件衍生值於外站請求或其他安全敏感操作前,請先驗證並限制自訂技能中的文件衍生值。 使用輸入驗證、目的地允許清單、URL 與主機名稱驗證、協定限制,以及只允許該技能所需的目的地與埠的最低權限網路存取。 欲了解更多資訊,請參閱網路 與連接架構策略。

為維持部署安全,請遵循以下做法:

  • 設定屬性uri只指向受信任端點,這些端點是用來接收 Azure AI 搜尋服務 請求的。
  • 設定authResourceId以識別預期會接收並驗證存取權杖的 Microsoft Entra 應用程式。
  • 確保接收請求的應用程式在處理請求前,先驗證標準令牌主張,包括受眾(aud)、發行者(iss)、租戶(tid)、以及任何必要的應用程式角色或權限。
  • 在授予 Azure AI 搜尋服務 管理身份權限時,應用最小權限原則。
  • 定期檢視自訂 Web API 技能定義、Microsoft Entra 應用程式註冊,以及 Azure AI 搜尋服務 管理身份所獲得的應用程式角色指派與權限。 透過您已建立的變更管理與安全審查流程來審查組態變更。
  • 定期檢視 Azure Functions、App Services、API 及 API 閘道的端點設定。
  • 監控應用程式登入日誌、認證事件及 API 存取日誌,防止意外或未經授權的活動。
  • 移除不再需要的端點、權限、應用程式註冊及角色指派。

限制技能組設定的存取

能建立、修改或執行技能組的使用者,可以同時控制目的地端點以及自訂 Web API 技能所使用的認證設定。 將這些權限限制給受信任的管理員,並在配置管理身份啟用自訂技能時,遵循標準的變更管理與安全審查流程。

Important

該 authResourceId 值用以識別存取權杖的預定接收應用程式。 確保該 uri 端點是預期接收並驗證該應用程式權杖的端點。 錯誤的設定可能導致認證失敗或請求傳送到非預期端點。

另請參閱