多 Agent 编排

多实例群控

让多个 qsdashi CLI 实例互相通讯:同机通过 Pipe IPC(UDS / Named Pipe)自动编排 main 与 sub, 跨机器通过 LAN Pipes(TCP + UDP Multicast)零配置发现并互相 attach。选定目标实例后,输入框里的 普通 prompt 会自动路由到远端执行,结果流式回传。

  • Pipe IPC
  • LAN 零配置发现
  • main / sub

这是什么

Pipes 系统提供 qsdashi CLI 实例之间的通讯能力,分两层,但共用同一套 NDJSON 协议与同一套命令:

  • Pipe IPC(本机):同一台机器上的多个实例通过 UDS(Unix Domain Socket / Windows Named Pipe)协作。首个启动的实例注册为 main,后续实例成为 sub 并被 main 自动 attach。
  • LAN Pipes(局域网):在 Pipe IPC 基础上扩展 TCP 传输层 + UDP Multicast 发现。 不同机器上的实例自动发现并互相 attach,跨机器时两边都可以是 main。

角色模型:

角色 说明
main 首个启动的实例,管理 registry
sub 同机后续启动的实例(或被 attach 的 LAN 实例)
master attach 了至少一个 slave 的实例
slave 被 master attach 控制的实例

选中目标实例后,在输入框正常输入普通 prompt 即可自动路由到远端执行;每个目标独立执行, 结果以 stream / done 流式回传到你的消息列表。当远端实例执行需要权限的 工具(如 BashTool)时,权限请求会转发回 master 弹出确认对话框。

i
与 Coordinator 的关系

多实例群控是跨进程 / 跨机器的实例协同,编排单位是「CLI 实例」,由你在输入框里手动 选择目标并路由。Coordinator 是单进程内的 agent 编排,由主 Claude 自动派发 worker。 两者互补:群控负责把 prompt 送到另一台机器,Coordinator 负责在这台机器内调度 agent。

前置条件

条件 说明
特性 UDS_INBOX 本机 Pipe IPC 全部功能。当前默认未启用(在 scripts/defines.ts 中被注释禁用)
特性 LAN_PIPES 局域网 TCP + beacon 扩展,依赖 UDS_INBOX。同样默认未启用
(仅 LAN)同一局域网 两台或以上机器在同一子网,ping 可达,路由器未开启 AP 隔离
(仅 LAN)防火墙 每台机器放行 UDP 7101 与 TCP 动态端口;Windows 网络需为「专用」
!
默认关闭,需显式启用

UDS_INBOX 与 LAN_PIPES 未包含在 DEFAULT_BUILD_FEATURES(注释说明:构建后在 Node 环境会卡住)。若不显式开启, /pipes、/attach、/send 等命令不会注册。

安装启用

  1. 启用特性 flag

    dev 模式在启动命令前注入两个 FEATURE_ 变量:

    Terminal
    # 本机 + 局域网管道
    FEATURE_UDS_INBOX=1 FEATURE_LAN_PIPES=1 bun run dev
    
    # build 产物:特性在编译期决定,需要带上变量重新构建
    FEATURE_UDS_INBOX=1 FEATURE_LAN_PIPES=1 bun run build
  2. (LAN)配置防火墙

    每台机器都需要放行组播 beacon 与动态 TCP。Windows 管理员 PowerShell:

    Windows PowerShell(管理员)
    New-NetFirewallRule -DisplayName "QSM LAN Beacon (UDP)" -Direction Inbound -Protocol UDP -LocalPort 7101 -Action Allow -Profile Private
    New-NetFirewallRule -DisplayName "QSM LAN Pipes (TCP)" -Direction Inbound -Protocol TCP -LocalPort 1024-65535 -Program (Get-Command bun).Source -Action Allow -Profile Private
    New-NetFirewallRule -DisplayName "QSM LAN Beacon Out (UDP)" -Direction Outbound -Protocol UDP -RemotePort 7101 -Action Allow -Profile Private
    # 确认网络为「专用」
    Get-NetConnectionProfile

    Linux / macOS 等价配置:

    Linux / macOS
    # Linux(firewalld)
    sudo firewall-cmd --zone=trusted --add-port=7101/udp --permanent
    sudo firewall-cmd --zone=trusted --add-port=1024-65535/tcp --permanent
    sudo firewall-cmd --reload
    
    # macOS:首次运行弹出「允许接受传入连接」对话框,点允许即可
  3. 启动多个实例

    本机场景:终端 1 启动即为 main,终端 2 启动即自动成为 sub-1 并被 main attach。LAN 场景:两台机器各自启动,等待 3-5 秒(beacon 广播间隔) 后自动发现并互相 attach。

  4. 查看并选择目标

    在任一台机器执行 /pipes 打开状态栏与选择面板,选中目标后输入 prompt 即自动路由。 详见「常用命令与参数」。

配置

特性与环境变量:

变量 作用
FEATURE_UDS_INBOX 启用本机 Pipe IPC 与 /pipes、/attach、/send 等命令
FEATURE_LAN_PIPES 启用局域网 TCP 传输与 UDP beacon 发现(依赖 UDS_INBOX)

LAN beacon 协议参数(源码常量,不可配置):

参数 值
Multicast 组 224.0.71.67
端口 7101
广播间隔 3000ms
Peer 超时 15000ms
TTL 1(不跨路由器)

存储位置:

路径 内容
~/.claude/pipes/<name>.sock 本机实例的 UDS / Named Pipe 套接字
~/.claude/pipes/registry.json 本机注册表(main + subs、machineId、角色绑定)
~/.claude/pipes/registry.lock 注册表文件锁

常用命令与参数

斜杠命令:

命令 行为
/pipes 显示所有发现的实例(本机 + LAN),并切换选择面板开合;同时让状态栏可见
/pipes select <name> 选中某实例,普通 prompt 会广播到它(别名 sel)
/pipes deselect <name> 取消选中(别名 desel / unsel)
/pipes all 选中所有已连接实例(别名 select-all)
/pipes none 取消全部选中(别名 deselect-all)
/attach <name> 手动 attach 一个实例使其成为 slave(LAN peer 会自动解析 TCP 端点)
/detach [name] 断开与某个 slave 的连接;不带参数断开全部
/send <name> <message> 向指定已连接 slave 发送一条 prompt(需处于 master 角色)
/claim-main 强制声明当前机器为 main(用于 main 意外退出后的恢复)
/pipe-status 显示当前管道角色的详细连接状态(master 模式下列出各 slave)
/peers 列出本机发现的对等节点(别名 /who)

选择面板快捷键:

快捷键 场景 作用
Shift+↓ 状态栏可见时 展开 / 收起选择面板
↑ / ↓ 面板展开时 上下移动光标
Space 面板展开时 切换当前光标所在实例的选中状态
Enter / Esc 面板展开时 确认 / 取消并关闭面板
← / → 有选中实例时(面板收起也可用) 切换路由模式
M 面板展开时 切换路由模式(同 ← / →)

两种路由模式(切换不会清空选择):

模式 状态栏 行为
selected pipes only 绿色高亮 普通 prompt 仅发送到选中的实例,本地不执行
local main 灰色 普通 prompt 仅在本地执行,不转发
i
斜杠命令不会被路由

路由只作用于普通输入。/ 开头的命令始终在本地处理。AI 侧还可通过 SendMessageTool 以 tcp:host:port 地址向远端发送消息, 但该路径属于工具调用(会向用户请求确认),与人类的 /send 命令不是同一条通道。

实战示例

本机多实例:把任务甩给 sub 执行

qsdashi 会话
# 终端 1:启动,自动成为 main;终端 2:启动,自动成为 sub-1 并被 attach
/pipes
# → 状态栏出现,列出 main 与 sub-1

# 展开面板并选中 sub-1
# Shift+↓ 展开 → ↓ 移动 → Space 选中 → Enter 确认

# 直接输入普通 prompt,自动路由到 sub-1 执行
帮我检查一下 git status

# 状态栏 ←/→ 或展开后 M 切到 local main,输入只在本地执行
# 再切回 selected pipes only 继续向远端发送

LAN 跨机器:零配置发现

两台机器
# 机器 A(192.168.50.22)与机器 B(192.168.50.27)分别启动
FEATURE_UDS_INBOX=1 FEATURE_LAN_PIPES=1 bun run dev

# 等待 3-5 秒 beacon 广播后,在任一台执行
/pipes
# → LAN Peers: ☐ [main] cli-04d67950  vmwin11/192.168.50.27
#             tcp:192.168.50.27:58853  [LAN]

# 手动 attach(可选,heartbeat 通常已自动完成)
/attach cli-04d67950

# 选中后输入 prompt,远端执行结果流式回传:
# [main vmwin11/192.168.50.27 / cli-04d67950] 正在检查 git status...
# [main vmwin11/192.168.50.27 / cli-04d67950] Completed

main 角色每 5 秒跑一次 heartbeat:清理死条目、刷新发现的实例(含 LAN peer)、构建统一的 attach 目标列表并自动连接未连接者。跨机器 attach 时通过 machineId 区分 LAN peer, 不要求对方是 sub 角色。

常见问题排错

!
看不到 LAN peer

按顺序检查:

  • 防火墙是否放行 UDP 7101
  • Windows 上用 Get-NetConnectionProfile 确认网络为「专用」
  • 两台机器在同一子网,ping 能通
  • 路由器未开启 AP 隔离
!
连接超时

检查 TCP 入站防火墙规则、确认没有 VPN 劫持流量。可用 /send <name> <msg> 或 AI 的 tcp:ip:port 消息直接测试连通性。

!
beacon 绑到了错误网卡

Windows 上 WSL / Docker 虚拟网卡可能劫持 multicast。beacon 会自动选择非内部 IPv4 接口并在该接口上 addMembership;若仍选错,检查 getLocalIp() 的返回值。

!
/send 提示不在 master 模式

/send 要求当前实例处于 master 角色(已 attach 至少一个 slave)。 先执行 /attach <name>,或确认 heartbeat 已完成自动 attach(用 /pipe-status 查看)。

*
安全提醒

TCP 连接当前无认证——同 LAN 内知道端口即可连接;beacon 明文广播 IP / hostname / machineId。组播 TTL=1 不跨路由器。建议仅在信任的局域网中使用。