You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CompleteChatStreamingAsync流式响应时AzureChatCitation无法获取

流式模式下获取Azure OpenAI on your data的引用(Citations)

在流式响应场景中,Azure OpenAI的引用信息不会随每个文本片段返回,而是会在最后一个流式更新包中携带。你的代码问题在于过早跳过了可能包含上下文的片段,且没有正确捕获最终的上下文数据。

关键修复点

  • 移除if (chatUpdate.Role.HasValue) continue;的判断:这个判断会跳过包含Assistant角色的最终响应片段,而引用信息正是在这个片段里。
  • 在遍历所有流式更新时持续捕获非null的上下文,确保最终拿到包含引用的完整数据。

修改后的代码

AzureOpenAIClient azureClient = new(
    new Uri(_endpoint),
    new AzureKeyCredential(_apiKey));
ChatClient chatClient = azureClient.GetChatClient(_deploymentName);

ChatCompletionOptions options = new()
{
    Temperature = (float)temperature,
    MaxTokens = maxTokens,
    FrequencyPenalty = (float)frequencyPenalty,
    PresencePenalty = (float)presencePenalty
};
options.AddDataSource(new AzureSearchChatDataSource()
{
    Endpoint = new Uri(_searchEndpoint),
    IndexName = _searchIndex,
    Authentication = DataSourceAuthentication.FromApiKey(_searchKey),
    VectorizationSource = Azure.AI.OpenAI.Chat.DataSourceVectorizer.FromDeploymentName("text-embedding-ada-002")
});
var chatUpdates = chatClient.CompleteChatStreamingAsync(
[
    new UserChatMessage(fullInput),
], options);
AzureChatMessageContext onYourDataContext = null;
var streamedContentParts = new List<string>();

await foreach (var chatUpdate in chatUpdates)
{
    // 处理流式文本内容,返回给前端
    foreach (var contentPart in chatUpdate.ContentUpdate)
    {
        var jsonResponse = JsonSerializer.Serialize(new { Text = contentPart.Text });
        streamedContentParts.Add(contentPart.Text);
        yield return jsonResponse;
    }

    // 捕获当前更新的上下文,仅保留非null结果
    var currentContext = chatUpdate.GetAzureMessageContext();
    if (currentContext != null)
    {
        onYourDataContext = currentContext;
    }
}

// 输出并处理引用信息
if (onYourDataContext?.Citations != null)
{
    foreach (AzureChatCitation citation in onYourDataContext.Citations)
    {
        Console.Write($"Citation: {citation.Content}");
        // 此处可将引用的文档链接、标题等信息返回给前端
    }
}

说明

  • 流式响应的结构中,前几个包仅包含文本片段(ContentUpdate),最后一个包会携带完整的角色标识(Role=Assistant)以及对应的上下文数据(含Citations)。
  • 移除Role判断的跳过逻辑后,才能捕获到包含引用信息的最终更新包。
  • 遍历过程中持续更新上下文变量,确保最终拿到的是完整的引用数据。

内容的提问来源于stack exchange,提问作者satyayy_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 13:07:23