Buzz 的 Agent 活动流(Activity Feed)设计:以「动词-对象-结果」为骨架构建可监督、可信任的代理协作界面
【免费下载链接】buzzA hive mind communication platform项目地址: https://gitcode.com/GitHub_Trending/buzz14/buzz
导读
本文将系统拆解 Buzz(A hive mind communication platform)中「Agent Activity Feed」这一核心功能的设计愿景与落地实现。它解决的是所有代理协作场景的共同痛点:当你把工作委托给一个 Agent 时,你信任的是一个看不见的过程——活动流就是通向这个过程的窗口。读完本文,你将掌握:活动流如何用「动词-对象-结果」三要素将原始事件流转化为一眼可读的监督界面;十二种渲染分类(render class)如何划分信息的阅读频率与后果权重;以及该设计在桌面端代码中如何以分类器、分组器与渲染器三层管线实现。文中所有实现细节均以当前仓库源码与测试为依据,可对照验证。
一、问题背景:为什么原始 IO 转储不是窗口
When you delegate work to an agent, you are trusting a process you cannot see. The activity feed is the window into that process — but a window is only useful if you can read it at a glance.
把工作委托给 Agent,本质是信任一个不可见的过程。活动流是这个过程的窗口,但窗口只有在可以一眼读懂时才有价值。原始输入/输出转储(raw input/output dump)不是窗口,而是需要解码的转录稿(transcript)——它强迫你先parse(解析)再judge(判断),这在监督场景中是致命的延迟。
该愿景在 VISION_ACTIVITY.md 中给出的目标是:让开发者像监督一名得力队友一样监督代理——扫一眼看进度、信任常规操作、只捕捉需要自己的那一件事,而不必逐行阅读。
这个理念在桌面端代码中体现为对「原始事件」与「语义卡片」的刻意分层:原始 ACP 帧(raw_json_rpc)会被归入 metadata 噪声门,正常叙事流中不渲染,只有按需进入 raw rail(见下文)。从源码结构看,桌面端由ObserverEvent(agentSessionTypes.ts)承载来自 relay 的原始事件,再由转录构建管线转换成语义化条目。
二、服务对象与三大问题:理解、信心、控制
活动流服务于监督委托方的开发者。他不是为了娱乐而观看,而是在决定是否介入。因此,feed 中的每一项都必须通过回答以下三个问题来赢得它占据的像素:
- Comprehension(理解)—— 它在做什么,为什么?
- Confidence(信心)—— 进展顺利,还是卡住或出错了?
- Control(控制)—— 我需要介入吗,从哪里介入?
能即时回答这三个问题的 feed,能把事件流转化为轨迹感(trajectory);回答不了的 feed,只是带滚动条的噪声(noise with a scrollbar)。
在实现层,AgentActivityTone("read" | "write" | "admin" | "neutral",见 agentSessionTypes.ts)正是为回答「信心/控制」问题而设计的维度:写操作与管理操作被赋予更响亮的呈现,读操作则安静地退居次席。
三、统摄框架:动词-对象-结果(Verb, Object, Outcome)
活动流中每个有意义的条目都是一句话:agent 对 [对象] 做了 [动词] → [结果]。
"Sent a message to #design." · "Edited
runtime.rs(+12/−3)." · "Reacted 👍 to Marge's review." · "Ran tests → 1248 passed."
feed 的职责是第一时间呈现动词、对象、结果,并把支撑细节——完整参数、原始输出、完整 diff——推入渐进式披露(progressive disclosure)。你读句子;只有句子让你想看时,才展开。
这一框架在代码中有直接对应物:AgentActivityAction类型({ verb: string; object?: string | null },见 agentSessionTypes.ts)与AgentActivityDescriptor中的label、preview、action、object字段。而分类器负责从工具调用中提取动词:
buzzOperationVerb把操作映射为规范动词:add→Added、create→Created、delete→Deleted、get/list/members→Read、send→Sent、search→Searched等(agentSessionToolClassifier.ts);buzzOperationObject把操作名还原为可读对象(如messages→ "message"),从而拼出 "Sent message to #design" 这类句子(同文件 L433-L444)。
四、十二种渲染分类(Render Classes):完整的事件分类学
每个事件最终都解析为十二种呈现类别之一,按被阅读的频率与承载后果的大小组织:
4.1 脊柱层(The spine)—— 常读常新
| 类别 | 含义 |
|---|---|
| Message | Agent 的声音(对外发言) |
| Buzz relay op | 在平台上的实际操作 |
| File-edit | 真正的代码工作 |
| Shell command | Agent 的双手 |
| Tool status & turn lifecycle | 心跳(回合生命周期) |
如果这五类不清楚,feed 就是失败的。
4.2 高价值上下文(High-value context)—— 用于判断正确性
| 类别 | 含义 |
|---|---|
| Thought | 推理过程,随取随用 |
| Plan/Todo | 路线图与进度条 |
| Permission | 控制闸门 |
| Error | 停止标志 |
4.3 环境安全网(Ambient safety net)—— 很少读,但必须存在
| 类别 | 含义 |
|---|---|
| Generic tool | 诚实的兜底呈现 |
| Raw rail | 按需取用的地面真相(ground truth) |
| Suppressed noise | 我们刻意不渲染的内容 |
关键论断:这不是愿望清单,而是完整的分类学——Agent 能发出的每个事件恰好落入其中一个类别,而最后三类保证了永远存在「地板」。
代码侧完全印证了这一「穷尽性」承诺:AgentActivityRenderClass在 agentSessionTypes.ts 中定义为 15 个值的联合类型(message、relay-op、file-edit、file-read、skill-read、image、shell、status、thought、plan、permission、error、generic、raw-rail、suppressed——其中读类在实现中被细分为 file-read / skill-read / image 三类,对应文档十二类的读操作家族),而路由表 TranscriptActivityItem.tsx 用satisfies Record<AgentActivityRenderClass, ActivityRenderClassPresenter>声明了从每个渲染类到呈现组件的穷尽映射——TypeScript 会在新增渲染类时强制补齐对应组件,从编译期保证了「每个事件都有归属」。
五、九条设计原则与源码印证
5.1 语义优先于传输(Semantics over transport)
渲染agent 做了什么,而不是它用了哪个 API。通过 MCP 工具发送的消息与通过 shellbuzz命令发送的消息,渲染为完全相同的卡片。Agent 如何到达 relay 是管道细节;做了什么才是契约。
代码印证:AgentActivityDescriptor.source("mcp" | "shell" | "acp" | "harness" | "fallback")只用于调试标注,不决定渲染类别。分类器classifyBuzzTool与parseBuzzCliCommand殊途同归——前者识别 MCP 工具名(如send_message),后者解析 shell 命令 token(如buzz messages send ...),两者都产出renderClass: "message"(agentSessionToolClassifier.ts),证明「同一语义、同一卡片」在实现层成立。
5.2 结果优先(Outcome-first)
以成功、失败或结果开头。读者在一秒内决定是否展开。原始转储是兜底,绝不是标题。
代码印证:classifyTool在识别出语义类别后,一旦isError为真,立即把渲染类升级为error并给标签追加 "failed"(agentSessionToolClassifier.ts)——失败永远占据最响亮的呈现位置。
5.3 原地更新(Mutate in place)
正在执行的动作在其自身行内从 pending → executing → done/failed 更新。一个动作就是一个条目,而不是一串重复的状态行副本。
代码印证:ToolStatus = "executing" | "completed" | "failed" | "pending"(agentSessionTypes.ts)与TranscriptItem的startedAt/completedAt字段,均为单条目多状态模型服务。
5.4 永不失明(Never go dark)
事件的缺席本身也是信息。Silence、idle、timeout 是被渲染的状态——"waiting…"、"timed out"——而不是空洞。这镜像了项目对 Agent 的规则:如果你没展示它,它就没发生(if you didn't show it, it didn't happen)。
5.5 失败上扬、阅读退后(Failures rise; reads recede)
显著性(salience)跟随后果。管理操作、写入、错误是响亮的;读取和推理是安静的。被埋没的错误就是坏掉的 feed。
代码印证:AgentActivityTone的 read/write/admin 三分法直接驱动显著性;buzzCliTone依据动词组判定音调(BUZZ_CLI_ADMIN_VERBS→ admin、BUZZ_CLI_READ_VERBS→ read,见 agentSessionToolClassifier.ts 与 L446-L451)。
5.6 解析引用(Resolve references)
展示 "#design"、"Marge's message"、文件名——绝不是一个原始 event id 或 pubkey。读者用名字思考,不用哈希。
5.7 合并流(Coalesce streams)
分块的文本合并为一个条目。开发者读的是消息,不是包追踪(packet trace)。
代码印证:这是实现中最精细的部分之一。agentSessionTranscriptGrouping.ts 实现两遍工具分组:
- 第一遍(same-kind):把同
groupKey的连续运行折叠成带具体标签的摘要——"Read 3 files"、"Edited 2 files"、"Ran 4 commands"(sameKindLabel,L365-L380); - 第二遍(mixed burst):把不同种类交错的常规工具工作折叠成 "Ran N tool calls" 摘要,并且容忍交错(search → read-summary → search → read-summary 可合并为一行监督记录);
- 关键边界:消息、权限、错误/失败工具、status/suppressed 行永不参与分组,且会打断 run——保证介入点始终可见(
isGroupingEligible,L351-L357)。这与 5.5「错误不能被埋没」互为表里。
5.8 诚实胜过猜测(Honesty over guessing)
被识别的操作得到语义卡片;未被识别的则降级为干净、真实、通用的行。绝不为了显得更丰富而编造语义。
代码印证:分类器按「load_skill → developer harness tool → buzz tool」三级providers链尝试(agentSessionToolClassifier.ts),全部未命中时落入genericDescriptor,渲染类为generic、label 为 "Ran tool"、source 标记为"fallback"——诚实兜底被显式建模。
5.9 默认打磨、按需原始(Polished by default, raw on demand)
策展(curation)是产品本身;raw rail 是安全网。二者之间的切换是同一真相的不同缩放级别,而不是两个不同的 feed。
代码印证:RawRailActivity组件把 metadata 条目渲染为可折叠的 section 列表,raw_json_rpc原始负载默认收进<details>折叠区,点击才展开<pre>原始文本(RawRailActivity.tsx);同时该渲染类的专属渲染测试覆盖了原始载荷路径(RawRailActivity.render.test.mjs)。
六、噪声门与「脊柱」识别:让信号可读的隐藏机制
「决定不显示什么」与「决定显示什么」同样重要。实现中有两层噪声治理:
- 噪声门(noise gate):
isMeaningfulItem过滤掉被抑制的工具行(renderClass === "suppressed")、生命周期噪声("turn started"、"session ready"、"wire parse error")以及原始 JSON-RPC 帧(raw_json_rpc),见 agentSessionTranscriptPresentation.ts; - 脊柱识别(spine detection):
isSpineItem判定哪些条目是「脊柱工作」(工具、消息、思考、计划、有意义的生命周期事件),metadata(系统提示、提示上下文)属于应退后的阅读类;BotActivityBar 用它做两档标题扫描——先收集脊柱标题,找不到时再回退包含 metadata,避免会话开始/空闲时栏为空(L86-L100)。
SuppressedActivity渲染器则负责把「刻意不渲染」的内容以最小化行呈现:只显示动词-对象与耗时(SuppressedActivity.tsx)。典型例子是开发 harness 的stop_hook("Checked todos")——它是心跳级动作,展示语义但占据最少像素(agentSessionToolClassifier.ts)。
七、会话边界与回合组织:长时监督的秩序感
feed 需要处理多会话、多回合的长时运行。buildTranscriptDisplayBlocks负责把扁平、按时间排序的条目流组织成展示块(agentSessionTranscriptGrouping.ts):
- 会话边界(session-boundary):当条目跨越多个会话(归档历史 + 实时会话)时,在连续会话运行之间注入分隔块,并区分三种标签状态:
"current"(最新可见且匹配 relay 实时会话)、"most-recent"(最新可见但会话已结束)、"earlier"(更早的会话)——让「当前上下文」与「历史」永远清晰; - 回合分组(turn bucket):同一
turnId的条目聚合为一个回合块,回合内再细分 prompt(用户提示 + 上下文 + setup 生命周期)、活动段与摘要段; - 边界键稳定性:会话边界块的 React key 使用
firstItemId(对前置插入稳定)而非runIndex,避免归档页加载更早会话时引起边界节点不必要的重挂载(L754-L764)。
这些机制共同构成「永不丢失」的保证:restart 时session/new标记会暂时驻留缓冲,直到新会话解析后重新锚定;流在重启中途结束时则把缓冲刷回当前会话——任何条目都不会被静默丢弃。
八、这一设计换来了什么:赢得委托(Earning Delegation)
活动流真正的工作是赢得委托(earn delegation)。可见的进度、可见的同意、可见的结果是复合增长的:每一次你看到回合顺利进行的观察,都让你更信任 agent 去承担更大的回合。决定不显示什么——抑制心跳与内部闲谈——与决定显示什么一样是功能,因为抑制正是让信号可读的原因。
这一 feed 在基础上是协议诚实(protocol-honest)的:任何符合规范的 agent 的消息、思考、工具调用、回合都会成为一等公民条目,无论它运行的是什么工具。而 Buzz 专属的丰富层——语义 relay 卡片、buzz-CLI 解析器、diff 渲染——是其上的一层增强,而非其下的硬性要求。非 Buzz 代理获得正确、可读的 feed;Buzz 代理获得原生(native)的 feed。
同一真相的两个高度:打磨版供判断,原始版供调试。窗口始终是窗口。
这句话在代码中的落点是:TranscriptActivityItem用一张穷尽的路由表在同一个 DOM 流里渲染所有呈现类(TranscriptActivityItem.tsx),而RawRailActivity在同一流中以折叠姿态存在——两者不是两个 feed,而是同一个真相的两种缩放。
九、延伸阅读
- 愿景文档:VISION_ACTIVITY.md
- 渲染类路由与穷尽映射:desktop/src/features/agents/ui/activityRenderClasses/TranscriptActivityItem.tsx
- 类型定义(渲染类、音调、动作、条目联合类型):desktop/src/features/agents/ui/agentSessionTypes.ts
- 工具分类器(Buzz MCP 工具 / buzz CLI 解析 / 兜底):desktop/src/features/agents/ui/agentSessionToolClassifier.ts
- 流合并与两遍分组、会话边界:desktop/src/features/agents/ui/agentSessionTranscriptGrouping.ts
- 标题生成与噪声门:desktop/src/features/agents/ui/agentSessionTranscriptPresentation.ts
- 十二类呈现组件目录:desktop/src/features/agents/ui/activityRenderClasses/
- 相关测试:渲染路由与分组行为见 agentSessionTranscriptGrouping.test.mjs、agentSessionTranscriptPresentation.test.mjs、RawRailActivity.render.test.mjs
【免费下载链接】buzzA hive mind communication platform项目地址: https://gitcode.com/GitHub_Trending/buzz14/buzz
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考