Sunday 的面试指南

用户点了“停止生成”,后端就真的停了吗?AI 任务怎么取消?

🧑‍💻 面试官:AI 报告生成页面上有一个“停止”按钮,你会怎么实现?

🙋‍♂️ 我:前端可以中断当前请求,不再接收后续输出。同时通知后端取消对应任务。

🧑‍💻 面试官:为什么还要通知后端?连接都断了,生成不就停了吗?

🙋‍♂️ 我:不一定。报告可能已经交给后台 Worker 处理,它还在查资料、调用模型,不依赖这个页面一直连着。

🧑‍💻 面试官:那收到取消请求,就把状态改成“已取消”?如果模型还在生成,甚至已经把报告发给别人了呢?

“不再显示”“请求取消”和“任务已经停止”不是同一件事。取消要传到真正执行工作的地方,也不能替我们撤回已经完成的外部动作。

面试速答(60 秒版)

用户点“停止生成”,不代表后端一定停止了。前端中断请求,首先影响的是这条连接;如果任务已经在后台独立运行,它还可能继续调用模型和工具。

所以,我会用任务 ID 发起明确的取消请求。后端检查用户有没有取消权限,记录“正在取消”,再通知执行任务的 Worker。

Worker 收到以后不再启动后续步骤,并把取消信号传给支持取消的模型请求和工具调用,处理好资源清理。确认应用控制的执行已经结束,再更新最终状态,不能刚收到请求就告诉用户一切都停了。

同时,取消不等于回滚。已经发出去的报告、已经写入的数据,要单独记录和处理。如果外部服务暂时不能取消,也要说明实际情况,不能承诺点击以后立刻停止所有计算、所有计费。

页面停止读取、后端接受取消请求、Worker 停止执行是三个不同阶段

知识点详解:一个停止按钮,要经过哪些地方?

页面断开了,任务为什么还会继续?

假设咱们做了一个报告助手:用户提交题目,后端创建任务,Worker 查找资料、调用模型整理内容,页面实时显示进度。

这时至少有两个不同的过程:页面正在接收输出,Worker 正在执行任务。页面刷新或网络中断,只说明第一个过程出了变化,不能据此判断用户不要这份报告了。

前端常用的 AbortController 可以中断关联的 Fetch 请求或响应流读取,这是 MDN 对它的能力说明。但它不是一个能够自动找到后台任务并终止所有工作的远程开关。

有些服务会把连接断开继续传给模型调用,于是两边都停了;有些不会,尤其是已经入队、脱离当前请求运行的任务。要看整个应用怎么实现,不能只凭前端调用了 abort() 就下结论。

后端先记住“用户要取消哪一个任务”

对于这种后台任务,咱们可以设计一个独立的取消请求,携带任务 ID,例如 run_123。这是示例编号,不是某个框架的固定字段。

后端收到以后,先验证当前用户是否有权取消它,再读取任务状态。如果任务还在排队,就让后续领取任务的 Worker 看到取消标记,别再开始执行;如果正在运行,就记录取消请求并通知对应 Worker。

为什么需要把取消请求保存下来?因为取消接口和 Worker 可能不在同一个进程。只改取消接口里的一个内存变量,另一个进程未必知道;只发一条临时消息,Worker 恰好重启,也可能错过。

可以用持久化任务记录保存取消意图,用消息加快通知。Worker 领取任务、准备开始下一步时,都要检查当前记录。

这里建议把状态至少区分成“执行中”“正在取消”和最终结果。“正在取消”说明请求已被接受,但还有执行或清理工作没结束。它不是换个名字的“已取消”。

收到信号以后,真正执行工作的代码还得配合

假设 Worker 此时正等待模型生成内容。收到取消通知后,它应停止安排后续检索和生成,把信号传给当前模型请求;如果下游提供专门的取消接口,也要按其协议调用。

已经并行启动的工具,同样要逐个处理,不能只停止最外层循环。还需要释放连接、结束本地读取、保存必要的部分结果和执行记录。

这就是常说的协作式取消:发出取消请求以后,执行方需要在合适的位置响应。比如 gRPC 的取消指南指出,服务处理代码可能还在忙,长任务需要检查取消状态并停止继续处理;Python 的任务取消也不是调用方法后就无条件立即终止。

如果工具正在执行一个不能中断的操作,就不能假装它已经停了。应用可以不再采用迟到的结果、不再启动后续步骤,但仍要记录这次外部操作的实际状态,必要时继续确认它有没有完成。

应用不再等待结果,和外部服务不再执行,仍然有区别。 “已取消”究竟保证到哪一层,应当在产品和接口里定义清楚。还没确认的外部执行,不能藏在一个绿色成功提示后面。

Worker 阻止新步骤并向当前模型和工具传播取消,不能取消的外部操作需继续记录实际状态

取消刚好撞上任务完成,怎么处理?

假设 Worker 正要保存完整报告,用户的取消请求也到了。如果两个地方随意覆盖状态,可能刚写下“已完成”,马上又变成“已取消”。

处理这类并发,需要让状态更新带上条件。例如:只有仍在执行中的任务才能进入正在取消;Worker 提交成功结果时,也要确认任务没有被取消流程接管。具体谁先赢,要由服务端的原子状态更新决定,而不是由前端最后收到哪条消息决定。

如果成功结果已经提交,再收到取消请求,就返回“任务已完成”,不要把历史改写成一次成功取消。重复点击停止,也应该返回当前取消进度或已有结果,不再启动另一套清理流程。

但这些状态规则仍然不能撤销外部动作。报告如果已经发送给同事,数据库里改成已取消,也不会把对方收到的内容收回来。涉及发送、扣费或修改业务数据时,要记录动作是否已经发生,再按业务规则决定能否撤销或补偿。

面试官继续追问

停止以后再点继续,能不能接着生成?

这需要另外设计。取消不自动等于暂停。保存了哪些中间结果、模型请求能否续接、哪些工具已经执行,都影响恢复方式。可以从安全的检查点重新启动一次执行,但不能默认所有外部动作都能重跑。

断网要不要自动取消?

取决于产品约定。短问答可以选择跟随连接中断;需要刷新后继续查看的后台报告,则通常保留任务,把断开订阅和主动取消分开。不要让用户换个网络,就无意中取消一份已经等了很久的报告。

怎么测试停止功能确实生效?

分别在排队、模型生成、工具执行和即将完成时点击取消,检查是否又启动了新步骤、状态是否正确、部分结果是否保留。还要测试重复取消、Worker 重启和无权取消。能确认的下游执行要追踪到结束;不能确认的,就在状态和说明中暴露出来。

面试速记卡

  • 前端中断:停止当前连接或读取,不保证后台任务停止。
  • 取消请求:携带任务 ID,校验权限并保存取消意图。
  • 执行配合:阻止后续步骤,取消可取消的调用,完成清理。
  • 状态处理:区分正在取消与最终结果,用条件更新处理完成竞争。
  • 外部动作:取消不是回滚,已发生的副作用需要单独处理。
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历