
作者:逆境不可逃
技术永无止境
希望我的内容可以帮助到你!!!!!
大家吼 ! 我是 逆境不可逃 今天给大家带来文章《【与我学 ClaudeCode】协作篇 之 Team Protocols :结构化请求 - 响应协作协议》.
Learn-Claude-Code 官方地址 : shareAI-lab/learn-claude-code: Bash is all you need - A nano claude code--like 「agent harness」, built from 0 to 1
上一篇文章:
Team Protocols 是迭代的第 10 个版本(s10),核心解决 多 Agent 团队协作中无结构化通信的混乱问题 。它在 s09 文件邮箱的基础上,构建了基于 request_id 关联的请求 - 响应协议框架,实现了优雅关机和计划审批两种关键协作流程,让队友之间的沟通有了统一的 "规矩"。
一、问题根源:为什么无结构化通信撑不起团队协作?
s09 中队友能干活、能通信,但缺少结构化协调,导致两个关键场景存在风险:
- 关机混乱 :直接杀线程会留下写了一半的文件和过期的
config.json,队友无法优雅收尾,数据完整性无法保证 - 计划失控:队友收到指令后立刻开干,高风险变更(如重构核心模块)没有审批流程,容易导致不可逆的错误
这两个场景本质上都是「请求 - 响应」模式:一方发起请求,另一方处理并返回结果。没有统一的协议框架,通信就像 "无信号的对讲机",容易出现请求丢失、响应错配、状态不一致等问题。
二、三大核心设计决策
Team Protocols 通过三个关键设计,构建了一个简单、可靠、可扩展的多 Agent 通信协议体系。
1. JSONL 收件箱文件而非共享内存
核心设计:每个队友都有自己的收件箱文件(团队目录中的 JSONL 文件)。发送消息意味着向接收者的收件箱文件追加一行 JSON;读取消息意味着读取收件箱文件并追踪上次读到的行。JSONL 天然是仅追加的,这意味着并发写入不会破坏彼此的数据(追加到不同的文件位置)。它在无需共享内存、互斥锁或 IPC 机制的情况下跨进程工作,也是崩溃安全的:如果写入者在追加中途崩溃,最坏情况是一行不完整的数据,读取者可以跳过。
替代方案的致命缺陷:
共享内存(如 Python multiprocessing.Queue)速度更快,但无法在独立启动的进程中工作;消息代理(Redis、RabbitMQ)提供健壮的发布 / 订阅功能,但会增加基础设施依赖;Unix 域套接字可以工作,但难以调试(没有人类可读的消息日志)。JSONL 文件是最简单的提供持久化、跨进程通信和可调试性的方法。
2. 恰好五种消息类型覆盖所有协调模式
核心设计:消息系统支持五种类型,映射到基本协调模式:
message:两个 Agent 间的点对点通信broadcast:全团队公告shutdown_request:优雅终止请求shutdown_response:终止确认响应plan_approval_response:组长审批或拒绝队友的计划
这五种类型覆盖了直接通信、广播、生命周期管理和审批流程,每种类型都有清晰明确的用途。
替代方案的致命缺陷:
单个通用消息类型(带元数据字段)会更灵活,但难以强制协议正确性;更多类型(10+)会提供更细粒度的语义,但会增加模型的决策负担。五种类型是兼顾灵活性和清晰度的平衡点。
3. 每次 LLM 调用前检查收件箱
核心设计:队友在每次 Agent 循环迭代的顶部、调用 LLM API 之前检查收件箱文件。这确保了对传入消息的最大响应性:一个终止请求会在一个循环迭代内被看到(通常几秒钟),而非在当前任务完成后(可能数分钟)。收件箱检查成本很低(读取小文件,检查是否有新行),相比 LLM 调用(秒级延迟、数千 token)微不足道。这个位置还意味着传入消息可以影响下一次 LLM 调用 ------ 一条 "停止 X,转去做 Y" 的消息会立即生效。
替代方案的致命缺陷:
在每次工具执行后检查收件箱响应性更好,但会给每个工具调用增加开销;单独的观察器线程可以持续监控收件箱,但会增加线程复杂度。每次 LLM 调用前检查是务实的平衡点:足够响应性以满足协调需求,又足够便宜不影响性能。
三、系统整体架构与工作原理
1. 核心协议框架:请求 - 响应模式
两种关键协议共享相同的 request_id 关联模式:
Shutdown Protocol Plan Approval Protocol
================== ======================
Lead Teammate Teammate Lead
| | | |
|--shutdown_req-->| |--plan_req------>|
| {req_id:"abc"} | | {req_id:"xyz"} |
| | | |
|<--shutdown_resp-| |<--plan_resp-----|
| {req_id:"abc", | | {req_id:"xyz", |
| approve:true} | | approve:true} |
- 发起方生成唯一
request_id,发送请求消息 - 接收方处理请求,返回带相同
request_id的响应消息 - 发起方通过
request_id关联请求和响应,更新状态机
2. 共享状态机(FSM)
两种协议使用相同的状态机:
[pending] --approve--> [approved]
[pending] --reject---> [rejected]
pending:请求已发送,等待响应approved:请求被同意,执行对应操作(如关机、执行计划)rejected:请求被拒绝,放弃对应操作
3. 关键组件与实现细节
(1) 请求跟踪器:关联请求与响应
# 全局请求跟踪器,线程安全
shutdown_requests = {}
plan_requests = {}
_tracker_lock = threading.Lock()
shutdown_requests:存储关机请求,键为request_id,值包含目标队友和状态plan_requests:存储计划审批请求,键为request_id,值包含发起队友、计划内容和状态
(2) 优雅关机协议实现
组长发起关机请求:
def handle_shutdown_request(teammate: str) -> str:
req_id = str(uuid.uuid4())[:8]
with _tracker_lock:
shutdown_requests[req_id] = {"target": teammate, "status": "pending"}
# 发送 shutdown_request 消息给队友
BUS.send(
"lead", teammate, "Please shut down gracefully.",
"shutdown_request", {"request_id": req_id},
)
return f"Shutdown request {req_id} sent to '{teammate}' (status: pending)"
队友处理关机请求并响应:
# 队友的 shutdown_response 工具处理
if tool_name == "shutdown_response":
req_id = args["request_id"]
approve = args["approve"]
# 更新请求状态
with _tracker_lock:
if req_id in shutdown_requests:
shutdown_requests[req_id]["status"] = "approved" if approve else "rejected"
# 发送 shutdown_response 消息给组长
BUS.send(
sender, "lead", args.get("reason", ""),
"shutdown_response", {"request_id": req_id, "approve": approve},
)
return f"Shutdown {'approved' if approve else 'rejected'}"
队友根据响应决定是否退出:
def _teammate_loop(self, name: str, role: str, prompt: str):
# ...
should_exit = False
for _ in range(50):
# ... 处理收件箱和工具调用 ...
if block.name == "shutdown_response" and block.input.get("approve"):
should_exit = True
# 循环结束后更新状态
member = self._find_member(name)
if member:
member["status"] = "shutdown" if should_exit else "idle"
self._save_config()
(3) 计划审批协议实现
队友提交计划审批请求:
# 队友的 plan_approval 工具处理
if tool_name == "plan_approval":
plan_text = args.get("plan", "")
req_id = str(uuid.uuid4())[:8]
with _tracker_lock:
plan_requests[req_id] = {"from": sender, "plan": plan_text, "status": "pending"}
# 发送 plan_approval_response 消息给组长
BUS.send(
sender, "lead", plan_text, "plan_approval_response",
{"request_id": req_id, "plan": plan_text},
)
return f"Plan submitted (request_id={req_id}). Waiting for lead approval."
组长审批计划:
def handle_plan_review(request_id: str, approve: bool, feedback: str = "") -> str:
with _tracker_lock:
req = plan_requests.get(request_id)
if not req:
return f"Error: Unknown plan request_id '{request_id}'"
# 更新请求状态
with _tracker_lock:
req["status"] = "approved" if approve else "rejected"
# 发送 plan_approval_response 消息给队友
BUS.send(
"lead", req["from"], feedback, "plan_approval_response",
{"request_id": request_id, "approve": approve, "feedback": feedback},
)
return f"Plan {req['status']} for '{req['from']}'"
(4) 队友工具集扩展
def _teammate_tools(self) -> list:
return [
# 基础工具(bash、read_file等)
{"name": "bash", ...},
{"name": "read_file", ...},
{"name": "write_file", ...},
{"name": "edit_file", ...},
# 通信工具
{"name": "send_message", ...},
{"name": "read_inbox", ...},
# 新增协议工具
{"name": "shutdown_response",
"description": "Respond to a shutdown request. Approve to shut down, reject to keep working.",
"input_schema": {"type": "object", "properties": {"request_id": {"type": "string"}, "approve": {"type": "boolean"}, "reason": {"type": "string"}}, "required": ["request_id", "approve"]}},
{"name": "plan_approval",
"description": "Submit a plan for lead approval. Provide plan text.",
"input_schema": {"type": "object", "properties": {"plan": {"type": "string"}}, "required": ["plan"]}},
]
(5) 执行流程

四、与 Agent Teams(s09)的关键变更对比
| 组件 | 之前(s09 Agent Teams) | 之后(s10 Team Protocols) |
|---|---|---|
| 工具集 | 9 个工具 | 12 个工具(新增 shutdown_request/response、plan_approval) |
| 关机机制 | 仅自然退出或强制杀线程 | 请求 - 响应握手,优雅关机 |
| 计划审批 | 无 | 提交 / 审查与审批流程 |
| 消息关联 | 无(纯文本消息) | 每个请求一个 request_id,关联请求与响应 |
| 状态机 | 无 | pending -> approved/rejected 共享 FSM |
| 通信模式 | 纯文本点对点 / 广播 | 结构化请求 - 响应协议 |
五、核心优势与创新点
- 结构化通信,避免混乱 :基于
request_id的关联模式,确保请求和响应一一对应,解决了无结构化通信的错配问题 - 优雅关机,数据安全:关机请求需要队友确认,队友可以在退出前完成收尾工作(如关闭文件、保存状态),避免数据损坏
- 计划审批,风险可控:高风险变更需要组长审批,防止队友擅自执行不可逆操作,提升团队协作的安全性
- 统一协议框架,可扩展:同一个请求 - 响应模式可以套用到更多协作场景(如资源申请、任务移交),为后续扩展打下基础
- 低侵入式实现,兼容旧系统:基于 JSONL 文件邮箱实现,无需修改 s09 的通信基础,仅新增消息类型和工具即可实现协议
六、运行示例
场景 1:优雅关机流程
- 组长判断任务完成,调用
shutdown_request(teammate="coder"),生成request_id="abc123" - 队友
coder收到shutdown_request消息,决定是否批准关机(如任务已完成则批准,如正在处理关键文件则拒绝) - 队友调用
shutdown_response(request_id="abc123", approve=True),发送响应消息 - 组长收到响应,更新
shutdown_requests["abc123"]状态为approved - 队友在循环结束后,将状态更新为
shutdown,线程安全退出
场景 2:计划审批流程
- 队友
coder需要重构认证模块,调用plan_approval(plan="重构认证模块,步骤1: 修改auth.py,步骤2: 更新测试用例"),生成request_id="xyz789" - 组长收到
plan_approval_response消息,审查计划是否合理、是否符合项目规范 - 组长调用
plan_approval(request_id="xyz789", approve=True, feedback="计划合理,按步骤执行即可"),发送审批响应 - 队友收到批准消息,开始执行重构计划
七、可扩展方向
- 更多协议类型:扩展协议框架,实现任务移交、资源申请、错误报告等请求 - 响应流程
- 协议超时与重试:为请求添加超时机制,未收到响应时自动重试或标记为失败
- 协议日志与审计:将所有协议消息单独归档,便于事后审计和问题排查
- 协议权限控制:为不同角色的 Agent 分配不同的协议权限(如普通队友不能发起关机请求)
- 协议自动生成:基于配置文件自动生成协议工具和状态机,降低新增协议的开发成本
