使用Azure OpenAI结合认知AI搜索Blob存储文件时结果受限问题
问题分析与解决方案
核心原因
你使用的Azure OpenAI Extensions API(chat/completions带dataSources参数),默认会从Cognitive Search返回的候选结果中,仅筛选最相关的5个左右文档作为上下文喂给大模型生成回答——即使你设置了top=20让Search返回20个候选。此外,你的代码目前只提取了大模型生成的回答内容,没有获取到Cognitive Search返回的完整检索结果列表。
解决方案
方案1:获取完整的检索结果列表
Extensions API的返回结果中,choices[0].messages[1].context.documents字段包含了Cognitive Search实际返回的所有候选文档(即你设置的top=20对应的结果)。修改代码提取这部分内容即可:
string responseContent = await response.Content.ReadAsStringAsync(); JObject parsedJson = JObject.Parse(responseContent); // 获取大模型生成的回答内容 resContent = (string)parsedJson["choices"]?[0]?["messages"]?[1]?["content"]; // 获取完整的检索结果列表 var retrievedDocuments = parsedJson["choices"]?[0]?["messages"]?[1]?["context"]?["documents"]; if (retrievedDocuments != null && retrievedDocuments.Type == JTokenType.Array) { foreach (JToken doc in retrievedDocuments) { string documentId = (string)doc["id"]; string documentContent = (string)doc["content"]; string documentSource = (string)doc["source"]; // 处理每个检索到的文档,比如存储到列表或输出 } }
方案2:让大模型基于更多文档生成回答
如果你需要大模型在生成回答时使用更多检索到的文档,可通过以下调整实现:
- 在
dataSources.parameters中添加semanticConfigurationName(需提前在Cognitive Search中配置语义搜索),提升结果相关性排序的准确性,让更多优质结果被纳入上下文。 - 增大
top参数值(比如设置为50),同时确保max_tokens足够大,能容纳更多文档的上下文内容(注意不超过模型的上下文窗口限制,比如gpt-3.5-turbo-16k最大支持16384 tokens)。 - 升级API版本到最新预览版(如
2024-02-15-preview),该版本支持更多控制检索结果使用的参数,例如maxRetrievalDocuments(部分区域可用)。
修改后的payload示例:
var payload = new { dataSources = new[] { new { type = "AzureCognitiveSearch", parameters = new { endpoint = azureSearchEndpoint, key = azureSearchKey, indexName = azureSearchIndex, top = 50, semanticConfigurationName = "你的语义搜索配置名", queryType = "semantic" } } }, messages = new[] { new { role = "user", content = userMessage } }, max_tokens = 16000 // 对应gpt-3.5-turbo-16k的上下文窗口 };
方案3:拆分调用流程(最灵活)
放弃使用Extensions API,改为手动拆分两步调用:
- 直接调用Azure Cognitive Search API,获取所有匹配的结果(可分页获取数千条结果)。
- 按需筛选或合并文档内容,将合适的上下文传入普通的OpenAI
chat/completionsAPI生成回答。
这种方式完全控制检索结果的数量和内容,不受Extensions API的默认限制。
内容的提问来源于stack exchange,提问作者vv_Coder
相关产品推荐
相关产品推荐

