AI 取消超时恢复

共 26 题
📑 题目列表 26 题
#
★★★

1. OpenAI/Anthropic 函数调用(tool use)

OpenAI 与 Anthropic 的函数调用(tool use)在协议与实现上有什么差异?前端如何统一处理?

  • 两家工具调用协议的差异(并行 tool_calls vs tool_use 内容块)
  • 参数 JSON 的流式增量与完整性判断
  • 统一抽象层的设计(执行、回传、多轮)

OpenAI 的 function calling 在流式响应中以 tool_calls 增量块出现(index 标识多个并行调用),参数是 JSON 字符串增量,需累积解析;Anthropic 的 tool use 以 content block 形式出现(tool_use 块含 id、name、input 增量),一次响应中可含多个块,input 同样是部分 JSON。差异:OpenAI 原生支持同轮并行多工具调用,Anthropic 同样支持并行工具调用(一次响应多个 tool_use 块),差异在事件结构与块化形态(OpenAI 的 delta 扁平、Anthropic 的块类型化)。前端统一处理:抽象出 ToolCall{ id, name, args(部分), status },按厂商解析器把各自增量归一化;参数 JSON 用"累积 + 完整校验"(schema 校验通过才执行);执行后统一构造 tool 角色消息回传。工程上建议封装 provider-agnostic 的 tool executor,管理"参数就绪 → 执行 → 结果回传 → 下一轮"的循环与并发限制。

答出两家协议的核心差异(并行 vs 块化、事件结构)与统一抽象层设计,体现"一次实现、多厂商接入"的工程思路。

#
★★★

2. LLM 流中断恢复(Last-Event-ID/本地补包/客户端 history)

LLM 流中断恢复如何实现?Last-Event-ID、本地补包与客户端 history 各有什么作用?

  • Last-Event-ID 断点续传的服务端配合
  • 本地补包(客户端缓存已收增量)的恢复
  • 客户端 history 重建上下文的场景

流中断恢复有三条路径。Last-Event-ID 是 SSE 原生机制:客户端在重连请求头携带最后处理的事件 id,服务端从该位置继续发送;但 LLM 生成有状态(KV Cache、工具执行),服务端需支持"按事件序号续传"或"重新生成但跳过已收部分",否则只能整段重来。本地补包:客户端把已收到的增量实时写入 IndexedDB(本地缓存),断线后先渲染本地已收内容(界面无空白),再决定是续传还是补请求,补包的价值是"视觉不中断、数据不丢失"。客户端 history:重连后携带最近 N 轮消息(含工具结果)作为上下文重建,让模型基于完整状态续答——这是不依赖服务端断点能力的通用方案,代价是可能重复计费与重新生成。生产实践按场景组合:短流用 history 重建,长流/计费敏感用续传协议,本地补包永远先做。

对比三条恢复路径的机制与适用场景,突出"本地补包保 UI、续传协议保一致性、history 重建做兜底"的组合策略。

#
★★★

3. Opus / 思维链(chain-of-thought)逐步流式渲染的工程价值

Opus / 思维链(chain-of-thought)逐步流式渲染有什么工程价值?前端如何实现?

  • CoT 逐步渲染对用户信任与可解释性的价值
  • reasoning 与 answer 分离的协议设计
  • 逐步渲染的性能与交互(折叠、聚焦)

思维链逐步流式渲染的工程价值:一是可解释性——用户能看到模型"如何得出结论",提升信任与纠错能力;二是即时反馈——思考过程先于答案出现,降低等待焦虑;三是调试价值——开发者在对话中定位错误推理步骤。实现要点:协议层把 reasoning 与 answer 分为独立流/块(如 Anthropic 的 extended thinking、OpenAI 的 reasoning_content),前端分别渲染;UI 上思考过程放折叠面板,默认半开或收起,流式时自动展开更新、完成后收拢,避免占据答案主视觉;逐步渲染同样走节流批处理,避免高频更新;思考内容标记"内部推理",不回传下一轮(防上下文污染与隐私泄漏);长思维链可分段渲染与"跳转到关键步骤"导航。性能上 reasoning 与 answer 并行到达时需统一调度,保证答案就绪即高亮。

答出"可解释性、即时反馈、调试"的价值与"协议分离、折叠交互、不回传"的实现,体现对 CoT 产品化的完整理解。

#
★★★

4. AbortController 取消生成、超时、重试、幂等、断线恢复

AbortController 如何统一实现 AI 生成的取消、超时、重试、幂等与断线恢复?

  • abort signal 的传递与超时组合(AbortSignal.timeout/any)
  • 取消后的状态清理与重试幂等
  • 断线恢复与取消的语义区分

AbortController 提供统一的中断原语:取消生成——用户点击停止时 controller.abort(),fetch 流中断并抛 AbortError,UI 转入 stopped 态;超时——用 AbortSignal.timeout(ms) 或手工定时器 + abort,超时后按策略(提示重试/自动重试一次)处理;重试——失败/超时后重新发起请求,携带同一 requestId 保证幂等(服务端去重、客户端覆盖同一消息槽位);断线恢复——abort 只取消当前请求,恢复时用 Last-Event-ID/本地补包续传或 history 重建。工程要点:区分"用户取消(AbortError,不告警)"与"网络错误(重试)",用 signal.reason 或错误类型分类;多请求场景用 AbortSignal.any([...]) 组合多个源(用户按钮 + 超时 + 组件卸载);abort 后清理计时器与资源(reader.cancel),防止泄漏。整体是一个"取消优先、超时兜底、幂等重试、断点续传"的请求生命周期框架。

把取消、超时、重试、幂等、恢复统一进"signal 驱动 + 错误分类 + 幂等键"的框架,答出各语义的区分与组合用法。

#
★★★

5. IndexedDB 在长对话历史与恢复的工程价值

IndexedDB 在长对话历史与恢复场景下有什么工程价值?如何使用?

  • IndexedDB 的存储模型(对象仓库、索引、事务)
  • 消息持久化的结构与增量写入
  • 恢复、迁移与容量管理

IndexedDB 的价值:浏览器内结构化大容量存储(远超 localStorage),适合长对话历史、流式断点与本地缓存。工程用法:建立 messages 仓库(键为会话 id + 消息 id),用索引按时间/会话查询,流式增量阶段"低频批量写入"(节流合并,避免每 token 一次事务);辅助仓库存会话元数据、token 用量与断点游标(Last-Event-ID)。恢复:页面刷新/断线后用"最后写入的消息 + 游标"恢复会话,渲染已持久化内容再继续;恢复流程要幂等(重复恢复不重复插入)。边界:事务与异步 API 易踩坑(版本升级需迁移 onupgradeneeded);存储配额(用 estimate 监控,淘汰旧会话);敏感内容加密(Web Crypto)与隐私清理(导出/删除入口)。把 IndexedDB 作为"本地事实源",UI 状态从它同步,是长对话产品的地基。

答出存储模型、增量写入与恢复幂等,并覆盖版本迁移、配额与隐私边界,体现对持久化工程的完整认知。

#
★★★

6. 浏览器原生 Streaming + IndexedDB 持久化恢复

浏览器原生 Streaming(ReadableStream)与 IndexedDB 持久化如何配合实现流式恢复?

  • 流式读取与持久化的管道(边收边存)
  • 恢复时"已存内容 + 续传"的衔接
  • 性能(写入节流)与一致性(崩溃安全)

配合模式是"边收边存、崩溃可恢复":fetch 的 ReadableStream 每读到一块增量,除了渲染外,把"累积文本 + 事件游标"节流写入 IndexedDB(如每 500ms 或每 N 块一次,控制事务频率);写入用事务保证原子性,游标(已处理的事件序号/字节位置)与内容同事务提交,保证崩溃后游标与内容一致。恢复流程:启动时先读 IndexedDB 最近会话(渲染已收内容),若存在未完成流,用游标发起续传(Last-Event-ID 或服务端断点)或基于已存消息 history 重建,续传增量追加到已存内容。一致性细节:写入失败(配额)时降级为内存态并提示;崩溃发生在"内容写入成功但游标未更新"时,用内容长度校验(append-only 日志 + 去重)避免重复段;IndexedDB 写入是异步的,渲染与持久化解耦,渲染照常、持久化尽力而为。

答出"边收边存 + 同事务游标 + 崩溃一致性(append-only 去重)"的管道设计,体现对流式持久化的底层理解。

#
★★★

7. 配额(rate limit)与 429 / Retry-After 退避策略的工程价值

AI 请求的配额(rate limit)与 429 / Retry-After 退避策略有什么工程价值?前端如何实现?

  • 429 响应的语义与 Retry-After 头
  • 指数退避 + jitter 的客户端实现
  • 配额感知的 UI(剩余额度、排队、降级)

429 Too Many Requests 表示超出配额,服务端用 Retry-After(秒或 HTTP 日期)告知重试时间。工程价值:合理退避避免"重试风暴"打爆服务端、保护计费与配额、提升请求成功率。客户端实现:收到 429 时读取 Retry-After,若存在按此等待(可加少量 jitter 防同震),否则用指数退避(1s、2s、4s…封顶,如 30s)+ 随机 jitter;重试要有最大次数,超过后转人工提示;注意区分 429 的配额类型(每分钟请求数/每分钟 token 数),token 配额可在客户端预计算排队。UI 层:展示剩余额度(由响应头 x-ratelimit-* 或服务端字段驱动),配额耗尽时提供"排队等待/稍后重试/切换模型/降级到本地模型"选项,避免静默失败;批量任务用令牌桶限速器平滑请求速率。

答出"Retry-After 优先 + 指数退避 jitter + 重试封顶 + 配额 UI"的完整策略,突出防重试风暴与用户可感知的设计。

#
★★★

8. 流式响应回放(如何避免重复请求/渲染)的工程边界

流式响应回放如何避免重复请求与重复渲染?有哪些工程边界?

  • 回放(replay)与重放攻击/重复消费的区别
  • 去重机制(请求指纹、requestId、服务端幂等)
  • 渲染层去重(消息 id 去重、增量拼接幂等)

流式响应回放指同一份流被消费多次(页面恢复、多端同步、调试回放)。工程边界分两层:请求层,用 requestId(客户端生成、服务端幂等键)保证同一次生成只计费一次,重复投递被服务端去重;客户端发起前检查该 requestId 是否已消费(内存/IndexedDB 记录状态),避免重复请求。渲染层,消息 id 稳定 + 增量追加幂等:重放时按 id 定位已有消息,只追加上一次未收到的尾部(用游标/事件序号),而不是整体覆盖或重复插入;对"重放导致 UI 闪烁"用骨架与"恢复中"状态衔接。边界:回放不等于重试——回放是同一流的重消费(幂等消费),重试是重新生成(新 requestId);服务端必须支持幂等键才有意义;流事件需带全局序号才能做精确续接;多端同步场景用服务端事件日志作为单一事实源。谨记:不能依赖"客户端不会重复消费"的假设,一切按"可能重放"设计。

区分回放与重试,答出请求层幂等键与服务端去重、渲染层按 id/游标幂等追加,并点出"按可重放设计"的工程原则。

#
★★

9. AI 流式响应的超时控制与指数退避重试

AI 流式响应的超时控制与指数退避重试如何实现?

  • 首包超时与总时长超时的区分
  • AbortSignal.timeout 与定时器实现
  • 指数退避 + jitter + 重试封顶

流式超时要分两种:首包超时(请求发出后多久必须收到第一个增量)与总时长超时(流式整体最长时长)。首包超时用 AbortSignal.timeout(或 setTimeout + abort),避免"连接挂死无响应";总时长超时针对超长生成(如 10 分钟上限),超时后停止并保留已收内容。实现:fetch 的 signal 用 AbortSignal.any([用户取消, 超时]);超时触发后分类处理——首包超时直接重试(网络可能抖动),总时长超时不再自动重试、提示用户分块继续。重试策略:指数退避(base 1s,倍数 2,封顶 30s)+ jitter 随机化防同震;区分可重试错误(超时、429、5xx、网络)与不可重试(400、401、校验失败);最大重试次数(如 3 次)后进入人工重试 UI。所有重试沿用同一 requestId 保幂等。

答出"双超时(首包/总时长)区分、AbortSignal.any 组合、指数退避 jitter 与可重试错误分类",体现超时重试的工程细节。

#
★★

10. 滚动与长内容性能(虚拟列表、分片渲染、IntersectionObserver 节流)

AI 流式响应的滚动与长内容性能如何优化?虚拟列表、分片渲染与 IntersectionObserver 节流各有什么作用?

  • 长内容渲染的性能瓶颈(DOM 数量、重排成本)
  • 虚拟列表 vs 分片渲染的适用场景
  • IntersectionObserver 懒渲染与节流

长内容(超长回答、大量代码块、多轮历史)的性能瓶颈在 DOM 规模与重排成本。优化手段:虚拟列表(@tanstack/virtual)只渲染视口内条目,适合"条目结构固定、数量巨大"的消息列表;分片渲染(时间切片)把大段内容分批渲染(如每帧渲染 N 行),适合"单条内容特别长"(如巨型代码块)的场景,用 requestIdleCallback 或 rAF 调度;IntersectionObserver 节流用于懒渲染——屏幕外内容(代码高亮、长图、远端历史)先渲染占位,进入视口再渲染实际内容,避免一次性计算。三者组合:列表级用虚拟化、单条大内容用分片、昂贵渲染(高亮/公式/图片)用 IntersectionObserver 触发;配合 content-visibility: auto 让浏览器跳过屏幕外渲染。注意:流式增量期间的高度测量与滚动位置要在渲染后的下一帧更新,虚拟列表需配合动态高度测量(measureElement)。

按"列表级虚拟化、条目级分片、昂贵渲染懒触发"三层作答,并点出流式下高度测量与下一帧时序的细节,体现长内容性能优化的分层思维。

#
★★

11. AI 请求的 AbortController 取消在用户取消与组件卸载的工程实践

AI 请求的 AbortController 取消在用户取消与组件卸载时有哪些工程实践?

  • 用户取消的交互(停止按钮)与状态流转
  • 组件卸载时的取消(防泄漏、防 setState)
  • 取消后的资源清理与幂等

用户取消:停止按钮在流式期间可用(isLoading/streaming 时),点击触发 controller.abort(),fetch 抛 AbortError,UI 把消息标记为 stopped(保留已生成部分 + "继续生成"入口);AbortError 不按错误上报、不弹错误提示。组件卸载:在 useEffect cleanup 中调用 abort 并清理监听器/定时器,避免请求继续占用连接、回调在卸载后 setState(React 18+ 已不再告警但仍是隐患);用 ref 持有当前 controller,卸载时统一 abort。工程要点:多请求场景维护 controller 集合;取消后资源清理(reader.cancel()、释放大对象);取消与重试衔接——用户取消后再次触发用新 controller、同一 requestId;服务端配合(流中止通知、停止计费)减少浪费。整体原则:"取消即清理、错误分类型、状态可恢复"。

答出用户取消与卸载取消两条路径的实践细节(AbortError 分类、cleanup 清理、reader.cancel、幂等衔接),体现内存与资源管理的严谨。

#
★★

12. AI 请求的超时(Timeout)处理与用户重试提示的现代应用

AI 请求的超时(Timeout)处理与用户重试提示在现代应用中有哪些做法?

  • 超时阈值设置(按场景:首包/总时长)
  • 超时后的 UI 状态(部分内容保留)
  • 重试提示的设计(自动/手动、继续生成)

超时处理分"检测与呈现"两步。检测:按场景设阈值——简单问答首包 5-10s、长文档生成总时长放宽,用 AbortSignal.timeout 或定时器;超时触发后把错误分类为 timeout。呈现:超时时若已有部分输出,保留并标记"生成中断",显示超时原因与"重试/继续"按钮;重试提示分自动(可重试错误自动退避重试一次,成功后无感)与手动(明确告知"请求超时,请重试"),手动重试入口要醒目且不打断用户阅读;"继续生成"比"整段重试"更省成本——把已收内容作为上下文续写。工程要点:超时阈值可配置(网络差设备放宽);超时统计上报监控;避免超时与重试循环(重试次数封顶后提示换网络/降级模型);给用户"重试中"状态反馈避免重复点击。

答出"按场景阈值检测、部分内容保留、自动/手动重试与继续生成"的呈现链路,突出对用户心理与成本的平衡。

#
★★

13. AI 请求的速率限制(Rate Limit)在客户端的工程处理

AI 请求的速率限制(Rate Limit)在客户端如何做工程处理?

  • 客户端限速器(令牌桶/滑动窗口)
  • 并发控制与队列管理
  • 限速与用户提示的配合

客户端速率限制用于"在服务端限制前主动平滑流量":令牌桶——按 rps 速率补充令牌,请求消耗令牌,不足则排队或丢弃;滑动窗口——统计时间窗内请求数,超限则等待。实现:限速器封装在请求层(如 fetch 包装器),配合并发控制(如最多 2 个并发生成请求,其余进队列 FIFO),避免打爆服务端或触发 429。队列管理:排队任务显示"排队中"状态与预计等待(基于令牌桶计算),支持取消排队;高优先级任务(用户主动点击)插队。与提示配合:队列过长时提示"当前请求较多,请稍等"或引导降级(切小模型、分批处理);令牌桶参数与 429 返回的额度信息联动(服务端告知剩余额度,客户端据此动态调整速率),实现"客户端自律 + 服务端反馈校准"。

答出令牌桶/滑动窗口实现、并发队列管理、排队可见性与服务端额度反馈校准,体现请求治理的工程闭环。

#
★★

14. AI 请求的乐观更新(Optimistic Update)与失败回滚的工程应用

AI 请求的乐观更新(Optimistic Update)与失败回滚如何应用到 AI 请求?

  • 乐观更新的应用点(消息上屏、工具结果、状态切换)
  • 回滚的粒度(单消息 vs 会话级)
  • 回滚与幂等、用户提示的配合

乐观更新在 AI 场景的应用:发送消息后立即上屏用户消息并创建 assistant 占位;工具调用结果先乐观展示(如"已发送")再校正;批量操作(清空会话、切换模型)先更新 UI 再请求。失败回滚设计:确定回滚粒度——单消息级(该消息转 error 态并保留草稿)通常优于会话级(整体回滚成本高、体验粗暴);回滚实现用"快照 + 撤销":发起前保存消息列表快照,失败时要么恢复快照(强一致)要么局部标记(软回滚,保留用户已读内容);工具类乐观更新失败要补偿(如"发送失败,已取消"提示并回滚状态)。与幂等配合:重试覆盖同一消息槽位而非追加;回滚后保留用户输入(不丢用户数据);回滚要可见——明确提示"操作未完成,已恢复原状"。

答出乐观更新的应用点与"快照回滚、粒度选择、补偿提示"的设计,强调"回滚不丢用户数据"与幂等衔接。

#
★★

15. AI 请求的会话恢复(Session Resume)在断线重连的现代实践

AI 请求的会话恢复(Session Resume)在断线重连场景有哪些现代实践?

  • 会话快照(消息、上下文、游标)的持久化
  • 重连后的恢复流程(渲染已存、续传、重建)
  • 多端恢复与一致性(服务端会话 id)

会话恢复的核心是"快照 + 游标":客户端把会话状态(消息列表、上下文摘要、最后事件序号、requestId 集合)持久化到 IndexedDB,断线重连后:先渲染本地快照(无空白),再按恢复策略续传——服务端支持断点(Last-Event-ID 或会话续传协议)则续传增量;否则用客户端 history(快照中的消息 + 游标后未收完的请求重发)重建。现代实践:会话有服务端 id(session id),重连时携带它恢复服务端上下文(KV Cache 命中、不重复计费);恢复过程幂等(重复恢复不重复插消息);多端同步以服务端会话为单一事实源,客户端快照仅作离线兜底;恢复时展示"正在恢复上次对话…"状态;敏感会话恢复前校验权限。断线期间的用户输入与工具结果也要本地缓存,恢复后一并同步。

答出"快照渲染、续传/重建双路径、服务端 session id 一致性、幂等恢复"的现代实践,体现离线到在线的无缝衔接设计。

#
★★

16. AI 请求的 Cost Limit(用户成本限制)与提示工程边界

AI 请求的 Cost Limit(用户成本限制)如何实现?它有哪些提示工程边界?

  • 成本核算(输入/输出 token 单价、会话/日/月预算)
  • 超限的拦截与提示(软限制/硬限制)
  • 成本感知的提示工程(截断、降级、缓存)

Cost Limit 是产品侧的成本护栏:按输入/输出 token 单价核算每次请求成本,累计到会话、日、月级预算,接近阈值(如 80%)触发软限制(提示"即将到达预算上限",建议精简输入),达到上限触发硬限制(拦截请求,引导次日/换模型/降级本地推理)。实现:客户端预估 token 成本(tiktoken)+ 服务端账单口径(最终以服务端为准),展示实时用量面板;超限拦截要有豁免(管理员、付费用户)。提示工程边界:成本敏感时自动调整策略——裁剪历史与工具定义(Prompt Trimming)、启用 prompt caching(命中缓存省输入费)、长任务拆分为多次短请求以利用缓存、高成本任务(长上下文/多模态)默认降级到小模型;同时防止"为省成本牺牲质量"——关键任务(安全、代码)不做激进裁剪。成本信息应透明展示给用户,形成"用量-成本"的自觉。

答出"分层预算核算、软硬限制、成本感知的提示工程(缓存/裁剪/降级)"与透明展示,体现成本治理与质量平衡。

#
★★

17. AI 请求的 Token Limit(输入输出限制)的客户端校验工程

AI 请求的 Token Limit(输入输出限制)如何在客户端校验?

  • 输入上限与输出上限(max_tokens)的区分
  • 发送前计数与超限处理(截断/拆包/提示)
  • 输出超限的截断策略与用户感知

Token Limit 分输入与输出两个方向。输入校验:发送前用 tokenizer(按模型编码器)对"系统提示 + 工具定义 + 历史 + 新消息"计数,超过输入上限(如 128k)时先走 Prompt Trimming(裁剪/摘要)而不是直接报错;仍超限则提示用户精简或拆分为多次请求(如长文档分段提问)。输出校验:请求参数 max_tokens 限制单次输出上限,流式累计超过时服务端终止;客户端感知"截断"标记(finish_reason === "length"),提示用户"回答已达长度上限",并提供"继续生成"(把已输出作为上下文续写)或分块获取(如"逐章生成")。工程要点:计数用实际模型编码器(不同模型不同);输入框实时显示用量/上限;截断标记要持久化(消息元数据),恢复会话时继续生成不会从头再来;对用户而言,"继续"比"重来"省 token 省时间。

分输入/输出两侧作答:输入预检与修剪拆包、输出 max_tokens 与截断标记 + 继续生成,体现双向限制的完整管理。

#
★★

18. AI 请求的 SSE 心跳(Heartbeat)检测与超时重连的现代应用

AI 请求的 SSE 心跳(Heartbeat)检测与超时重连有哪些现代应用?

  • 心跳的协议设计(注释行/空行/专用事件)
  • 心跳超时的判定与重连触发
  • 与代理/防火墙 idle 超时的对抗

SSE 心跳用于探测连接活性:服务端周期性发送心跳(SSE 注释行 : ping、空行或专用 ping 事件),客户端若在超时窗口(如 45-60s)内未收到任何数据(含心跳)则判定连接僵死,主动重连。心跳双重价值:对抗中间设备(nginx/负载均衡/移动网络)的空闲连接回收——这些设备常按"无流量超时"断开长连接,心跳保持流量活跃;同时作为服务端存活信号,区分"服务端正常但无输出"与"连接已死"。现代应用:心跳间隔适配(网络差时加密心跳);心跳与业务数据共用通道(data 事件即心跳,无需单独机制);客户端用"收到任意数据重置计时器"策略;重连沿用退避与 Last-Event-ID 续传;前端监控上报心跳失败率,预警服务端稳定性。注意心跳事件在 UI 上不可见、不计入消息内容。

答出心跳的协议形式、保活价值(对抗 idle 回收)、超时判定与重连续传,以及监控上报,体现长连接运维的完整认知。

#
★★

19. AI 请求的多模型切换(GPT-4、Claude、Gemini)

AI 请求的多模型切换(GPT-4、Claude、Gemini)如何实现?有什么工程取舍?

  • 多 provider 的统一抽象(协议适配、错误归一)
  • 切换策略(用户手动、自动路由、降级)
  • 上下文迁移与成本差异

多模型切换的前提是统一抽象层:把各家 API(消息格式、流式事件、工具调用协议)适配为内部统一接口(Vercel AI SDK 或自研 provider 层),业务代码不感知厂商差异。切换策略分三种:用户手动选择(UI 模型选择器,展示能力/成本标签);自动路由(按任务类型——代码题选 Claude、长文总结选 Gemini、成本敏感选小模型);降级切换(模型 429/超限/质量不达标时自动降级到备选,如 GPT-4 → GPT-4o-mini → 端侧模型)。工程取舍:上下文迁移——切换模型时携带同一消息历史(tokenizer 差异导致计数不同需重算),流式中途切换不现实(已生成内容保留、新模型续写可能有风格断裂);成本与质量权衡——高成本模型默认只用于关键任务;切换记录要展示("本回答由 Claude 生成")且可配置默认模型与组织级策略。

答出"统一抽象、三类切换策略、上下文迁移与成本权衡",突出降级路由与透明展示,体现多模型治理能力。

#
★★

20. AI 请求失败重试与降级到小模型路由的工程实践与价值

AI 请求失败重试与降级到小模型路由有哪些工程实践与价值?

  • 失败分类与重试策略(可重试 vs 不可重试)
  • 降级路由的触发条件(质量/成本/失败)
  • 降级对用户体验与成本的影响

失败重试的实践:按错误分类——网络/429/5xx/超时可重试(指数退避 + jitter),4xx 校验错误不可重试(修正参数再发);重试携带同一 requestId 幂等;重试次数封顶后触发降级或人工处理。降级路由:触发条件有三类——失败(重试耗尽)、成本(预算告急)、质量(如评测得分低或用户反馈差);降级目标按阶梯:大模型 → 中型 → 小模型 → 端侧模型 → 规则引擎/缓存答案。价值:可用性(失败有兜底)、成本控制(低价值任务走便宜模型)、体验(降级透明提示"已切换模型,回答可能简化")。工程要点:降级决策放服务端(统一策略)或客户端可配置;记录降级原因与审计日志;降级后质量校验(关键任务宁可失败不降级,fail closed);A/B 验证降级对任务成功率的影响,防止"为了省钱牺牲质量"。

答出"失败分类重试、三类降级触发、降级阶梯与 fail closed 边界",体现可用性-成本-质量三角的平衡。

#
★★

21. 客户端流式响应超时(AbortSignal.timeout)的工程价值

客户端流式响应超时(AbortSignal.timeout)有什么工程价值?如何使用?

  • AbortSignal.timeout 的语义(到点自动 abort)
  • 与用户取消的区分(AbortSignal.any 组合)
  • 超时后的处理流程(保留、重试、提示)

AbortSignal.timeout(ms) 提供声明式超时:传入 fetch 的 signal,到点自动触发 abort,错误 reason 为 TimeoutError,无需手写定时器与清理逻辑,代码简洁且不易泄漏。工程价值:统一"用户取消 + 超时"的组合——用 AbortSignal.any([AbortSignal.timeout(ms), userController.signal]) 让任一条件触发中断;错误分类清晰(TimeoutError vs AbortError vs 网络错误),据此决定重试(超时可重试、用户取消不重试)与提示文案。超时后流程:保留已收内容标记中断,自动退避重试一次(幂等)或提示手动重试;超时阈值按场景配置(首包/总时长),并上报监控。注意:timeout 信号触发后不可复用(新请求需新建);要区分"服务端慢"与"连接死"(首包超时更敏感)。

答出声明式超时的用法、与用户取消的组合(any)、错误分类驱动的处理流程,体现现代取消/超时 API 的正确使用。

#

22. AI 请求的 Batch API(非流式批量)在异步任务的工程价值

AI 请求的 Batch API(非流式批量)在异步任务中有什么工程价值?

  • Batch API 的模型(提交任务、轮询/回调结果)
  • 适合批量异步的场景(数据标注、批量翻译)
  • 与流式单请求的成本/延迟取舍

Batch API 允许一次提交多个请求(如 OpenAI Batch API),服务端排队处理,客户端异步获取结果。工程价值:成本低(官方批量价通常 50% 折扣)、适合大批量非实时任务(数据标注、批量翻译、内容分类、离线摘要)、便于集中管理与重试(单任务失败不影响整批)。实现:提交批次获得 batch id,轮询状态(或配置回调),下载结果文件;前端对"任务型"产品(导入文件 → 批量处理 → 导出结果)非常适合,需提供任务列表、进度(完成数/总数)、失败项下载与断点续跑。与流式取舍:交互式对话必须流式(低延迟);批量异步任务用 Batch(省成本、吞吐高);混合场景(如首屏流式 + 批量增强)可组合。注意 Batch API 的延迟与排队时间不可控,不适合实时性要求高的功能。

答出 Batch API 的异步模型、成本优势与任务型产品的 UI 配套,并对比流式的延迟取舍,体现按任务性质选型。

#

23. AI 请求的 Stream 与 Non-Stream 切换的工程取舍

AI 请求的 Stream 与 Non-Stream 切换有什么工程取舍?

  • 流式与一次性响应的场景差异
  • 切换的触发条件(任务类型、网络、设备)
  • 同一代码路径的兼容设计

流式(Stream)适合交互式对话:首 token 延迟低、体验好、可中途取消,但实现复杂(解析、重连、心跳)且代理/网络差时易断流;非流式(Non-Stream)适合对延迟不敏感或需要"完整结果再处理"的任务(批量、后台、一次性生成文件),实现简单、可靠、易缓存。切换的工程触发:按任务类型——聊天默认流式、后台批处理非流式;按网络——弱网下长任务可退化为非流式(一次返回,减少断流重试);按设备——端侧模型可能只支持非流式;按用户偏好——可配置"秒出结果 vs 边想边出"。兼容设计:客户端请求层提供 stream 开关,响应统一封装为"事件流或一次性事件"两种形态,渲染层与业务层不感知差异;成本上非流式可能更省(无需长连接资源),但用户感知差;切流式失败(SSE 不支持)时自动降级非流式。

答出两种形态的场景与成本差异、按任务/网络/设备触发的切换逻辑,以及统一抽象兼容设计,体现请求形态管理的灵活性。

#

24. AI 请求的 Quota 与用户限流的前端提示工程实践

AI 请求的 Quota(配额)与用户限流在前端有哪些提示工程实践?

  • 配额来源(用量/套餐/服务端额度)与实时同步
  • 限流触发的前端提示(软硬分层)
  • 配额消耗的透明展示与引导

配额提示的核心是"透明 + 分层"。数据来源:服务端返回配额信息(剩余额度、重置时间、限流参数),客户端同步展示(剩余 X 次/每日);配额消耗在每次请求后更新(按 token 或次数)。分层提示:软限制——用量达 70-80% 时展示进度条与提示("本月额度即将用完"),引导查看套餐或降级;硬限制——触顶后拦截请求,说明原因("今日额度已用完,X 点重置")并提供替代路径(切换模型、等待重置、升级套餐)。工程要点:提示不阻断阅读(toast/banner 而非弹窗打断流式);配额计算以服务端为准(客户端仅展示);限流(rate limit)与配额(quota)区分——限流是瞬时频率、配额是总量,分别提示"请求太频繁"与"额度用完";离线或服务端不可用时显示缓存配额并标注;引导入口(升级/看用量明细)就近提供。

答出"配额数据同步、软硬分层提示、限流与配额区分、服务端为准"的实践,突出不打断体验的提示设计与用户引导。

#

25. AI 请求的 Latency(延迟)与用户感知的工程优化

AI 请求的 Latency(延迟)如何影响用户感知?有哪些工程优化手段?

  • 延迟组成(网络、排队、TTFT、生成)与感知阈值
  • 感知优化(占位、骨架、渐进呈现、乐观 UI)
  • 真实优化(缓存、流式、边缘、模型降档)

延迟组成:请求排队 → 网络 → 首 token(TTFT)→ 生成速率。用户感知研究表明:100ms 内反馈"即时"、1s 内"流畅"、3s 以上开始流失,所以"感知延迟"比"真实延迟"更关键。感知优化:发送即反馈(乐观 UI、按钮 loading)、流式输出让"等待变阅读"(TTFT 优化比总时长更重要)、骨架屏与打字动画、渐进呈现(先结构后内容)、显示预计时间。真实优化:prompt caching(命中省 TTFT)、预连接与边缘部署(靠近用户)、模型降档(快模型先答、慢模型精修)、并行请求(RAG 检索与生成并行)、缓存常见回答(LLM 网关缓存)、按任务切流式/非流式。工程上把两类优化组合:先保"感知不卡",再降"真实延迟",并用性能监控(TTFT/tokens/s 分位数)持续验证。

答出延迟组成与感知阈值、感知层优化与真实层优化,强调"TTFT 优先、让等待变阅读",体现对性能与体验的辩证管理。

#

26. AI 请求的 Failure Mode(部分响应、损坏响应)的工程处理

AI 请求的 Failure Mode(部分响应、损坏响应)有哪些?前端如何处理?

  • 部分响应(中途截断、流中断)的识别与处理
  • 损坏响应(JSON 损坏、格式非法)的校验与回退
  • 错误响应(安全拦截、内容过滤)的呈现

Failure Mode 分三类:部分响应——流中断/超时/max_tokens 截断导致内容不完整,处理:标记"生成中断",保留已收内容,提供"继续生成"或整段重试(幂等),截断原因(finish_reason)持久化;损坏响应——结构化输出 JSON 损坏、Markdown 畸形,处理:schema 校验失败走"重试(带修复提示)+ 降级为文本展示 + 报错上报",渲染层对畸形 Markdown 容错(未闭合块按闭合处理);错误响应——模型触发安全策略(内容被过滤、返回空)、检测到提示注入、拒绝回答,处理:展示原因("已拒绝该请求")、区分"模型拒绝"与"系统错误"、引导改写问题或联系支持。工程原则:所有失败模式都有可见状态(不静默)、可恢复路径(重试/继续/改写)、可诊断信息(错误码 + 上下文日志,脱敏上报)。

分类列举三类失败模式并给出各自处理(保留续传、校验回退、可见提示),收尾于"可见、可恢复、可诊断"三原则。