orchestrating-agent-relay

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Orchestrating Agent Relay

Agent Relay 编排

Self-bootstrap agent-relay infrastructure and manage a team of agents autonomously.
自引导agent-relay基础设施并自主管理一组Agent。

Overview

概述

A headless orchestrator is an agent that:
  1. Starts the local relay broker itself (
    agent-relay node up
    )
  2. Spawns and manages worker agents on that broker
  3. Monitors agent lifecycle events
  4. Coordinates work without human intervention
The orchestrator drives the team and reads/sends/lists through the Agent Relay MCP server (
agent-relay mcp
), which auto-registers the orchestrating session as the
orchestrator
agent when a workspace key is present. Lifecycle control — starting the broker, spawning/releasing local agents, streaming broker debug events — goes through the
agent-relay node
command group. The workers it spawns are registered participants too; their peer-messaging reference is the
using-agent-relay
skill.
无头编排器是一种Agent,它可以:
  1. 自行启动本地Relay代理(
    agent-relay node up
  2. 在该代理上生成并管理工作Agent
  3. 监控Agent生命周期事件
  4. 无需人工干预即可协调工作
编排器驱动整个团队,并通过Agent Relay MCP服务器
agent-relay mcp
)进行读取/发送/列表操作,当存在工作区密钥时,编排会话会自动注册为
orchestrator
Agent。生命周期控制——启动代理、生成/释放本地Agent、流式传输代理调试事件——通过
agent-relay node
命令组完成。它生成的工作Agent也是已注册的参与者;它们的对等消息传递参考是**
using-agent-relay
**技能。

The model

模型

  • Agent Relay delivers messages node-only: every agent is owned by a node, and the engine routes that agent's messages to its node reliably (ordered, resumable). The local broker is a node; agents you spawn on it are bound to it.
  • A fleet is the set of nodes advertising capabilities (
    spawn:<harness>
    plus custom node actions). The engine places a spawn or action onto a node by capability + liveness + capacity + least-loaded, or onto a named
    target_node
    . Spawning and releasing agents are actions. Most orchestration spawns on the local broker; fleets matter when coordinating across nodes.
  • Agent-to-agent coordination is messages — channels, DMs, threads — plus reactions and read receipts. Reading another agent's replies is a messaging operation (
    check_inbox
    ,
    list_messages
    ,
    get_message_thread
    ), not a broker-event tail.
  • Agent Relay 仅通过节点传递消息:每个Agent都归属于一个节点,引擎会可靠地将该Agent的消息路由到其所属节点(有序、可恢复)。本地代理是一个节点;在其上生成的Agent会绑定到该节点。
  • 集群是一组宣传能力的节点集合(
    spawn:<harness>
    加上自定义节点操作)。引擎会根据能力、活跃度、容量和负载最低原则,将生成或操作任务分配到某个节点,或者分配到指定的
    target_node
    。生成和释放Agent属于操作任务。大多数编排操作会在本地代理上生成Agent;当跨节点协调时,集群才会发挥作用。
  • Agent间的协调通过消息(频道、私信、线程)以及反应和已读回执实现。读取其他Agent的回复是一种消息传递操作(
    check_inbox
    list_messages
    get_message_thread
    ),而非代理事件流。

When to Use

使用场景

  • Agent needs full control over its worker team
  • No human available to run
    agent-relay node up
    manually
  • Agent should manage agent lifecycle autonomously
  • Building self-contained multi-agent systems
  • Agent需要完全控制其工作团队
  • 无人手动运行
    agent-relay node up
  • Agent应自主管理Agent生命周期
  • 构建独立的多Agent系统

Quick Reference

快速参考

StepCommand/Tool
Verify installation
command -v agent-relay
or
npx agent-relay --version
Verify Node runtime if shim fails
node --version
or fix mise/asdf first
Start broker
agent-relay node up --background --verbose
Check broker readiness
agent-relay node status --wait-for 10
Workspace + cloud + broker status
agent-relay status
Spawn worker
agent-relay node agent spawn claude --name Worker1 --task "..."
List workers
agent-relay node agent list
Resource usage
agent-relay node metrics
Send DM to worker (MCP)
send_dm(to: "Worker1", text: "...")
Post to channel (MCP)
post_message(channel: "general", text: "...")
Read worker replies (MCP)
check_inbox(limit: 20)
/
list_messages(channel: "general")
Give a human a follow-along link
agent-relay observer
Inspect a worker's TTY
agent-relay node agent attach Worker1 --mode view
Release worker
agent-relay node agent release Worker1
Stop broker
agent-relay node down
步骤命令/工具
验证安装
command -v agent-relay
npx agent-relay --version
如果垫片失败,验证Node运行时
node --version
或先修复mise/asdf
启动代理
agent-relay node up --background --verbose
检查代理就绪状态
agent-relay node status --wait-for 10
工作区 + 云端 + 代理状态
agent-relay status
生成工作Agent
agent-relay node agent spawn claude --name Worker1 --task "..."
列出工作Agent
agent-relay node agent list
资源使用情况
agent-relay node metrics
向工作Agent发送私信(MCP)
send_dm(to: "Worker1", text: "...")
向频道发送消息(MCP)
post_message(channel: "general", text: "...")
读取工作Agent的回复(MCP)
check_inbox(limit: 20)
/
list_messages(channel: "general")
为人类提供跟进链接
agent-relay observer
检查工作Agent的TTY
agent-relay node agent attach Worker1 --mode view
释放工作Agent
agent-relay node agent release Worker1
停止代理
agent-relay node down

Bootstrap Flow

引导流程

Step 0: Verify Installation

步骤0:验证安装

bash
undefined
bash
undefined

Check if agent-relay is available

检查agent-relay是否可用

command -v agent-relay || npx agent-relay --version
command -v agent-relay || npx agent-relay --version

If your shell reports a mise/asdf shim error, fix Node first

如果shell报告mise/asdf垫片错误,先修复Node

node --version
node --version

e.g. for mise: mise use -g node@22.22.1

例如,对于mise:mise use -g node@22.22.1

If not installed, install globally

如果未安装,全局安装

npm install -g agent-relay
npm install -g agent-relay

Or use npx (no global install)

或使用npx(无需全局安装)

npx agent-relay --version
undefined
npx agent-relay --version
undefined

Step 1: Start the Broker

步骤1:启动代理

bash
undefined
bash
undefined

Starts a detached broker and returns after API readiness

启动后台代理,API就绪后返回

agent-relay node up --background --verbose

Verify broker readiness before spawning any workers:

```bash
agent-relay node up --background --verbose

在生成任何工作Agent之前,验证代理是否就绪:

```bash

Polls for readiness; must report the daemon running before you spawn workers

轮询就绪状态;必须报告守护进程正在运行,才能生成工作Agent

agent-relay node status --wait-for 10

`agent-relay status` (top level) reports workspace, cloud login, and local
broker status together; `agent-relay node status` is the focused broker-daemon
readiness check.

> The broker/agent lifecycle commands live under `agent-relay node …`. The old
> flat `agent-relay local …` group still works as a **hidden, deprecated alias**
> and prints a removal warning — use `node` in new work.

When verifying from a source checkout or throwaway git worktree, run these
commands from the project/worktree root. The CLI writes runtime state to
`.agentworkforce/relay/` and may create `.mcp.json`; clean those files after
validation if the worktree should remain clean.

The broker:

- Auto-creates a Relaycast workspace if no workspace key is set
- Removes the `CLAUDECODE` env var when spawning (fixes nested session error)
- Persists state to `.agentworkforce/relay/` (broker connection metadata,
  lock/pid, and `.agentworkforce/relay/connection.json`)
agent-relay node status --wait-for 10

`agent-relay status`(顶层命令)会一起报告工作区、云端登录和本地代理状态;`agent-relay node status`是针对代理守护进程就绪状态的专项检查。

> 代理/Agent生命周期命令位于`agent-relay node …`下。旧的扁平化`agent-relay local …`命令组仍可作为**隐藏的已弃用别名**使用,并会打印移除警告——在新工作中请使用`node`命令。

如果从源代码检出或临时git工作树进行验证,请从项目/工作树根目录运行这些命令。CLI会将运行时状态写入`.agentworkforce/relay/`,并可能创建`.mcp.json`;如果工作树需要保持干净,请在验证后删除这些文件。

代理特性:

- 如果未设置工作区密钥,会自动创建Relaycast工作区
- 生成Agent时会移除`CLAUDECODE`环境变量(修复嵌套会话错误)
- 将状态持久化到`.agentworkforce/relay/`(代理连接元数据、锁/进程ID,以及`.agentworkforce/relay/connection.json`)

Step 2: Spawn Workers

步骤2:生成工作Agent

The orchestrator's MCP session can spawn through the relay MCP, or you can spawn directly on the local broker via the CLI.
CLI:
bash
agent-relay node agent spawn claude \
  --name Worker1 \
  --task "Implement the authentication module following the existing patterns"
MCP (relay MCP, when the orchestrating session runs
agent-relay mcp
):
text
add_agent(
  name: "Worker1",
  cli: "claude",
  task: "Implement the authentication module following the existing patterns"
)
node agent spawn
takes the provider as a positional argument (
claude
,
codex
,
gemini
,
droid
, …) and
--name
/
--task
/
--channels
/
--model
/
--cwd
flags. By default the agent joins the
general
channel and runs in
interactive
spawn mode; pass
--exit-after-task
for a one-shot worker.
Expect a 30–60s gap between spawn and the first ACK. A worker shows in
node agent list
within ~5s (the process is up), but the underlying CLI (claude/codex) is still cold-starting and won't send its ACK DM until it finishes booting — typically 30–45s, occasionally longer, after it appears. Appearing in the list means "process alive," not "agent responsive." Don't treat ACK silence in the first minute as a stuck worker; size ACK-wait loops for at least 60s (e.g. a 30-iteration poll) before escalating to troubleshooting.
编排器的MCP会话可以通过Relay MCP生成Agent,也可以直接通过CLI在本地代理上生成。
CLI方式:
bash
agent-relay node agent spawn claude \
  --name Worker1 \
  --task "按照现有模式实现身份验证模块"
MCP方式(当编排会话运行
agent-relay mcp
时,通过Relay MCP):
text
add_agent(
  name: "Worker1",
  cli: "claude",
  task: "按照现有模式实现身份验证模块"
)
node agent spawn
将提供商作为位置参数(
claude
codex
gemini
droid
等),并接受
--name
/
--task
/
--channels
/
--model
/
--cwd
标志。默认情况下,Agent会加入
general
频道并以
interactive
模式生成;若要生成一次性工作Agent,请传递
--exit-after-task
生成后到首次ACK之间会有30–60秒的间隔。工作Agent会在约5秒内出现在
node agent list
中(进程已启动),但底层CLI(claude/codex)仍在冷启动,直到启动完成后才会发送首次ACK私信——通常在出现后30–45秒,偶尔会更长。出现在列表中意味着“进程存活”,而非“Agent响应就绪”。不要将最初一分钟内的ACK静默视为工作Agent卡住;在排查问题之前,ACK等待循环至少要设置60秒(例如30次轮询)。

Step 2.5: Give the Human a Way to Watch (optional)

步骤2.5:为人类提供观察方式(可选)

A human driving an autonomous run usually wants to see what the team is saying without joining it. Hand them a read-only observer link:
bash
agent-relay observer
That prints a URL backed by a scoped
ot_live_
token — read-only, expiring in 24 hours, agent DMs excluded. Narrow it with
--channels build,review
, widen it with
--include-dms
or
--expires 7d
, and cut it off early with
agent-relay observer revoke <id>
.
From the relay MCP, the equivalent is
get_observer_url
.
Never build an observer URL from the workspace key.
rk_live_
is an administrative credential — it can send messages, spawn agents, and change workspace settings — and a URL query string is not a place to put one. The realtime endpoint rejects it anyway; only a scoped observer token with
stream:read
is accepted.
驱动自主运行的人类通常希望查看团队的对话内容,而无需加入其中。为他们提供只读观察者链接:
bash
agent-relay observer
这会打印一个由范围限定的
ot_live_
令牌支持的URL——只读,24小时后过期,不包含Agent私信。可以使用
--channels build,review
缩小范围,使用
--include-dms
--expires 7d
扩大范围,使用
agent-relay observer revoke <id>
提前撤销。
在Relay MCP中,对应的命令是
get_observer_url
切勿使用工作区密钥构建观察者URL
rk_live_
是管理凭证——它可以发送消息、生成Agent和更改工作区设置——而URL查询字符串并非存放此类凭证的安全位置。实时端点会拒绝此类请求;只有带有
stream:read
权限的范围限定观察者令牌才会被接受。

Step 3: Monitor and Coordinate

步骤3:监控与协调

The orchestrator reads and sends through the relay MCP (it is auto-registered as
orchestrator
):
text
undefined
编排器通过Relay MCP进行读写操作(它会自动注册为
orchestrator
):
text
undefined

Read messages directed to you — DM replies, mentions, reactions

读取发送给你的消息——私信回复、提及、反应

check_inbox(limit: 20)
check_inbox(limit: 20)

Read a channel's history

读取频道历史

list_messages(channel: "general", limit: 50)
list_messages(channel: "general", limit: 50)

Read a full thread off a specific message

读取特定消息的完整线程

get_message_thread(message_id: "msg_123")
get_message_thread(message_id: "msg_123")

Send a targeted DM to a specific worker

向特定工作Agent发送定向私信

send_dm(to: "Worker1", text: "Also add unit tests")
send_dm(to: "Worker1", text: "同时添加单元测试")

Broadcast to a channel

向频道广播消息

post_message(channel: "general", text: "All workers: wrap up current task")
post_message(channel: "general", text: "所有工作Agent:完成当前任务")

See who is present

查看在线Agent

list_agents(status: "online")

For broker-side liveness and resource visibility, use the CLI:

```bash
list_agents(status: "online")

对于代理端的活跃度和资源可见性,请使用CLI:

```bash

Agents running on the local broker (pid, status, uptime)

本地代理上运行的Agent(进程ID、状态、运行时间)

agent-relay node agent list
agent-relay node agent list

Resource usage for the broker and its agents

代理及其Agent的资源使用情况

agent-relay node metrics

> **Reading worker replies is a messaging operation, never `node tail`.**
> `agent-relay node tail` streams **broker debug events** (spawn/exit/queue
> internals); `agent-relay node tail --agent <name>` streams that worker's
> **raw output/TTY**. Neither is the durable message log workers write to each
> other. To read a worker's ACK, STATUS, or DONE, use `check_inbox` /
> `list_messages` / `get_message_thread` over the relay MCP. Use `node tail`
> only when debugging broker delivery or watching a worker's raw output.
agent-relay node metrics

> **读取工作Agent的回复是消息传递操作,而非`node tail`**。`agent-relay node tail`会流式传输**代理调试事件**(生成/退出/队列内部信息);`agent-relay node tail --agent <name>`会流式传输该工作Agent的**原始输出/TTY**。两者都不是工作Agent之间通信的持久消息日志。要读取工作Agent的ACK、STATUS或DONE消息,请通过Relay MCP使用`check_inbox`/`list_messages`/`get_message_thread`。仅在调试代理交付或查看工作Agent原始输出时使用`node tail`。

Step 4: Release Workers

步骤4:释放工作Agent

text
remove_agent(name: "Worker1", reason: "Work accepted")
CLI equivalent:
bash
agent-relay node agent release Worker1
text
remove_agent(name: "Worker1", reason: "工作已接受")
对应的CLI命令:
bash
agent-relay node agent release Worker1

Step 5: Shutdown (optional)

步骤5:关闭(可选)

bash
agent-relay node down
bash
agent-relay node down

Coordination Commands

协调命令

Lean on the relay MCP for messaging and on
agent-relay node
for lifecycle.
Together they give full visibility into agent activity.
依赖Relay MCP进行消息传递,依赖
agent-relay node
进行生命周期管理
。两者结合可全面了解Agent活动情况。

Channel vs DM — When to Use Each

频道 vs 私信——使用场景

DM — targeted, private, for responses you need to read back:
  • send_dm(to: "Worker1", text: "...")
    — sends a DM to Worker1
  • Worker replies arrive in your inbox; read new ones with
    check_inbox
    , and re-read consumed history with
    list_dms
    +
    agent-relay message dm list <conversationId>
Channel post — broadcast, visible to all agents on that channel:
  • post_message(channel: "general", text: "...")
    — posts to #general
  • Use for coordination messages, status updates, announcements
  • Read channel history with
    list_messages(channel: "general")
check_inbox
is the canonical way to read unread messages directed at you
— it returns unread DMs, mentions, and reactions and does not resurface messages once read. For a full channel transcript use
list_messages
; for one thread use
get_message_thread
. To re-read a DM conversation you already consumed (an ACK/DONE you saw earlier, or a worker's full DM history), enumerate conversations with
list_dms
, then read one persistently with the CLI
agent-relay message dm list <conversationId>
— unlike
check_inbox
, that view does not clear on read.
text
undefined
私信——定向、私密,用于需要读取回复的场景:
  • send_dm(to: "Worker1", text: "...")
    ——向Worker1发送私信
  • 工作Agent的回复会进入你的收件箱;使用
    check_inbox
    读取新消息,使用
    list_dms
    +
    agent-relay message dm list <conversationId>
    重新读取已消费的历史消息
频道消息——广播,对该频道的所有Agent可见:
  • post_message(channel: "general", text: "...")
    ——发布到#general频道
  • 用于协调消息、状态更新、公告
  • 使用
    list_messages(channel: "general")
    读取频道历史
check_inbox
是读取未读定向消息的标准方式
——它返回未读私信、提及和反应,且不会重新显示已读消息。如需完整频道记录,请使用
list_messages
;如需单线程消息,请使用
get_message_thread
。要重新读取已消费的私信对话(之前看到的ACK/DONE消息,或工作Agent的完整私信历史),请使用
list_dms
枚举对话,然后通过CLI
agent-relay message dm list <conversationId>
读取持久对话——与
check_inbox
不同,该视图不会在读取后清除消息。
text
undefined

WRONG — node tail --agent streams the worker's raw output, not durable messages

错误方式——node tail --agent流式传输工作Agent的原始输出,而非持久消息

agent-relay node tail --agent Worker1
agent-relay node tail --agent Worker1

RIGHT — read messages addressed to you (DM replies, mentions)

正确方式——读取发送给你的消息(私信回复、提及)

check_inbox(limit: 20)
check_inbox(limit: 20)

RIGHT — read a channel's evidence trail (diffs, grep counts, GO/NO-GO)

正确方式——读取频道的证据记录(差异、grep计数、GO/NO-GO)

list_messages(channel: "general", limit: 100)
list_messages(channel: "general", limit: 100)

RIGHT — read one thread end to end

正确方式——完整读取一个线程

get_message_thread(message_id: "msg_123")

CLI-only equivalents (agent-token based, useful from a plain shell) live under
the `message` group: `agent-relay message inbox check`,
`agent-relay message list <channel>`,
`agent-relay message dm list <conversationId>` (persistent DM history —
`list_dms` gives the conversation id),
`agent-relay message get_thread <messageId>`,
`agent-relay message dm send <agent> <text>`,
`agent-relay message post <channel> <text>`,
`agent-relay message reply <messageId> <text>`.
get_message_thread(message_id: "msg_123")

仅CLI可用的等效命令(基于Agent令牌,适用于普通shell)位于`message`命令组下:`agent-relay message inbox check`、`agent-relay message list <channel>`、`agent-relay message dm list <conversationId>`(持久私信历史——`list_dms`提供对话ID)、`agent-relay message get_thread <messageId>`、`agent-relay message dm send <agent> <text>`、`agent-relay message post <channel> <text>`、`agent-relay message reply <messageId> <text>`。

Monitoring Workers (Essential)

监控工作Agent(必备)

Spawn/send/release commands are in the Quick Reference and Bootstrap Step 3 — not repeated here. For monitoring specifically: poll
agent-relay node agent list
for broker-side liveness (pid, status, uptime) instead of scraping the worker TTY, and use
agent-relay node agent attach <name> --mode view
to watch real-time output when debugging.
Harness note: don't poll with a bare foreground
sleep
.
Many harnesses (Claude Code included) block a foreground
sleep
used to wait for ACK/DONE — e.g.
sleep 25; check_inbox ...
is rejected with a directive to use a backgrounded loop or a Monitor/until-loop instead. The inline
sleep
-based snippets shown elsewhere in this skill are illustrative of the logic; in a harnessed environment, run the wait loop with
run_in_background
(or the harness's Monitor + until-loop), polling
check_inbox
and
agent-relay node agent list
from inside the backgrounded loop rather than blocking the foreground on
sleep
.
生成/发送/释放命令已在快速参考和引导步骤3中列出——此处不再重复。专门针对监控:轮询
agent-relay node agent list
获取代理端活跃度(进程ID、状态、运行时间),而非抓取工作Agent的TTY;调试时使用
agent-relay node agent attach <name> --mode view
查看实时输出。
工具提示:不要使用前台
sleep
进行轮询
。许多工具(包括Claude Code)会阻止用于等待ACK/DONE的前台
sleep
——例如
sleep 25; check_inbox ...
会被拒绝,并要求使用后台循环或Monitor/until-loop替代。本技能中展示的内联
sleep
代码片段仅用于说明逻辑;在工具环境中,请使用
run_in_background
(或工具的Monitor + until-loop)运行等待循环,在后台循环内轮询
check_inbox
agent-relay node agent list
,而非在前台阻塞
sleep

Troubleshooting

故障排查

bash
undefined
bash
undefined

Release an unresponsive worker (graceful stop)

释放无响应的工作Agent(优雅停止)

agent-relay node agent release Worker1
agent-relay node agent release Worker1

Re-check broker status

重新检查代理状态

agent-relay node status
agent-relay node status

Workspace + cloud + broker overview

工作区 + 云端 + 代理概览

agent-relay status
agent-relay status

If a worker looks stuck, attach in view mode to inspect its TTY

如果工作Agent看起来卡住,以查看模式附加到其TTY进行检查

agent-relay node agent attach Worker1 --mode view

**Tip:** Attach with `--mode view` or watch `agent-relay node tail --agent
<name>` to monitor worker progress and catch errors early.
agent-relay node agent attach Worker1 --mode view

**提示:** 使用`--mode view`附加或查看`agent-relay node tail --agent <name>`以监控工作Agent进度,及早发现错误。

Orchestrator Instructions Template

编排器指令模板

Give your lead agent these instructions. The bootstrap/spawn/monitor commands are in the Bootstrap Flow and Quick Reference above — the paste-worthy part is the Protocol, the ruleset a lead agent can't infer from the command list:
text
You are an autonomous orchestrator. Bootstrap the local broker
(Bootstrap Flow Steps 0–2), then spawn and manage workers per the
Quick Reference. Then enforce this protocol:
为你的主导Agent提供以下指令。引导/生成/监控命令已在上述引导流程和快速参考中列出——可直接复制的部分是协议,即主导Agent无法从命令列表中推断出的规则集:
text
你是一个自主编排器。引导本地代理
(引导流程步骤0–2),然后根据快速参考生成并管理工作Agent。随后执行以下协议:

Protocol

协议

  • Workers will ACK when they receive tasks — but expect a 30–60s cold-start gap after spawn: a worker appears in
    node agent list
    (~5s) well before the CLI is booted enough to send its first ACK. Don't troubleshoot a "stuck" fresh worker until at least 60s has passed
  • Workers will send DONE when complete
  • In a harnessed environment, never wait with a bare foreground
    sleep
    (it is blocked) — run ACK/DONE poll loops with run_in_background or a Monitor/until-loop, polling
    check_inbox
    and
    node agent list
    from inside it
  • ACK/DONE target:
    orchestrator
    (the auto-registered spawning identity) or the
    general
    channel — NEVER
    broker
    .
    broker
    is the broker's internal routing self-name, not a spawnable/DM-able agent: a worker DM to
    broker
    fails with
    Agent "broker" not found
    . Write the worker task prompt to DM
    orchestrator
    (or post
    general
    ) — never "DM the broker"
  • Tell every worker explicitly: do NOT self-remove/release after DONE — stay alive and idle so you can DM them review findings to fix
  • After DONE, run a reviewer; on NO-GO, DM the findings back to the SAME worker. If the worker is gone, spawn a fresh one and re-inject branch + commit SHA + the full verdict
  • Read worker replies with
    check_inbox
    /
    list_messages
    /
    get_message_thread
    over the relay MCP — never
    node tail
    (that streams broker debug events, not worker messages). See the "Channel vs DM" section for the full reading model
  • Poll
    agent-relay node agent list
    for worker liveness; set a wall-clock fallback so a silently-dead worker can't hang the loop
  • If a human is watching, give them a follow-along link with
    agent-relay observer
    and print the URL it returns. Never print the workspace key or put it in a URL
undefined
  • 工作Agent收到任务后会发送ACK——但生成后会有30–60秒的冷启动间隔:工作Agent会在约5秒内出现在
    node agent list
    中,但CLI启动完成并发送首次ACK之前还需要一段时间。在至少60秒过去之前,不要排查“卡住”的新工作Agent
  • 工作Agent完成任务后会发送DONE
  • 在工具环境中,切勿使用前台
    sleep
    等待(会被阻塞)——使用run_in_background或Monitor/until-loop运行ACK/DONE轮询循环,在循环内轮询
    check_inbox
    node agent list
  • ACK/DONE目标:
    orchestrator
    (自动注册的生成身份)或
    general
    频道——绝不要发送给
    broker
    broker
    是代理的内部路由名称,并非可生成/可私信的Agent:工作Agent向
    broker
    发送私信会失败,提示
    Agent "broker" not found
    。将工作Agent的任务提示写入私信发送给
    orchestrator
    (或发布到
    general
    频道)——绝不要指示“向代理发送私信”
  • 明确告知每个工作Agent:完成DONE后不要自行移除/释放——保持存活并处于空闲状态,以便你可以向其发送评审结果进行修复
  • 收到DONE后,运行评审Agent;如果返回NO-GO,将结果私信发送给同一个工作Agent。如果该工作Agent已消失,生成一个新的工作Agent,并重新注入分支、提交SHA和完整评审意见
  • 通过Relay MCP使用
    check_inbox
    /
    list_messages
    /
    get_message_thread
    读取工作Agent的回复——绝不要使用
    node tail
    (它流式传输代理调试事件,而非工作Agent消息)。有关完整读取模型,请参阅“频道 vs 私信”部分
  • 轮询
    agent-relay node agent list
    获取工作Agent活跃度;设置时钟回退机制,以免静默死亡的工作Agent导致循环无限挂起
  • 如果有人类在观察,使用
    agent-relay observer
    为其提供跟进链接,并打印返回的URL。切勿打印工作区密钥或将其放入URL
undefined

Multi-Round Review Loops (DONE → NO-GO → fix → re-review)

多轮评审循环(DONE → NO-GO → 修复 → 重新评审)

Spawning, monitoring, and releasing a worker is the easy path. The hard part the basic flow does not cover: a worker reports DONE, a reviewer comes back NO-GO, and now the work has to go back. Plan for this topology before you spawn anything.
生成、监控和释放工作Agent是简单流程。基本流程未涵盖的难点是:工作Agent报告DONE,评审Agent返回NO-GO,此时工作需要返工。在生成任何Agent之前,请规划好这种拓扑结构。

Workers must not self-remove until you tell them

工作Agent必须在你指示后才能自行移除

A worker's natural hygiene instinct is to release itself right after reporting DONE. That kills the review→fix→re-review loop: when the reviewer returns NO-GO there is no agent left to send the findings to, so you are forced to spawn a fresh worker and re-inject the entire context (branch, commit, full verdict) instead of just DMing the existing one.
Put this in every implementer/worker task prompt explicitly:
text
Do NOT release yourself (no remove_agent / agent-relay node agent release on
yourself). Report DONE and stay alive and idle. The orchestrator will send you
review findings to fix, or release you when the work is fully accepted.
Self-removing before then breaks the fix loop.
The "release when done" guidance elsewhere in this skill applies to the orchestrator releasing workers — never to a worker releasing itself mid-loop.
工作Agent的自然“卫生本能”是在报告DONE后立即自行释放。这会破坏评审→修复→重新评审循环:当评审Agent返回NO-GO时,已没有Agent可以接收结果,因此你必须生成一个新的工作Agent并重新注入整个上下文(分支、提交、完整评审意见),而不仅仅是私信现有Agent。
在每个实现者/工作Agent的任务提示中明确添加以下内容:
text
不要自行释放(不要执行remove_agent / agent-relay node agent release命令)。报告DONE后保持存活并处于空闲状态。编排器会向你发送评审结果进行修复,或在工作完全通过后释放你。在此之前自行移除会破坏修复循环。
本技能中其他地方提到的“完成后释放”指导适用于编排器释放工作Agent——绝不适用于工作Agent在循环中自行释放。

The respawn-with-full-context fallback

重新生成并注入完整上下文的回退方案

If a worker did self-remove (or died), you cannot just DM it. Spawn a fresh worker and re-inject everything it needs to act with no prior memory:
bash
agent-relay node agent spawn codex --name Implementer2 \
  --task "Continuation of prior work. \
Branch: feature/auth. Last commit: <sha>. \
The reviewer returned NO-GO with these findings: <full verdict text>. \
Check out the branch, address every finding, re-run tests, report DONE. \
Do NOT self-remove — stay alive for re-review."
Always pass branch + commit SHA + the complete reviewer verdict. A fresh worker has none of the loop's history; a summarized verdict loses the specifics it needs to fix.
如果工作Agent已自行移除(或死亡),你无法再向其发送私信。生成一个新的工作Agent,并重新注入其所需的所有信息,使其无需依赖历史记忆即可工作:
bash
agent-relay node agent spawn codex --name Implementer2 \
  --task "继续先前的工作。 \
分支:feature/auth。最后一次提交:<sha>。 \
评审Agent返回NO-GO,结果如下:<完整评审文本>。 \
检出分支,解决所有问题,重新运行测试,报告DONE。 \
不要自行移除——保持存活以便重新评审。"
始终传递分支、提交SHA和完整评审意见。新的工作Agent没有循环历史;摘要式评审意见会丢失修复所需的具体信息。

Detecting a silently-dead worker

检测静默死亡的工作Agent

Inbox polling fires on messages only. A worker that exits or self-removes produces no message, so the inbox just goes quiet — indistinguishable from a worker still thinking. Defenses:
  • Poll
    agent-relay node agent list
    for liveness instead of inferring it from inbox silence. A worker that vanishes from the list is gone.
  • agent-relay node agent attach <name> --mode view
    (or
    node tail --agent <name>
    ) will show a self-issued release call — but it is noisy TTY/event scraping, a last resort, not a signal.
  • Always set a wall-clock fallback (e.g. a ScheduleWakeup ~30 min out) so a silently-dead worker can't hang the loop forever waiting on a message that will never arrive.
收件箱轮询仅在有消息时触发。退出或自行移除的工作Agent不会产生消息,因此收件箱会保持静默——这与工作Agent仍在思考的情况无法区分。防御措施:
  • 轮询
    agent-relay node agent list
    获取活跃度,而非通过收件箱静默推断。从列表中消失的工作Agent已死亡。
  • agent-relay node agent attach <name> --mode view
    (或
    node tail --agent <name>
    )会显示自行触发的释放调用——但这是嘈杂的TTY/事件抓取,属于最后手段,而非可靠信号。
  • 始终设置时钟回退机制(例如约30分钟后的ScheduleWakeup),以免静默死亡的工作Agent导致循环无限挂起等待永远不会到达的消息。

Lifecycle Events

生命周期事件

agent-relay node tail
streams broker events. The broker emits these (also available via SDK subscriptions):
EventWhen
agent_spawned
Worker process started
worker_ready
Worker connected to relay
agent_idle
Worker waiting for messages
agent_exited
Worker process ended
agent_permanently_dead
Worker failed after retries
agent-relay node tail
会流式传输代理事件。代理会发出以下事件(也可通过SDK订阅获取):
事件触发时机
agent_spawned
工作Agent进程启动时
worker_ready
工作Agent连接到Relay时
agent_idle
工作Agent等待消息时
agent_exited
工作Agent进程结束时
agent_permanently_dead
工作Agent重试后失败时

Fleet and Capabilities

集群与能力

When you coordinate across nodes rather than only the local broker, capabilities and placement come into play:
bash
undefined
当你跨节点而非仅在本地代理上协调时,能力和分配机制会发挥作用:
bash
undefined

Enable fleet nodes for the workspace FIRST — it is off by default, and a

首先为工作区启用集群节点——默认情况下是关闭的,启用前启动的节点不会注册/列出

node you bring up before enabling will not register/list

agent-relay fleet enable agent-relay fleet config # inspect workspace fleet config agent-relay fleet status # local broker status + this node's provider attachment
agent-relay fleet enable agent-relay fleet config # 检查工作区集群配置 agent-relay fleet status # 本地代理状态 + 此节点的提供商附件

Bring this node up, serving its node definition (advertises its capabilities).

启动此节点,提供其节点定义(宣传其能力)。

fleet serve
was replaced by
node up
; --config points at the node file

fleet serve
已被
node up
替代;--config指向节点文件

(auto-discovers agent-relay.{ts,tsx,js,...} when omitted)

(省略时自动发现agent-relay.{ts,tsx,js,...})

agent-relay node up --config ./node.ts
agent-relay node up --config ./node.ts

List fleet nodes in the workspace

列出工作区中的集群节点

agent-relay fleet nodes
agent-relay fleet nodes

Register a custom capability (command) on this node — both flags are required

在此节点上注册自定义能力(命令)——两个标志都是必需的

agent-relay capabilities register <command> --description "<what it does>" --handler <agent> agent-relay capabilities list

From the relay MCP, `query_nodes` finds nodes by capability or name and `spawn`
invokes the fleet spawn action — the engine places it on an eligible node (or a
named `target_node`).
agent-relay capabilities register <command> --description "<功能描述>" --handler <agent> agent-relay capabilities list

在Relay MCP中,`query_nodes`按能力或名称查找节点,`spawn`调用集群生成操作——引擎会将其分配到符合条件的节点(或指定的`target_node`)。

Is the node actually available?

节点是否真正可用?

online
is not the same as available for placement. A node can be live and still never receive a spawn. Check the capability list, not the status field:
bash
undefined
online
并不等同于可分配。节点可能处于活跃状态,但永远不会接收生成任务。请检查能力列表,而非状态字段:
bash
undefined

fleet nodes
HIDES offline/non-fleet records by default (it hid 385 of 390

fleet nodes
默认隐藏离线/非集群记录(在实际工作区中,390个节点中有385个被隐藏),因此你要查找的节点可能根本不会被打印。

on a real workspace), so a node you are looking for may simply not be printed.

agent-relay fleet nodes --all > /tmp/nodes.raw # redirect: output truncates at 64KB through a pipe python3 - <<'PY' import json, re raw = open("/tmp/nodes.raw").read() m = re.search(r"^{", raw, re.M) # first brace at start of a line, not inside the preamble if not m: raise SystemExit("No JSON in output. Raw:\n" + raw[:500]) for n in json.loads(raw[m.start():]).get("nodes", []): caps = [c["name"] for c in n.get("capabilities", [])] print(f'{n.get("name")} id={n.get("id")} {n.get("status")} live={n.get("live")} {caps}') PY

`id` is printed because that is the field you compare against in the placement
proof below — `dispatchedNodeId` is a node **id**, not a name.

A placement target must carry the `spawn:<agent-type>` capability for the spawn
you are requesting — a node advertising only `spawn:claude` is a valid target for
`fleet spawn claude` and not for `fleet spawn codex`. `release` and
`relay:delivery-cursor-v1` are separate lifecycle capabilities, needed to manage
the worker once placed. A record with no `spawn:*` capability at all is
registered but cannot receive a spawn.

Prove placement end to end rather than trusting the roster — spawn **from a
different machine** so you are testing placement and not a local spawn, confirm
`dispatchedNodeId` matches the target's node id, then verify on the target host
that the process actually exists, and release:

```bash
agent-relay fleet nodes --all > /tmp/nodes.raw # 重定向:通过管道输出会在64KB处截断 python3 - <<'PY' import json, re raw = open("/tmp/nodes.raw").read() m = re.search(r"^{", raw, re.M) # 行首的第一个大括号,而非在序言内 if not m: raise SystemExit("输出中无JSON。原始内容:\n" + raw[:500]) for n in json.loads(raw[m.start():]).get("nodes", []): caps = [c["name"] for c in n.get("capabilities", [])] print(f'{n.get("name")} id={n.get("id")} {n.get("status")} live={n.get("live")} {caps}') PY

打印`id`是因为这是下面分配验证中要比较的字段——`dispatchedNodeId`是节点**ID**,而非名称。

分配目标必须具备你请求的生成任务对应的`spawn:<agent-type>`能力——仅宣传`spawn:claude`的节点是`fleet spawn claude`的有效目标,但不是`fleet spawn codex`的有效目标。`release`和`relay:delivery-cursor-v1`是单独的生命周期能力,管理已分配的工作Agent时需要这些能力。完全没有`spawn:*`能力的节点已注册,但无法接收生成任务。

端到端验证分配,而非信任列表——从**不同机器**生成Agent,以便测试分配而非本地生成,确认`dispatchedNodeId`与目标节点ID匹配,然后在目标主机上验证进程是否实际存在,最后释放:

```bash

STEP 0 — run everything below from a machine OTHER than <node>. Spawning on the

步骤0——从<node>以外的机器运行以下所有命令。在测试分配的同一主机上生成Agent无法证明任何关于分配的内容。

same host you are testing proves nothing about placement.

读取令牌,避免留在shell历史或
ps
参数中。

Read the token without leaving it in shell history or
ps
argv.

read -r -s -p 'Agent token: ' RELAY_AGENT_TOKEN; printf '\n' export RELAY_AGENT_TOKEN trap 'unset RELAY_AGENT_TOKEN' EXIT
agent-relay fleet spawn claude
--name placement-proof --node <node> --channel general
--task "Run hostname -s and reply with its output only." > /tmp/spawn.json
read -r -s -p 'Agent令牌: ' RELAY_AGENT_TOKEN; printf '\n' export RELAY_AGENT_TOKEN trap 'unset RELAY_AGENT_TOKEN' EXIT
agent-relay fleet spawn claude
--name placement-proof --node <node> --channel general
--task "运行hostname -s并仅回复其输出。" > /tmp/spawn.json

STEP 1 — the control plane says it dispatched where you asked. The response carries

步骤1——控制平面表示已按请求分配。响应在JSON之前包含人类可读的序言。切勿在此处中止:生成失败也是结果,回溯会跳过步骤3的释放并导致Agent泄漏。

a human-readable preamble before the JSON. Never abort here: a failed spawn is a

result, and a traceback would skip the STEP 3 release and leak a running agent.

python3 - <<'PY' import json, re raw = open("/tmp/spawn.json").read() m = re.search(r"^{", raw, re.M) # first brace at start of a line inv = None if m: try: inv = json.loads(raw[m.start():]).get("invocation") except ValueError: pass if not inv: print("Spawn did not return an invocation — it likely failed. Raw output:\n" + raw) else: print("dispatched to:", inv.get("dispatchedNodeId"), "| name:", (inv.get("node") or {}).get("name"), "| status:", inv.get("status")) PY
python3 - <<'PY' import json, re raw = open("/tmp/spawn.json").read() m = re.search(r"^{", raw, re.M) # 行首的第一个大括号 inv = None if m: try: inv = json.loads(raw[m.start():]).get("invocation") except ValueError: pass if not inv: print("生成未返回调用信息——可能失败。原始输出:\n" + raw) else: print("分配到:", inv.get("dispatchedNodeId"), "| 名称:", (inv.get("node") or {}).get("name"), "| 状态:", inv.get("status")) PY

dispatchedNodeId
must equal <node>'s
id
from the roster command above — it is an

dispatchedNodeId
必须等于上述列表命令中<node>
id
——它是ID(
node_…
),而非名称。不匹配意味着分配忽略了你的目标;匹配仍无法证明执行情况,因此需要步骤2。

id (
node_…
), not a name. A mismatch means placement ignored your target; a match

步骤2——进程实际存在。在目标主机上运行此命令。

still proves nothing about execution, hence STEP 2.

STEP 2 — the process actually exists. Run this ON THE TARGET HOST.

pgrep -fl placement-proof # broker pty + CLI process must both be present
pgrep -fl placement-proof # 代理pty + CLI进程必须都存在

STEP 3 — release from the control plane. Works regardless of how the node's broker

步骤3——从控制平面释放。无论节点代理如何启动,此命令都有效。请勿在此处使用
node agent release
:使用--state-dir启动的集群节点(如LaunchAgent)无法通过该子命令访问。

was started. Do NOT use
node agent release
here: a fleet node started with

--state-dir (as the LaunchAgent does) is unreachable from that subcommand.

agent-relay fleet release placement-proof

Steps 1 and 2 are separate claims. Step 1 alone is the mistake that makes a broken
node look healthy — dispatch is recorded by the control plane whether or not
anything ran.
agent-relay fleet release placement-proof

步骤1和步骤2是独立的验证步骤。仅执行步骤1是导致故障节点看起来健康的错误——无论是否实际运行,控制平面都会记录分配情况。

Enrolling a new machine as a fleet node

将新机器注册为集群节点

Enrollment is a two-step API flow — mint on the control plane, redeem from the node:
  1. POST /api/v1/fleet/enrollment-tokens
    → single-use
    ocl_node_enr_…
  2. POST /api/v1/fleet/register
    , from the machine being enrolled
The node-side script is
sandbox-node-bootstrap.sh
, with
README.md
alongside it as the authoritative reference. Both live at
dev-stack/fleet-node-bootstrap/
in the
AgentWorkforce/cloud
repository — they are not shipped with this skill, so you need access to that repo to run an enrollment. It supports Daytona, CF Containers, the local dev-stack runner, and Mac minis.
The script takes its inputs from the environment so secrets never reach
ps
argv. Populate the token with a silent read so it does not land in shell history either:
bash
read -r -s -p 'Enrollment token: ' RELAY_ENROLLMENT_TOKEN; printf '\n'
trap 'unset RELAY_ENROLLMENT_TOKEN' EXIT

RELAY_ENROLLMENT_TOKEN="$RELAY_ENROLLMENT_TOKEN" \
RELAY_ENROLLMENT_URL='https://<app>/api/v1/fleet/register' \
RELAY_NODE_NAME='<name>' \
  sandbox-node-bootstrap.sh enroll
Never skip
sandbox-node-bootstrap.sh preflight
on a machine that already runs brokers.
agent-relay node up
calls
killOrphanedBrokerProcesses(projectRoot)
at startup, terminating every broker whose CWD is that root.
findProjectRoot()
walks up for markers (
.git
,
package.json
,
.agentworkforce/relay
), so a
$HOME
-rooted workdir resolves
projectRoot=$HOME
and reaps every
$HOME
-rooted broker. That is relay#1328 — a real incident that killed production brokers on a shared machine. Pin
AGENT_RELAY_PROJECT
to a unique per-instance dir and drop a physical
.agentworkforce/relay
marker there.
Enrollment persists to
~/.agentworkforce/relay/fleet-enrollments.json
(holds a live
nt_live_…
node token — never echo this file). Once enrolled, a
com.agentrelay.fleet-node
LaunchAgent brings the node back automatically across reboots; a rebooted machine does not need re-enrolling.
注册是两步API流程——在控制平面生成令牌,在节点上兑换:
  1. POST /api/v1/fleet/enrollment-tokens
    → 一次性
    ocl_node_enr_…
    令牌
  2. POST /api/v1/fleet/register
    ,从要注册的机器发起请求
节点端脚本是
sandbox-node-bootstrap.sh
,旁边的
README.md
是权威参考。两者都位于**
AgentWorkforce/cloud
**存储库的
dev-stack/fleet-node-bootstrap/
中——它们随本技能一起提供,因此你需要访问该存储库才能运行注册。它支持Daytona、CF Containers、本地dev-stack运行器和Mac mini。
脚本从环境获取输入,因此机密信息永远不会出现在
ps
参数中。使用静默读取填充令牌,以免其进入shell历史:
bash
read -r -s -p '注册令牌: ' RELAY_ENROLLMENT_TOKEN; printf '\n'
trap 'unset RELAY_ENROLLMENT_TOKEN' EXIT

RELAY_ENROLLMENT_TOKEN="$RELAY_ENROLLMENT_TOKEN" \
RELAY_ENROLLMENT_URL='https://<app>/api/v1/fleet/register' \
RELAY_NODE_NAME='<名称>' \
  sandbox-node-bootstrap.sh enroll
切勿在已运行代理的机器上跳过
sandbox-node-bootstrap.sh preflight
agent-relay node up
启动时会调用
killOrphanedBrokerProcesses(projectRoot)
,终止所有工作目录为该根目录的代理
findProjectRoot()
会向上查找标记(
.git
package.json
.agentworkforce/relay
),因此以
$HOME
为根的工作目录会解析为
projectRoot=$HOME
,并终止所有以
$HOME
为根的代理。这是relay#1328问题——一个导致共享机器上生产代理死亡的真实事件。将
AGENT_RELAY_PROJECT
固定到唯一的每个实例目录,并在那里放置一个物理
.agentworkforce/relay
标记。
注册信息会持久化到
~/.agentworkforce/relay/fleet-enrollments.json
(包含有效的
nt_live_…
节点令牌——切勿回显此文件)。注册后,
com.agentrelay.fleet-node
LaunchAgent会在重启时自动恢复节点;重启后的机器无需重新注册

Reaching a
--state-dir
broker

访问
--state-dir
代理

agent-relay node up --state-dir <dir>
(how the
com.agentrelay.fleet-node
LaunchAgent starts every fleet node) writes its connection file to
<dir>/connection.json
. Every
node agent
subcommand except
attach
reads only the default
~/.agentworkforce/relay/connection.json
, rejects
--state-dir
, and ignores
AGENT_RELAY_DATA_DIR
— so those subcommands report
No running broker found
against a perfectly healthy broker (
relay#1446
).
Prefer the control plane.
agent-relay fleet nodes
,
fleet spawn
and
fleet release
need no local connection file and work on any node regardless of how its broker was started. Reach for the workaround below only for a node-local subcommand that has no fleet equivalent.
bash
DEF=~/.agentworkforce/relay/connection.json
SD=<state-dir>                       # the --state-dir the broker was started with
agent-relay node up --state-dir <dir>
com.agentrelay.fleet-node
LaunchAgent启动每个集群节点的方式)会将其连接文件写入
<dir>/connection.json
。除
attach
外,所有
node agent
子命令仅读取默认
~/.agentworkforce/relay/connection.json
,拒绝
--state-dir
,并忽略
AGENT_RELAY_DATA_DIR
——因此这些子命令会针对完全健康的代理报告
No running broker found
(relay#1446问题)。
优先使用控制平面
agent-relay fleet nodes
fleet spawn
fleet release
无需本地连接文件,无论节点代理如何启动,都可在任何节点上工作。仅当没有集群等效命令时,才使用下面的解决方法执行节点本地子命令。
bash
DEF=~/.agentworkforce/relay/connection.json
SD=<state-dir>                       # 代理启动时使用的--state-dir

-e alone is FALSE for a dangling symlink, which is exactly what a previous run

-e单独对悬空符号链接返回FALSE,这正是先前运行在清理前死亡时留下的情况——因此还要测试-L,否则
ln -s
会因"文件已存在"而失败,子命令会静默不运行。

leaves behind if it died before its cleanup — so test -L as well, or
ln -s

fails with "File exists" and the subcommand silently never runs.

if [ -e "$DEF" ] || [ -L "$DEF" ]; then echo "REFUSING: $DEF already exists — on some hosts this is a real connection file" echo "and clobbering it would break the default broker. If it is a dangling symlink" echo "from an interrupted run, remove it; otherwise inspect it before proceeding." else mkdir -p "$(dirname "$DEF")" # may not exist yet on a freshly provisioned node ln -s "$SD/connection.json" "$DEF" agent-relay node agent list # ... or whichever node-local subcommand you need [ -L "$DEF" ] && rm "$DEF" # remove ONLY a symlink, and only one we created fi

Never use `ln -sf` here. The `-f` silently destroys a pre-existing connection file,
and that file is a real regular file on some hosts — not a stale leftover. Delete
this whole workaround once `relay#1446` lands rather than letting it outlive the bug.
if [ -e "$DEF" ] || [ -L "$DEF" ]; then echo "拒绝:$DEF已存在——在某些主机上这是真实的连接文件" echo "覆盖它会破坏默认代理。如果是中断运行留下的悬空符号链接,请删除它;否则在继续前检查它。" else mkdir -p "$(dirname "$DEF")" # 在新配置的节点上可能尚未存在 ln -s "$SD/connection.json" "$DEF" agent-relay node agent list # ...或你需要的任何节点本地子命令 [ -L "$DEF" ] && rm "$DEF" # 仅删除我们创建的符号链接 fi

切勿在此处使用`ln -sf`。`-f`会静默销毁预先存在的连接文件,而该文件在某些主机上是真实的常规文件——并非过时的遗留文件。一旦relay#1446问题修复,请删除整个解决方法,避免其在问题修复后继续存在。

Common Mistakes

常见错误

MistakeFix
agent-relay: command not found
or mise/asdf shim error
Ensure Node is available first (
node --version
); if a shim is broken, fix the runtime manager, then install/use
agent-relay
"Nested session" errorBroker handles this automatically; if running manually, unset
CLAUDECODE
env var
Broker not startingTry
agent-relay node down
first, then
agent-relay node up --background --verbose
and
agent-relay node status --wait-for 10
Broker not ready after
node status --wait-for
The process is alive but the broker API is not ready; inspect logs, retry readiness, or restart with
agent-relay node down --force
if it remains stuck
Broker stops immediately after startCheck
ps aux | grep agent-relay-broker
and
.agentworkforce/relay/connection.json
; if the process is alive but status is stopped, rerun status from the project root or pass
--state-dir
Half-started broker: process alive but
node status
says stopped and
Failed to read broker connection metadata
node up
spawned a broker that never finished writing connection metadata (readiness timed out) and was not cleaned up. Do NOT just retry
node up
— it won't reap the orphan.
pkill -f agent-relay-broker
(or
agent-relay node down --force
), delete
.agentworkforce/relay/
, then
agent-relay node up
clean and
agent-relay node status --wait-for 30
Worktree verification leaves git status dirtyRun
agent-relay node down --force
, then remove generated
.agentworkforce/relay/
and
.mcp.json
from throwaway validation worktrees before committing
Spawn fails with
internal reply dropped
Broker likely is not fully ready yet; wait for readiness, then spawn one worker first
Workers not connectingEnsure broker started; check
agent-relay node agent list
and worker logs
Not monitoring workersAttach with
agent-relay node agent attach <name> --mode view
frequently to track progress
Workers seem stuckInspect with
agent-relay node agent attach <name> --mode view
for errors
Messages not deliveredCheck channel history with
list_messages(channel: "general")
; for new DMs use
check_inbox
, for already-read DM history use
list_dms
+
agent-relay message dm list <conversationId>
Tried to read replies with
node tail
node tail
streams broker events;
node tail --agent <name>
streams the worker's raw output — neither is durable messages. Read replies with
check_inbox
/
list_messages
/
get_message_thread
Worker DM to
broker
fails with
Agent "broker" not found
Expected —
broker
is the broker's internal routing self-name, not a DM-able agent. Workers must ACK/DONE to
orchestrator
or
general
. Fix the worker task prompt; never instruct "DM the broker"
node status
says running but
node agent list
/MCP calls return empty or
Failed to query broker session
The CLI is dialing a stale/wrong broker — leftover
.agentworkforce/relay/connection.json
from a prior run on an old port, or a second broker process.
ps aux | grep -c '[a]gent-relay-broker'
(>1 ⇒ kill extras), compare
.agentworkforce/relay/connection.json
to the actual listening port, then
agent-relay node down --force
, delete
.agentworkforce/relay/
,
agent-relay node up
clean
Invalid agent token
while broker + workers keep working
The orchestrator shell has an unresolved
${RELAY_WORKSPACE_KEY}
-style template
being used as a literal key (broker/workers hold real tokens). Ensure the workspace key/token is actually resolved in the orchestrator env
New worker appears in
node agent list
but no ACK yet
Expected — appearing means process up (~5s); the CLI cold-starts for another 30–45s before its first ACK DM. Wait ≥60s before troubleshooting a fresh worker
A node you know exists is missing from
agent-relay fleet nodes
The default view hides offline/non-fleet records (385 of 390 hidden on a real workspace) — and the node may be present but past the cut. Use
agent-relay fleet nodes --all
fleet nodes
JSON fails to parse mid-object
Output truncates at 64KB through a pipe. Redirect to a file first (
agent-relay fleet nodes --all > /tmp/nodes.raw
) and parse the file, never the pipe
node agent list
/
release
says
No running broker found (…/relay/connection.json does not exist)
while the fleet node is clearly running
The subcommand is reading the default connection path, not the broker's
--state-dir
one (
relay#1446
). Use the control-plane equivalent —
agent-relay fleet release <name>
/
fleet nodes
— which needs no local connection file. See Reaching a
--state-dir
broker
for the guarded workaround when only a node-local subcommand will do
Targeted
fleet spawn
fails with
Targeted Fleet spawn requires an agent token
Pass
--token
or set
RELAY_AGENT_TOKEN
; mint one with
agent-relay agent register <name> --type system
(capture it without echoing).
--task
is also mandatory and the error only surfaces one problem at a time
Node shows
online
but never receives a spawn
online
≠ available. Check
capabilities
contains
spawn:*
— a record can be live with no spawn capacity. Confirm with a throwaway targeted spawn, verified by
pgrep
on the target host, then release
Harness blocks
sleep 25; check_inbox ...
Bare foreground
sleep
wait loops are disallowed in harnessed environments. Run the poll loop with
run_in_background
(or Monitor + until-loop); the inline
sleep
snippets show logic only
Worker self-removed; can't send review fixesInstruct workers not to self-remove until told. If already gone, spawn a fresh worker and re-inject branch + commit SHA + full verdict (see Multi-Round Review Loops)
Told the user to open an observer URL built from the workspace keyThat is an admin credential in a query string, and the realtime endpoint rejects it. Run
agent-relay observer
(or
get_observer_url
) and share the
ot_live_
URL it returns
Worker died silently; loop hangsInbox polling fires on messages only. Poll
agent-relay node agent list
for liveness and set a wall-clock fallback (~30 min ScheduleWakeup)
错误修复方案
agent-relay: command not found
或mise/asdf垫片错误
确保Node可用(
node --version
);如果垫片损坏,修复运行时管理器,然后安装/使用
agent-relay
"Nested session"错误代理会自动处理此问题;如果手动运行,请取消设置
CLAUDECODE
环境变量
代理无法启动先尝试
agent-relay node down
,然后运行
agent-relay node up --background --verbose
agent-relay node status --wait-for 10
node status --wait-for
后代理仍未就绪
进程已存活,但代理API未就绪;检查日志,重试就绪检查,或如果仍卡住,使用
agent-relay node down --force
重启
代理启动后立即停止检查
ps aux | grep agent-relay-broker
.agentworkforce/relay/connection.json
;如果进程存活但状态为已停止,请从项目根目录重新运行状态检查或传递
--state-dir
代理半启动:进程存活但
node status
显示已停止且
Failed to read broker connection metadata
node up
生成的代理从未完成写入连接元数据(就绪超时)且未被清理。请勿仅重试
node up
——它不会清理孤立进程。运行
pkill -f agent-relay-broker
(或
agent-relay node down --force
),删除
.agentworkforce/relay/
,然后干净启动
agent-relay node up
并运行
agent-relay node status --wait-for 30
工作树验证导致git状态脏运行
agent-relay node down --force
,然后从临时验证工作树中删除生成的
.agentworkforce/relay/
.mcp.json
,再提交
生成失败并提示
internal reply dropped
代理可能尚未完全就绪;等待就绪,然后先生成一个工作Agent
工作Agent无法连接确保代理已启动;检查
agent-relay node agent list
和工作Agent日志
未监控工作Agent经常使用
agent-relay node agent attach <name> --mode view
附加以跟踪进度
工作Agent看起来卡住使用
agent-relay node agent attach <name> --mode view
检查错误
消息未送达使用
list_messages(channel: "general")
检查频道历史;对于新私信使用
check_inbox
,对于已读私信历史使用
list_dms
+
agent-relay message dm list <conversationId>
尝试使用
node tail
读取回复
node tail
流式传输代理事件;
node tail --agent <name>
流式传输工作Agent的原始输出——两者都不是持久消息。使用
check_inbox
/
list_messages
/
get_message_thread
读取回复
工作Agent向
broker
发送私信失败,提示
Agent "broker" not found
预期结果——
broker
是代理的内部路由名称,并非可私信的Agent。工作Agent必须向
orchestrator
general
发送ACK/DONE。修复工作Agent的任务提示;切勿指示“向代理发送私信”
node status
显示运行中但
node agent list
/MCP调用返回空或
Failed to query broker session
CLI正在连接陈旧/错误的代理——先前运行留下的
.agentworkforce/relay/connection.json
使用旧端口,或存在第二个代理进程。运行
ps aux | grep -c '[a]gent-relay-broker'
(>1表示需要杀死多余进程),比较
.agentworkforce/relay/connection.json
与实际监听端口,然后运行
agent-relay node down --force
,删除
.agentworkforce/relay/
,干净启动
agent-relay node up
代理 + 工作Agent持续运行但提示
Invalid agent token
编排器shell使用未解析的
${RELAY_WORKSPACE_KEY}
样式模板
作为文字密钥(代理/工作Agent持有真实令牌)。确保工作区密钥/令牌在编排器环境中已实际解析
新工作Agent出现在
node agent list
中但尚未收到ACK
预期结果——出现意味着进程已启动(约5秒);CLI还需要30–45秒冷启动才能发送首次ACK私信。在排查新工作Agent之前等待≥60秒
你知道存在的节点未出现在
agent-relay fleet nodes
默认视图隐藏离线/非集群记录(在实际工作区中390个节点中有385个被隐藏)——节点可能存在但超出显示限制。使用
agent-relay fleet nodes --all
fleet nodes
JSON在对象中间解析失败
通过管道输出会在64KB处截断。先重定向到文件(
agent-relay fleet nodes --all > /tmp/nodes.raw
),然后解析文件,而非管道
node agent list
/
release
提示
No running broker found (…/relay/connection.json does not exist)
但集群节点明显在运行
子命令正在读取默认连接路径,而非代理的
--state-dir
路径(relay#1446问题)。使用控制平面等效命令——
agent-relay fleet release <name>
/
fleet nodes
——无需本地连接文件。如需执行节点本地子命令,请参阅访问
--state-dir
代理
中的受保护解决方法
定向
fleet spawn
失败并提示
Targeted Fleet spawn requires an agent token
传递
--token
或设置
RELAY_AGENT_TOKEN
;使用
agent-relay agent register <name> --type system
生成令牌(捕获时不要回显)。
--task
也是必需的,错误只会一次显示一个问题
节点显示
online
但从未接收生成任务
online
≠可用。检查
capabilities
是否包含
spawn:*
——节点可能处于活跃状态但无生成能力。通过临时定向生成验证,在目标主机上使用
pgrep
确认,然后释放
工具阻止
sleep 25; check_inbox ...
工具环境中不允许使用前台
sleep
等待循环。使用
run_in_background
(或Monitor + until-loop)运行轮询循环;内联
sleep
代码片段仅展示逻辑
工作Agent自行移除;无法发送评审修复指示工作Agent不要自行移除,直到收到通知。如果已消失,生成新的工作Agent并重新注入分支、提交SHA和完整评审意见(参阅多轮评审循环)
告知用户打开使用工作区密钥构建的观察者URL这是查询字符串中的管理凭证,实时端点会拒绝它。运行
agent-relay observer
(或
get_observer_url
)并分享返回的
ot_live_
URL
工作Agent静默死亡;循环挂起收件箱轮询仅在有消息时触发。轮询
agent-relay node agent list
获取活跃度并设置时钟回退机制(约30分钟的ScheduleWakeup)

Prerequisites

先决条件

  1. agent-relay CLI installed (required)
    bash
    npm install -g agent-relay
    # Or use npx without installing: npx agent-relay <command>
  2. For spawning Claude agents: Valid Anthropic credentials
    • Set
      ANTHROPIC_API_KEY
      or authenticate via
      claude auth login
  3. For MCP-based coordination: run
    agent-relay mcp
    as the relay MCP stdio server in your client's MCP settings. With a workspace key present it auto-registers the session as
    orchestrator
    ; messaging tools (
    send_dm
    ,
    post_message
    ,
    check_inbox
    , …) then work from the orchestrating session.
  1. 已安装agent-relay CLI(必需)
    bash
    npm install -g agent-relay
    # 或使用npx无需安装:npx agent-relay <command>
  2. 生成Claude Agent所需:有效的Anthropic凭证
    • 设置
      ANTHROPIC_API_KEY
      或通过
      claude auth login
      认证
  3. 基于MCP的协调所需:在客户端的MCP设置中,将
    agent-relay mcp
    作为Relay MCP标准输入输出服务器运行。当存在工作区密钥时,它会自动将会话注册为
    orchestrator
    ;此时编排会话即可使用消息传递工具(
    send_dm
    post_message
    check_inbox
    等)。