这一节只讲相对 S16 新增的内容:
队友 Agent 不再只等 Lead 指令,而是进入 IDLE 状态后可以自己轮询任务板并自动认领任务。
scan_unclaimed_tasks():扫描可认领任务。idle_poll():队友空闲时轮询收件箱和任务板。WORK -> IDLE -> WORK / SHUTDOWN。list_tasks、claim_task、complete_task。consume_lead_inbox():Lead 统一处理协议响应和普通消息。队友 Agent 不再是“跑 10 轮就结束”。
它变成:
WORK
↓ 没有 tool_use / 当前任务结束
IDLE
↓ 有收件箱消息
WORK
↓ 有可认领任务
WORK
↓ 收到 shutdown 或超时
SHUTDOWN
scan_unclaimed_tasks()作用:从 .tasks/ 里找可以自动认领的任务。
筛选条件:
status == "pending"
owner 为空
can_start(task["id"]) 为 True
返回结构:
list[dict]
例如:
[
{
"id": "task_001",
"subject": "补充测试",
"status": "pending",
"owner": None,
"blockedBy": []
}
]
idle_poll(name, messages, role)作用:队友空闲时做轮询。
每隔几秒检查:
1. 收件箱有没有消息
2. 有没有 shutdown_request
3. 任务板上有没有可认领任务
返回值是:
"work" # 有新消息或认领到任务,回到工作状态
"shutdown" # 收到关闭请求
"timeout" # 空闲太久,结束
S17 中,队友也能操作任务板:
list_tasks
claim_task
complete_task
这意味着 Lead 不一定要明确分配任务。
队友可以:
查看任务板
认领未分配任务
完成后标记 completed
代码里有一段:
if len(messages) <= 3:
messages.insert(0, {
"role": "user",
"content": "<identity>你是 ...</identity>"
})
它的作用是:当上下文很短或被压缩后,重新提醒队友自己的身份和角色。
对于长期运行 Agent,这很重要。
consume_lead_inbox() 会:
读取 lead 的收件箱
如果是协议响应,就调用 match_response()
返回所有消息,供 Agent 注入上下文
这样 Lead 不会漏掉队友的计划审批、关闭确认、普通结果消息。
Autonomous Agent 的关键不是“模型自己活了”,而是 Harness 加了生命周期:
WORK:执行当前任务
IDLE:轮询消息和任务板
AUTO-CLAIM:发现任务后自动认领
SHUTDOWN:收到协议或超时后退出
所谓自主性,本质上是:
循环 + 状态机 + 任务板 + 收件箱 + 工具权限