s08
后台任务
并发Background Threads + Notifications
37 LOC6 个工具BackgroundManager + notification queue
Run slow operations in the background; the agent keeps thinking ahead
s01 > s02 > s03 > s04 > s05 > s06 | s07 > [ s08 ] s09 > s10 > s11 > s12
"慢操作丢后台, agent 继续想下一步" -- 后台线程跑命令, 完成后注入通知。
Harness 层: 后台执行 -- 模型继续思考, harness 负责等待。
问题
有些命令要跑好几分钟: npm install、pytest、docker build。阻塞式循环下模型只能干等。用户说 "装依赖, 顺便建个配置文件", 智能体却只能一个一个来。
解决方案
Main thread Background thread
+-----------------+ +-----------------+
| agent loop | | subprocess runs |
| ... | | ... |
| [LLM call] <---+------- | enqueue(result) |
| ^drain queue | +-----------------+
+-----------------+
Timeline:
Agent --[spawn A]--[spawn B]--[other work]----
| |
v v
[A runs] [B runs] (parallel)
| |
+-- results injected before next LLM call --+
工作原理
- BackgroundManager 用通知队列追踪任务。
class BackgroundManager {
constructor() {
this.tasks = {};
this.notificationQueue = [];
}
}
run()启动后台执行, 立即返回。
run(command: string): string {
const taskId = randomUUID().slice(0, 8);
this.tasks[taskId] = { status: "running", command };
setTimeout(() => this.execute(taskId, command), 0);
return `Background task ${taskId} started`;
}
- 子进程完成后, 结果进入通知队列。
execute(taskId: string, command: string) {
const result = spawnSync(command, {
shell: true,
cwd: WORKDIR,
encoding: "utf8",
timeout: 300_000,
});
const output = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim();
this.tasks[taskId].status = "completed";
this.notificationQueue.push({
task_id: taskId,
result: output.slice(0, 500),
});
}
- 每次 LLM 调用前排空通知队列。
async function agentLoop(messages: ChatMessage[]) {
while (true) {
const notifications = BG.drainNotifications();
if (notifications.length) {
const notifText = notifications.map((n) => `[bg:${n.task_id}] ${n.result}`).join("\n");
messages.push({ role: "user", content: "<background-results>\n" + notifText + "\n</background-results>" });
messages.push({ role: "assistant", content: "Noted background results." });
}
const response = await client.messages.create({ ... });
循环保持单线程。只有子进程 I/O 被并行化。
相对 s07 的变更
| 组件 | 之前 (s07) | 之后 (s08) |
|---|---|---|
| Tools | 8 | 6 (基础 + background_run + check) |
| 执行方式 | 仅阻塞 | 阻塞 + 后台线程 |
| 通知机制 | 无 | 每轮排空的队列 |
| 并发 | 无 | 守护线程 |
试一试
cd learn-claude-code-typescript
npx tsx agents/s08_background_tasks.ts
试试这些 prompt (英文 prompt 对 LLM 效果更好, 也可以用中文):
Run "sleep 5 && echo done" in the background, then create a file while it runsStart 3 background tasks: "sleep 2", "sleep 4", "sleep 6". Check their status.Run pytest in the background and keep working on other things