所有页面
本页内容

监视会话 0.9.10 新增

智能体可以监视其他会话,而不必一遍遍地去查看它们。它先订阅,然后继续自己的工作或等待;被监视的会话中发生某些事情时,OAR 会唤醒它:有提问在等待回答、某一轮失败、某个会话给出回复、某个后台任务结束。唤醒的方式是 OAR 在监视者的对话中写入一条简短消息。

典型的请求:

  • 照看一批会话。 “监视那三个审查会话。其中一个提问或失败时唤醒我,等它们全部完成后汇总它们的回复。”
  • 等待一项耗时任务。 “在一个会话中启动完整的测试运行并监视它。它的后台任务完成时告诉我,如果失败了也要说。”
  • 留意另一台机器。 “监视 build-box 上的夜间部署会话,有错误就告诉我。”

这些会话可以在此中继上(需启用智能体会话),也可以在已配对的中继上。除 Claude Cloud 和 OpenAI Image 外,每个提供商都可以监视;这两者的会话无法订阅(见按提供商)。工具本身,即 relay_tool 的 subscribe,列在参考的监视会话中;本页说明你会看到什么、可以控制什么。

什么会唤醒监视者 #

订阅会指明要监视的会话,或者某台中继的所有会话(包括之后创建的会话)。它可以要求在以下情况得到通知:

事件 通俗地说
Question(提问) 被监视的会话在等待回答或审批。消息中带有问题及其选项。0.9.16 新增 对于不阻塞的提问,订阅稍后还会得知你的回答。
Error(错误) 某一轮失败、达到了用量上限,或者会话的智能体进程意外终止。
Reply(回复) 某个会话完成了一轮。消息中带有回复的开头部分。
Task started, finished, failed(任务已开始、已结束、已失败) 被监视会话的某个后台智能体或 shell 任务开始了(仅当订阅要求时)、完成了或失败了。以非零状态退出的 shell 命令算作失败。
Stalled(停滞) 某个会话仍在工作,但已经有一段时间没有动静。
All idle(全部空闲) 被监视的会话中已没有任何东西在运行。

0.9.13 新增 没有指明事件的订阅,不会因为某个 shell 命令或 monitor 正常结束而被唤醒:繁忙的会话大约每分钟就会结束一个,而每次唤醒都要让监视者带着完整上下文跑一轮。已完成的子智能体和失败的任务仍会唤醒它。必须跟踪每条命令的智能体,要明确要求所有任务结束事件。此前创建、没有指明事件的订阅会自动切换到这个默认设置;指明了事件的订阅保持不变。

确切的事件名称,以及订阅可用的选项(回复和任务结果必须匹配的正则表达式、触发一次后结束、判定为 stalled 之前的静默时间),见参考。

监视者自己的对话永远不会被监视,因此它自己的轮次不会唤醒它。

订阅只负责通知

它不批准任何事,也不回答任何事。被监视会话中的提问会一直保持待回答状态,直到你或被允许回答它的智能体作答,与以前完全一样。被监视会话中的审批卡片只能由你回答;事件中会说明这一点。

审批卡片 #

对话中的智能体第一次订阅某台中继的会话时,必须先询问你。该对话中会出现一张审批卡片:

This agent wants to watch “Review: server/” (3f9c…), “Review: web/” (a12b…) and be woken by their events.

Events: question_asked, error, turn_end, subagent_finished, task_failed, stalled, all_idle
你的选择 结果
Allow(允许) 订阅被创建。该对话之后对同一中继上会话的订阅不再需要新卡片。
Deny(拒绝) 订阅被拒绝。智能体会得到通知,并在没有该订阅的情况下继续工作。

特殊情况:

  • 所有会话。 对 all 的订阅总会写明:“ALL sessions of this relay, including ones created later”(此中继的所有会话,包括之后创建的);0.9.16 新增 当它排除了某些会话时,还会加上“except N it leaves out”(不含其排除的 N 个)。如果第一张卡片针对的不是 all,之后对 all 的订阅会再次询问。如果是,Allow 就涵盖之后的所有订阅,包括 all。
  • 已配对的中继。 卡片会注明该中继。每台中继单独询问,且不会在另一台中继上询问任何事。
  • 接管。 取代另一个监视者的智能体,可以接手旧监视者的全部订阅。这种情况总会询问,无论你之前允许过多少张卡片。卡片会说明有多少个订阅要转移、来自哪个会话;旧会话不再收到这些订阅的事件,订阅保留原有设置。你的 Allow 同时算作对所涉及中继上订阅的批准;如果其中有订阅监视了所有会话,也包括 all。

0.9.16 新增 卡片还会注明订阅的选项:once(仅一次)、heartbeat every N min(每 N 分钟心跳)、digest every N min(每 N 分钟汇总)以及带时区的 quiet HH:MM–HH:MM(免打扰 HH:MM–HH:MM)。

卡片在每种中继模式下都会出现:它与 ask、plan 或 agent 无关。批准归属于该对话,中继重启后依然保留。

你会看到什么 #

小标签及其列表 #

对话有订阅时,其标题栏显示 watching N sessions(正在监视 N 个会话),统计它监视的所有不同会话。如果有订阅监视全部会话,则显示 watching all sessions(正在监视所有会话);如果对话还按名称列出了会话,后面会跟上 (+N listed)(+N 个已列出)。0.9.16 新增 旁边的小提示会显示订阅的选项,digest N min(摘要 N 分钟)或 quiet HH:MM–HH:MM,最多两个。点击小标签会打开列表:每个订阅一行,列出会话(或中继)、事件,以及它是否为 once 或带有心跳,0.9.16 新增 是否设置了摘要、免打扰时段或排除了会话,排除的会话显示为 N left out(已排除 N 个)。Unsubscribe(取消订阅)会立即结束该订阅,无需询问智能体。

watched 徽标 #

被另一个对话按名称监视的会话,会在会话列表和它的标题栏中带有 watched(监视)徽标。将鼠标悬停在徽标上可以看到谁在监视;已配对中继上的智能体显示为它的会话和中继。对所有会话的订阅不会在会话列表中添加徽标,只会出现在每个会话的标题栏中。你在已配对中继上的订阅不会在你这一侧添加徽标。0.9.16 新增 被“全部会话”订阅排除的会话,不会因该订阅显示徽标。

事件行 #

在监视者的对话记录中,事件显示为一个标有 relay event(中继事件)的紧凑行,绝不会作为你的消息显示。它折叠成一行,例如:

relay event   3 events · question, reply

展开即可阅读各行内容,例如:

[relay event] session "Review: server/" (3f9c…): turn_end (done) "Found 4 places without input checks: …"

包含提问或错误的行保持展开。汇总了因每小时上限而被扣留的事件的行,以 Digest(摘要)开头;0.9.16 新增 由订阅的摘要选项汇总的行也是如此,而在免打扰时段内被扣留的事件所在的行以 After quiet hours(免打扰时段后)开头。标有 replayed(已重放)的行,包含已配对中继在连接中断期间保留的事件。

这一行背后是一条消息,消息开头有一行说明:它是自动发出的,不是你发的,也不批准任何事。智能体同样会读到这一行。

监视者正忙时 #

  • 空闲。 消息会开始新的一轮。
  • 一轮进行中。 在 Claude、DeepSeek 以及 GitHub Copilot 和 OpenAI 的 SDK 引擎上,消息会被引导进正在运行的这一轮。在其他提供商上,它会等待,并成为下一轮。消息仍在等待时到达的事件会并入这条消息,因此忙碌的监视者只会收到一条后续消息,而不是每个事件一条。

节奏控制 #

每次唤醒都要让监视者跑一轮,所以 OAR 会限制唤醒次数。

  • 合并。 30 秒内的事件合并为一条消息送达。
  • 每小时上限。 最近一小时内已唤醒 20 次后,其余事件会被扣留,每 10 分钟以摘要形式发送一次。一旦最近一小时内的唤醒少于 20 次,就恢复按 30 秒合并唤醒。
  • 从不扣留。 提问、0.9.16 新增 你对非阻塞提问的回答以及错误总是立即送达,即使超过上限也一样。但它们仍计入上限。
  • 停滞。 当某个会话在某一轮或后台任务仍在运行时已静默 15 分钟(或订阅选定的时间),就算作停滞。每段静默期只报告一次。正在等待回答的会话不算停滞:它的提问已经报告过了。
  • 心跳。 如果智能体要求了心跳,那么在被监视的轮次或任务运行期间,它会按该间隔收到消息;一切空闲时则不会收到。心跳让监视者知道监视在正常工作。心跳不会被扣留到摘要中,也不计入上限。

同样的数值也列在参考的事件如何送达中。

减少唤醒 0.9.16 新增 #

智能体可以为每个订阅要求减少唤醒。提问和错误仍会立即送达;其他一切都要等待。

选项 作用
Digest(digest_minutes,1 到 1440) 该订阅的事件每 N 分钟合并为一条消息送达,下一条最早在上一条之后 N 分钟。
免打扰时段(quiet_hours,例如 {"from":"23:00","to":"06:00","tz":"Europe/Berlin"}) 某个时区中的每日时间窗口,可以跨越午夜,并随夏令时调整。窗口内发生的事情会在窗口结束时合并为一条消息送达,并标明是在免打扰时段内扣留的。窗口内不发送心跳。
排除会话(exclude,最多 50 个会话 id) 监视全部会话的订阅会忽略这些会话,判断“已没有任何东西在运行”和发送心跳时也一样。

在时钟回拨、结束时间出现两次的那一夜,窗口在第一次到达结束时间时结束,在重复的那一小时内不会再次进入;在时钟拨快、跳过结束时间的那一夜,窗口在时钟跳变的那一刻结束。有一个限制:如果开始时间落在重复的那一小时内,窗口会在第一次经过时开始,而第二次经过时,开始时间之前的那几分钟算在窗口之外。

不回显。 当监视者自己向某个会话发送提示词并等待完整回复(通过 send、create_session 或之后的 wait)时,那一轮的回复不会再次唤醒它。那一轮的错误和提问仍会唤醒它,而它没有等待的提示词也会像以前一样唤醒它。

被扣留的事件在中继重启后依然保留,每小时上限也仍然叠加生效。智能体可以用 list_subscriptions 查看每个订阅扣留了多少事件、何时送达。详情见参考的减少唤醒。

订阅持续多久 #

订阅在以下情况下结束:

  • 智能体或你取消订阅;
  • 监视者的对话被归档或删除;
  • 被监视的会话被归档或删除。列出多个会话的订阅会保留其他会话,直到最后一个会话结束时才结束;
  • 它是 once 订阅且已触发(带正则表达式时,在第一次匹配时触发);
  • 对于已配对的中继,配对被移除:那台中继上的订阅立即结束。

订阅和尚未送达的事件在中继重启后依然保留。

一个对话同时最多可有 20 个订阅。

已配对中继上的会话 #

监视已配对中继上的会话,所需条件与在那里进行任何 relay_tool 调用相同:

  • 该中继在对话中已解锁;
  • 它针对此中继的 Agents may(智能体可以)级别至少允许读取(已配对的中继允许什么);
  • 另一台中继接受其他中继的智能体:Accept prompts from other relays' agents(接受其他中继上智能体的提示词)。

如上所述,卡片在这里询问。配对只需单向存在。你的中继每隔几秒从另一台中继获取事件,这些行以另一台中继的名称开头:

[relay event] build-box · session "Nightly deploy" (77aa…): turn_end (done) "Deployed. The health check is green."

如果另一台中继一分钟内没有响应,连接就视为已断开。另一台中继会保留期间发生的事情:每个订阅最多 500 个事件,最长 7 天。它再次响应时,一个标有 replayed 的行会把这些事件带回来,提问和错误排在前面,位于 link_lost 行和 link_restored 行之间。如果发生的事件超出它能保留的数量,最后一行会说明丢弃了多少。7 天内无人获取的订阅会在那台中继上结束。0.9.16 新增 重放的事件和其他事件一样,遵守订阅的摘要和免打扰时段设置;这时最后一行会说明其中有多少条稍后送达。

0.9.16 新增 对已配对中继的订阅,其摘要和免打扰时段在这里,即监视者所在的地方生效;另一台中继会被告知哪些会话被排除。运行旧版 OAR 的已配对中继不认识 exclude:你的中继仍会丢弃这些会话的事件,但那台中继在判断“已没有任何东西在运行”、判断停滞以及生成心跳列表时,仍会把它们算在内。

运行旧版 OAR 的已配对中继会答复说它需要更新。

按提供商 #

哪些会话可以被监视与提供商无关:中继上的任何会话都可以。区别在于进行监视的那个会话。

监视方会话的提供商 能否订阅 一轮运行期间的事件
Claude 能 被引导进正在运行的这一轮
DeepSeek 0.9.17 新增 能 被引导进正在运行的这一轮
GitHub Copilot、OpenAI,SDK 引擎 能 被引导进正在运行的这一轮
GitHub Copilot、OpenAI,扩展引擎 能 成为下一轮
Cursor 能 成为下一轮
Grok 能 成为下一轮
Claude Cloud 否:它没有 relay_tool
OpenAI Image 否:它调用 Images API,不运行智能体

哪些提供商才有 relay_tool,见智能体工具。

更新前启动的会话

会话 worker 在启动时构建自己的工具。如果你更新到 0.9.10 时某个对话的智能体已在运行,那么在重启之前它没有 subscribe:对空闲会话执行 Kill session(强制结束会话)就够了。