基于专用终结点的Azure认知搜索:内置技能代理函数实现问询
实现Azure内置技能代理的Azure Function方案
核心思路
要在内网环境(禁用公网)下使用Azure认知搜索内置技能,需通过部署在同一虚拟网络、支持专用终结点的Azure Function作为代理,转发搜索服务的技能调用请求到同虚拟网络内的Azure AI服务,全程不通过公网传输。
关键实现步骤
1. 项目依赖配置
在Azure Function项目中引入必要的NuGet包:
Microsoft.Azure.Search:用于处理搜索服务的技能请求/响应模型Microsoft.Azure.CognitiveServices.Language.TextAnalytics(以文本分析技能为例,可根据实际使用的内置技能调整):用于调用Azure AI服务的原生SDKMicrosoft.Azure.Functions.Worker:Azure Function运行时依赖
2. 代理函数核心代码实现
以下是文本分析内置技能的代理示例,可根据其他内置技能(如实体识别、关键短语提取等)调整:
using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Azure.Search.Models; using Microsoft.Azure.CognitiveServices.Language.TextAnalytics; using Microsoft.Azure.CognitiveServices.Language.TextAnalytics.Models; using System.Net; using System.Text.Json; public class CognitiveSkillProxy { private readonly ITextAnalyticsClient _textAnalyticsClient; // 通过依赖注入初始化Azure AI服务客户端(使用虚拟网络内的专用终结点) public CognitiveSkillProxy(ITextAnalyticsClient textAnalyticsClient) { _textAnalyticsClient = textAnalyticsClient; } [Function("TextAnalyticsProxy")] public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req) { // 解析搜索服务发送的技能请求 var requestBody = await new StreamReader(req.Body).ReadToEndAsync(); var skillRequest = JsonSerializer.Deserialize<WebApiSkillRequest>(requestBody); if (skillRequest == null || skillRequest.Values == null || !skillRequest.Values.Any()) { return req.CreateResponse(HttpStatusCode.BadRequest); } // 处理每个输入项 var responseValues = new List<WebApiSkillResponseValue>(); foreach (var value in skillRequest.Values) { try { // 从请求中提取要分析的文本(根据内置技能的输入字段调整) if (!value.Data.TryGetValue("text", out var textObj) || string.IsNullOrEmpty(textObj.ToString())) { responseValues.Add(new WebApiSkillResponseValue { RecordId = value.RecordId, Errors = new List<WebApiError> { new WebApiError { Message = "Missing or empty 'text' field" } } }); continue; } var text = textObj.ToString(); // 调用同虚拟网络内的Azure AI服务文本分析接口(以关键短语提取为例) var result = await _textAnalyticsClient.KeyPhrasesAsync(new MultiLanguageBatchInput( new List<MultiLanguageInput> { new MultiLanguageInput("zh", value.RecordId, text) })); // 转换为搜索服务期望的响应格式 var keyPhrases = result.Documents.FirstOrDefault()?.KeyPhrases ?? new List<string>(); responseValues.Add(new WebApiSkillResponseValue { RecordId = value.RecordId, Data = new Dictionary<string, object> { { "keyPhrases", keyPhrases } } }); } catch (Exception ex) { responseValues.Add(new WebApiSkillResponseValue { RecordId = value.RecordId, Errors = new List<WebApiError> { new WebApiError { Message = ex.Message } } }); } } // 构造并返回响应 var skillResponse = new WebApiSkillResponse { Values = responseValues }; var response = req.CreateResponse(HttpStatusCode.OK); await response.WriteAsJsonAsync(skillResponse); return response; } }
3. 客户端配置要点
- 配置Azure AI服务客户端时,指定专用终结点URL(而非公网URL),确保请求在虚拟网络内传输。
- 使用Azure AD身份验证或资源密钥进行身份验证,密钥需从Azure门户的AI服务资源中获取。
4. 搜索服务技能集成
在认知搜索的技能集中,将原本的内置技能替换为自定义Web API技能,指向该Azure Function的专用终结点URL,并配置对应的输入输出字段(与原内置技能保持一致)。
注意事项
- 确保Azure Function、认知搜索服务、Azure AI服务都部署在同一虚拟网络中,且已配置专用终结点,关闭公网访问。
- 不同内置技能的输入输出字段存在差异,需根据具体技能(如实体识别、情感分析等)调整代码中的数据提取和响应构造逻辑。
- 需为Azure Function配置足够的权限,确保能访问同虚拟网络内的Azure AI服务。
内容的提问来源于stack exchange,提问作者dafad_dew
相关产品推荐
相关产品推荐

