Munder Difflin GOD 编排器深入解析路由、裁决与升级机制【免费下载链接】munder-difflinA local multi-agent harness that works with your existing Claude Code, Codex subscriptions, allows you to run an office of agents项目地址: https://gitcode.com/GitHub_Trending/mu/munder-difflin导读本文深入剖析 Munder Difflin 中GOD orchestratorGOD 编排器的工作原理作为整座 AI agent 办公室hive的监督者它如何通过机制与智能分离的架构完成四件核心工作——维护花名册roster、路由route任务、裁决adjudicateagent 间的日常消息、以及把真正关键的事项升级escalate给人类。读完本文你将理解编排器的消息协议、防死循环的跳数机制、单提交者 git 与审批队列的实现细节以及如何通过编辑 prompt 而非代码来调整编排器的行为策略。TL;DRGOD 编排器是运行一整座 Claude Code agent hive 的监督者 agent。它本身只是一个普通的 Claude 进程承担智能外层由 harness 提供机制消息路由器、单提交者 git、人工审批队列。它的四件工作维护花名册、路由工作、裁决日常的 agent 间通信、只把少量关键事项升级给人类。为什么多 agent 系统需要一个负责的agent任何多 agent 系统最终都需要有一个 agent 来说了算——不是为了亲自干活而是决定谁去干。在 Munder Difflin 中这个角色就是GOD orchestrator办公室里的Michael常驻 Corner Office拥有专属工位。它随 hive 一起启动作为另一个claude进程与 worker 们并肩运行——只不过它是一个特殊的进程。智能与机制分离Intelligence vs. mechanism整个设计中最关键的决定是编排器是什么。一种诱人的做法是把路由逻辑写成代码——一个大 dispatcher 检查每个请求并分配任务。但这很脆弱每来一种新任务就要写新代码。Munder Difflin 的解法是把编排器拆成两半机制mechanism存在于 harness 的主进程中。它运行单提交者 gitsingle-committer git、在 agent 之间搬运消息的路由器、append-only 事件日志以及存放等待人类审批事项的审批队列。机制没有判断力它是可靠的管道。智能intelligenceGOD agent 本身——一个普通的claude进程被标记为编排器orchestrator负责读取请求并决定如何处理。它的路由和升级策略写在 system prompt 里。收益在于你想改变编排器的行为只需编辑 prompt而无需发布代码。想让它在某些情况下升级得更激进或者更偏袒某个专家 agent调整指令即可。底层的机制保持不变、保持安全。更宏观的原则参见 orchestrating Claude Code agents。源码中的身份标识从源码看GOD 只是一个被标记的普通进程并非修辞。在 src/shared/godIdentity.ts 中默认的 GOD 名字是MichaelDEFAULT_GOD_NAMEresolveGodName()负责在每次重spawn 时解析显示名——它会优先读回持久化的名字只有在新 hive、注册表尚未写入时才会回退到默认值export const DEFAULT_GOD_NAME Michael; export function resolveGodName(persistedName: string | undefined | null): string { const trimmed persistedName?.trim(); return trimmed ? trimmed : DEFAULT_GOD_NAME; }对应的测试 test/god-identity.test.cjs 验证了持久化的改名优先于默认值以及空/空白名字会回退默认。同时src/shared/agentRole.ts 定义了角色的持久化规则preferredAgentRole()在 GOD 没有持久化角色时返回orchestrator (god)作为兜底roleForHiveSpawn()在 spawn/restart 时把 GOD 的角色作为orchestrator (god)发送给 hive 注册表。工作一维护花名册Keep the roster编排器只有知道办公室里有谁才能做好路由。harness 维护一份注册表registry——每个 agent 的 id、名字、角色role、能力capabilities和当前状态idle / working / blocked / gone。当一个 agent 被 spawn 时即被注册编排器读取注册表来了解自己有哪些选项。在源码中注册表对应 src/main/hive.ts 的registry.jsonhive 身份id/role/cwd/session——agent 读取的就是它它与 UI 层的 floor rosterharnessHome/roster.json是分开的两份数据。AgentMeta接口明确定义了每个 agent 记录的字段export interface AgentMeta { id: string; name: string; provider?: AgentProvider; // 运行在哪个 CLI 上默认 claude role?: string; // 职位 / 一次 hire 的一句话描述 capabilities?: string[]; cwd: string; isGod?: boolean; isAssistant?: boolean; // Michael 的 prep assistant只发送不接收 }注册表就是路由表。给新端点写测试这样的请求会发给角色与能力标明tests的 agent而不是碰巧空闲的任意一个。角色不是装饰性的——它是编排器做出合理指派而非随机指派的方式。值得注意的是每个 agent 在注册时都会触发hive: register id提交见 hive.ts 第 763 行注册本身也被写进 git 历史。工作二路由工作Route work当你用自然语言描述一个目标时编排器会把它分解并分别路由。关键细节在于怎么路由它不会伸手进 worker 的文件系统去告诉对方做什么而是发送一条消息——一份自包含的任务规格task spec——进入 worker 的 inbox走的是每个 agent 共用的同一条路由器。这条消息是一个结构化对象。借鉴 agent 通信研究中一个有用的概念——言语行为speech act——每条消息声明自己的意图{ to: agent.coder, act: request, // request | inform | propose | query | agree | refuse | done subject: Add validation to signup, body: …self-contained task spec…, conversation: conv-7f3 // 用于归组一个线程 }harness 会补全 id、发送者、跳数hop count和时间戳。一份好的任务规格意味着 worker 不用追问就能直接开工——这正是加速团队的路由与只是多一跳的路由之间的区别。源码中的消息结构在 src/main/hive.ts 中HiveMessage接口与文档中的 JSON 示例一一对应并额外补全了 harness 自动填写的字段export type MessageAct request | inform | propose | query | agree | refuse | done; export interface HiveMessage { id: string; conversation: string; in_reply_to: string | null; from: string; to: string; // 一个 agentId、god 或 broadcast act: MessageAct; subject: string; body: string; hops: number; requires_reply: boolean; needs_human: boolean; created_at: string; }normalize()hive.ts 第 1520 行起负责把 partial 消息补全为完整HiveMessage其中两项默认值直接对应文档中的两条防循环规则hops: typeof partial.hops number ? partial.hops : 0, requires_reply: partial.requires_reply ?? [request, query, propose].includes(act), needs_human: partial.needs_human ?? false,也就是说只有request、query、propose这三种 act 默认要求回复inform和done是终态消息默认不要求回复——这正是文档所说回复它们就是两个 agent 永远循环下去的起点的实现基础。路由器的实际投递逻辑routeMessage()hive.ts 第 1556 行起是真正的消息中枢它处理了几类重要边界情况human 即 godresolveTo()把to human || to god统一解析为 godId。这印证了文档的说法——hive 没有独立的人工审批队列发往human的消息由 god人类的代理处理审批原生地发生在每个 agent 自己的 Claude Code 会话里可远程批准。broadcast 扇形广播to broadcast时通过selectBroadcastTargets()选择活动注册表中的所有可接收 agent并跳过只发送不接收的 prep assistant。永不投递给自己过滤掉t msg.from防止 god → human 的消息又循环回 god 自己。无 inbox 的接收者对于没有安全空闲生命周期状态的 hookless 自定义 CLI先尝试 terminal work-order 交接失败则带说明回弹给 god绝不静默丢失消息。未知 agent id记录dropreason: no-inbox并回弹给 god附带提示检查 id 是否在花名册上。每次路由都会appendLog一条消息记录并触发hive: msg from→to (act)的 git 提交——完整可审计。工作三裁决日常通信Adjudicate the routine traffic这一项工作让自治成为现实。随着 agent 们工作它们会互相提出各种问题按哪个 schema 校验、staging URL 是否最新、计划的小改动。如果每个问题都弹回给你这个团队就只是你亲力亲为的慢速版本。所以编排器负责裁决它持续排空自己的 inbox自己回答日常问题并用清晰的任务规格把工作路由给合适的专家。绝大多数 agent 间的流量永远不会到达你这里——因为本就不需要。两条规则防止裁决演变成混乱并非每条消息都要求回复。只有request、query、propose期待回答。inform和done是终态——回复它们就是两个 agent 无限循环的开始因此协议禁止回复它们。源码中requires_reply的默认计算直接落实了这条规则见上文normalize()。跳数有上限。每条回复都会使跳数计数器 1。超过上限后条目被升级给人类而不是允许它在 agent 间弹来弹去。这是一个livelock 熔断器。源码中对应的常量是 src/main/hive.ts 第 192 行的const HOP_CAP 12;当msg.hops HOP_CAP时routeMessage()记录一条dropreason: hop-cap并终止投递而不是继续弹跳。共享计划同样被裁决编排器是白板的唯一记录者single scribe。其他 agent 可以提议修改但只有编排器写入。这保证唯一一份真正共同所有的文档不会发生冲突。底层的消息传输机制参见 atomic file mailboxes for agents。在源码中这份共享计划有两部分见 hive.ts 的 guardrailsLineboard.md自由格式god 是唯一记录者和tasks.json结构化看板——todo/doing/blocked/done。裁决还体现在spawn queue和circuit breaker等护栏上熔断器会监视整个楼层一旦检测到 agent 循环或超支会发出 Circuit breaker: steer/constrain 消息要求 agent 停止重复、总结已尝试的方案并遵循指示。工作四升级关键少数Escalate the critical few编排器最重要的边界是知道什么不该由自己决定。它的升级策略是一份简短而明确的关键事项清单破坏性操作——任何难以撤销的删除或覆盖。花真钱——有美元成本的动作。范围变更——偏离你实际要求的工作。无法解决的冲突——两个 agent 僵持不下编排器无法打破。当条目命中清单时编排器升级而不是自行行动。机制上它发送一条收件人为human的消息或标记为需要人类关注harness 将其转入 UI 中展示的审批队列approvals queue。你批准或拒绝——可附注比如可以但上限 $5——该附注作为来自人类的消息被回传给提问的 agent。agent 带着你的指引从断点继续。源码印证了这条路径needs_human字段与to: human的寻址方式配合resolveTo把 human 解析为 godIdrouteMessage投递时emitMessage会用珊瑚色渲染楼层中的信封标示这是一条 agent 标记为需要人类关注的消息。而HiveTask.humanQAhive.ts 第 98-104、115-118 行把人类问答直接记录在任务卡片上god 在卡片只能靠人类输入推进时把状态置为blocked并追加{q}harness UI 负责填{a}完整历史永远保留在卡片上——决策轨迹与它解锁的工作待在一起。所有不在关键清单上的事项保持自治。这种选择性升级——human-in-the-loop done right——正是一个 hive 能长时间无人照看运行的全部原因它恰好在应该打断你的时刻打断你其余时间绝不打扰。它也是模型的主要安全护栏——策略就是控制面你通过编辑 prompt 收紧或放松它。一个请求的完整旅程把四件工作串起来看一条指令的生命周期你用自然语言向编排器描述一个目标。它读取花名册分解目标把任务规格路由到正确的 agent 的 inbox。agent 们在隔离的会话中工作。需要时通过自己的 outbox 给另一个 agent 发消息路由器负责投递。编排器裁决日常问题回答或重新路由保持楼层运转。出现关键事项时升级到审批队列等待你的决定。每一步都提交进 hive 的 git 仓库并写入 append-only 日志整个事件可审计、可重放。什么让它健壮几个属性让编排器不至于成为单点故障机制是笨而可靠的。路由、提交、队列在编排器做出错误决策时仍能工作——坏路由是可恢复的因为它仍流经单写者文件和串行化提交。源码中这体现为单提交者 git 重试/退避 过期锁恢复hive.ts 第 2663 行起只有主进程提交agent 从不调用 git——它们只写文件。幂等的消息处理。每个 agent 跟踪一个已处理消息的游标cursor确保每条消息只被处理一次。再次看到已处理的消息是 no-op。这与 per-agent workspace 中的cursor.json对应。升级是 fail-safe 的。拿不准时——跳数超限、寻址边界情况——系统路由给人类而不是猜测。默认是问不是做。在源码中hop-cap、no-inbox、hookless 无法投递等所有异常路径都会回弹给 god 并记录 drop 日志而不是让消息悄悄消失。这些选择背后的设计原理参见 coordinating AI coding agents 中编排器所依赖的单写者与单提交者原则。编排器的界面Command Center在 v0.1.6 中Michael 的界面大幅扩展。他的侧边栏变成完整的Command CenterTasks 标签页一个 kanban 看板跨 agent 跟踪工作并支持依赖链接。源码中对应 src/renderer/src/components/TasksKanban.tsx 和 src/renderer/src/components/TaskDetailOverlay.tsx任务的dependsOn字段在 src/main/hive.ts 的HiveTask接口中定义。Triggers 标签页汇总所有无需你干预即可唤醒 hive 的东西——首当其冲是计划任务schedules——让你预先编程周期性指令在你两次检查之间楼层保持活跃。源码对应 src/renderer/src/components/triggers/SchedulesSection.tsx 和 TriggerHistoryTab.tsx。Activity 标签页展示每个 agent 的真实 token 与美元成本数据来自 transcript 文件。源码对应 src/renderer/src/components/CommandCenterPanel.tsx 的 Activity 区块hive 事件日志 看板成本数据来自 src/main/costLifetime.ts 的 append-only 成本台账cost-ledger.jsonl。Floor 标签页中的 GitHub Issues 区块让 Michael 直接接收和路由仓库 issue。入口是 GOD agent 的专属面板当选中 god agent 时src/renderer/src/components/AgentDetailPanel.tsx 会渲染CommandCenterPanel作为其详情面板。编排器还是同一个 agent——harness 只是给了他更好的工具。FAQ可以不用编排器运行吗可以运行没有编排器的 agent但那样你自己就是编排器——手工分配工作和转达消息。GOD agent 的存在就是把这个角色从你身上卸下来。编排器住在哪里它是一个固定的、常驻的 agent住在 Corner Office自然是 Michael 的房间有保留工位。它随 hive 启动作为又一个claude进程与 worker 们并肩运行——只不过是一个特殊的进程。GOD 编排器是一种特殊模型吗不是。它只是一个带有编排器标记和定义其职责的 system prompt 的普通 Claude Code 进程。智能是一个普通 agent围绕它的 harness 提供机制——路由、git 和人工审批队列。编排器会把什么升级给人类只有真正关键的事项破坏性操作、花真钱、范围变更以及它无法解决的冲突。其他一切——澄清、数据请求、小计划调整——它自己解决让团队保持自治。编排器如何避免 agent 之间无限循环消息携带跳数每次回复 1超过上限源码中HOP_CAP 12后条目被升级而不是无限弹跳。只有 request、query、propose 要求回复——纯 informational 消息是终态的。【免费下载链接】munder-difflinA local multi-agent harness that works with your existing Claude Code, Codex subscriptions, allows you to run an office of agents项目地址: https://gitcode.com/GitHub_Trending/mu/munder-difflin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考