基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
  • 知识卡片碎片时间过考点
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
    • AI 热点每日 AI 资讯与动向
AI 工作台
简历
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
技术实践2026-11-06 06:54

流式回答断连后,别让模型继续计费

dev.to · AI#Next.js#流式响应#成本优化
Editor brief · 编辑速览

文章指出,Next.js 流式接口的客户端断连后,上游模型请求仍可能继续生成,产生无人消费的 token 费用。示例利用自建 ReadableStream 的 cancel() 回调中止上游请求。

文章思维导图
Knowledge map
拖拽缩放
AI deep read

AI 深度解读

用户关掉聊天页面,模型却可能还在生成答案,账单也继续累积。作者指出,Next.js 流式接口能把 token 送进浏览器,只完成了链路的一半:浏览器断开后,还需要把取消操作传给上游模型。

这篇短文的价值在于提醒一个容易漏掉的生产细节:AI 接口除了能输出,还要能停止、能持续运行、能核算成本。不过,作者没有提供节省比例,也没有验证不同部署环境下的断连行为。

页面关了,为什么模型还在生成?

在 Next.js App Router 中,一次 AI 流式响应涉及两段连接:浏览器连接你的路由,路由再连接模型服务。

用户跳转页面或关闭标签页,首先断掉的是浏览器这一段。按作者描述,如果路由没有继续取消上游请求,模型就可能生成到答案结束。后续 token 无人阅读,却仍然产生费用。答案越长,用户越容易中途离开,这类浪费就越容易积累。

浏览器停止接收,不等于模型停止生成。

这里真正需要补齐的是取消传播:客户端不再需要结果时,服务端也要结束对应的上游工作。仅仅看到聊天窗口能逐字显示,还不足以判断这个接口已经适合上线。

用 cancel() 接住断连,再终止上游请求

作者自己构建 SSE(Server-Sent Events,服务端向浏览器持续推送事件)流,并通过 ReadableStream 的 cancel() 回调调用 upstream.abort()。

下面是原文的关键代码,用来把下游流的取消传递给 Anthropic 上游请求:

export function POST(req: Request) {
  const upstream = anthropic.messages.stream({ model, max_tokens, messages });

  const body = new ReadableStream({
    async start(controller) {
      for await (const event of upstream) controller.enqueue(encode(event));
      controller.close();
    },
    cancel() {
      // 浏览器已离开,停止生成和继续付费。
      upstream.abort();
    },
  });

  return new Response(body, {
    headers: {
      "content-type": "text/event-stream",
      "cache-control": "no-cache, no-transform",
    },
  });
}

关键是 cancel() 里的 upstream.abort()。model、max_tokens、messages 控制上游生成请求,encode(event) 则负责把事件编码后写入响应流;这些变量和函数的定义,原文没有展开。

作者把客户端断连描述为触发 cancel() 的时机。但这段代码仍应放到实际部署环境中验证,不能仅凭本地演示就认定关闭标签页后一定能立即终止生成。原文也没有展示取消之后,异步迭代抛错等情况的处理代码。

不缓冲、不超时、算得清,才是完整链路

作者还提醒了三个配套问题。

首先是代理缓冲。某些代理会把 SSE 内容攒起来,最后一次性返回,用户看到的便不是持续输出。代码里的 Cache-Control: no-cache, no-transform 包含了要求中间层不要转换响应的提示。它值得保留,但原文没有给出具体代理配置,也没有证明这个响应头能解决所有缓冲情况。

其次是执行时长。长回答可能超过平台默认超时,需要调整路由的 maxDuration。原文没有提供默认值或建议值,实际设置要结合部署平台限制和业务允许的等待时间。

最后是成本计量。作者建议按请求记录 input、output 和 cache tokens,再按模型价格计算费用。否则,即使加入了取消逻辑,也很难知道实际省了多少。原文提到作者另有计量 schema,但没有在这里给出字段结构。

我的判断

我认同把取消传播和成本记录放进 AI 应用基础设施。前端能正常显示流式内容,只能证明数据送达;它没有回答用户离开后资源是否释放、长请求是否被截断、每次调用花了多少钱。

但「加一个方法就不再漏钱」这个结论需要收窄。取消不能抹去已经产生的 token 费用,实际节省还取决于断连何时被发现、上游何时停止。作者没有给出修复前后的费用对照,因此这里是工程经验和实现建议,还不是经过量化验证的收益报告。

如果项目已经使用封装好的流式 SDK,可以先检查它是否传递取消信号,再决定是否自行构建 ReadableStream。原文没有比较不同方案的完整性与维护成本。

文章末尾也在推广作者的 Shipwright:一个基于 Next.js 16 + Claude 的 starter kit,打包了按请求计费、typed tool use、带 eval harness 的版本化提示词,以及按套餐限制的配额。作者称其演示会显示每次请求的确切成本,但文中没有展开核算细节,不能据此判断计费精度。

能拿来做什么

  • 检查现有 Next.js AI 聊天路由,确认关闭标签页或跳转页面后,取消操作是否真的传到了上游模型请求。
  • 在实际部署环境测试 SSE,分别观察首批内容何时到达、代理是否缓冲,以及长回答是否触发超时,再调整响应头和 maxDuration。
  • 为每次模型请求记录 input、output 和 cache tokens,并关联具体模型价格;评估取消效果时使用实际费用记录,不把前端少显示的字符数当成节省金额。
Original source

本文由 AI 通读原文后重新编写,观点部分为站内判断,细节以原文为准,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
GPT-6 Cyber 发布,强化漏洞验证与修复
下一篇
谷歌视频模型升级:15 秒生成与低成本编辑

资讯速览

dev.to · AI · 2026-11-06 06:54

AI 评分 8.0 / 10

相关标签

#Next.js#流式响应#成本优化

继续阅读

  • 用二分定位智能体补丁引发的测试污染
  • GPT-6 Cyber 发布,强化漏洞验证与修复
  • 谷歌视频模型升级:15 秒生成与低成本编辑
  • 本地模型内存预算要算清三笔账
  • 克隆仓库后先审查 Claude 技能权限