首页
首页/s09
s0995 行代码

Background Tasks

Slow Operations Go to the Background

核心洞察:

The agent can keep reasoning while slow work completes elsewhere.

慢操作在后台线程中执行,使 agent 可以继续推理。结果被推送到事件总线,无需轮询。这大幅提升了长时间运行的测试、网络调用、文件下载等操作的吞吐量。

架构流程图

问题:阻塞操作扼杀 Agent 吞吐量

当 agent 运行慢命令(如 npm install、测试套件或 git clone)时,循环被阻塞。模型处于空闲状态,等待结果。30 秒的测试运行意味着 30 秒的闲置。后台任务通过将执行与推理解耦来解决这个问题。Agent 启动任务,继续推理(规划后续步骤、准备后续工作),并在结果通过事件总线到达时获取。这将串行的等待时间转化为并行的生产能力。

事件总线:并行工作流之间的粘合剂

事件总线是一种简单的发布-订阅机制。后台任务在完成时发出事件;agent 循环监听这些事件并将结果合并到对话中。这种模式比回调更灵活(多个监听器可以响应同一事件),比轮询更高效(无需浪费周期检查任务状态)。事件总线还解决了合并问题:如果 agent 调度了多个后台任务,它可以等待所有任务完成,或响应最先完成的那一个。

真实实现:Promotion 模式

OpenCode 实际的 BackgroundJob 系统使用 promotion 模式而非简单的启动等待方式。任务经历一系列状态转换:start、extend(链式顺序工作)、promote(标记为后台)、wait for promotion。关键在于任务可以以前台模式启动,随后提升为后台,反之亦然。这实现了先前台后决定的模式:agent 同步启动任务,如果耗时过长则将其提升为后台。子代理 task tool 正是使用这种模式:前台子代理等待结果,后台子代理独立继续。

设计决策

后台任务使用 agent 自身的工具系统。执行 'npm run build' 使用相同的 bash 工具,区别仅在于 agent 不等待结果。后台任务继承了所有工具能力和安全控制。

事件总线在 agent 进程内同步运行。没有消息队列,没有序列化,没有网络延迟。这使延迟接近于零,并避免了分布式系统的复杂性。

对比 Claude Code

Claude Code 同步处理任务:每个工具调用阻塞 agent 循环。OpenCode 的后台任务系统是一个明显的差异化优势。长时间运行的操作(网络搜索、代码编译、测试套件)在后台运行,同时 agent 继续推理。结果通过事件总线到达并在准备好时注入对话,实现非阻塞、并发的工作流。

深入设计决策

Agent 永远不应该等待

慢操作在后台执行。agent 继续推理,可以稍后检查结果。这让 agent 保持响应性。

备选方案: 同步执行更简单,但会完全阻塞 agent。后台执行增加了复杂性,但大幅提高了吞吐量。

通过事件总线通知结果

后台任务完成时,向事件总线推送通知。agent 主循环在准备好时获取通知并处理结果,无需轮询。

备选方案: 轮询更简单,但浪费 token 和时间。基于推送的通知对 agent 流更高效。

Learn OpenCode — Built with Next.js