一、本周任务:把“中台能力”变成“可交互体验”

在前两篇周报中,我已经完成了 AI 中台侧的“输入准备”与“长文处理”基础能力:

  • B 站字幕获取与失败降级(无字幕/风控/需登录时回退模拟样例)
  • 文本清洗引擎(预编译正则、去时间轴/HTML/口语赘词、标点收敛)
  • 语义切片与 Map-Reduce 摘要编排(多块先 Map 摘要,再 Reduce 归并)

但这些能力如果只停留在“后端一次性返回完整字符串”,就很难支撑一个真正好用的笔记工作站:用户会长时间等待、无法中断,也无法做到“边生成边看到”的沉浸式体验。因此第八周我的主线是:

把 AI 摘要能力接入 SSE(Server-Sent Events)长连接,实现流式输出与可取消机制,为前端打字机渲染做接口契约。

这一步属于“工程化交互层”的关键拼图,它不直接提高摘要质量,却决定了系统是否能像 Notion/ChatGPT 那样顺畅交互。


二、选择 SSE:面向长耗时与长文本的最小闭环

大模型摘要属于典型的“长耗时任务”:

  • 生成可能持续几十秒;
  • 输出经常是几千字甚至更长;
  • 中途用户可能想停止或修改输入。

如果用普通 HTTP 请求“等全篇生成完再返回”,那么会出现三个问题:

  1. 体验差:页面只能转圈,用户看不到进度;
  2. 失败不可控:网络抖动、网关超时更容易导致整次失败;
  3. 成本浪费:用户想停止时没办法及时取消,token 与时间都被浪费。

SSE 是一种很适合本项目的折中方案:单向推送、实现简单、浏览器原生支持;配合前端的 ReadableStream 或 EventSource,可做打字机渲染。对我当前角色而言,SSE 更像一个“传输契约”:先把接口形状、事件语义、取消策略定下来,后续即使换成真正的 LLM 流式接口也不会推翻整体结构。


三、本周实现 1:异步线程池

任务书在“高并发与长耗时 AI 请求”部分明确要求后端采用异步非阻塞架构,并建议线程池规模为:

  • 核心线程数 20
  • 最大线程数 50

这是为了避免 SSE 长连接 + AI 生成把 Tomcat 的请求线程占满,导致其它 API 卡死。
因此本周我在后端新增了专用的 AI 异步线程池(aiTaskExecutor),用于执行摘要与推送任务,使得:

  • SSE 连接建立后,真正耗时的工作不占用 Web 请求线程;
  • 并发量上来时有上限,避免“无限开线程”引发 OOM;
  • 线程名有前缀,便于排查日志与定位性能瓶颈。

这一步虽然看起来“只是配置”,但它决定了系统在中期演示时能不能稳定承受多次摘要触发与多个 SSE 连接。


四、本周实现 2:SSE 流式接口与事件协议(meta / delta / done / error)

为了尽快与前端联调,我新增了一组专门的 SSE Controller:/api/ai/stream/**,核心是一个摘要流式接口:

  • POST /api/ai/stream/summarize
  • 请求体:{"text":"..."}(与之前的纯文本 DTO 一致)
  • 返回:SseEmitter 长连接

为了让前端实现更清晰,我把推送内容拆成 4 类事件:

  1. meta:首次返回 streamId用途:前端拿到 streamId 后,可用于显式取消
  2. delta:持续推送文本片段
    • 用途:前端拼接渲染,实现打字机效果
  3. done:结束标记
    • 用途:前端停止渲染、进入“可编辑/可保存”状态
  4. error:异常信息
    • 用途:前端展示错误态与重试按钮

这套协议的好处是:前端不需要理解 Map-Reduce、切片或模型细节,只要按事件语义做 UI 状态机即可。


五、本周实现 3:可取消(中断)机制

“能开始”只是第一步,“能停止”才是一个可用系统的重要细节。本周我同时实现了两种取消方式:

  1. 前端断开连接取消
    • 客户端主动关闭 SSE 连接,后端会在 completion/error 回调中清理任务标记;
  2. 服务端显式取消接口
    • POST /api/ai/stream/abort/{streamId}
    • 后端对该 stream 的取消标志置为 true,推送循环立即停止。

这满足了任务书中“可中断”的工程需求,也能在真实使用中减少无意义 token 消耗(比如用户发现输入粘错了文本,能立刻停止生成)。


六、一个阶段性取舍:“伪流式”依然有价值

目前我这边的 LLM 客户端仍是“非流式调用”(一次请求拿到完整结果)。为了第八周按时交付并完成前端联调,我借鉴了一个工程上常见的过渡方案:

  • 先生成完整 Markdown
  • 再把 Markdown 按固定粒度切片
  • 通过 SSE 逐段推送

这样的“伪流式”不等价于真正的 token-by-token 流式,但它能先解决最关键的工程问题:

  • SSE 链路是否通、前端是否能稳定拼接渲染;
  • 线程池是否能承载长耗时任务;
  • 取消机制是否能正确生效;
  • 事件协议是否合理、是否需要扩展(例如 progress、heartbeat)。

等学校下发 API Key 并确认模型网关支持 stream 输出后,我会把“伪流式”的生成部分替换为“真流式”,而 SSE 协议和取消机制可以直接复用,这样迭代成本最低。


七、本周阶段性成果总结

第八周我完成的核心成果可以概括为三点:

  • 异步并发基础:按任务书指标提供 AI 专用线程池,避免长耗时任务阻塞 Web 请求线程;
  • 流式交互骨架:建立 SSE 长连接接口与事件协议(meta/delta/done/error),为前端打字机渲染提供稳定契约;
  • 可取消机制:支持断开即取消与服务端 abort,减少无意义生成与资源浪费。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐