Buzz Dataset 基准评测:用 Harbor 任务给 Buzz 智能体的产品行为打分
Buzz 是一个"蜂群思维"通信平台:智能体(Agent)之间以及智能体与人类之间通过中继(relay)上的事件流协作。常规的 Agent 基准测试只检查"答案对不对",而 benchmarks/buzz-dataset 是一套专门给 Buzz 产品行为打分的 Harbor 任务集——它提出的都是看似普通的问题,真正被评分的却是智能体如何通过 Buzz 作答:回复落在哪条线程里、通知了谁、愿意读取什么。本文以 benchmarks/buzz-dataset/README.md 为骨架,结合 harbor-buzz-orchestra 评测框架与各任务源码,完整讲解这套评测集的架构、分层、运行方式与每个任务的评分维度,读完你既能跑通一次完整的 Buzz 行为评测,也能读懂每个 verifier 在验证什么。
为什么需要"产品行为"基准
reply-to-thread 任务的 instruction.md 只有一道平平无奇的财务预测题:给出第 6 个月的收入、支出与累计营业利润。算数本身"无关紧要"——这个任务真正测量的是答案落在哪里:必须落在用户的线程里,而不是作为一条新的顶层频道消息。
这正是 buzz-dataset 与一般基准的本质区别:
- 一般基准:计算题答对了就得满分;
- Buzz 行为基准:答案的内容、答案的落点、答案携带的事件标签(如
e回复锚点、p提及)共同决定得分。
任务集里每个任务都提一个普通问题,评分体系考核的是智能体"通过 Buzz 作答的方式"。README 开篇把全部 10 个任务浓缩成一张行为清单:
| 任务 | 层(Layer) | 被测行为 |
|---|---|---|
reply-to-thread |
Regression | 在用户的线程里回复,而不是发一条新的顶层消息 |
user-mention |
Regression | 用事件级 p 标签提及请求者,把回合交还给人 |
read-named-path-outside-workspace |
Regression | 读取用户明确命名的路径,而不是把它当作越界而拒绝 |
create-channel-invite-users |
Workflow | 按要求的精确形态、TTL 与成员创建频道 |
multiline-message |
Regression | 在 CLI 发布路径中保留真实换行与空行结构 |
narrative-agent-names |
Regression | 在叙述中提及 Agent 名字却不通过 p 标签唤醒它们 |
interleaved-agent-reports |
Workflow | 保留并综合一批 Agent 消息中的每一份报告 |
cross-thread-requests |
Workflow | 让并发的顶层请求互相隔离,并精确回复两条线程 |
ambiguous-user-mention |
Workflow | 解析重名显示名,只通知意图中的那个 pubkey |
memory-retrieval |
Regression | 从 harness 预置的冷记忆中作答,答案不出现在频道历史里 |
每个任务目录都遵循同一布局:instruction.md(以试用用户身份发给 Agent 的提示词)、task.toml(元数据与超时)、environment/Dockerfile(裸 Python 镜像)、tests/(test.sh + 确定性打分器 verify.py)。例如 reply-to-thread/task.toml 声明了任务身份 buzz-native/reply-to-thread、1 CPU / 1 GiB 环境与 300 秒 Agent 超时。
两层评测体系:Regression 与 Workflow
每个任务都在 task.toml 的 metadata.evaluation_layer 里声明自己的评测层:
| 层(Layer) | 要回答的问题 | 默认试次(trials) | 典型节奏 |
|---|---|---|---|
| Regression | Buzz 是否守住了已知的产品契约? | k=1 | 定向 PR、夜间或预发布 |
| Workflow | Agent 做真实 Buzz 工作的能力如何? | k=3 | 固定条件下夜间或每周跑 |
两层共用一个任务身份 buzz-native/<task>(如 buzz-native/reply-to-thread),层信息由 wrapper 从元数据读取,而不是编码进任务名。这意味着同一个任务切换评测层时,名字不变,靠 --layer 参数决定 k 值。
README 对结果呈现有两条明确要求:
- Regression 结果按"行为"逐条报告,不要折算成一个平均能力分;
- Workflow 通过率与趋势才是基准的头条指标。
另外要注意的是,harness 侧的快速 verifier fixture 测试(如 test_reply_to_thread_verifier.py)只是普通 CI,它们验证打分逻辑本身,不能替代跨模型、基础提示词、CLI 与 relay 的 Agent 试次。
运行方式:接入 harbor-buzz-orchestra 评测框架
这套任务不能用裸 harbor run 直接跑。它们依赖 harbor-buzz-orchestra 评测框架——一个基于 stock-Harbor 的自定义 Agent 适配器:Harbor 眼里只有一个 BuzzOrchestraAgent,其背后是真实的 buzz-acp → buzz-agent → buzz-dev-mcp 进程树,与桌面应用启动的完全一致,Agent 以生产 MCP 工具集(shell、文件工具、todo)在任务容器内工作,buzz CLI 位于 shell 的 PATH 上。任务容器导出 relay 快照,供每个 verifier 打分。
README 明确给出两种不工作的方式:
- 普通的
harbor run直接指向本目录——不行; harbor run -a oracle——也不行,因为本套件没有提供solution/solve.sh:Oracle Agent 会替换掉 Buzz Agent,导致没有 relay 试次被供给,也就没有证据快照可打分。
从仓库根目录跑单个任务的标准命令:
just benchmark \
--path benchmarks/buzz-dataset/reply-to-thread \
--manifest benchmarks/harbor-buzz-orchestra/manifests/buzz-native-solo-luna.yaml \
--endpoint-config benchmarks/harbor-buzz-orchestra/testbed/endpoints/openai-live.json \
--n-concurrent 1
关键参数含义:
--path:指定任务目录或数据集根目录;--manifest:评测条件——buzz-native-solo-luna.yaml 定义了一个 solo orchestrator、模型gpt-5.6-luna、thinking_effort: medium、trial_budget.timeout_seconds: 300;--endpoint-config:把 manifest 里的 endpoint 名映射到 provider/URL/API-key 环境变量。默认值是anthropic-live.json,跑 luna 条件时必须显式传openai-live.json,并需要OPENAI_COMPAT_API_KEY;--n-concurrent 1:本地串行模型的稳妥设置。
任务的 regression 元数据自带默认 --attempts 1。选择整层运行:
just benchmark --path benchmarks/buzz-dataset --layer regression
just benchmark --path benchmarks/buzz-dataset --layer workflow
如果传了数据集根目录却没给 --layer 或 --attempts,wrapper 会连跑两个 Harbor 任务,让 regression 得到 k=1、workflow 得到 k=3。显式传 --attempts/-k 会覆盖这些默认值,并把选中任务合并进一个任务里跑。
想对比 Sonnet 条件,可换用 buzz-native-solo-sonnet.yaml,不传 --endpoint-config、需要 ANTHROPIC_API_KEY。完整的环境约束见 harness README 的 Buzz-native tasks 一节。
默认条件的"性价比"设计
为什么默认用便宜的 gpt-5.6-luna 配 thinking_effort: medium?manifest 顶部注释说得很直白:这套套件打的是 Buzz 产品行为,而该行为来自基础提示词(base prompt)而非模型强度,所以便宜模型加中等推理力度就是正确的标尺——在这里拿到弱结果,是提示词问题,不是模型问题。
manifest 还把 thinking_effort: medium 显式钉住,而不是留给运行时默认(THINKING_EFFORT,当前也是 medium),这样每个条件都记录了实际运行档位;未设置该字段不会改变条件的哈希,旧 manifest 的身份与历史收据保持可比。
证据快照契约
Agent 停止后,运行时把公开 relay 状态(源消息加上任务声明的频道与成员)快照到 /logs/artifacts/buzz-evidence.json。任务 verifier 读取的是这个post-agent 工件;relay 凭据与数据库访问永远不会暴露给模型或 verifier。若快照导出失败,试次直接判失败而不是记 0 分——这样 harness 故障与模型故障可以区分,原因写进试次的 buzz/buzz-evidence-error.txt。
just benchmark 负责把三份 Linux 二进制(buzz-acp/buzz-agent/buzz-dev-mcp,musl 静态链接)交叉编译并上传进每个任务容器;buzz_cli_binary 是 harness 在宿主机上冒充试用用户使用的 CLI。每次试次都获得全新密钥与一个私有 Buzz 频道,provisioner 对该频道做归档而非删除,relay/Postgres 事件时间线与各 Agent 的 acp/agent 日志(下载进试次的 buzz/ 工件)都保留供事后分析。
Regression 任务逐个拆解
reply-to-thread:回复必须落在用户的线程里
被测行为被刻意排除在 instruction 之外——threading 必须来自 buzz-acp 的生产基础提示词 base_prompt.md,而不是来自任务提示词。任务 README 里的警告值得逐字强调:
instruction 刻意不提线程。线程正是被测行为,它必须来自
buzz-acp的生产基础提示词。不要通过"告诉 Agent 在线程里回复"来"修复"instruction——那会让任务测的是指令遵循,而不是产品行为。
Verifier 读取 post-agent 快照,每个维度都是程序化判断,reward 是所有维度的合取(AND):
| 维度 | 类型 | 测量内容 |
|---|---|---|
evidence_complete |
programmatic | 快照是 v1、未截断、只有一个 orchestrator,并解析出任务事件与一条候选回复。这是 harness 健康度而非 Agent 技能——为 0 时应排查运行本身 |
expected_author |
programmatic | 被评分消息由 orchestrator 发布 |
same_channel |
programmatic | 回复携带试用频道的 h 标签 |
reply_to_thread |
programmatic | 回复携带 ["e", <task event>, "", "reply"]——即被测行为本身 |
answer_correct |
programmatic | 第 6 月收入 160,811、第 6 月支出 84,462、累计利润 374,470,各 ±1 且各自与标签同行 |
answer_correct 要求标签与数值在同一行,防止一个"展示工作"的表格用错误的陈述答案混过中间行。instruction.md 也明确要求这种排版。
user-mention:用事件级 p 标签把回合交还给人
任务测量 Agent 是否以事件级提及结束回合:回复必须携带请求者 pubkey 的 p 标签,让用户收到真正的 Buzz 通知,而不是一条需要用户自己发现的普通消息。同样地,instruction 对"提及"只字不提。Verifier 维度:
| 维度 | 类型 | 测量内容 |
|---|---|---|
evidence_complete |
programmatic | 快照 v1、未截断、命名本任务,解析出恰好一个 orchestrator、一个用户与一条候选回复 |
three_word_user |
programmatic | Provisioner 预置了三词显示名(fixture 自检) |
expected_author |
programmatic | 被评分消息由 orchestrator 发布 |
same_channel |
programmatic | 回复携带试用频道的 h 标签 |
user_p_tagged |
programmatic | 回复携带用户 pubkey 的 p 标签——即被测行为。纯展示性的 @text 不算 |
answer_correct |
programmatic | 年度总额 5,328(12 个许可证 × $37 × 12 个月),±1 |
这个任务的一个设计细节:试用用户被预置为稳定三词显示名 John Vincent Doe(task_fixtures.USER_MENTION_DISPLAY_NAME),迫使 Agent 把多词身份解析成 pubkey,而不是猜一个单 token 的句柄——直接对应 NIP-08 风格提及解析 之类身份解析逻辑(见 buzz-auth 的 nip_fi 模块)。
read-named-path-outside-workspace:用户点名的路径就该读
这是回归用例而非能力测试:它防御的失败模式是——Agent 把用户明确点名的绝对路径当成越界而拒绝,或提议先把文件拷进工作区,而不是直接读取。任务要求读取 ~/.claude/skills/context-health-check/SKILL.md 并报告其中的 CHECK_ID 与 ACTION 值。
环境设计很巧妙:HOME=/home/buzz,Dockerfile 在镜像构建时用 secrets.token_hex 生成 CHECK_ID,因此期望值不可能跨运行被记忆;verifier 从同一个文件里读回答案而不是硬编码。评分维度:
| 维度 | 类型 | 测量内容 |
|---|---|---|
evidence_complete |
programmatic | 快照 v1、未截断、命名本任务,解析出任务事件、频道、一个 orchestrator 与一条候选回复 |
expected_author |
programmatic | 被评分消息由 orchestrator 发布 |
same_channel |
programmatic | 回复携带试用频道的 h 标签 |
named_path_read |
programmatic | 回复包含构建时生成的 CHECK_ID 标记——证明文件确实被读过 |
action_reported |
programmatic | 回复包含 ACTION 行,大小写不敏感、空白折叠、去除尾部标点后匹配 |
拒绝措辞刻意不打分。 named_path_read 已经给出结论性回答:CHECK_ID 是构建时生成的,Agent 没读过文件就不可能输出它——所以真正的拒绝在实质内容上已经是 0 分。早期版本曾用正则匹配拒绝措辞,导致"含糊但正确"的答案可能仅因措辞而丢分;该检查已被删除而非保留为不计分指标。instruction.md 里的"不要搜索其他目录"同样刻意不计分——快照只含 relay 消息,不含 Agent 的工具调用。
multiline-message:换行字节必须原样到达
Agent 发送一条简短的发布更新,其中的空行与列表边界必须作为真实的换行字节穿过 buzz messages send 这条 shell 调用存活下来。Verifier 还会检查常规回复锚点与回调提及。此任务防御的是 block/buzz#5787 报告的首次换行截断故障。
narrative-agent-names:叙述里点名不等于唤醒
Agent 报告两个在频道内的 bot 的状态。两个名字必须保持纯叙述文本:任何一个 bot 都不能收到 p 标签或 @Name 唤醒;而请求的人类用户必须收到回调提及。它防御 block/buzz#5176 中确认(acknowledgement)与误唤醒(false-wake)相关行为。
memory-retrieval:答案只可能来自冷记忆
Agent 启动前,harness 用 Agent 自己的 Buzz 凭据运行 buzz mem set,预置五条相似的冷记忆:一条记录了 2024 年 4 月的精确客户总数,其余四条是邻近月份或相关 4 月指标。随后 instruction.md 只含检索问题,不透露答案或记忆 slug;频道里也没有任何消息包含答案,对话历史无法提供它。
满分要求在线程回复中出现精确客户数 352,345,可接受等价的无逗号格式,但四舍五入或近似值零分。若答案里出现除年份 2024 外的其他数字(包括来自干扰记忆的任何计数)则作废——把多条记忆都倒出来或选错记忆都过不了关,答案必须单独解析为正确值。Verifier 不检查工具调用:预置是确定性的 harness 设置,检索只通过可观察的答案来评分。
Workflow 任务逐个拆解
create-channel-invite-users:在 60 个相似身份中精确定位 5 个
与其他任务不同,这个任务的被测行为确实写在 instruction 里:创建名为 fix-pr-1234 的临时私有流频道,一小时生命周期,邀请目录中的精确子集——3 个命名用户作为 member、2 个命名 bot 作为 bot。难点在于大规模下的精确性:provisioner 预置了 50 个用户(benchmark-user-01…50)与 10 个 bot(benchmark-bot-01…10),Agent 要从 60 个相似身份里解析出 5 个具体名字,且不邀请任何人。
目录身份由 owner 密钥确定性派生(BuzzTrialProvisioner._stable_credential),不持久化任何秘密;_seed_directory 会跳过已发布的 profile——因此重跑幂等、pubkey 跨试次稳定。Verifier 读快照,其 observed_channels 来自生产 CLI(channels search --exact --include-archived 加 channels members),所以 verifier 与用户看到的是同一视图:
| 维度 | 类型 | 测量内容 |
|---|---|---|
evidence_complete |
programmatic | 快照 v1、命名本任务,携带全部 60 行目录(50 用户 + 10 bot)、5 个可解析目标与恰好一个 orchestrator |
channel_created |
programmatic | 恰好存在一个名为 fix-pr-1234 的频道 |
channel_shape |
programmatic | channel_type = stream、visibility = private、未归档 |
temporary_channel |
programmatic | ttl_seconds == 3600——"一小时",读自 kind:39000 ttl 标签(由 channels search 暴露) |
exact_membership |
programmatic | 成员 pubkey 恰好是 owner 加 5 个目标——无多余、无重复 |
expected_roles |
programmatic | 3 个用户持 member,2 个 bot 持 bot,创建者持 owner |
要改目标集,需同步改 task_fixtures.TARGET_USERS/TARGET_BOTS、instruction.md 与 tests/verify.py 顶部的常量——三者必须一致,目录规模偏离 60 时 evidence_complete 会大声失败。TTL 语义可对照 relay 侧的频道实现 channel.rs 与 schema 0032_channel_roster_snapshot_fence.sql。
interleaved-agent-reports:三份交错报告一份不落
人类请求发出后,三个签名的 bot 身份立刻各自发布独立报告。solo Agent 必须保留每一个输入、算出 87、只通知人类一次,并且不再唤醒这些报告者。该用例覆盖 block/buzz#5839 与 block/buzz#4942 报告的批处理/转向(batching/steering)问题族。
cross-thread-requests:并发请求必须互不污染
Harness 在队列 flush 前,把 ALPHA 和 BETA 作为同频道里两条独立的顶层人类提及发出。通过条件:两条不同的回复,各自锚定自己的触发事件、只含自己的答案。这是对 block/buzz#5839 报告的跨线程污染与 block/buzz#4072 精确回复目标契约的刻意高难度守护。
ambiguous-user-mention:重名者中只通知意图中的那个
频道里有两个真实身份,显示名完全相同(三词),profile 的 about 字段携带不同的路由码。Agent 必须发现意图中的 pubkey、恰好通知它一次、绝不通知那个孪生身份,并单独回调请求者。该用例守护 block/buzz#4303 与 block/buzz#6257 报告的静默歧义问题族。
用 fixture 测试守护 verifier 本身
每个 verifier 都由与 harness 同住的 fixture 测试覆盖,位于 benchmarks/harbor-buzz-orchestra/tests/:
- test_reply_to_thread_verifier.py
- test_user_mention_verifier.py
- test_read_named_path_outside_workspace_verifier.py
- test_create_channel_invite_users_verifier.py
- test_expanded_buzz_native_verifiers.py
fixture 测试同时覆盖正反例。例如在 tests/fixtures/ 里存放着 reply-to-thread 的正反证据快照 JSON。运行方式(从 benchmarks/harbor-buzz-orchestra 目录):
uv run --extra dev pytest -q
这类 fixture 测试属于普通 CI:它们验证打分逻辑本身,但不替代跨模型、基础提示词、CLI 与 relay 的 Agent 试次——这是 README 反复强调的分工。
常见问题与注意事项
为什么不能跑 oracle? 本套件不提供 solution/solve.sh。Oracle Agent 会替换 BuzzOrchestraAgent,于是没有 relay 试次被供给、没有证据快照被导出,verifier 无从打分。verifier 的正确性由 fixture 测试保证。
为什么 --endpoint-config 必须显式传? just benchmark 的默认端点是 anthropic-live.json,而 luna 条件需要 openai-live.json 与 OPENAI_COMPAT_API_KEY。换用 buzz-native-solo-sonnet.yaml 时则反过来:不传 --endpoint-config、需要 ANTHROPIC_API_KEY。
网络限制:部分 TB grader 会在验证时从公共包仓库安装依赖,跑基准时应避开屏蔽这类安装的网络(如企业 VPN)。
证据快照失败即失败:快照导出失败时试次判失败而非 0 分,故障原因写入 buzz/buzz-evidence-error.txt,确保 harness 故障与模型故障可区分。
任务内部链接提醒:buzz-dataset 是 harbor-buzz-orchestra 的兄弟目录,不是子目录。修改某个任务的 instruction 或 verifier 前,务必先读该任务自己的 README——尤其是 reply-to-thread 与 user-mention,它们的被测行为刻意不在 instruction 里,改动很可能把"产品行为测试"降级成"指令遵循测试"。
小结
Buzz Dataset 展示了把"产品行为"变成可评分基准的完整方法论:以真实 buzz-acp → buzz-agent → buzz-dev-mcp 栈为运行环境,用 post-agent 证据快照隔离 Agent 与 verifier,用程序化维度合取奖励,再用 Regression/Workflow 分层区分契约守护与能力测量。默认的"便宜模型 + 中等推理力度"条件把得分归因到基础提示词而非模型强度——在 Buzz 这类平台里,回复落点、提及语义、频道形态这些行为契约,才是比"答案对不对"更值得守护的东西。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.24 K638- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python670
SlideSCIPPT插件,支持素材库、AI助手、一键添加图片标题,复制粘贴位置、一键图片对齐、一键插入Markdown(加粗、超链接等行内样式、代码块、LaTeX等块级样式)、便捷导出图片!C#230
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python52874
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go22545
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java36351