6.6 KiB
异步 Agent Loop 是怎么调度的
DeepSeek 的设计文章在第 4.1 节把长工具调用拆成启动和完成两次交互。启动先返回「已启动」通知,工具继续运行。Agent Loop 可以在当前推理步结束后处理新输入,执行器在工具结束后把结果送回原会话。本文核对了文章中文镜像、DeepSeek Harness fcc0ad4 和公开原型 6337fc8 的源码、文档与上游测试,时序数字为假设值。 设计文章 §4.1
一个会话里发生了什么
在 DeepSeek Harness 的术语里,一次模型请求和它调用的工具组成一个 step,一个 turn 可以包含多个 step。Loop 在 step 边界取出可处理的输入,组装下一次模型请求。同步执行长命令时,当前 step 要等命令的最终结果。命令实现即使用了 JavaScript 的 async/await,同一会话仍在等这个 step 结束。异步工具则把工作交给后台执行器,返回 job_id,让当前 step 可以结束。此后用户消息和后台完成通知都可以成为模型的输入,后台任务的进度独立推进。 Turn 与 Step、Bash 工具的两个分支
公开原型的 Worker 会在前台 shell 命令等待超过 5 秒时把命令交给后台。Harness 也支持直接使用 run_in_background,任务获准后先返回 ID,启动失败可以随后以失败结果结算。完成通知会进入正在运行的 Agent 的下一步,或者在开启唤醒投递时让空闲 Agent 发起后续一轮。短输出可以随通知一起返回,长输出留给 job_output 读取。 原型的 Worker 调度、Bash 工具文档、完成通知的投递
如果后续工作确实依赖结果,Agent 可以调用 job_output(wait: true)。Harness 的这个等待可以被当前 step 的用户 steer 提前结束,返回仍在运行的状态,让新消息进入下一步,原命令继续运行。排给后续 turn 的消息会继续等待。上游测试分别覆盖这两条路径,此处核对了测试代码。 等待与 steer 的实现、上游测试
等一分钟的测试,谁省下了时间
假设修完过期判断后启动一组本地回归,耗时 60 秒。第 10 秒你问「把刚才的 diff 给我看一下」,这一步只读现有改动,假设模型处理和回答用 3 秒,异步版此时可以开始下一步。
| 从测试启动计时 | 同步调用 | 异步调度 |
|---|---|---|
| 第 0 秒 | 当前 step 开始等待测试结果 | 后台任务开始,工具先返回 job_id |
| 第 10 秒 | 追问已发送,当前 step 仍在等测试 | Loop 开始处理追问 |
| 第 13 秒 | 测试仍在跑 | Agent 已回 diff,测试继续跑 |
| 第 60 秒 | 测试结束,Loop 可以处理追问 | 测试结束,完成通知交回原会话 |
| 第 63 秒 | Agent 回 diff | Agent 可以已经在汇报回归结果 |
在这个示意里,追问到回答从 53 秒变成 3 秒,测试本身两边都是 60 秒。若追问换成「测试通过了吗」,第 60 秒才有最终结果,前面只能回答当前状态。若等待期间还有独立工作,例如只读检查同一改动的边界条件,就可能把这段工作和回归重叠起来。若每一步都依赖前一步结果,或者工具本身很快,重叠空间就很小。结果自动投回会话还能让 Agent 在命令完成后自行继续,用户可以等汇报再回来。
并发带来的成本落在执行器和会话管理上。任务要有明确的归属、状态和取消方式,完成结果要对应启动它的任务。如果测试途中改了代码,已有结果应标明对应的版本,必要时重新验证。后台进程也会占用资源。Harness 的本地 job 服务提供并发限制,任务在所属 Agent 被释放或 Harness 关闭时结束。持久化与重启恢复需要额外机制。 本地 Job 服务与生命周期
和 T3 Code 的关系
T3 的 Queue 表达「等后续一轮」,Steer 表达「交给当前一轮」。输入框接受了消息、Provider 收到了消息、模型把它纳入下一次请求,是三个不同时间点。Provider 决定当前工具会继续、等待还是被中断。T3 与文章直接对应的机制是后台完成事件,例如 Codex 适配器在符合条件的命令结束后提交通知,T3 服务把它送回原线程,当前轮忙时排在后面。开另一个会话可以并行做另一件事,而这个例子关注同一会话如何继续处理输入并接回测试结果。 T3 的 Queue 与 Steer、Codex 后台结果、T3 同线程续跑
周五的演示边界
两遍都跑同一个本地测试,输入同一个只读追问,分别展示同步等待与后台执行。模型用固定桩,测试命令真实运行。记录测试启动、追问到达、Loop 将追问交给模型桩、测试退出、结果进入会话的时间。让观众看见异步版在测试还运行时已经回答,以及结束后会话确实收到退出码。Demo 验证交互顺序,现场时长用于说明等待发生在哪里。