Skip to content

合作式中断——Agent 的 Ctrl+C 不再暴力终止推理,而是在安全检查点优雅停止,保留有效的 KV cache 状态。

为什么需要合作式中断 ​

ds4-agent 运行时,用户按 Ctrl+C 可能发生在:

  • Prefill 中间:正在处理长 prompt 的某个 chunk
  • 生成循环中:正在逐 token 采样
  • Compaction 中间:正在压缩对话上下文

之前的行为:Ctrl+C 直接终止操作,KV cache 可能处于不一致状态——下次推理需要从头 prefill。

合作式中断的核心思想:在安全点检查中断信号,优雅地回退到 IDLE 状态。

中断回调 API ​

c
// ds4.h — 中断回调
typedef bool (*ds4_session_cancel_fn)(void *ud);
#define DS4_SESSION_SYNC_INTERRUPTED 2

// 注册回调:推理引擎在每个安全点调用 fn(ud) 检查是否应中断
void ds4_session_set_cancel(ds4_session *s, ds4_session_cancel_fn fn, void *ud);

ds4_session_sync() 的返回值现在有三种:

  • 0 — 正常完成
  • 1 — 错误
  • DS4_SESSION_SYNC_INTERRUPTED (2) — 被中断,但检查点有效

Agent Worker 的中断流 ​

关键步骤:

  1. UI 线程设置 worker_should_interrupt = true
  2. Worker 在 prefill 前 ds4_session_set_cancel(session, worker_cancel_session_cb, w)
  3. 推理引擎在 chunk/token 边界检查回调
  4. 中断后返回 DS4_SESSION_SYNC_INTERRUPTED,checkpoint_valid = true
  5. Worker 清除中断标志(worker_clear_interrupt),防止过期中断阻塞下一轮

各阶段的中断行为 ​

阶段中断处理状态保留
Prefillchunk 边界检查,在最后一个有效前缀处停止KV cache 到中断点有效
Generation每个 token 后检查,推送 EOS完整对话状态保留
Compaction中断时保留压缩前的对话状态"Compaction interrupted; keeping the previous conversation state"

Web 工具的中断扩展 ​

合作式中断延伸到 ds4_web 浏览器工具:

c
// ds4_web.h — 可取消的阻塞操作
typedef bool (*ds4_web_cancel_fn)(void *privdata);

// 可中断的睡眠:每 50ms 检查一次取消
web_sleep_ms(web, timeout);

// 所有阻塞操作(CDP WebSocket 连接、页面加载、滚动等)都检查取消

之前 google_search 或 visit_page 可能阻塞 30+ 秒等待 Chrome,现在 Ctrl+C 可以立即中断。

HTTP 服务器的第三个使用者(2026-08,e9ded97) ​

ds4-server 现在也接入同一套取消回调——客户端断开即中断:client 线程等待推理完成时每 100ms 探测 socket(零超时 poll + 排干,EOF 即断开),断开就置 job->cancelled;worker 注册的 job_cancelled 回调让引擎在 chunk/token 边界停止,GPU 不再为已消失的连接空算。同一个 API,三种信号源:agent 的 Ctrl+C、web 工具的阻塞操作、HTTP 客户端的断开——"在安全检查点轮询取消"这一机制与触发方式解耦。

相关概念 ​

  • dsml — DSML 解析器支持中断后的状态恢复
  • kv-cache — 合作式中断保证 KV cache 在中断后仍然有效
  • sse — 服务层的中断传播机制

详见 Part 5 — ds4-agent。