IT技术博客大学习 共学习 共进步

从「能用」到「好用」:LLM 流式响应实现方式的探索之路

元视角 2026-06-03 09:03:24 累计浏览 1 次
本机暂存
你在屏幕上看到 AI「正在输入」的光标时,有没有想过:这几个字节是怎样跨越千山万水,在屏幕上一个个「蹦」出来的?当 ChatGPT、Kimi、Claude 们用流式的方式「打字」给你看时,这种近乎人类的交互体验背后,藏着一个不起眼却至关重要的技术——Server-Sent Events(SSE)。它不像 WebSocket 那样大名鼎鼎,却在 AI 时代成为了事实上的标准。诚然,在 ASP.NET Core 中实现一个「能工作」的 SSE 接口,仅仅需要十分钟。但是,如果要实现一个「好用」的 SSE 接口——支持事件抽象、复用性好、能优雅地取消,你需要多久呢?本文将为你拆解这个挑战,展示如何整个设计从「能用」走向「好用」。 当 AI 开始「思考」 试想这样一个场景:用户向 Agent 提问「讲一个关于小狐狸的故事」。传统的 HTTP 请求-响应模式下,服务器需要等待大语言模型生成完整回答后,再能将结果返回给用户。这意味着用户可能要盯着屏幕等待十几秒后,才能看到完整的答案。但是,在真实的产品体验中,我们期望看到的是:Agent 首先展示它的「思考过程」——它如何理解用户意图、如何规划回答策略;然后是工具调用的实时反馈——搜索资料、查询数据库;最后才是回答内容的逐字输出。这种「实时可见」的体验,远比「等待-呈现」的模式更加自然和引人入胜。 SSE 正是实现这种体验的关键技术,它基于 HTTP 协议,允许服务器主动向客户端推送数据,相比 WebSocket 更加轻量,且能复用现有的 HTTP 基础设施。对于 LLM 流式输出这类场景,SSE 几乎是完美的选择。 第一阶段:最朴素的实现 一切的开始,是一段朴实无华的代码。博主直接在控制器中拼接 SSE 格式的字符串,然后写入响应流: [HttpGet("chat")] public async Task ChatStream(CancellationToken cancellationToken) { Response.ContentType = "text/event-stream; charset=utf-8"; Response.Headers["Cache-Control"] = "no-cache"; Response.Headers["Connection"] = "keep-alive"; foreach (var chunk in GenerateText()) { string message = $"data: {JsonConvert.SerializeObject(new { text = chunk })}\n\n"; await Response.

建议继续学习

  1. 微博 × MCP:社交媒体新玩法解锁 (累计阅读 1)
  2. Agent Loop 简介 (累计阅读 4)