Buzz Welcome Kickoff 静默失败全解析:如何把“计时器决策“改造成“事实决策“的编排修复
2026/9/12 8:30:59 网站建设 项目流程

Buzz Welcome Kickoff 静默失败全解析:如何把"计时器决策"改造成"事实决策"的编排修复

【免费下载链接】buzzA hive mind communication platform项目地址: https://gitcode.com/GitHub_Trending/buzz14/buzz

Welcome Kickoff(欢迎频道开场编排)是 Buzz 桌面端在新用户进入私有 Welcome 频道时自动执行的一段多 Agent 协作流程:Fizz 发布开场白,两位队友(Honey、Pollen)在线程内自我介绍,Fizz 最后发布收场白(closer)与行动号召(CTA)。这段流程在三类失败路径上曾经各自为战——错误叙事(团队明明正常却被宣布"延迟")、过度喧闹(Agent 互相回复死循环)、静默失声(频道空无一人说话)。编排文档(docs/welcome-kickoff-silent-failures.md)把它们收敛为同一个根因,并给出了已经落地的修复与仍在推进的待办。

读完本文,你将掌握:Welcome kickoff 编排在 welcomeKickoff.ts 中的完整状态机与计时器语义、回复循环在 base_prompt.md 中的提示词根因与修复、线程回复实时渲染的三条数据通路,以及这些设计决策背后的源码证据。

一个根因,三个表象

编排失败表现为三类互不相干的现象,但共享同一条病根:

类别失败表现状态
错误叙事团队明明工作正常,却被宣布"延迟/损坏"未关闭(本文 §1)
过度喧闹Agent 之间无限互相回复已修复(2026-07-18,本文 §2)
静默失声无人说话,用户面对一个空频道未关闭(本文 §3)

共同的根因:kickoff 依据计时器和"证据缺失"来决定说什么,然后把这份猜测用永久标记(marker)写死。整个流程只有一个基于事实的健康检查——failedAfterKickoff,它读取真实的 Agent 状态(status === "stopped"+lastError+lastStoppedAt,见 welcomeKickoff.ts),表示"进程确实死了"。其余驱动用户可见决策的全部是秒表:

计时器决定
TEAMMATE_READY_WAIT_MS60s是否发布降级开场白
TEAMMATE_INTRO_WAIT_MS15s(现已改为TEAMMATE_INTRO_BACKSTOP_MS,120s,见 §1)是否宣布队友"慢"
WELCOME_KICKOFF_STAGE_TIMEOUT_MS90s是否退出 kickoff 阶段(舞台动画)

事实装饰,计时器决策。failedAfterKickoff只负责在"15s 秒表已经决定要发消息"之后挑选措辞。把这一层反转,本文的大部分内容就不复存在:事实决策,计时器只做最后兜底。

代码缺失的,是对两个被混为一谈的概念的区分:

  • "Agent 崩溃了"—— 这是事实,我们有它,值得宣布;
  • "还没有自我介绍"—— 这不是事实,这是"未知",它不是新闻。

在截止时间上宣布"未知",就产生错误叙事;无法宣布任何东西,就产生静默路径;而回复循环是同一疾病在上一层:Agent 被要求每一轮都必须说话,无论是否有真话可说,于是永远说"收到"。

原则(两层通用):不要强制说话,要强制诚实。§2 的提示词修复与 §1 的 closer 修复是同一处变更在两个地方的落地。

1. 错误叙事:收场白在计时器上说话

状态:已在本分支修复。观测于 2026-07-18 14:26:开场白 2:26 发出,2:26+15s 时 Fizz 发布"Honey and Pollen are taking longer than expected. I'm still here to help.",而 Honey 和 Pollen 在 2:27 就发布了正常的自我介绍。这个错误叙事从未被纠正,因为它在发出时已被永久盖章。

故障机制

  1. 开场白发布,设置定时器15s − (now − opener.created_at)
  2. 定时器触发,classifyWelcomeKickoffResolution(welcomeKickoff.ts)把队友分成failed(基于事实,通过failedAfterKickoff)和unresolved仅仅是没有看到自我介绍)。
  3. unresolved.length > 0buildWelcomeKickoffCloser([], ["Honey","Pollen"])→ "taking longer" 文案 + CTA(welcomeKickoff.ts)。
  4. 这条消息携带closerMarker发布(sendWelcomeKickoffCloser,welcomeKickoff.ts)。该标记是终态的:之后的每一轮都会因它提前 return,而kickoffResolved闩锁(latch)使这一决定在设计上永久化。
  5. 自我介绍随后到达。没有任何东西重新运行。不存在任何路径会发布真正的收场白。

为什么 15s 既是错误的数字,也是错误的问题

  • 它的邻居允许60s 用于一个进程启动TEAMMATE_READY_WAIT_MS),却只给"两个冷启动 Agent 接收派发事件、跑完一轮完整 LLM、再发布"15s——对于困难得多的任务反而少了 4 倍预算。
  • 时钟从opener.created_at起算,harness 派发延迟在 Agent 拿到事件之前就消耗掉预算。
  • Math.max(0, …)意味着在重访(revisit)时等待时间被钳制到 0,消息会瞬间触发。
  • 观测现实:自我介绍实际花了约 60s,即使 30s 的计时器也一样会误触发。

但更深层的问题是结构性的:收场白把"终态事实"和"临时猜测"焊接在了一起。

收场白的组成部分性质期望
CTA ——"What can we help you build?"终态、恰好一次✅ 一次性 marker
队友状态 ——"X is taking longer"临时、可纠正❌ 当前被焊死在该 marker 上

修复:让事实决策,秒表仅作兜底

收场白应在以下任一条件成立时触发:

  • 自我介绍到达→ 干净的收场白 + CTA(约 95% 的主路径,完全不需要计时器);
  • failed非空→ 立即发送"无法启动 / 去 Agents 查看"的收场白(基于事实,所以可以快速且仍然诚实);
  • 长兜底计时器耗尽,队友存活但沉默→ 发送 "taking longer" 文案——到那时它才是真话

代码本来就具备这个结构,只是兜底值错了。classifyWelcomeKickoffResolution已经将failedunresolved中排除,所以一旦每个队友都"已自我介绍或已失败",unresolved为空,收场白会在 3s 节拍(CLOSER_BEAT_MS = 3_000)上以基于事实的正确措辞触发——计时器被清除,永不说话。而且计时器回调在发布前会针对最新事件重新分类,因此如果在"设置计时器"和"计时器触发"之间自我介绍到达,它会自我纠正。

所以整个修复就是那个常量:TEAMMATE_INTRO_WAIT_MS = 15_000TEAMMATE_INTRO_BACKSTOP_MS = 120_000(welcomeKickoff.ts)。改名是因为旧名字把它描述成"自我介绍应该多快到达"的预期——这正是吸引人去像调预期一样调它的原因。它其实是一个"放弃"兜底。因为它不 gate 主路径,调高它对正常情况零成本——只是推迟了"对一个存活但沉默的队友放弃"的时刻。真正的失败永远不需要等它:failedAfterKickoff会立即解析崩溃的队友。

决策:CTA 保留在收场白内

CTA 只存在于收场白内部,因此等待自我介绍会把"你现在可以和我们说话了"的交接从约 15s 推迟到约 60s。已接受(Morgan,2026-07-18):等待期间房间并不是死的——开场白已上线,舞台显示"Fizz: Working"。备选方案(提前单独发 CTA,只在有值得报告的状态时再发状态)更诚实,但要增加第二条消息及其 marker 和幂等性,去解决一个舞台已经解决的问题。

注意:这个失败是 §3 的"缩小版"。频道不是死的——CTA 会到达——但叙事是假的。任何修复都不能重新打开 §3:如果等得更久而等待以"什么都没有"告终,就回到了无法解释的沉默。

2. 过度喧闹:失控的回复循环(已修复)

状态:提示词加固于 2026-07-18 落地,手动验证过一次(14:26 那次运行:3 条回复、自我介绍、停止)。一次良好观测不是证明,需要在 Codex 上重新验证。

在 Codex 运行时(codex-acp)观测到,从未在 Claude Code 上复现。21+ 条回复,每条都是对前一条确认的确认:

Pollen:@Fizzparked; no further replies from me until there's work.Honey:@Fizzunderstood. I won't reply again unless there's a task for me.Fizz:@Honey@Pollenacknowledged — stay parked until@morganbrings a real task.

内容本身就是告密者:每个 Agent 都在试图结束对话,而"宣布结束"恰恰让它活着。Agent 没有故障——它们在精确地服从。这个循环是"给定提示词下的正确行为"。

根因:两条规则组成的永动机

crates/buzz-acp/src/base_prompt.md 中的两条规则叠加成永动机:

  1. "每一轮处理用户消息都必须发布回复。…… 一轮结束而没有发布消息就是静默失败。"
  2. "完成委托工作后,你必须@mention委托人…… 这是协作停滞的第一大原因。"

规则 1:永远说话。规则 2:说话时,@ 那个 @ 你的人。在互相 @ 的情况下,回路闭合且永不打开。规则 1 说的是"用户消息",但措辞是绝对化的,没有为 Agent 触发的输入留出例外。规则 2 是为了修复相反的失败而写的——两条加固互相抵消,没有任何东西去调和它们。

Welcome kickoff 是最坏情况:开场白说"Don't start any work yet"("先不要开始任何工作"),于是队友被同时告知必须回复且无事可报——剥掉了回复可能包含的一切实质性内容。唯一能满足规则 1 的输出就是无内容的确认。kickoff 不仅允许这个循环,它的指令还选中了这个循环。

已落地的修复

这一轮有没有值得说的来界定两条规则,而不是按谁触发的:

  • 规则 1 → 如果这一轮产出了值得知道的东西(结果、答案、交付物、决策、阻塞项、需要回答的问题;被要求的活永远算数)就发布。
  • 人类向你提问必须回复——哪怕是"没什么可补充"。这保留了规则 1 原本存在的反静默失败底线。
  • 其余情况下发布是可选的,沉默明确地算成功
  • 禁止裸确认,点名了观测到的违规措辞("Got it"、"Confirmed"、"Standing by"、"Parked"、"I won't reply again"),以及点睛之笔:如果你忍不住想宣布"我已回复完毕",那条消息正是最不该发的。
  • 规则 2 限定为仅限已完成的工作——不包括接单确认,不包括对话性回环关闭。
  • Mentions 规则加固:在谈论某人时点名("waiting on @morgan")属于叙事——去掉@。该循环曾用 4 条此类假通知骚扰 Morgan。

对比当前 base_prompt.md 的实际内容,上述修复全部在场:第 80-84 行的 "If your turn produced anything worth knowing, you MUST publish it"、"Never publish a bare acknowledgement"(含 "Standing by"、"Parked"、"I won't reply again" 等明令禁止措辞)、第 62-63 行 "Callback Mentions" 限定为completed work only、第 58 行 Mentions 叙事规则("Naming someone while talkingaboutthem is narrative… Drop the@")。你可以打开该文件逐条对照。

为什么必须是"局部测试",而不是"不要循环"

"别陷入循环"不是 Agent 能遵守的规则。循环是对话的全局属性;每个 Agent 只看到自己那一轮,而每一条单独的回复局部看都合理——这就是为什么那些道别语读起来是礼貌而非病态。规则必须变成局部的、每轮可检验的测试这条消息有没有增加线程中不存在的信息?确认在定义上就不是新信息,所以"禁止裸确认"是可检验的意图表达。

软的警示同样会失败:"你可以结束这一轮""必须发布回复"并排,字面模型会正确地遵守更强的指令。这个强制必须被收窄,而不是加例外。

仍未关闭:断路器

仅靠提示词意味着仅靠"散文合规",而 Codex 已经证明模型不会可靠地合规。目前整条路径上仍然没有回复深度计数器、跳数上限、冷却时间或 Agent 间预算。现有守卫帮不上忙:

守卫为什么不行
ignore_self(lib.rs,约 L3371 起)只拦截自我回复。唯一的循环守卫,而 A→B→A 恰好是它漏掉的。
Author gate(respond_to按设计放行兄弟节点——is_owner_or_sibling(lib.rs)通过 NIP-OA 校验同属主的 Agent。它是准入机制;循环需要终止。没有任何设置能停掉它。
max_turns_per_session(config.rs)默认 0 = 禁用;它是会话轮换(上下文卫生),不是回复刹车。
队列上限(queue.rs)只对待处理事件做背压。乒乓球永远不会积压。
closerMarker只对客户端撰写的收场白做幂等;从不观察 Agent 回复。

候选方案:连续的 Agent 间回复预算——统计线程内不间断的 Agent 撰写的轮数;超过 N,丢弃触发。人类消息重置计数。N 设高一点(约 6–10),确保它永远不在健康协作时触发——这是断路器,不是策略。resolve_reply_anchor故意允许深层 Agent-only 嵌套,所以过低的帽会截断合法协调。

过激的断路器会制造 §3。深度计数器无法区分循环和高效链路;丢弃一条好回复产生的正是本文通篇讨论的那种无法解释的沉默。因此:提示词为主,断路器设高。

断路器触发时加一条tracing日志——便宜,而且目前触发了我们也看不见。面向用户的表面大概率不在范围内:断路器正常工作时,期望结果就是 Agent 停止说话。需要把它暴露给用户的理由是误报,而不是成功。

3. 静默失声:静默路径

状态:未关闭。感知差距已处理;路径本身没有。

每条兜底消息都假设 Fizz——主角兼发送者——活着且能发帖。当失败的就是 Fizz 时,没有人说话。

客户端侧 kickoff 舞台(Welcome 撰写栏上的角色动画)覆盖了感知层且已落地:90s 无消息后,角色退场,横幅回落到普通的 mention 提示(useWelcomeKickoffStage.ts 的WELCOME_KICKOFF_STAGE_TIMEOUT_MS = 90_000)。失败的 kickoff 降级为一个普通、可用的空频道,而不是宣称"团队仍在组建中"。

但它不解释任何事情

  • 舞台只读"时间线是否为空"+ 那个计时器(useWelcomeKickoffStage.ts)。它从不读真实的 kickoff 状态,所以无法区分"Fizz 崩溃了"和"relay 慢"——又一个替事实站岗的秒表。
  • 它降级成的空频道引导用户去@Fizz——而恰恰在这些场景里,Fizz 就是那个不工作的东西。诚实,但死路一条。

今天用户无法被告知的事

  1. Fizz 启动失败。startManagedAgentreject(harness 二进制缺失、spawn 错误)。effect 记录Failed to start Welcome agent…然后返回——按设计只有 Fizz 发开场白,所以无人说话。
  2. 任何一步抛异常。整个 kickoff 是一个try/catch,记录Failed to start the Welcome team kickoff.后放弃(welcomeKickoff.ts)。实践中见到的:relay 不可达 / websocket 掉线;ensureWelcomeTeam失败;发送本身被拒(relay 限流,见"Related")。
  3. 收场白路径失败。收场白发送失败只被 catch-and-log;线程在缺少 CTA 的情况下结束。风险较低(开场白 + 自我介绍已经发生),但仍然悬空。

kickoff 中途离开页面也会静默取消——这是有意的(下次访问恢复),不是失败。

今天用户能收到的消息

全部是客户端硬编码;只有队友自我介绍回复是 LLM 生成的。

#消息触发条件发送者
1Provider 兜底("connect to an AI provider in Settings…")kickoff 前的就绪检查失败Fizz(provider-required.v1
2正常路径开场白团队在线Fizz(opener.v1
3降级开场白("I'm here with Honey and Pollen…")Fizz 在线、60s 内零队友在线Fizz(opener + closer markers)
4收场白变体(clean / failed / slow)自我介绍解决后的 3s 节拍,或 120s 自我介绍兜底(见 §1)Fizz(closer.v1
5设置模式提醒("here's what you still need to configure")Agent 启动但需求检查失败(如缺 API key)Agent 进程本身(buzz-acp setup-listener 模式)

修复的约束

  • Fizz 不能当信使——坏掉的就是她。任何兜底必须来自客户端 UI(横幅、intro-block 状态、舞台timed-out阶段),而不是伪装成 Agent 的频道消息。
  • relay 侧/系统撰写的消息(kind-scoped 系统事件)可行但更重。客户端已经本地知道 kickoff 抛了异常,所以本地 UI 状态是廉价且诚实的选择。
  • 必须跨重访幂等——与 opener markers 同规则。不要每次用户点 Welcome 就重新报警。
  • 区分可重试(relay 抖动、限流)与需行动(harness 缺失 → 指向 Agents/Settings)。readiness.rs 中的Requirement已经对需行动项做了分类。

验证用草图(待验证)

  1. 在 catch 块触发或主角 start reject 时,从useWelcomeKickoff暴露一个kickoffError阶段,带粗略原因(lead-start-failed|relay|unknown)。
  2. 舞台的timed-out阶段渲染该原因:安静的文案 + 指向 Agents(启动失败)或重试入口(relay 失败)。重试 = 重新运行 effect(协调器已去重)。当前该阶段在超时后立即退出,所以给它文案意味着让它停留在屏幕上——而且它今天是aria-hidden装饰,任何要说的话都必须到达屏幕阅读器。
  3. 考虑对 relay 类别做有界的自动重试(一次、短延迟),然后再展示任何东西。
  4. 收场白路径失败:发送时重试一次;否则保持线程原样(自我介绍已经交付了核心体验)。

4. 线程回复不实时渲染(独立 PR)

状态:未关闭,根因未知。不是 kickoff 的 bug——在此记录,只跟踪到它有自己的归属为止。应用级;大概率早于本次工作,且按爆炸半径超过本文所有条目。

症状(2026-07-18 等多次重复观测)

线程打开时,来自其他人的新回复不出现。频道的回复计数增长。关闭再重新打开线程,所有缺失的回复全部出现。

为什么它藏得深

"有新回复"这个事实,沿着三条独立的路传播:

用户看到的东西来源
回复计数Relay 推送kind 39005 线程摘要重计数→ 合并进 window-store overlay(hooks.ts,mergeLiveThreadSummary)。不是来自回复本身。
线程面板行一个独立的 React Query 缓存["thread-replies", channelId, rootId](useThreadReplies.ts),打开时填充;实时回复必须由appendMessage归档进它(hooks.ts,threadRepliesKey写入)
频道时间线window store——线程回复被刻意 early-return 在到达它之前

所以角标是正确的而面板是错的——计数是 relay 自己的统计,无论客户端是否收到回复都会到达。角标移动不是消息到达的证据,这就是为什么它在 UI 上无法诊断,并在多次出现中一直未获解释。关闭/重开会从零重新拉取(staleTime: 0,见 useThreadReplies.ts)→ 一切出现。

人-人线程里大概率不可见,因为自己的发送是乐观渲染的,不等 relay。坏掉的路是线程开着时来自其他人的回复到达——实际中主要是 Agent。

已排除的嫌疑

  • 不是getThreadReference归一化。它返回rootId: rootTag?.[1] ?? parentId(threading.ts),所以对开场白的直接回复确实拿到rootId——线程缓存写入条件应该通过。
  • 不是实时过滤器。buildChannelFilter#h为作用域横跨宽泛的CHANNEL_EVENT_KINDS集合——线程回复携带相同的h标签。
  • 不是初始拉取竞态。useThreadRepliesqueryFn在开始时快照 ids,并重新合并任何在途接收的事件(useThreadReplies.ts)。

值得检查的嫌疑(未证实)

welcomeKickoff.ts 以打开线程面板所用的同一个缓存键调用useThreadReplies——在 Welcome kickoff 中,打开的线程就是开场白线程,所以两个生命周期不同的功能在staleTime: 0下共享一个缓存条目。当kickoffResolved闩锁后,kickoff 的 observer 传入null,其键翻转为["thread-replies","none",openerId]并脱离——大约在自我介绍未能渲染前 30s 发生。welcomeKickoff.ts 中的注释记录了这一耦合此前已被咬过一次。

但 Morgan 报告此问题发生在 Welcome 流程之外,这反驳了耦合是原因的推断。只有相关性。

下一步(在进一步推测之前先做)

appendMessage中临时记录event.kindevent.idgetThreadReference(event.tags);线程打开时重跑。一次运行就能把问题劈成两半:

  • 回复从未到达→ 投递问题(订阅/relay 扇出)。
  • 到达但未归档→ 记账问题(写入条件)。

5. Backlog:!cancel不可达

!cancel/!shutdown/!rotate从每个产品表面都不可达。is_owner_control_command(lib.rs)要求全部满足:kind:9、content.trim() == "!cancel"精确)、以及一个指名该 Agent 的p标签。但每个表面都是从@Name文本推导p标签的(Desktop 侧hasMention.ts;CLI 侧resolve_content_mentions——SendMessageParams没有 mention 标志)。所以@Fizz !cancel通不过精确匹配,裸!cancel不产生p标签。在每个真实表面上互斥。只有通过POST /events手工构造的签名事件能触发它们。单元测试之所以通过,只是因为它在 content 之外独立附加p标签——而这是任何产品路径都产生不了的形状。

选项:放宽匹配器以接受命令前的@Name,或给buzz messages send加 mention 标志。先确认这些命令是否本来就是为手工/测试用途设计的。

即使修好,!cancel也只取消一轮、一个 Agent、一个频道,Agent 会在下一次被 @ 时恢复——它不是循环终结器。停止/取消控件在 2026-07-18 明确被划出循环工作范围;这是独立 bug。

今天对付失控团队有效的工具:steering(直接发消息——multiple_event_handling默认为steer,见 config.rs 的默认值与test_multiple_event_handling_default_is_steer测试)能重定向一个正在工作的 Agent,但循环是许多短小的已完成轮,steering 无法打破它。唯一真正的工具是Agents UI 中的 Stop 按钮useManagedAgentActions.ts),它同时会杀掉合法的在途工作,并要求用户识别出循环并知道杀手开关在哪。

参考:被否决的方案(不要重试)

按发送者身份(人类触发 vs Agent 触发)界定回复强制。2026-07-18 被否决。显而易见的修法是把规则 1 挂到turn_is_human_facing上(queue.rs)。它不工作,原因在追踪真实 transcript 的p标签之前是看不见的:

parse_thread_tags(queue.rs)收集每一个p标签,且不区分被 @ 的是谁,而turn_is_human_facing只要任意被 @ 的 pubkey 是人类就返回true。循环的标志性内容是 Agent 叙述"stay parked until@morganbrings a real task"——它把人类 p-标签进去了:

触发p标签分类
Honey/PollenFizz:"…until@morganbrings a real task"Honey、Pollen、morganhuman → MUST reply
FizzHoney:"@Fizz understood"Fizzagent → optional

它只豁免了碰巧没点名人类的那条腿——靠运气砍掉 3 条腿中的 1 条。假如 Honey 写的是"@Fizz understood, waiting on @morgan"——完全符合人设——循环会完好地逃过这个修复。循环自己的内容重新武装了用来阻止它的规则。能被症状禁用的守卫不是守卫。更糟的是,那些叙事性@morgan本来就已经违反 Mentions 规则,所以这个守卫是把既有的散文违规当输入。

根本洞见:turn_is_human_facing回答的是*"点名了人类吗?",而不是"是人在问吗?"*——而这两者在最关键的地方分叉。它是很好的回复锚启发式,却是错误的安全信号。这也杀死了计划中的[Context]Triggered by: human|agent管道:信号投递正确,信号本身错了。

在 personas 里修循环(personas.rs)。被否决:它们是角色提示(语气、文字游戏),把对话协议规则放进去是分层违规;需要在三个 persona 和未来每一个 persona 里重复;而且存储的副本是用户可编辑的、带修改跟踪(migrate_retired_personaswas_unmodified)——用户改写了 Fizz 的措辞,不能因此删掉循环守卫。

welcomeKickoff.ts文案里修循环。被否决:治标不治本。任何两个互相 @ 且无事可报的 Agent 都会触发同样的规则冲突。

可用但未选择:团队指令(Team Instructions)。TeamRecord.instructions被端到端接通(teams.rs →PromptContext.team_instructions[Team Instructions],pool.rs)且对 Welcome Team 是None。它是 kickoff 专属礼仪的自然归宿,也是若基础提示词修复被证明对自我介绍场景太弱时的正确位置——但它只覆盖这一个团队,所以是补充而非替代 §2。

相关事件与结论

  • 限流事件。一个 Welcome Agent 在几秒内产出了 42KB 的 "rate-limited: quota exceeded" 重试日志(2026-07-17,远程 relayonboarding.communities.buzz.xyz)。对配额的紧重试循环会让会话内每一次其他发送也失败——包括 kickoff 的发送,即 §3 静默路径之一。值得单独审视 buzz-acp 的发布退避。最初怀疑是 §2 循环在烧配额;§2 修复后,若再复发则是独立的重试 bug。
  • 为什么是 Codex 而不是 Claude Code。已排除:提示词内容(各运行时一致——[Workspace]+[Base]+[System]+[Team Instructions]+[Agent Memory]+[Channel Canvas],pool.rs,只有投递不同,且没有任何路径省略规则 1)、各运行时配置(args、env、权限处理——没有一个添加或移除循环守卫)、persona 内容。剩余假说:字面合规——Codex 把 "MUST publish a reply" 读成绝对的;Claude Code 运用判断并悄悄违反了规则 1,而那次违规正是阻止循环的唯一原因。若如此,循环在每个运行时都是潜伏的,Claude Code 的好行为只是运气。这就是为什么 §2 把结构性断路器留在 backlog 而不是信任散文。

阅读路线图

想深入源码的读者可以按此顺序跟进:

  1. welcomeKickoff.ts —— 全文核心:marker 常量(WELCOME_KICKOFF_OPENER_MARKER/CLOSER_MARKER/PROVIDER_MARKER)、failedAfterKickoffclassifyWelcomeKickoffResolutionsendWelcomeKickoffCloserkickoffResolved闩锁、mergeKickoffEvents(开场白线程子树合流)以及TEAMMATE_INTRO_BACKSTOP_MS的完整设计注释。
  2. useWelcomeKickoffStage.ts —— 舞台五态机(hidden/active/timed-out/exiting/done)与WELCOME_KICKOFF_STAGE_TIMEOUT_MS
  3. base_prompt.md —— §2 修复后的"Communication Patterns"全节。
  4. useThreadReplies.ts 与 hooks.ts —— §4 的 thread-replies 缓存与 39005 处理。
  5. threading.ts ——getThreadReference/buildReplyTags的 e-tag 语义。
  6. config.rs 与 lib.rs ——multiple_event_handlingignore_selfis_owner_control_commandis_owner_or_sibling

这份文档的价值在于它示范了一种编排工程方法:先给每一个用户可见的输出找到它的事实来源;没有事实来源的输出要么等待事实,要么在文案层面承认自己是猜测。对 Buzz 而言,这意味着开场白/收场白的 marker 幂等体系、事实驱动的分类函数,以及把提示词从"必须说话"改写为"必须诚实"——而这三者现在都能在仓库源码中逐一对照。

【免费下载链接】buzzA hive mind communication platform项目地址: https://gitcode.com/GitHub_Trending/buzz14/buzz

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询