如何在Azure OpenAI .NET Web API后端实现流式补全响应?
在ASP.NET Core Web API中实现OpenAI流式补全响应传输
要把你提供的OpenAI流式代码整合到Web API控制器中,需要利用ASP.NET Core的流式响应能力,将OpenAI返回的分段内容实时推送给客户端。以下是具体实现步骤:
1. 安装依赖
首先安装OpenAI官方.NET SDK:
Install-Package OpenAI # 或者使用.NET CLI dotnet add package OpenAI
2. 创建流式响应控制器动作
创建一个API控制器,实现接收请求并流式返回OpenAI响应的动作:
using Microsoft.AspNetCore.Mvc; using OpenAI; using OpenAI.Chat; [ApiController] [Route("api/chat")] public class ChatStreamController : ControllerBase { private readonly string _openAiApiKey; // 通过构造函数注入配置,获取API密钥 public ChatStreamController(IConfiguration configuration) { _openAiApiKey = configuration["OpenAI:ApiKey"] ?? throw new ArgumentNullException("OpenAI API密钥未配置"); } [HttpPost("stream-response")] public async Task<IActionResult> GetStreamingChatResponse([FromBody] ChatConversation request) { // 初始化OpenAI客户端 var client = new OpenAIClient(_openAiApiKey, new OpenAIClientOptions()); // 构建对话参数 var chatOptions = new ChatCompletionsOptions { DeploymentName = "gpt-3.5-turbo", // 非Azure客户端用此属性指定模型 Messages = { new ChatRequestSystemMessage("你是一个乐于助人的助手,说话风格像海盗。"), // 可替换为从请求传入的完整对话历史 new ChatRequestUserMessage("能帮我个忙吗?"), new ChatRequestAssistantMessage("Arrrr!当然可以,伙计!有什么我能为你做的?"), new ChatRequestUserMessage(request.UserQuery) } }; // 配置响应头,确保流式传输生效 Response.ContentType = "text/plain"; Response.Headers.CacheControl = "no-cache"; Response.Headers.Pragma = "no-cache"; Response.Headers.Expires = "-1"; // 遍历流式更新并推送给客户端 await foreach (var update in client.GetChatCompletionsStreaming(chatOptions)) { if (!string.IsNullOrEmpty(update.ContentUpdate)) { // 写入分段内容并立即推送 await Response.WriteAsync(update.ContentUpdate); await Response.Body.FlushAsync(); } } return new EmptyResult(); } // 定义接收前端请求的模型 public class ChatConversation { public string UserQuery { get; set; } = string.Empty; // 可扩展添加完整对话历史列表,比如List<ChatMessage> History } }
关键实现细节
- 响应头配置:禁用缓存是为了确保客户端能实时接收每一段响应内容,避免被浏览器或代理缓存。
- 流式写入:使用
Response.WriteAsync逐段写入OpenAI返回的内容,配合FlushAsync强制将缓冲区内容推送给客户端,实现实时流效果。 - 动态对话历史:示例中仅传入用户最后一条查询,实际项目中可以扩展请求模型,接收完整的对话历史,动态构建
ChatCompletionsOptions.Messages。 - 错误处理:实际部署时需添加异常捕获逻辑(如API密钥无效、网络异常等),返回对应的HTTP错误状态码(如401、500)。
可选:使用Server-Sent Events(SSE)格式
如果需要前端更便捷地监听流,可以改用SSE格式,只需调整两处:
- 修改响应Content-Type:
Response.ContentType = "text/event-stream";
- 调整内容写入格式:
await Response.WriteAsync($"data: {update.ContentUpdate}\n\n");
前端可通过EventSource对象直接监听该接口,实时接收流式响应。
内容的提问来源于stack exchange,提问作者barteloma
相关产品推荐
相关产品推荐

