← [ BACK_TO_NOTES ]

Abort Generation

Abort Generation 是 AI 流式输出中“停止生成”的端到端交互:前端停止本地 transport,同时通过显式 CancelRun 让服务端 durable Run 进入 cancelled 并传播取消。

#concept #evergreen #frontend #ai

[!info] related notes

Abort Generation

一句话定义

“停止生成”是一个端到端业务动作,而 AbortController.abort() 只是其中可能使用的浏览器 transport 取消原语。

可靠实现要同时处理:

1. explicit server-side CancelRun
2. durable cancelled state/event
3. cancellation propagation to live execution
4. client transport/UI cleanup

为什么不能把 Stop 按钮等价成 abort()

controller.abort();

只能直接保证调用方停止等待/读取支持 AbortSignal 的本地异步操作。

它不自动证明:

server Run cancelled
LLM/provider stopped
Tool stopped
partial output was durably reconciled
other clients know the final state

特别是对于 detached/durable Agent Run,浏览器网络断开后服务端本来就应该能够继续执行。因此不能让同一个“连接关闭”信号既代表普通网络故障,又代表用户明确取消。

正确的停止生成流程

User clicks Stop
      ↓
UI enters cancelling
      ↓
POST/command CancelRun(run_id)
      ↓
server authorizes + atomically resolves current state
      ↓
run becomes cancelled
      ↓
propagate cancellation to active execution where possible
      ↓
persist/emit run.cancelled
      ↓
frontend observes terminal state
      ↓
abort/close local SSE reader as cleanup

具体顺序可以根据 API 设计调整,但必须保证业务取消由服务端权威状态决定,而不是由浏览器 socket 状态决定。

Disconnect 与 Stop 是两条路径

Network/Wi-Fi/proxy disconnect
→ recover / reconnect / replay

Explicit Stop button
→ CancelRun

这是 production streaming 最重要的分界之一。

如果把 disconnect 自动映射成 cancel,会误杀仍可继续的 Run;如果把 Stop 只做本地 abort,则后台仍可能继续消耗模型/工具资源并生成用户已经不想要的结果。

前端状态机

可以显式建模:

streaming
  ├─ transport lost → reconnecting/recovering
  ├─ explicit stop  → cancelling → cancelled
  ├─ run.completed  → completed
  └─ run.failed     → failed

注意 reconnecting 与 cancelling 完全不同:

reconnecting = 我不知道/暂时看不到 Run,但没有要求它停止
cancelling   = 我已经明确要求服务端停止 Run,等待权威确认

Partial Output

是否保留已生成的部分内容取决于产品/领域契约。常见做法是:

partial text remains visible
+
message/run marked cancelled or partial

但不要让前端在没有服务端事实时自行伪造最终状态。更稳的是用 durable message/run/read-model 做最后 reconciliation。

BodySense 当前实践

当前 BodySense 已有显式 API:

POST /consultation-runs/:id/cancel

服务端路径会对 Run 做授权/状态裁决,触发 active execution cancellation,并产生 durable run.cancelled。普通 transport disconnect 则保留 Run 并由客户端通过 Runtime Event Log / after_seq 恢复。

主要代码边界:

apps/web/src/features/consultation/services/consultationService.ts
apps/api/internal/handler/consultation_handler.go
apps/api/internal/consultation/runtime.go
apps/api/internal/service/run_service.go
apps/api/internal/repository/run_repository.go

常见错误

  • Stop button 只执行 AbortController.abort()。
  • 网络断线被误判为用户取消。
  • 服务端已 cancelled,但 LLM/tool execution 没收到 propagation。
  • 前端先显示 cancelled,服务端实际上已经完成,造成终态分叉。
  • Cancel/Complete race 没有 atomic server state transition。
  • 把 cancellation 当 rollback,假设已经提交的外部副作用能自动撤销。

最短记忆

AbortController = stop local transport/work
CancelRun        = request business cancellation
run.cancelled    = authoritative terminal fact
Disconnect       = recovery problem, not cancellation intent
创建于 2026/6/30 更新于 2026/9/10
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本