# 后台任务、loop 与 monitor · 让 agent 边等边干

> 长命令、定时任务、盯日志——agent 怎么不被它们卡住？这一章看 grok 的后台任务：monitor 把日志流成通知、/loop 交给调度器、后台命令完成后用一条合成 prompt「叫醒」模型。

- 作者：David（道雾轩）
- 专栏：Grok Build 源码解读（https://daiw.org/manual/grok-build.md）
- 最后更新：2026-09-15
- 原文：https://daiw.org/manual/grok-build/background-tasks
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# 后台任务、loop 与 monitor · 让 agent 边等边干

一个能自己动手的 agent，常要跑长命令(启服务、跑测试)、盯日志、做定时任务——还不能被这些卡住。grok 有一套后台执行机制。

## monitor：把日志流成通知

`monitor` 工具(`run_monitor_pipeline`)盯一条命令的输出，每有新行就发一个 **`MonitorEvent`** 通知给模型(包成 `<monitor-event>` 标签)。两个生产级细节：

- **速率限制**：一个令牌桶(`TokenBucket`)，事件太多先压制，持续过载 30 秒以上 → 直接 **auto-kill**，防日志刷屏把上下文冲爆；
- **持有 `Weak` 终端引用**：一个「持久」monitor **不能**跨会话把终端进程/actor 钉住(共享运行时的主机上会泄漏)——用 `Weak` 而非 `Arc`，会话一放手它就停。

## /loop：交给调度器

`/loop [间隔] <prompt>` 定时重复一个 prompt。有意思的是**宿主侧没有默认间隔**——若你不给 `5m` 这种 token，宿主也不去解析「every hour」这类自然语言，而是原样交给**模型自己推断**节奏(或问你)。真正的调度落到 `scheduler_create` 工具 + 一个调度器 actor:`ScheduledTask`(可重复/持久/一次性)，会话恢复后调度器会把已有任务**重新播报**给客户端(`announce_existing_tasks`)，上限 50 个(`MAX_SCHEDULED_TASKS`)，重复任务 7 天后过期(`RECURRING_TASK_TTL_DAYS`)。

写作之后变了的一点：**每次触发都跑在一个脱离对话的后台 subagent 里**(`fire_as_loop_subagent`)，不再是你对话里的一轮。它看不到对话上下文，所以存下来的 prompt 必须自成一体，回到对话里的只有结果。

## 后台命令 + 「叫醒」模型

命令带上 `is_background`(bash 工具的参数)→ `run_background` **立刻返回一个 task_id**，不阻塞。跑完发 `TaskCompleted`。关键是**怎么让模型知道它完了**：`notification_bridge` 把 `TaskCompleted` 转成一条**合成 prompt**(`task-completed-<id>`)塞进队列——**这条合成 prompt 就是「叫醒」**。

```mermaid
flowchart LR
  BG[后台命令 run_background] -->|立即| TID[task_id 返回,不阻塞]
  BG -.跑完.-> TC[TaskCompleted]
  TC --> WAKE["合成 prompt 入队<br/>(叫醒模型)"]
  WAKE --> M[模型下一轮看到结果]
```

正因为完成会主动叫醒，阻塞等待才敢设得宽：模型面的 `get_command_or_subagent_output`(内部 id 仍叫 `get_task_output`)一次最多等 20 个任务、全部完成才返回，正数 `timeout_ms` 封顶 **1 小时**(`MAX_WAIT_BLOCK_MS_DEFAULT`，写作时是 600 秒，可用 `GROK_MAX_WAIT_BLOCK_MS` 调低)；原来单独的 `wait_commands_or_subagents` 已并进它。等超了也不会真卡死，任务完成自会 ping。等待是**事件驱动**的(`Notify`，不轮询)。

TUI 侧(这两个快捷键和写作时**对调**了)：<kbd>Ctrl+B</kbd> 把正在跑的前台命令**转到后台**(`SendToBackground`；命令还在跑时直接发新消息，也会让它转后台而不是被杀)、<kbd>Ctrl+G</kbd> 开关任务面板(后台命令 + subagent + monitor/loop 统一列)、dashboard 总览多会话。

## 和《从 LLM 到 Coding Agent》对照

对照 [subagents](https://daiw.org/manual/llm-to-agent/subagents) 与 [Claude Code 的 /loop、后台任务](https://daiw.org/manual/claude-code/commands-collaboration)：最小实现里没有「边等边干」。grok 的增量是把后台执行做成完整能力：monitor 流式 + 速率保护、调度器、以及「完成主动叫醒」这个让阻塞等待变安全的关键设计。下一章总览它的 CLI 与启动。

---

上一篇：[ACP · 编辑器后端](https://daiw.org/manual/grok-build/acp) · 下一篇：[CLI 与启动](https://daiw.org/manual/grok-build/cli-surface)
