在前面十五章,我们的 Agent 已经拥有了循环、工具、计划、子代理、技能、压缩、权限、Hook、记忆、提示词流水线、错误恢复、任务系统、后台任务、定时调度、多 Agent 团队十五大核心能力,能独立执行复杂任务,也能创建长期队友、通过邮箱互相发消息。
但如果团队所有协作都只靠自由文本,很快就会出现混乱:
- 高风险计划需要明确审批,不能只靠一句模糊回复
- 多个请求同时存在时,系统无法知道 “这条回复对应哪一件事”
- 队友优雅关机、任务交接这类关键流程,没有统一的标准处理方式
这一章 S16,我们给团队加上结构化协议层:定义请求 - 响应模式,用 request_id 追踪状态,让团队协作从 “自由聊天” 升级为 “按规矩办事”。
本章核心信息
- 核心闭环:发起协议请求 → 写入请求记录 → 投递消息到对方邮箱 → 接收响应更新状态 → 执行后续动作
- 工具数量:12 个
- 核心思想:有了邮箱以后,团队已经能说话;有了协议以后,团队才开始会 “按规矩协作”
先看懂本章所有名词
协议
双方提前约定好 “消息长什么样、收到以后怎么处理” 的规则,让协作流程可预期、可调试、可扩展。request_id
请求的唯一编号,每个协议请求都有一个独立的 ID,后续的批准、拒绝、超时都能准确指向这一个请求。请求 - 响应模式
发起方发送带 ID 的请求,接收方给出明确的同意 / 拒绝响应,双方通过同一个 request_id 对应,流程闭环清晰。协议消息
带 type、request_id、payload 字段的结构化消息,专门用于审批、关机、交接、签收这类关键流程。请求追踪表(RequestRecord)
记录协议请求的类型、发送方、接收方、当前状态(pending/approved/rejected/expired),让系统知道 “这件事现在走到哪一步”。状态机
协议请求的状态流转规则,例如:pending → approved、pending → rejected、pending → expired,保证流程可预测。
这一章到底要解决什么问题?
到 S15,队友之间已经可以通过邮箱互相发消息,但存在两个明显问题:
- 关键动作无法明确审批:队友关机、高风险计划这类操作,不能只靠模糊的自然语言回复
- 多请求无法追踪:当多个请求同时存在时,系统无法将回复和请求一一对应,很容易混乱
本章要解决的核心问题:把 “口头表达” 升级成 “结构化数据”,让团队协作有统一的请求 - 响应规则,流程可追踪、可审批、可调试。
最小心智模型:两层结构看懂团队协议
团队协议的核心,是 “协议消息 + 请求追踪表” 两层结构:
1. 协议消息(ProtocolEnvelope) { "type": "shutdown_request", "from": "lead", "to": "alice", "request_id": "req_001", "payload": {}, "timestamp": 1710000000.0, } 2. 请求追踪表(RequestRecord) requests = { "req_001": { "kind": "shutdown", "from": "lead", "to": "alice", "status": "pending", } }只要这两层都存在,系统就能同时回答:
- 现在发生了什么?(看协议消息的 type 和 payload)
- 这件事目前走到哪一步?(看请求追踪表的 status)
一句话:普通消息解决 “说了什么”,协议消息解决 “这件事走到哪一步了”。
最推荐的 2 类基础协议(先做这两个就够)
优雅关机协议解决队友有序退出的问题:先发起关机请求,对方明确回复同意 / 拒绝,同意后先收尾再退出,避免强制终止导致任务中断。
计划审批协议解决高风险操作的审批问题:队友提交计划请求,领导明确批准 / 拒绝,带 request_id 追踪,保证流程透明可追溯。
关键数据结构(本章灵魂)
1. ProtocolEnvelope(协议消息信封)
message = { "type": "shutdown_request", "from": "lead", "to": "alice", "request_id": "req_001", "payload": {}, "timestamp": 1710000000.0, }比普通消息多出的关键字段:
type:协议类型(如 shutdown_request、plan_approval)request_id:请求唯一编号payload:请求携带的结构化数据
2. RequestRecord(请求追踪记录)
request = { "request_id": "req_001", "kind": "shutdown", "from": "lead", "to": "alice", "status": "pending", }负责记录:
- 这是哪种请求(kind)
- 谁发给谁(from/to)
- 当前状态是什么(status)
教学版建议直接落盘存储在.team/requests/目录下,每条请求一个 JSON 文件,保证请求状态可恢复、协议过程可检查。
3. 状态机流转
pending(待处理) → approved(已批准) pending(待处理) → rejected(已拒绝) pending(待处理) → expired(已超时)状态机不是复杂理论,只是 “状态之间如何变化的规则表”,让协议流程可预测。
最小实现代码(极简可运行)
第一步:优雅关机协议实现
def request_shutdown(target: str): # 生成唯一request_id request_id = new_id() # 写入请求追踪表 requests[request_id] = { "kind": "shutdown", "target": target, "status": "pending", } # 发送协议消息到对方邮箱 bus.send( "lead", target, msg_type="shutdown_request", extra={"request_id": request_id}, content="Please shut down gracefully.", ) def handle_shutdown_response(request_id: str, approve: bool): # 根据request_id更新请求状态 record = requests[request_id] record["status"] = "approved" if approve else "rejected" # 如果批准,执行收尾退出逻辑 if record["status"] == "approved": graceful_exit(target)第二步:计划审批协议实现
def submit_plan(name: str, plan_text: str): request_id = new_id() requests[request_id] = { "kind": "plan_approval", "from": name, "status": "pending", "plan": plan_text, } bus.send( name, "lead", msg_type="plan_approval", extra={"request_id": request_id, "plan": plan_text}, content="Requesting review.", ) def review_plan(request_id: str, approve: bool, feedback: str = ""): record = requests[request_id] record["status"] = "approved" if approve else "rejected" # 发送响应给提交方 bus.send( "lead", record["from"], msg_type="plan_approval_response", extra={"request_id": request_id, "approve": approve}, content=feedback, )协议请求的完整流转链路
某个队友 / lead 发起请求 │ ▼ 写入RequestRecord(请求追踪表) │ ▼ 把ProtocolEnvelope投递进对方inbox │ ▼ 对方下一轮drain inbox(排空收件箱) │ ▼ 按request_id更新请求状态(approved/rejected) │ ▼ 必要时再回一条response消息 │ ▼ 请求方根据状态执行后续动作(执行/放弃)你可以把它理解成:S15 给了团队 “邮箱”,S16 给邮箱里的关键消息加上了 “编号 + 状态机 + 回执”。
核心对象边界区分(容易混淆的 4 个对象)
| 对象 | 它回答什么问题 | 典型字段 |
|---|---|---|
| MessageEnvelope | 谁跟谁说了什么 | from / to / content |
| ProtocolEnvelope | 这是不是一条结构化请求或响应 | type / request_id / payload |
| RequestRecord | 这件协作流程现在走到哪一步 | kind / status / from / to |
| TaskRecord | 真正的工作项是什么、谁在做、还卡着谁 | subject / status / blockedBy / owner |
关键提醒:
- 协议请求不是任务本身
- 请求状态表也不是任务板
- 协议只负责 “协作流程”,任务系统才负责 “真正的工作推进”
初学者最容易犯的 4 个坑
没有 request_id没有编号,多个请求同时存在时很快就会混乱,回复和请求无法一一对应。
收到请求后只回自然语言例如 “好的,我知道了”,人类能看懂,但系统无法稳定处理,无法更新请求状态。
没有请求状态表不记录 pending/approved/rejected 状态,协议就没有真正落地,流程无法追踪。
把协议消息和普通消息混成一种结构这样后面一多,处理逻辑会越来越混,关键流程和普通聊天无法区分。
S15 → S16 升级了什么?
| 模块 | S15 | S16 |
|---|---|---|
| 协作方式 | 自由文本聊天 | 结构化请求 - 响应 |
| 关键流程 | 无标准处理方式 | 有统一的审批、关机等协议模板 |
| 请求追踪 | 无法对应回复和请求 | 用 request_id 追踪请求全流程 |
| 状态管理 | 无协作状态记录 | 请求追踪表记录状态流转 |
| 架构地位 | 多 Agent 团队底座 | 团队协作规则层 |
本章教学边界
教学版先只讲 2 类协议就够了:
- shutdown(优雅关机)
- plan_approval(计划审批)
等这套模板学稳以后,可以再扩展:
- 任务认领协议
- 交接协议
- 结果签收协议
本章先不展开这些扩展,只牢牢守住一条主线:团队协议的核心,是 “请求 - 响应 + request_id + 状态表”,让关键协作流程结构化、可追踪、可审批。
一句话总结本章
有了邮箱,团队已经能说话;有了协议,团队才开始会 “按规矩协作”。它给团队加上了结构化的请求 - 响应规则,让关键流程可追踪、可审批、可调试,为后续更复杂的自治协作打下基础。