sequenceDiagram
participant C as Client
participant S as Herdr Server
C->>S: {"jsonrpc":"2.0","method":"server.status","id":1}
S->>C: {"jsonrpc":"2.0","result":{...},"id":1}
C->>S: {"jsonrpc":"2.0","method":"events.subscribe","id":2,"params":{"event":"agent.*"}}
S->>C: {"jsonrpc":"2.0","result":{"subscriptionId":"sub_1"},"id":2}
Note over S: Agent 状态变化
S->>C: {"jsonrpc":"2.0","method":"event","params":{"subscriptionId":"sub_1","data":{...}}}
15 第 13 章 Socket API
15.1 概述
CLI 是人类与 Herdr 交互的主要方式,但当你需要从外部程序(如 Python 脚本、Node.js 服务)控制 Herdr 时,频繁调用 CLI 会有以下问题:
- 每次调用都要启动新进程,开销大
- 输出需要文本解析,容易出错
- 无法实时接收事件通知
- 难以管理多个并发操作
Socket API 解决了这些问题。它提供了基于 Unix Socket 的 JSON-RPC 接口,让你可以直接与 Herdr Server 通信,获取完整的结构化数据和实时事件流。
读完本章,你将能够:
- 理解 Socket API 与 CLI 的关系和取舍
- 使用原始 JSON-RPC 方法控制 Herdr
- 订阅事件流并实现实时监控
- 用 Python 编写完整的 Herdr 自动化脚本
15.2 何时用 Socket API vs CLI
| 特性 | CLI | Socket API |
|---|---|---|
| 使用门槛 | 低(直接输入命令) | 中(需要写代码) |
| 性能 | 每次调用有进程启动开销 | 持久连接,无额外开销 |
| 输出格式 | 文本(可指定 JSON) | 原生 JSON-RPC |
| 事件订阅 | 不支持(需轮询) | 原生支持 |
| 并发 | 每次调用独立 | 单连接多请求 |
| 适用场景 | 日常操作、简单脚本 | 自动化系统、监控面板、IDE 集成 |
经验法则: - 用 CLI:当你在 Shell 中手动操作,或写简单的 Bash 脚本 - 用 Socket API:当你构建自动化系统、需要事件订阅、或从非 Shell 语言(Python、TypeScript)控制 Herdr
15.3 Schema 获取
Herdr 的 API Schema 是自描述的——你不需要记忆所有方法名,可以随时查询。
15.3.1 获取完整 Schema
# 人类可读格式
herdr api schema
# JSON 格式(推荐用于程序化处理)
herdr api schema --json > herdr-api-schema.json15.3.2 Schema 结构
{
"version": "1.2.3",
"methods": {
"server.status": {
"params": {},
"returns": { "running": "boolean", "version": "string" }
},
"pane.read": {
"params": { "paneId": "string", "source": "string?", "lines": "int?" },
"returns": { "content": "string" }
}
},
"events": {
"agent.stateChanged": { "fields": { "agentName": "string", "newState": "string" } }
}
}Schema 版本化:Schema 中的 version 字段对应 Herdr 版本。不同版本的可用方法可能不同。始终检查 Schema 以确认方法是否可用。
15.4 Socket 路径与传输
15.4.1 Socket 路径
Herdr Server 启动后,会在以下位置创建 Unix Socket:
$TMPDIR/herdr-<uid>/herdr.sock
或(如果 TMPDIR 未设置):
/tmp/herdr-<uid>/herdr.sock
你可以通过以下方式获取实际路径:
# 方法 1:CLI 查询
herdr api socket-path
# /var/folders/xx/herdr-501/herdr.sock
# 方法 2:环境变量
echo "$HERDR_SOCKET"
# 方法 3:status 命令
herdr status --json | jq -r '.socket_path'15.4.2 传输协议
Socket API 使用 JSON-RPC 2.0 协议:
15.4.3 手动测试连接
# 用 socat 连接并手动发送请求
echo '{"jsonrpc":"2.0","method":"server.status","id":1}' | \
socat - UNIX-CONNECT:$(herdr api socket-path)
# 用 curl(如果支持 Unix Socket)
curl --unix-socket $(herdr api socket-path) \
-X POST \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"server.status","id":1}' \
http://localhost/15.5 原始方法名参考
以下按功能区域列出所有 Socket API 方法。
15.5.1 Server / 通知 / 客户端
| 方法 | 说明 | 对应 CLI |
|---|---|---|
server.status |
获取 Server 状态 | herdr status |
server.stop |
停止 Server | herdr server stop |
server.reloadConfig |
重新加载配置 | herdr server reload-config |
notification.list |
列出通知 | herdr notification show |
client.identify |
标识客户端连接 | — |
15.5.2 Session
| 方法 | 说明 | 对应 CLI |
|---|---|---|
session.list |
列出所有会话 | herdr session list |
session.get |
获取会话详情 | herdr session attach |
session.stop |
停止会话 | herdr session stop |
session.delete |
删除会话 | herdr session delete |
15.5.3 Workspace / Worktree
| 方法 | 说明 | 对应 CLI |
|---|---|---|
workspace.create |
创建工作空间 | herdr workspace create |
workspace.list |
列出工作空间 | herdr workspace list |
workspace.get |
获取工作空间详情 | herdr workspace get |
workspace.focus |
切换工作空间 | herdr workspace focus |
workspace.rename |
重命名 | herdr workspace rename |
workspace.close |
关闭 | herdr workspace close |
worktree.create |
创建 worktree | herdr worktree create |
worktree.list |
列出 worktree | herdr worktree list |
worktree.open |
打开 worktree | herdr worktree open |
worktree.remove |
移除 worktree | herdr worktree remove |
15.5.4 Tab
| 方法 | 说明 | 对应 CLI |
|---|---|---|
tab.create |
创建 Tab | herdr tab create |
tab.list |
列出 Tab | herdr tab list |
tab.get |
获取 Tab 详情 | herdr tab get |
tab.focus |
切换 Tab | herdr tab focus |
tab.rename |
重命名 Tab | herdr tab rename |
tab.close |
关闭 Tab | herdr tab close |
15.5.5 Pane
| 方法 | 说明 | 对应 CLI |
|---|---|---|
pane.split |
分割窗格 | herdr pane split |
pane.swap |
交换窗格 | herdr pane swap |
pane.move |
移动窗格 | herdr pane move |
pane.close |
关闭窗格 | herdr pane close |
pane.read |
读取内容 | herdr pane read |
pane.sendText |
发送文本 | herdr pane send-text |
pane.sendKeys |
发送按键 | herdr pane send-keys |
pane.run |
执行命令 | herdr pane run |
pane.waitOutput |
等待输出 | herdr pane wait-output |
pane.reportAgent |
报告 Agent 状态 | herdr pane report-agent |
pane.reportAgentSession |
报告 Agent 会话 | — |
pane.releaseAgent |
释放 Agent | — |
pane.focus |
聚焦窗格 | herdr pane focus |
pane.resize |
调整大小 | herdr pane resize |
pane.zoom |
放大/恢复 | herdr pane zoom |
pane.rename |
重命名 | herdr pane rename |
pane.layout |
应用布局 | herdr pane layout |
pane.processInfo |
进程信息 | herdr pane process-info |
pane.neighbor |
查询邻居 | herdr pane neighbor |
pane.edges |
查询边界 | herdr pane edges |
15.5.6 Agent
| 方法 | 说明 | 对应 CLI |
|---|---|---|
agent.start |
启动 Agent | herdr agent start |
agent.prompt |
发送提示 | herdr agent prompt |
agent.wait |
等待状态 | herdr agent wait |
agent.read |
读取输出 | herdr agent read |
agent.get |
获取信息 | herdr agent get |
agent.list |
列出所有 Agent | herdr agent list |
agent.explain |
解释行为 | herdr agent explain |
agent.sendKeys |
发送按键 | herdr agent send-keys |
agent.rename |
重命名 | herdr agent rename |
agent.focus |
聚焦 | herdr agent focus |
15.5.7 Events
| 方法 | 说明 |
|---|---|
events.subscribe |
订阅事件 |
events.unsubscribe |
取消订阅 |
events.wait |
阻塞等待事件(长轮询) |
events.list |
列出当前订阅 |
15.5.8 Integrations / Plugins
| 方法 | 说明 | 对应 CLI |
|---|---|---|
integration.install |
安装集成 | herdr integration install |
integration.uninstall |
卸载集成 | herdr integration uninstall |
integration.status |
集成状态 | herdr integration status |
plugin.install |
安装插件 | herdr plugin install |
plugin.uninstall |
卸载插件 | herdr plugin uninstall |
plugin.list |
列出插件 | herdr plugin list |
plugin.action.list |
列出 Action | herdr plugin action.list |
plugin.action.invoke |
调用 Action | herdr plugin action.invoke |
15.6 请求/响应格式
15.6.1 标准请求
所有请求遵循 JSON-RPC 2.0 格式:
{
"jsonrpc": "2.0",
"method": "pane.read",
"params": {
"paneId": "p1",
"source": "recent",
"lines": 50
},
"id": 1
}15.6.2 标准响应
{
"jsonrpc": "2.0",
"result": {
"content": "file.rs\nfn main() { ... }",
"paneId": "p1",
"timestamp": "2026-08-01T15:52:00Z"
},
"id": 1
}15.6.3 错误响应
{
"jsonrpc": "2.0",
"error": {
"code": -32602,
"message": "Invalid params",
"data": {
"field": "paneId",
"detail": "Pane 'p99' does not exist"
}
},
"id": 1
}15.6.4 错误码参考
| 错误码 | 含义 |
|---|---|
-32700 |
解析错误(无效 JSON) |
-32600 |
无效请求 |
-32601 |
方法不存在 |
-32602 |
参数无效 |
-32603 |
内部错误 |
-32000 |
Agent 超时 |
-32001 |
Agent stalled |
-32002 |
Agent blocked |
-32003 |
资源不存在 |
15.6.5 批量请求
Socket API 支持批量请求,一次发送多个调用:
[
{"jsonrpc":"2.0","method":"agent.list","id":1},
{"jsonrpc":"2.0","method":"server.status","id":2},
{"jsonrpc":"2.0","method":"workspace.list","id":3}
]响应也以批量方式返回:
[
{"jsonrpc":"2.0","result":{"agents":[...]},"id":1},
{"jsonrpc":"2.0","result":{"running":true},"id":2},
{"jsonrpc":"2.0","result":{"workspaces":[...]},"id":3}
]批量请求的性能优势:当你需要同时获取多个独立信息时,批量请求可以显著减少往返延迟。例如,初始化监控面板时,可以用一个批量请求获取所有 Agent 的状态、工作空间列表和通知。
15.7 事件订阅机制
事件订阅是 Socket API 相对于 CLI 的最大优势。你可以实时接收 Herdr 内部发生的变化,而无需轮询。
15.7.1 events.subscribe
{
"jsonrpc": "2.0",
"method": "events.subscribe",
"params": {
"event": "agent.stateChanged",
"filter": {
"agentName": "my-helper"
}
},
"id": 1
}响应:
{
"jsonrpc": "2.0",
"result": {
"subscriptionId": "sub_a1b2c3"
},
"id": 1
}15.7.1.1 通配符订阅
// 订阅所有 Agent 相关事件
{"event": "agent.*"}
// 订阅所有事件
{"event": "*"}15.7.1.2 可订阅事件列表
| 事件 | 说明 | 字段 |
|---|---|---|
agent.stateChanged |
Agent 状态变化 | agentName, oldState, newState |
agent.started |
Agent 启动 | agentName, kind, paneId |
agent.stopped |
Agent 停止 | agentName, reason |
agent.output |
Agent 产生输出 | agentName, content |
pane.created |
窗格创建 | paneId, tabId |
pane.closed |
窗格关闭 | paneId |
pane.output |
窗格产生输出 | paneId, content |
workspace.activated |
工作空间切换 | workspaceName |
notification.created |
新通知 | type, message |
15.7.2 events.wait
events.wait 是一个便捷方法,阻塞直到匹配的事件发生(超时返回)。
{
"jsonrpc": "2.0",
"method": "events.wait",
"params": {
"event": "agent.stateChanged",
"filter": {
"agentName": "my-helper",
"newState": "done"
},
"timeout": 300
},
"id": 2
}events.wait vs events.subscribe: - subscribe:注册长期订阅,持续接收事件。适合监控面板。 - wait:一次性等待,超时即返回。适合编排脚本中的「等待某个条件满足」。
15.7.3 事件消息格式
当订阅的事件发生时,Server 会推送通知:
{
"jsonrpc": "2.0",
"method": "event",
"params": {
"subscriptionId": "sub_a1b2c3",
"event": "agent.stateChanged",
"data": {
"agentName": "my-helper",
"oldState": "working",
"newState": "idle",
"timestamp": "2026-08-01T15:52:00Z"
}
}
}15.8 Agent 状态报告
Socket API 提供了比 CLI 更细致的 Agent 状态控制。
15.8.1 pane.report-agent
主动报告窗格中 Agent 的状态:
{
"jsonrpc": "2.0",
"method": "pane.report-agent",
"params": {
"paneId": "p2",
"state": "working",
"detail": "正在分析代码..."
},
"id": 3
}15.8.2 pane.report-agent-session
报告 Agent 会话信息(更详细):
{
"jsonrpc": "2.0",
"method": "pane.report-agent-session",
"params": {
"paneId": "p2",
"sessionId": "session-abc",
"model": "claude-sonnet-4",
"tokenCount": 15234
},
"id": 4
}15.8.3 pane.release-agent
释放窗格的 Agent 关联(Agent 停止但进程可能继续):
{
"jsonrpc": "2.0",
"method": "pane.release-agent",
"params": {
"paneId": "p2",
"reason": "task completed"
},
"id": 5
}15.9 读取窗格输出
// 请求
{
"jsonrpc": "2.0",
"method": "pane.read",
"params": {
"paneId": "p1",
"source": "recent",
"lines": 100
},
"id": 6
}
// 响应
{
"jsonrpc": "2.0",
"result": {
"content": "$ npm test\n\n> my-app@1.0.0 test\n> jest\n\nPASS src/index.test.js\nTests: 3 passed",
"paneId": "p1",
"rows": 6,
"timestamp": "2026-08-01T15:52:00Z"
},
"id": 6
}15.10 等待状态变化
结合 events.wait 实现「等待 Agent 完成后读取结果」的模式:
// 步骤 1: 发送提示
{
"jsonrpc": "2.0",
"method": "agent.prompt",
"params": { "name": "my-helper", "message": "修复 bug" },
"id": 7
}
// 步骤 2: 等待完成
{
"jsonrpc": "2.0",
"method": "events.wait",
"params": {
"event": "agent.stateChanged",
"filter": { "agentName": "my-helper", "newState": "idle" },
"timeout": 600
},
"id": 8
}
// 步骤 3: 读取结果
{
"jsonrpc": "2.0",
"method": "agent.read",
"params": { "name": "my-helper", "source": "recent", "lines": 100 },
"id": 9
}15.11 布局导入导出
15.11.1 layout.export
// 请求
{
"jsonrpc": "2.0",
"method": "layout.export",
"params": {},
"id": 10
}
// 响应
{
"jsonrpc": "2.0",
"result": {
"layout": {
"type": "split",
"direction": "horizontal",
"ratio": 0.5,
"children": [
{ "type": "pane", "id": "p1" },
{
"type": "split",
"direction": "vertical",
"ratio": 0.6,
"children": [
{ "type": "pane", "id": "p2" },
{ "type": "pane", "id": "p3" }
]
}
]
}
},
"id": 10
}15.11.2 layout.apply
{
"jsonrpc": "2.0",
"method": "layout.apply",
"params": {
"layout": {
"type": "split",
"direction": "horizontal",
"ratio": 0.3,
"children": [
{ "type": "pane" },
{ "type": "pane" },
{ "type": "pane" }
]
}
},
"id": 11
}布局 JSON 的递归结构:
graph LR
Root["Split (horizontal)"] --> P1["Pane p1"]
Root --> Right["Split (vertical)"]
Right --> P2["Pane p2"]
Right --> P3["Pane p3"]
15.12 实验性功能
以下功能标记为实验性,API 可能在未来版本中变更。
15.12.1 Pane Graphics(Kitty Graphics 协议)
支持在窗格中渲染图像(基于 Kitty Terminal Graphics Protocol):
{
"jsonrpc": "2.0",
"method": "pane.renderGraphics",
"params": {
"paneId": "p1",
"image": "<base64-encoded-png>",
"format": "png",
"placement": "center"
},
"id": 12
}兼容性:Pane Graphics 依赖于终端的 Kitty Graphics 协议支持。目前支持的终端:Kitty、WezTerm、Ghostty。iTerm2 使用不同的协议,部分支持。macOS Terminal.app 不支持。
15.12.2 Terminal Session Observe / Control
允许第三方程序观察和控制终端会话:
// 开始观察
{
"jsonrpc": "2.0",
"method": "terminal.observe",
"params": { "paneId": "p1" },
"id": 13
}
// 响应中包含一个 observeId,之后所有 pane 的输出都会推送// 接管控制
{
"jsonrpc": "2.0",
"method": "terminal.control",
"params": {
"observeId": "obs_abc",
"mode": "shared"
},
"id": 14
}适用于构建远程协作工具、录制/回放系统等。
15.13 协议稳定性说明
Herdr 的 Socket API 遵循以下版本化策略:
graph TD
A[API 版本] --> B[Stable 核心]
A --> C[Stable 扩展]
A --> D[Experimental]
B -->|"保证向后兼容"| E["语义化版本控制<br/>major 变更才 break"]
C -->|"次要版本可扩展"| F["新方法可加入<br/>现有方法不变"]
D -->|"随时可能变更"| G["可能有 breaking change<br/>使用前检查 Schema"]
| 分类 | 说明 | 稳定性 |
|---|---|---|
| Stable 核心 | Server/Pane/Agent/Workspace/Tab 的基本 CRUD | ✅ 向后兼容 |
| Stable 扩展 | Events/Layout/Integration | ✅ 次要版本只新增 |
| Experimental | Graphics/Terminal observe/Plugin actions | ⚠️ 可能变更 |
生产环境建议: 1. 在程序启动时调用 api schema 检查方法是否可用 2. 对实验性方法做降级处理(graceful degradation) 3. 订阅 server.apiChanged 事件,在 API 变更时收到通知
15.14 实战示例:Python Herdr 监控脚本
以下是一个完整的 Python 脚本,展示如何通过 Socket API 实现多 Agent 监控。
#!/usr/bin/env python3
"""
Herdr 多 Agent 监控面板
通过 Socket API 实时监控所有 Agent 的状态变化。
"""
import json
import socket
import sys
import time
from dataclasses import dataclass, field
from typing import Optional
# ──────────────────────────────────────────────
# Herdr Client
# ──────────────────────────────────────────────
class HerdrClient:
"""Herdr Socket API 客户端"""
def __init__(self, socket_path: Optional[str] = None):
self.socket_path = socket_path or self._discover_socket()
self.sock: Optional[socket.socket] = None
self._id = 0
def _discover_socket(self) -> str:
"""自动发现 Socket 路径"""
import subprocess
result = subprocess.run(
["herdr", "api", "socket-path"],
capture_output=True, text=True
)
path = result.stdout.strip()
if not path:
raise RuntimeError("无法发现 Herdr Socket 路径")
return path
def connect(self):
"""连接到 Herdr Server"""
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.sock.connect(self.socket_path)
self.sock.settimeout(300) # 5 分钟超时
print(f"✅ 已连接: {self.socket_path}")
def close(self):
"""关闭连接"""
if self.sock:
self.sock.close()
self.sock = None
def call(self, method: str, **params) -> dict:
"""发送 JSON-RPC 请求"""
self._id += 1
request = {
"jsonrpc": "2.0",
"method": method,
"id": self._id
}
if params:
request["params"] = params
data = json.dumps(request) + "\n"
self.sock.sendall(data.encode())
# 读取响应
buffer = b""
while True:
chunk = self.sock.recv(4096)
if not chunk:
break
buffer += chunk
if b"\n" in buffer:
break
response = json.loads(buffer.decode().strip())
if "error" in response:
raise Exception(
f"API Error {response['error']['code']}: "
f"{response['error']['message']}"
)
return response.get("result", {})
def recv_event(self, timeout: float = 300) -> Optional[dict]:
"""接收一个事件(阻塞)"""
self.sock.settimeout(timeout)
try:
buffer = b""
while True:
chunk = self.sock.recv(4096)
if not chunk:
break
buffer += chunk
if b"\n" in buffer:
break
msg = json.loads(buffer.decode().strip())
if msg.get("method") == "event":
return msg["params"]
except socket.timeout:
return None
return None
# ──────────────────────────────────────────────
# Agent 监控器
# ──────────────────────────────────────────────
@dataclass
class AgentInfo:
name: str
kind: str
state: str
pane_id: str
last_change: float = field(default_factory=time.time)
class AgentMonitor:
"""多 Agent 状态监控器"""
def __init__(self, client: HerdrClient):
self.client = client
self.agents: dict[str, AgentInfo] = {}
def refresh(self):
"""刷新所有 Agent 状态"""
result = self.client.call("agent.list")
agents = result.get("agents", [])
self.agents.clear()
for a in agents:
info = AgentInfo(
name=a["name"],
kind=a.get("kind", "unknown"),
state=a.get("state", "unknown"),
pane_id=a.get("paneId", "?")
)
self.agents[info.name] = info
self._render()
def subscribe(self):
"""订阅 Agent 状态变化事件"""
self.client.call("events.subscribe", event="agent.*")
print("📡 已订阅 Agent 事件\n")
def listen(self):
"""监听事件并更新状态"""
while True:
event = self.client.recv_event(timeout=600)
if event is None:
continue
event_type = event.get("event")
data = event.get("data", {})
name = data.get("agentName", "?")
if event_type == "agent.stateChanged":
old = data.get("oldState", "?")
new = data.get("newState", "?")
if name in self.agents:
self.agents[name].state = new
self.agents[name].last_change = time.time()
print(f"🔄 [{name}] {old} → {new}")
elif event_type == "agent.started":
kind = data.get("kind", "?")
pane = data.get("paneId", "?")
self.agents[name] = AgentInfo(
name=name, kind=kind, state="idle", pane_id=pane
)
print(f"🚀 [{name}] 启动 (kind={kind}, pane={pane})")
elif event_type == "agent.stopped":
reason = data.get("reason", "?")
self.agents.pop(name, None)
print(f"🛑 [{name}] 停止 (reason={reason})")
self._render()
def _render(self):
"""渲染状态表格"""
print("\n" + "=" * 60)
print(f"{'Agent':<20} {'Kind':<10} {'State':<12} {'Pane':<6}")
print("-" * 60)
state_emoji = {
"idle": "🟢",
"working": "🔵",
"blocked": "🟡",
"done": "✅",
"error": "🔴"
}
for name, info in sorted(self.agents.items()):
emoji = state_emoji.get(info.state, "⚪")
print(
f"{name:<20} {info.kind:<10} "
f"{emoji} {info.state:<8} {info.pane_id:<6}"
)
print("=" * 60 + "\n")
# ──────────────────────────────────────────────
# 主程序
# ──────────────────────────────────────────────
def main():
# 连接 Herdr
client = HerdrClient()
client.connect()
monitor = AgentMonitor(client)
# 初始刷新
monitor.refresh()
# 订阅事件
monitor.subscribe()
# 持续监听
print("🎧 监听中... (Ctrl+C 退出)\n")
try:
monitor.listen()
except KeyboardInterrupt:
print("\n👋 退出监控")
finally:
client.close()
if __name__ == "__main__":
main()15.14.1 运行效果
$ python3 monitor.py
✅ 已连接: /var/folders/xx/herdr-501/herdr.sock
============================================================
Agent Kind State Pane
------------------------------------------------------------
code-reviewer claude 🟢 idle p2
fixer codex 🔵 working p3
orchestrator claude 🟡 blocked p1
============================================================
📡 已订阅 Agent 事件
🎧 监听中... (Ctrl+C 退出)
🔄 [fixer] working → done
🔄 [fixer] done → idle
🛑 [orchestrator] 停止 (reason=timeout)
🚀 [test-runner] 启动 (kind=claude, pane=p4)
============================================================
Agent Kind State Pane
------------------------------------------------------------
code-reviewer claude 🟢 idle p2
fixer codex 🟢 idle p3
test-runner claude 🟢 idle p4
============================================================15.14.2 扩展:自动分配任务
基于监控框架,你可以进一步实现自动任务分配:
def auto_dispatch(client: HerdrClient, monitor: AgentMonitor):
"""当有 idle Agent 时,自动从任务队列分配任务"""
task_queue = ["写单元测试", "更新文档", "修复 lint 错误"]
for name, info in monitor.agents.items():
if info.state == "idle" and task_queue:
task = task_queue.pop(0)
print(f"📤 分配任务给 [{name}]: {task}")
client.call(
"agent.prompt",
name=name,
message=task
)
# 异步等待完成
client.call(
"events.wait",
event="agent.stateChanged",
filter={"agentName": name, "newState": "idle"},
timeout=600
)
# 读取结果
result = client.call(
"agent.read",
name=name,
source="recent",
lines=50
)
print(f"✅ [{name}] 完成: {result.get('content', '')[:200]}")进阶方向: 1. Web 仪表盘:用 Flask/FastAPI 包装 Socket API,提供浏览器可访问的监控面板 2. Slack/飞书通知:Agent 完成任务后自动发送消息通知 3. 自动扩缩容:根据任务队列长度自动启动/停止 Agent 4. 日志聚合:收集所有 Agent 的输出,统一搜索和分析
15.15 小结
本章深入探讨了 Herdr 的 Socket API——从底层协议到实战应用。
| 特性 | CLI | Socket API |
|---|---|---|
| 日常操作 | ✅ 首选 | 过重 |
| 自动化脚本 | ✅ 简单可用 | ✅ 更强大 |
| 实时监控 | ❌ 需轮询 | ✅ 事件驱动 |
| IDE 集成 | ⚠️ 可用 | ✅ 推荐 |
| 批量操作 | ⚠️ 多次调用 | ✅ 批量请求 |
下一章我们将进入进阶篇,讨论 Herdr 的深度配置、性能调优和高级部署模式。