代理协作协议 (Agent Collaboration Protocol)
使用共享文件夹作为可移植的协调总线,适用于无法直接相互发送消息的代理。ACP 是一种严格的协议:它是一个带有结构化事件和就绪门控的状态机,而不是松散的 Markdown 对话。
任何兼容的代理必须能够读取 Markdown 和 JSON、写入 Markdown、追加 JSONL 事件,并且能够运行或精确复现捆绑脚本的行为。不要依赖 Codex 线程 API、Claude 特定钩子、仅 OpenCode 的状态、仅 Kiro 的元数据或隐藏的对话记忆来保证正确性。
必需输入
开始之前,需要以下输入:
collaboration_folder:绝对路径或相对于仓库的共享文件夹路径。objective:协作必须决定或产出的目标。completion_gates:结束协作的具体门控条件。participants:所有参与者的 ID,例如server、reader、reviewer或agent-a。participant_id:当前代理的身份标识。
如果任何必需输入缺失,在创建文件或写入事件之前先询问。不要自行发明完成门控条件。
文件
ACP 文件夹使用以下文件:
protocol.json:目标、参与者、完成门控条件、当前阶段、提案所有者、等待中的参与者以及时间戳。events.jsonl:仅追加的事件日志。每行是一个紧凑的 JSON 对象。proposal.md:仅包含当前提案。review.md:结构化的参与者评审。decisions.md:仅包含已接受的决策。readiness.md:开放问题分类、阻塞项、延期的非阻塞项以及实施就绪状态。conclusion.md:最终讨论结论。它说明是否继续、不继续、延期或阻塞;原因;如何实施或为什么不能实施;以及下一步行动。
不要创建或使用 state.log、discussion.md 或 opinions.md。它们不是协议文件,不得出现在完成门控条件或指令中。
初始化
优先使用捆绑脚本:
python3 <skill>/scripts/init_collaboration.py \
--folder <collaboration_folder> \
--participant <participant_id> \
--participant <other_participant_id> \
--objective "<objective>" \
--completion "<completion gate>" \
--completion "<another gate>"
如果 protocol.json 已存在,除非提供 --resume,否则初始化会失败。重复初始化不是追加操作。
事件
使用 scripts/append_event.py 或精确复现其行为。不要手写事件,除非运行时无法执行脚本。
必需的事件字段:
seq:events.jsonl中连续的整数。from:在protocol.json中列出的参与者 ID。event:允许的事件名称。at:ISO-8601 格式的 UTC 时间戳。summary:一句简短的描述。
推荐字段:
doc:相对于协作文件夹的路径。reply_to:较早事件的seq。
允许的事件:
initializedproposal_submittedreview_submittedproposal_revisedquestion_classifieddecision_proposeddecision_acceptedreadiness_passedcompletedblocked
所有响应必须在使用 reply_to 时指向先前的现有事件。事件时间戳不得随着 seq 增加而倒退。如果发现错误,追加 blocked 或一个新的纠正事件;不要重写较早的事件。
阶段
代理必须根据 protocol.json.currentPhase 和 protocol.json.waitingFor 行动:
drafting:提案所有者更新proposal.md,然后追加proposal_submitted。reviewing:仅waitingFor中列出的参与者向review.md追加结构化评审,然后追加review_submitted。revising:提案所有者处理要求的更改并追加proposal_revised。decision_review:提案所有者首先对readiness.md中的每个开放问题进行分类,并追加question_classified;然后只有waitingFor中列出的参与者通过追加decision_accepted来接受decisions.md中的明确决策。readiness_check:参与者对所有问题进行分类、清除阻塞项并通过就绪检查,然后提案所有者编写conclusion.md。completed:停止,除非用户明确启动新的一轮。blocked:停止,直到阻塞项被解决。
completed 仅在先前有 readiness_passed 事件后才有效。completed 必须引用 conclusion.md。不要仅凭 decisions.md 就完成;决策是输入,而 conclusion.md 才是协作目标的最终答案。
提案所有者在 proposal_submitted 后必须等待。当阶段为 reviewing 时,所有者可以轮询下一步行动或为真实的超时/阻塞项追加 blocked,但不得编辑 proposal.md、decisions.md、readiness.md 或 protocol.json,并且在所需评审提交之前不得追加推进事件。
评审格式
每个 review_submitted 事件必须有一个匹配的 review.md 标题,其 seq 等于该事件的 seq:
## <ISO-8601 UTC> - <participant_id> - seq <review_submitted event seq>
Context:
- Read `proposal.md` after event seq `<seq>`.
Position:
- ...
Concerns:
- ...
Required Changes:
- ...
Questions:
- ...
不要在评审标题中使用被回复事件的 seq。将回复上下文放在 Context 和 reply_to 中。
就绪门控
在 readiness_passed 或 completed 之前:
- 每个开放问题必须被分类为
[resolved]、[deferred_nonblocking]或[blocking]。 - 每个
[deferred_nonblocking]项必须包含Reason: ...。 - 不得留有
[blocking]或[unresolved]项。 - 最终设计检查清单必须包含并勾选 "Ready to implement"。
validate_collaboration.py必须通过。
阻塞的就绪项也阻止 decision_accepted。未解决的问题和缺少 Reason: ... 的延期项也阻止 decision_accepted。
最终设计文档必须分离:
- 已接受的决策 (Accepted Decisions)
- 假设 (Assumptions)
- 延期的后续事项 (Deferred Follow-ups)
- 实施阻塞项 (Implementation Blockers)
- 准备好实施 (Ready to Implement)
最终结论
在 completed 之前,编写 conclusion.md 作为结论文档,而非日志。它必须包含:
- 决策结果 (Decision Outcome):恰好是
[proceed]、[do_not_proceed]或[defer]中的一个。 - 理由 (Rationale)。
- 已接受的决策 (Accepted Decisions)。
- 实施方法 (Implementation Approach)。
- 假设 (Assumptions)。
- 延期的后续事项 (Deferred Follow-ups)。
- 实施阻塞项 (Implementation Blockers)。
- 下一步行动 (Next Action)。
当实施应立即开始时使用 [proceed];当特性或计划不应被实施时使用 [do_not_proceed];当在实施之前必须进行后续工作时使用 [defer]。协作被阻塞时可能存在 [blocked] 结果,但它不可完成。
轮询与监视器
参与者必须在协作循环中保持活跃,直到阶段变为 completed、blocked 或达到明确的用户/协调者截止时间。不要仅仅因为你追加了一个有效事件就停止。每次行动后,再次读取 protocol.json,然后执行下一个允许的行动,或者等待下一个事件。
如果运行时具有监视器,它可以在 events.jsonl 或 protocol.json 发生变化时通知参与者。监视器必须保持被动:它只检测变化,从不编写分析或决策。
如果不存在监视器,请使用:
python3 <skill>/scripts/next_action.py \
--folder <collaboration_folder> \
--participant <participant_id>
对于自主参与者,优先使用阻塞辅助工具:
python3 <skill>/scripts/wait_for_turn.py \
--folder <collaboration_folder> \
--participant <participant_id>
wait_for_turn.py 在以下情况下返回:参与者出现在 waitingFor 中,或者协作变成 completed 或 blocked。默认超时为 30 分钟,以避免参与者进程永久卡住;仅当外部监督者拥有取消权时才使用 --timeout 0。返回后,检查 next_action.py,如果轮到你就行动,追加所需事件,并重复等待/行动循环。例如 "检查新意见" 之类的手动用户提示仅是备用方案,而非预期的协作循环。
启动参与者的协调者提示应要求每个参与者运行此循环,而不是只做一个阶段就退出。未在 waitingFor 中列出的参与者可以在 wait_for_turn.py 中阻塞,但在等待期间不得编辑共享状态。
验证
运行:
python3 <skill>/scripts/validate_collaboration.py --folder <collaboration_folder>
验证器检查必需文件、无过时文件、事件形状、seq 连续性、时间戳单调性、阶段转换、waitingFor 所有权、reply_to、评审标题 seq、就绪分类、结论完整性以及完成顺序。
退出代码:
0:有效。1:有效但有警告。2:无效。