将自定义技能添加到 Azure AI 搜索扩充管道
AI 扩充管道可以包含你个人创建和发布的内置技能和自定义技能。 自定义代码在搜索服务的外部执行(例如,作为 Azure 函数执行),但像任何其他技能一样,它接受输入并将输出发送到技能组。
自定义技能听起来很复杂,但它的实现可能非常简单直接。 如果你通过现有的包提供模式匹配或分类模型,可将从 Blob 提取的内容传递给这些模型进行处理。 由于 AI 扩充基于 Azure,因此模型也应该在 Azure 上。 一些常用的托管方法包括使用 Azure Functions 或容器。
如果要构建自定义技能,本文介绍了用于将该技能集成到管道中的接口。 主要的要求是,要能够以在技能组内作为整体使用的方式接受输入并发出输出。 因此,本文的重点是扩充管道需要的输入格式和输出格式。
自定义技能的优点
通过生成自定义技能,可插入对内容唯一的转换。 例如,可以生成自定义分类模型,以区分商业与金融领域的合同和文档,或者,添加语音识别技能,以便深入探究音频文件获取相关内容。 有关分步示例,请参阅示例:为 AI 扩充创建自定义技能。
设置终结点和超时时间间隔
自定义技能的接口是通过自定义 Web API 技能指定的。
"@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
"description": "This skill has a 230 second timeout",
"uri": "https://[your custom skill uri goes here]",
"authResourceId": "[for managed identity connections, your app's client ID goes here]",
"timeout": "PT230S",
URI 是函数或应用的 HTTPS 终结点。 在设置 URI 时,请确保该 URI 是安全的 (HTTPS)。 如果你的代码托管在 Azure 函数应用中,则 URI 应将 API 密钥包括在标头中或将其用作 URI 参数以对请求进行授权。
如果你的函数或应用使用 Azure 托管标识和 Azure 角色进行身份验证和授权,则自定义技能可以在请求中包含身份验证令牌。 以下几点说明了此方法的要求:
代表索引器发送请求的搜索服务必须配置为使用托管标识(系统分配或用户分配的标识),以便调用方可以通过 Microsoft Entra ID 进行身份验证。
必须为 Microsoft Entra ID 配置函数或应用。
自定义技能定义必须包括
authResourceId
属性。 此属性采用受支持格式的应用程序(客户端)ID:api://<appId>
。
在默认情况下,如果在 30 秒的时间段 (PT30S
) 内未返回响应,到终结点的连接就会超时。 索引管道是同步的,如果未在超时时限内收到响应,索引就会生成超时错误。 可以通过设置 timeout 参数 (PT230S
),将超时间隔增大至最大值 230 秒。
设置 Web API 输入的格式
Web API 必须接受要处理的一组记录。 在每条记录中,提供一个属性包作为 Web API 的输入。
假设要创建一个基本的扩充器来识别合同文本中提到的第一个日期。 在此示例中,技能接受一个输入“contractText”作为合同文本。 技能也具有单个输出,即合同的日期。 若要使扩充器更有趣,请将此“contractDate”以多部分复杂类型的形式返回。
你的 Web API 应该可以接收一批输入记录。 “values”数组中的每个成员都表示某个特定记录的输入。 每条记录都需要具有以下元素:
一个“recordId”成员,它是某个特定记录的独一无二的标识符。 在扩充器返回结果时,它必须提供此“recordId”,以便允许调用方将记录结果匹配到它们的输入。
一个“data”成员,它基本上是用于每条记录的一包输入域。
生成的 Web API 请求可能如下所示:
{
"values": [
{
"recordId": "a1",
"data":
{
"contractText":
"This is a contract that was issues on November 3, 2023 and that involves... "
}
},
{
"recordId": "b5",
"data":
{
"contractText":
"In the City of Seattle, WA on February 5, 2018 there was a decision made..."
}
},
{
"recordId": "c3",
"data":
{
"contractText": null
}
}
]
}
在实践中,可能会结合数百甚至数千条记录调用你的代码,而不仅仅是这里显示的三条记录。
设置 Web API 输出的格式
输出的格式是一组包含“recordId”的记录,以及一个属性包。 这个具体示例仅有一个输出,但你可以输出多个属性。 最佳做法是,如果无法处理某个记录,请考虑返回错误消息和警告消息。
{
"values":
[
{
"recordId": "b5",
"data" :
{
"contractDate": { "day" : 5, "month": 2, "year" : 2018 }
}
},
{
"recordId": "a1",
"data" : {
"contractDate": { "day" : 3, "month": 11, "year" : 2023 }
}
},
{
"recordId": "c3",
"data" :
{
},
"errors": [ { "message": "contractText field required "} ],
"warnings": [ {"message": "Date not found" } ]
}
]
}
将自定义技能添加到技能组
创建 Web API 扩充器时,可将 HTTP 标头和参数描述为请求的一部分。 以下代码片段显示了如何在技能组定义中包含请求参数和可选的 HTTP 标头。 如果需要将配置设置传递到代码,设置 HTTP 标头就会很有用。
{
"skills": [
{
"@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
"name": "myCustomSkill",
"description": "This skill calls an Azure function, which in turn calls TA sentiment",
"uri": "https://indexer-e2e-webskill.chinacloudsites.cn/api/DateExtractor?language=en",
"context": "/document",
"httpHeaders": {
"DateExtractor-Api-Key": "foo"
},
"inputs": [
{
"name": "contractText",
"source": "/document/content"
}
],
"outputs": [
{
"name": "contractDate",
"targetName": "date"
}
]
}
]
}
后续步骤
本文介绍了将自定义技能集成到技能组时所需的接口要求。 通过下面的链接可继续详细了解自定义技能和技能组构成。