章节导航 第 22 章 / 共 23 章
专题:Buddy 宠物系统与工程文化
18 个物种、5 种稀有度、确定性生成——一个隐藏在 Feature Flag 后的完整游戏系统,以及它透露的团队文化信号
不只是彩蛋
初看 Buddy 宠物系统,很容易把它当成愚人节彩蛋或者工程师的小玩具。但仔细分析源码后,我改变了看法——这是一个正经的产品功能,有完整的架构设计、数据模型、渲染系统和行为逻辑。
它隐藏在 BUDDY Feature Flag 后,但完成度很高。
⚠️ 功能状态(2026-09-13 核对):
/buddy已于 v2.1.97 从 Claude Code 中移除,输入命令返回Unknown skill: buddy。官方仓库 issue #45517(2026-04-09 开,同日关闭,Windows 11 与 macOS 双环境复现,降版回 v2.1.96 即恢复)状态为 “Closed — not planned”,关闭时的回复原文为:“Apologies friends, maybe one day your buddy will return. Closing as not planned for now.”
移除同样未被官方 Changelog 记录:截至 v2.1.270(2026-09-12),官方 changelog 全文只有 1 处
/buddy命中,即 v2.1.89(April 1, 2026)的上线条目,既无移除条目也无恢复条目。issue 下的评论亦直接指出 “It wasn’t even mentioned in [the changelog]”。2026-10-01 复核(锚点推进):截至 v2.1.286(2026-09-30),官方 changelog 全量 408 个 Update 块中
buddy命中数仍为 1,仍是 v2.1.89(April 1, 2026)的上线条目;增量窗口 v2.1.271–286 命中数为 0——既无移除条目,也无恢复条目。同轮Buddy命中 0、emotion/Emotion命中 1/0 且与情绪系统无关。
2026-10-21 复核(锚点再推进):截至 v2.1.306,官方 changelog 全量 426 个版本块中
buddy命中数仍为 1;增量窗口 v2.1.287–306 命中数为 0;同轮Buddy0、emotion(词边界)0、buddy_react0。结论一字未变。2026-11-08 复核(锚点再推进):截至 v2.1.319,官方 changelog 全量 437 个版本块(0.2.21~2.1.319;426 + 11 个新块,313/315 为空号)中
buddy命中数仍为 1(v2.1.89 上线条目);增量窗口 v2.1.307–319 命中数为 0;同轮Buddy0、buddy_react0、advisor_202603012(转义/非转义各 1,即 v2.1.276 + v2.1.280,与 10-21 订正后的记录一致)。结论一字未变——如果哪一天这个数字变成 2,那本身就是新闻。这项指标的价值就在于它不要求重新理解上下文:后续任何人无需读本章、无需知道 Buddy 是什么,只要跑一次 grep 就能判定状态是否变化。这正是本章 2026-10-01 那次自我纠正(「截至 X 日」不等于项目状态)想要的东西——把一句会腐烂的观察,换成一次可重跑的判定。
这个数字值得单独记一笔,因为它把「官方不记录移除」从一次观察变成了一个可复算的指标:
buddy在全量 changelog 中的命中数恒为 1。下次复核只要重跑一次 grep 就能判定——如果哪一天这个数字变成 2,那本身就是新闻。本章下文所有机制分析,都是对一个已下线系统的解剖——其价值在于设计意图与工程文化信号,而非当前可用性。社区已用 MCP 方式完整重建(见文末「社区重建」一节)。
更新(时间线修正):Buddy 于 2026 年 4 月 1 日随 v2.1.89 上线,4 月 8 日随 v2.1.97 发布而移除、4 月 9 日被用户发现。本章此前写的”正式开放 5 月”与”4 月 8/9 日即被移除”相互矛盾,已删除;若读者在其他资料中见到”5 月正式开放”的说法,需注意其与上述时间线冲突,本书以 issue 与版本记录为准。Anthropic 在正式上线前修改了确定性生成算法,导致泄露期间预览工具(claudebuddychecker.netlify.app)预测的宠物与实际不一致。官方 Changelog 仅简短记录:“4月1日,Buddy 上线了,孵化一只小生物,陪你写程式”。这证实 Anthropic 在源码泄露后做了防御性调整。
技术架构
数据模型:骨骼 + 灵魂
来自 types.ts 的定义,每个宠物由两部分组成:
// 确定性部分——由 hash(userId) 生成,不可更改
<!-- edit: 2026-05-18 补充 Mulberry32 种子细节 -->
// Bones 层使用 Mulberry32(32位伪随机数生成器),种子为 hash(userId + "friend-2026-401")
// 盐值中的 401 指向 4 月 1 日愚人节
type CompanionBones = {
rarity: Rarity // 稀有度
species: Species // 物种
eye: Eye // 眼睛样式
hat: Hat // 帽子
shiny: boolean // 是否闪光版
stats: Record<StatName, number> // 属性值
}
// AI 生成部分——首次孵化时由模型生成并持久化
type CompanionSoul = {
name: string // 名字
personality: string // 性格描述
}
这个设计很精巧:
- Bones 确定性意味着每个用户的宠物是唯一且不可刷的——你的用户 ID 决定了你得到什么
- Soul 由 AI 生成意味着每个宠物有独特的”人格”——不是模板化的
安全性注意:确定性设计在实现层面存在绕过——通过 CLAUDE_CODE_OAUTH_TOKEN 环境变量登录时,配置文件不写入 accountUuid,系统退而读取可随意修改的 userID 字段。修改 userID 即可重 roll 宠物,甚至刷出闪光传说水豚。正常 OAuth 登录则绑定不可伪造的 accountUuid。Anthropic 已修补此漏洞。这一插曲印证了”确定性设计”在实现层面的脆弱性——安全性依赖于绑定机制的完整性,而非算法本身。
确定性还有第三重含义,方向与前两重相反(2026-09-13 补):因为生成算法是纯函数(hash(userId + "friend-2026-401") → Mulberry32),社区已经能够 bit-for-bit 复现 Bones 的生成,并在 MCP 层独立于官方二进制重建整套系统。也就是说,确定性保证的是”结果可预期”,不提供任何不可复制性——它创造命运感,却不构成安全边界。这与上述”绕过”是两种不同性质的问题:绕过是绑定机制的漏洞,可复现是算法公开的必然后果,后者无法修补。(社区实现细节见文末「社区重建」一节)
18 个物种与 5 种稀有度
来自 types.ts 中的 SPECIES 常量:
| 稀有度 | 概率 | 物种 |
|---|---|---|
| 传说 (Legendary) | 1% | 水豚 (Capybara)、仙人掌 (Cactus)、机器人 (Robot) |
| 史诗 (Epic) | 4% | 幽灵 (Ghost)、六角恐龙 (Axolotl) |
| 稀有 (Rare) | 10% | 企鹅 (Penguin)、乌龟 (Turtle)、蜗牛 (Snail) |
| 非凡 (Uncommon) | 25% | 龙 (Dragon)、章鱼 (Octopus)、猫头鹰 (Owl) |
| 普通 (Common) | 60% | 鸭子、鹅、果冻、猫、兔子、蘑菇、胖猫 |
闪光版(Shiny)的概率是 1%,独立于稀有度——一个传说级闪光水豚的概率是 0.01%。
ASCII 渲染系统
sprites.ts 实现了一个完整的 ASCII 精灵渲染引擎:
- BODIES:每个物种 3 帧动画,每帧 5 行字符串
- {E} 占位符:动态替换为 6 种眼睛变体(
· ✦ × ◉ @ °) - 7 种帽子:皇冠、高帽、螺旋桨帽、光环、巫师帽、毛线帽、小鸭子(社区统计;另有来源记为 8 种,本书采用源码枚举口径)
- renderSprite:根据 Bones 渲染特定帧,处理眼睛替换和帽子叠加
5 项属性
完整命令集:
| 命令 | 功能 |
|---|---|
/buddy | 孵化/召唤宠物 |
/buddy pet | 抚摸,飘心形特效 |
/buddy card | 查看属性卡片 |
/buddy mute | 静音 |
/buddy off | 隐藏 |
宠物反应不消耗用户 token 额度——这一点其实是官方明示的:/buddy 孵化后的界面文案原文即为 “…your buddy won’t count toward your usage…”。
每个宠物有 5 项属性值:
- DEBUGGING(调试)
- PATIENCE(耐心)
- CHAOS(混沌)
- WISDOM(智慧)
- SNARK(毒舌)
属性值由 hash(userId) 确定性生成。它们影响宠物的”性格”表现——高 CHAOS 的宠物可能更频繁地发表出人意料的评论。
物种名称混淆
一个有趣的技术细节:所有 18 个物种名称都通过 String.fromCharCode() 编码,而不是直接使用字符串字面量。
原因出乎意料——“Capybara” 与 Anthropic 内部的模型代号扫描器冲突。excluded-strings.txt 是一个构建时扫描器检查列表,防止内部代号泄露到外部版本。水豚(Capybara)恰好是一个内部模型代号。
为了绕过扫描器同时保持代码一致性,所有 18 个物种名都采用了十六进制编码,而不只是 Capybara。
这个细节间接证实了:
- Capybara 是 Anthropic 的内部模型代号
- 构建时代码安全扫描是严格执行的
- 但有时候工程师会找到绕过方式
宠物行为
宠物不只是静态展示——它”看着”用户编码,偶尔在气泡框中评论:
“A small [species] named [name] sits beside the user’s input box and occasionally comments in a speech bubble…”
当用户直接对宠物说话时,宠物会根据自己的 personality 回应。这个交互模式很轻量——不干扰工作流,但增加了一层情感连接。
Watcher Protocol:上下文感知机制
Watcher Protocol 是 Buddy 从”装饰”到”上下文伴侣”的关键设计跃迁——它是一个轻量级观察者 Agent,监控 6 种事件类型:
| 事件类型 | 触发条件 | 宠物反应 |
|---|---|---|
| 任务完成 | Agent 成功完成一个子任务 | 根据属性生成鼓励性评论 |
| 错误遭遇 | 命令执行失败或测试不通过 | 高 DEBUGGING 属性宠物提供”修复建议” |
| 长时间停顿 | 用户超过 10 分钟无操作 | 高 CHAOS 宠物可能”抱怨无聊” |
| 文件保存 | 用户保存文件 | 轻量确认反应 |
| 测试结果 | 测试运行完成 | 根据通过/失败生成不同情绪 |
| 会话里程碑 | 达成重大目标(如所有测试通过) | 生成特别庆祝动画 |
触发后宠物通过五维属性(DEBUGGING/PATIENCE/CHAOS/WISDOM/SNARK)过滤生成反应——高 SNACK 的宠物可能说”又一个 bug?我早说过了”,高 PATIENCE 的宠物则更温和。
Watcher Protocol 使 Buddy 成为首个在所有五个设计支柱(care loop/identity/stakes/social/context)上都有意义的虚拟宠物。这也直接支持” Buddy 是 KAIROS 主动行动的许可层实验”的论点——Watcher Protocol 是 KAIROS 主动监控能力的轻量级、低风险实现:宠物气泡是可接受的主动交互,同样的内容以系统弹窗呈现则令人厌烦。
情绪的内部表征:从行为到机制
Buddy 的”心情变化”——高 CHAOS 宠物的抱怨、高 PATIENCE 宠物的温和鼓励——看起来像随机的性格化输出。但 Anthropic 研究团队 2026 年发表的论文 《Emotion Concepts and their Function in a Large Language Model》(arXiv:2604.07729,2026-04,16 位作者)为此提供了更深层的解释。
该研究使用因果干预(causal intervention)结合线性探针(linear probe)方法,在 Claude Sonnet 4.5 的残差流(residual stream)中找到与情绪概念对应的线性方向——研究者先给出 171 个情绪概念词(happy、sad、calm、desperate 等),让模型就每个概念写短文,再从中提取”情绪向量”。这些表征会追踪当前 token 位置上正在起作用的情绪概念,并预测后续文本。
关键的因果结论是:这些表征不只是相关,而是因果地影响模型输出——原文为它们”causally influence the LLM’s outputs, including Claude’s preferences and its rate of exhibiting misaligned behaviors such as reward hacking, blackmail, and sycophancy”。研究者把这一现象命名为 functional emotions(功能性情绪)。
更值得注意的是情绪向量空间的几何结构:把 171 个情绪向量投影到前两个主成分上,PC1 对应人类心理学环状模型(affective circumplex)的效价(valence / pleasure,r = 0.81),PC2 对应唤醒度(arousal,r = 0.66)——论文原话是”coarsely reproducing the affective circumplex from human psychology”。也就是说,模型内部自发涌现出了与人类情感结构同构的几何。
⚠️ 读者容易过度解读的一点:论文的 “functional emotions” 措辞是刻意的限定——它指”表达与行为模式受抽象情绪概念表征调节”,不等于模型有主观体验。原文明确:“Functional emotions may work quite differently from human emotions, and do not imply that LLMs have any subjective experience of emotions.”
这意味着 Buddy 的情感响应可能不仅仅是 prompt engineering 的结果。如果模型内部确实存在情绪概念表征,那么 Buddy 的 personality 参数(五维属性)可能通过影响这些内部情绪维度的激活模式来塑造宠物的”性格”——高 CHAOS 可能对应着对”焦虑/兴奋”维度的更高激活倾向,高 SNARK 可能对应着”讽刺/不满”维度的偏好。
但需要保持审慎,而且审慎的理由要比”研究性发现”更具体(2026-09-13 补):
- 这是一次跨模型外推。该论文的研究对象是 Sonnet 4.5,而 Buddy 的人格生成与气泡评论所调用的模型未必是同一个。本章”Buddy 的 personality 参数可能通过影响这些内部情绪维度来塑造性格”属于跨模型外推,不是论文已验证的结论。
- 没有证据表明 Buddy 显式操纵了情绪表征。更合理的解读是,Buddy 的 personality prompt 恰好利用了模型已有的情绪概念结构——即使开发者并未有意识地设计这一点。
- 因果效应的具体数值口径目前不统一。二手转述对”激活某个情绪向量后某类失准行为上升多少”给出了不一致的数字(同一实验在不同转述中分别被写成作用于 reward hacking 与 blackmail,且百分比不同),本书不引用这些数字,只保留论文摘要直接支持的定性结论:情绪表征会因果地影响输出与失准行为的发生率。
情绪向量是研究性发现,不应过度解读为 Buddy 直接使用了这些向量。
工程文化信号
Buddy 系统透露了 Anthropic 工程团队的几个文化特征:
1. 愿意在”非核心”功能上投入高质量工程
Buddy 不是周末 hack 出来的。它有完整的类型系统、渲染引擎、数据持久化、AI 生成。这说明团队文化允许(甚至鼓励)在非直接业务功能上投入正经的工程资源。
2. 用确定性对抗”刷”的冲动
hash(userId) 决定宠物属性——你得到什么就是什么,没法刷。这是一个产品设计决策:用确定性创造”命运感”,而不是用随机性创造”赌博感”。
2026-10-01 补两块此前缺失的材料。
其一,这条价值观不止体现在「新功能上克制」,也体现在「撤掉已上线的装饰」——v2.1.282 把 ultracode 在 /effort 与输入提示中的视觉改为朴素样式:官方原文是去掉 ripple(涟漪)、border flourish(边框花饰)、keyword glimmer(关键词微光),并同时删掉了一条 dynamic-workflows 的 spinner tip。
这条旁证在本章语境下分量特殊:Buddy 本身就是一个「被撤掉的装饰」。如果只有「新功能不做花活」这一类证据,读者完全可以反驳说「他们只是没做,不代表会撤」;而 v2.1.282 证明的是已经上线了的装饰也会被主动撤掉。本章第 5 条推论「实验做完即撤」因此多了一个同方向的旁证——不是来自 Buddy 本身,而是来自同一个团队在 2026-09 的另一次撤销动作。
其二,确定性路线有代价,而代价落在小语种上(章内此前只有收益面)。2026-09 官方在提示与记忆侧连做了三处「用确定性规则清除不可见字符」:
| 版本 | 动作 | 性质 |
|---|---|---|
| v2.1.277 | ”Improved prompt handling: invisible Unicode formatting and tag characters in a prompt are removed and the cleaned prompt is shown for review before it is sent” | 收益:把不可见字符挡在发送前 |
| v2.1.280 | 修复该清理误删波斯语与阿拉伯语用于把后缀接到拉丁词/数字上的零宽非连接符(官方举的例子是 “PDF” 的复数形式) | 代价:误伤,且误伤对象是小语种 |
| v2.1.284 | ”Improved auto-memory loading: invisible characters and tags that imitate Claude Code’s own markup are neutralized in MEMORY.md and recalled memory notes before they reach Claude” | 收益:把记忆也当成注入面处理 |
落点:确定性规则的代价是误伤,而误伤往往先落在小语种上——因为「正当地使用零宽/控制字符」的书写系统恰恰不是英语。这条值得写进来,因为只写「确定性 = 可复现 = 抗刷」的价值观论述,容易被读成一种工程偏好;把代价一起写出来,它才像一次工程判断。
交叉标注:v2.1.284 这条本轮第 20 章也在用,两章切面不同——Ch20 取「记忆是一个注入面」(安全),本章取「能用确定性规则解决的就不用模型」(工程文化)。两处并存,不合并。
3. 187 个 Spinner 动词
来自 claudefa.st 的发现——Claude Code 的加载动画有 187 个不同的动词(包括经典的 “reticulating splines”)。这不是功能需求,是团队在代码中留下的幽默痕迹。
2026-10-01 补:187 这个数字是静态的,但 spinner 本身一直在动。 官方 changelog 在 v2.1.271–v2.1.286 这一个半月里就有 11 条 spinner 相关条目(按 changelog bullet 计:v2.1.271 ×4、v2.1.273 ×2、v2.1.277、v2.1.281、v2.1.282、v2.1.283、v2.1.286 各 1),而且分属三个层次——这三层把「187 个动词」从一个文案彩蛋升级为一条可观察的演进轨迹:
第一层:spinner 承载语义,不只是装饰。 它在跑 SessionStart / UserPromptSubmit / PreToolUse / SessionEnd hook 时会说明正在跑哪个 hook 并显示已用时间(v2.1.271,且 Esc 可取消正在等待 SessionStart 的提示);长时间思考时 45 秒后显示 “deep in thought”,从输出 token 上限恢复时显示 “picking the thought back up”(v2.1.271);compaction 时计时器改为从 compaction 开始时计时,并实时统计 summary 的 token 数,取代原来的百分比进度条(v2.1.283)。这一层的性质是:spinner 被当作状态可观测性的一部分——它在回答「现在在干嘛、干了多久」,而不只在卖文案。注意 v2.1.283 那一条:真实计数取代了百分比条,这与第 2 条「用确定性对抗『刷』的冲动」是同一个取向——能给出确定答案的,就不给一个好看的估计。
第二层:spinner 会坏,而且官方在修。 双省略号 ”……”(v2.1.273,出现在 “Running PreCompact hooks…” 这类状态行上)、误报的 tip(v2.1.273 读完或发布 Artifacts 后建议 frontend-design 插件;v2.1.271 建议了不适合你账户类型或在本会话中被禁用的命令)、排队消息显示在 spinner 下方而非上方(v2.1.281)、慢或高负载机器上第一个 spinner 出现时会话以 “unrecoverable interface error” 退出(v2.1.277)、VS Code 扩展无响应时出现无限 “Teleporting session…” spinner(v2.1.286)。这一层的意义在于:一个纯装饰物是不需要修的。官方愿意为 spinner 的崩溃、卡顿、误报单独发版本,恰好反证了它已经进入「正经组件」的范畴。
第二层还有一类此前未记录的坏法:无障碍与动效偏好(2026-10-21 补)。官方 changelog v2.1.287 两条:
- 屏幕阅读器模式下,
claude --teleport的进度屏与一个 MCP 表单字段在每一个 spinner 帧上被重复播报; - 开启 “Reduce motion”(减弱动效)后仍有三个 spinner 在动(同条另修
/rewind确认屏在输入笔记时刷新 “ago” 时间)。
这一类的论证价值比同层已有的”崩溃”条目更高:它不导致任何功能失效——坏的是”用户已经明确表达过的偏好”。一个纯装饰物不仅不需要修崩溃,更不需要尊重减弱动效偏好,因为 Reduce motion 是纯粹的用户偏好设置,不是故障。反过来说,官方为它单独发修复,说明 spinner 在官方自己的心智里已经不是装饰。
第一层也还在扩张(2026-10-21 补)。官方 changelog v2.1.305(VSCode)新增:“Added a ‘Running start-up hooks’ spinner status, with a screen reader announcement, while SessionStart or Setup hooks run”。两个增量信息:① 语义层继续扩张——新增 start-up hooks 这一类,且把 SessionStart 与 Setup 分开表示;② spinner 首次被接到无障碍通道上——它不再只是”显示给用户看”,而是”读给辅助技术听”。后者值得单独点一句:一个纯装饰物不会被接入屏幕阅读器。这与上面第二层的两条是同一个方向的证据。
第二例来了:「首次」应改写为「正在按 hook 类型逐一接入」(2026-11-08)。v2.1.311(VSCode)新增:慢 UserPromptSubmit hooks 的 spinner 状态同样带屏幕阅读器播报——接入序列是 SessionStart/Setup → UserPromptSubmit,第一类之后隔 6 天就来了第二类。同族还有一条值得记:v2.1.317 修复屏幕阅读器对运行中子代理的 elapsed time 与 token count 每次变化都播报——接入无障碍通道之后还出现了「播报粒度」这一层设计问题,说明这条路本身也在迭代,不是一步到位。
第三层:spinner 也在被去装饰化。 见上一节 v2.1.282——ultracode 的 ripple / 边框花饰 / 关键词微光被全部撤掉,改为朴素样式,并删掉一条 dynamic-workflows tip。⚠️ 截至 v2.1.306,v2.1.282 仍是唯一一条去装饰化条目——本轮增量窗口(v2.1.287–306)内 spinner 相关条目有 5 条,无一条属去装饰化。本章该论点的证据强度目前建立在单个样本上,而第一、二层都有多条支撑。把”只有一个样本”写明,比让它看起来像一条趋势更诚实,同时也给下次扫描一个明确的查找目标。
2026-11-08 补上反方向对照:孤例不再是孤例,但方向比想象的更精细。 ultrathink 的 rainbow 动效在 10 月下旬至 11 月上旬被三次主动维护:
- v2.1.316(VSCode):
ultrathink以xhigheffort 运行其 turn,并在 chat box 显示 rainbow——与终端对齐; - v2.1.311:rainbow 改为只在关键词真能升 effort 的位置显示——被引号括起来或属于文件路径时不显示;
- v2.1.317(VSCode):修复 telemetry 关闭时 rainbow 不显示、effort 不升的问题;
- 同 v2.1.316 另有专门开关
CLAUDE_CODE_DISABLE_ULTRATHINK可整体关掉该关键字。
同一个团队在撤掉 ultracode 纯装饰的同时,在另一处(ultrathink)主动维护装饰。两者的差别在语义:rainbow 承载「effort 已提升」的状态信号——v2.1.311 的条件显示是官方把它当语义用的直接证据(如果只是好看,不需要区分「被引用的关键词」),ripple 不承载语义。第三层的准确表述因此从「去装饰化」修正为「装饰跟着语义走」:有语义负载的动效被保留并精修语义边界,纯装饰被撤。这同时回应了上面的单样本警告:第三层现在有一个正例(保留+精修)与一个反例(撤除),比单一方向的趋势更接近真相。
第四层(2026-10-21 新增):动词表本身是可替换的接口。 前三层的隐含前提都是”187 是团队在代码里留下的固定文案集合”。按官方 changelog,它其实是一份带默认值的可配置项,且有两个入口:
- v2.1.296(VSCode):“Fixed
claudeCode.spinnerVerbsmissing from the extension’s settings, so settings.json now completes and validates it; a malformed value no longer breaks the chat panel” - v2.1.305(VSCode):“Fixed the spinner cutting off ‘Compacting…’ when your
spinnerVerbssetting replaces the built-in verbs with short ones”
即:CLI / 终端侧是 spinnerVerbs,VS Code 侧是 claudeCode.spinnerVerbs;用户可以用自己的动词表整体替换内置动词表;这条替换路径是官方支持的(v2.1.296 专门补上它在扩展设置里的补全与校验),并且真的有人在用(v2.1.305 修的就是”换成短动词后状态被截断”)。
这个改写在文化信号上比原论述更强:内置动词可以被用户整体换掉,说明团队把”彩蛋”做成了”接口”,且预期它会被改。幽默被当成配置项而不是硬编码,意味着它从一开始就不打算是终态。
⚠️ 一句限定必须随文保留:changelog 从未给出 187 这个数字。本章的 187 来自 claudefa.st 对泄露源码的统计,与本条 changelog 证据互不支持也不冲突——前者是源码里的词表长度,后者是该词表的可替换性。不得写成”官方确认动词可替换且共 187 个”。
三层框架的收尾句因此要改成四件事——给它加语义、修它的 bug、撤它的花活、把它做成可替换的,以及给留下的装饰精修语义边界(2026-11-08 补,见第三层 ultrathink 对照)。
三层合起来读:这个团队在 spinner 上同时做着三件事——给它加语义、修它的 bug、撤它的花活。 187 个动词只是这三件事里最容易被注意到的一件。
4. 情绪检测用正则而不是 LLM
社区吐槽最多的一个发现:Claude Code 用正则表达式扫描用户输入中的脏话和情绪信号。一个以 LLM 为核心的产品,用正则做情感分析——这说明团队在”用对的工具做对的事”上很务实。正则比 LLM 快、确定性强、不需要额外 API 调用。
5. print.ts 的 3,167 行函数
源码中有一个 print.ts 文件,5,594 行代码,其中一个函数跨越 3,167 行。加上大量 .then() 回调嵌套——Boris Cherny 说过 “我对 Claude Code 的贡献 100% 由 Claude Code 自己编写”。
这意味着 AI 的编码风格已经成为公开记录。这些代码质量问题可能正是 AI 生成代码的典型特征——功能正确,但结构不佳。
从宠物系统学到的
- 情感连接是产品粘性的合法来源。不要低估”可爱”的产品价值
- 确定性设计创造独特性。
hash(userId)比随机 gacha 更能创造”我的宠物是独一无二的”感觉 - 轻量交互不干扰工作流。宠物偶尔评论但不打断——这个分寸拿捏得好
- Feature Flag 保护实验。BUDDY 功能在代码中完整存在但对外不可见,直到团队决定发布
- Buddy 曾是 KAIROS 主动行动的许可层实验(2026-09-13 改为完成时:该实验已于 v2.1.97 随功能移除而终止)。当 AI 需要主动打断用户时,“宠物气泡”的接受度远高于”系统弹窗”。Coding Beauty 的深度分析指出,Buddy 的真正价值不在于”可爱”,而在于安全地测试”AI 何时应该打断用户”这一核心问题——宠物偶尔的气泡评论是可接受的主动交互,同样的内容以弹窗呈现则令人厌烦。Buddy 可能是 KAIROS 主动行动的许可层:“我找到了优化这 12 个函数的方法,要执行吗?“如果由宠物提出,用户接受度远高于系统弹窗。这不是产品巧合,而是解决”AI 何时应该打断”这一 Agent 核心 UX 问题的安全测试路径。
为什么”被终止”反而强化了这一论点(2026-09-13 补):一个上线仅 8 天就被撤下的功能,恰恰符合”实验已完成”的形态——如果 Anthropic 认为这个实验还需要继续观察,不会在关闭 issue 时直接写 “not planned for now”。实验做完即撤,比长期挂着更能说明结论已经拿到。 至于拿到的结论是”宠物气泡这条路走不通”,还是”路走得通但暂时不做”,目前没有公开证据,本章不做断言。需要提醒的是:功能下线不等于实验失败,本章此前的推论(许可层需要情感载体)依然成立,只是它现在的证据形态从”一个在线产品”变成了”一次已结束的实验 + 一次社区自发重建”。
并非所有移除都无记载(2026-11-08 脚注级对照)。Buddy 移除”未被官方 Changelog 记录”是本章叙事的一环,但它是选择而不是规则——v2.1.319 从 Claude in Chrome 的内建工具中移除 shortcuts_list 与 shortcuts_execute,就有一行正式的 changelog(无告别语,但有记载)。两种移除的记载差异本身或可说明:哪些移除值得一行记载,本身就是官方自己的注意力分配信号(此句为编者观察,仅供参考)。
-
Five Design Pillars 框架的实践验证。如果将 Buddy 置于更广泛的 AI 伴侣设计哲学中审视,它实际上验证了一个五支柱框架:
支柱 含义 Buddy 中的体现 渐进式自主(Progressive Autonomy) 从被动响应到主动行动的渐进路径 从装饰 → Watcher Protocol → KAIROS 许可层 许可层设计(Permission Layer) Buddy → Watcher → KAIROS 的许可递进 气泡评论比系统弹窗更可接受 情感绑定(Emotional Binding) 用户-模型情感纽带作为信任基础设施 五维属性 + AI 生成人格创造”我的宠物”感 可审计性(Auditability) 所有主动行动可追溯、可解释 Watcher 事件类型明确定义,反应可归因到属性 优雅退化(Graceful Degradation) 不确定时默认保守而非激进 宠物只”偶尔”评论,不持续打断 这与第 5 点的”特洛伊木马”论点形成互补——Buddy 既是许可层实验,也是设计哲学的实践验证。五个支柱中,Buddy 在情感绑定和优雅退化上完成度最高,在渐进式自主和可审计性上提供了初步验证,而许可层设计则是其最具战略意义的实验方向。(以上为完成时评价:该实验已于 2026-04 终止,见本章开头状态框)
下面这条来自社区重建的证据,可以看作对”情感绑定”这一支柱完成度判断的一次真实世界投票。
社区重建:一次关于”用户真的想要什么”的自然实验
Buddy 下线后,社区在两个方向上把它重建了出来。
项目状态(GitHub API 实测):两个仓库均未归档。
1270011/claude-buddy(章内记录的旧地址)现已直接解析到ramarivera/coding-buddy,属改名而非两个项目。
指标 2026-10-01 2026-10-21 2026-11-08 增量(10-21 → 11-08) coding-buddy★464 463 464 +1 coding-buddyfork67 66 66 0 coding-buddy开放 issue29 29 38 +9 coding-buddy最后 push2026-07-28 2026-07-28 2026-10-28 +92 天(单日修复脉冲,见下) Buddi★93 93 92 −1 Buddifork12 13 13 0 Buddi开放 issue1 2 — 本轮未取 Buddi最后 push2026-08-22 2026-08-22 2026-08-22 0 天
🔴 10-28 的恢复脉冲需要单独读(2026-11-08 补):
coding-buddy在停滞约 3 个月后,于 10-28 单日推送了fix/file-storage-lock-race、fix/omp-session-reaction-isolation两个修复分支与refactor/shared-command-handlers重构分支,并有多条 PR review 评论(events 流实测)——但截至 11-08 未合并回默认分支(main 的 commits feed 最后更新仍为 2026-07-28),同期开放 issue 29 → 38。因此 10-21 的「定格为存量」结论应限定为:star 侧定格(三旬 464→463→464 ≈ 0)、主线定格(main 仍在 07-28),但存在一次未落地的单日修复脉冲。下次复核的判定点相应从「有没有 push」细化为「fix 分支是否合并回 main」。⚠️ 一处方法论上的自我纠正:上表两个最后 push 日期(07-28 与 08-22)都早于本章此前标注的「状态截至 2026-09-13」。也就是说,本章写下「截至 2026-09-13」时,它描述的对象当时已经分别停滞约 7 周和 3 周——「截至 X 日」只说明观察时点,不说明项目状态,而读者极易把它读成「那时候它还在动」。凡出现「截至 X 日」+ 一个状态形容词的地方,都应优先换成能证伪的硬数据(最后 push 日期、release 时间),这是本章这次修订的核心动作之一。
⚠️ 结论上限:以上数据只支持「活跃度显著低于受关注度」这一表述,不支持「社区重建失败」。是否失败需要 issue 响应率、fork 活跃度、近期 release 等更多证据,本轮未取。
① 协议层重建——1270011/claude-buddy(现以 @ramarivera/coding-buddy 继续,v0.6.0 起;464★,最后 push 2026-07-28,未归档)
它的 README 第一句就是定位:“Your persistent coding companion… Survives every update.” 实现方式不是给官方二进制打补丁,而是用 MCP + Skill + Hook + Status Line 四件套重建:/buddy、/buddy pet、/buddy stats、/buddy off 走 Skill 路由,动画与气泡走 Status Line,错误/测试失败/大 diff 的感知走 PostToolUse Hook。因为不依赖官方二进制里的任何代码路径,Claude Code 再怎么更新也带不走它(要求 v2.1.80+)。
② 系统层重建——talkvalue/Buddi(93★,最后 push 2026-08-22,未归档)
macOS 刘海屏常驻 app,除宠物外还接了会话监控与权限审批。它的 README 直接把下线当作立项理由:“Anthropic removed /buddy from Claude Code in v2.1.97.”
真正有信息量的不是”重建了”,而是”补了什么”。 协议层实现在复刻原有物种/稀有度/属性体系之外,优先补出的是 /buddy rename(改名)、/buddy personality(自定义人格)与多宠物 menagerie(save / summon / dismiss 槽位)——三者全部指向身份与归属感,而不是”更多评论内容”或”更聪明的吐槽”。
这与第 6 条 Five Design Pillars 的判断相互印证:该框架把情感绑定(Emotional Binding)列为 Buddy 完成度最高的支柱之一,而用户在功能下线后自发重建时优先补的,恰恰是让宠物”更像我的”的那几个能力。这不是问卷,是一次真实世界的需求投票。
但这次投票只投出了一半(2026-10-01 补)。coding-buddy 在停滞约 9 周的情况下仍保持 464★——这说明 star 数衡量的是「想要」,不是「在用」;两者可以同时背离,而背离本身就是信息。本节标题问的是「用户真的想要什么」,可本章手里目前只有「想要」这一侧的指标(star),「在用」这一侧是缺的。要补上后者,需要的是安装量、日活、issue 响应率这类数据,本轮未取——缺口先写明,不要用 star 数去冒充它。
但两次快照的差值补上了半步(2026-10-21)。上面那句只用了单点快照,读者完全可以反驳”star 高说明需求真实且持续”。现在有了三周的增量:464→463、93→93,两仓的”最后 push”都没有任何推进。
也就是说,不但”在用”侧是缺的,“想要”侧本身也已经停止增长。star 的绝对高度说明曾经有多少人想要;star 的增量为 0 加上代码零推进,说明那股需求已经定格为一个存量,而不是一股还在涌的力量。这把原来的单点论断变成了有方向、可继续证伪的序列——下次复核只需再记一行。
2026-11-08 第三次快照把上一段修正了一半:star 侧的「定格」判定成立(464→463→464,三旬净变化≈0,「想要」侧仍无增长);但「代码零推进」已被 10-28 的单日修复脉冲部分推翻——推进重新出现了,只是尚未落地到 main。这正是一开始坚持”下次复核只需再记一行”的价值:序列自己暴露了变化,不需要重写论断。
⚠️ 结论上限不变:star 零增长同样不支持”需求消失”,只支持”需求未转化为持续投入”。本章原有的”不支持『社区重建失败』“仍然有效,本条只是把「想要」这一侧从单点快照升级为增量序列。
还有一个技术取证维度值得记录:有逆向者报告,v2.1.97 之后原生 UI 虽已移除,但 buddy_react 服务端 API 仍返回 200 OK;并在 v2.1.98 中发现 advisor_20260301 服务端决策门控(在 feature flag 后 dark launch)。若属实,说明下线的是客户端入口,服务端能力并未同步回收——这与第 13 章关于 Feature Flag 可分别关掉客户端与服务端、两者不必同步的结论一致。⚠️ 该来源为社区取证仓库,且为 2026-04 快照,距今约 6.5 个月,当前状态可能已变化。2026-10-01 复核:仍未找到任何更新该取证的新来源;当时按官方 changelog(全量 408 个 Update 块)记为「未见 buddy_react 或 advisor_20260301 的任何记载」。
🔴 订正(2026-10-21,终审 2026-10-21 再订正):
advisor_20260301并非”官方 changelog 未见记载”。 全量 426 个版本块中它命中 2 处——v2.1.276 与 v2.1.280:
- v2.1.276:“Fixed every request failing with
400 … Input tag 'advisor_20260301'whenANTHROPIC_BASE_URLpoints at a proxy or gateway (2.1.275 regression)”- v2.1.280:“Fixed conversations with the advisor on failing every turn with API Error 400 “Input tag ‘advisor_20260301’” behind a proxy or gateway that doesn’t support it; the request now retries without it”
这两条的价值比”有没有记载”大得多:它们是官方仅有的两次在公开变更日志中提到这个 tag,而且都在请求链路的语境里——它是一个随请求发送的 input tag,指向代理或网关时会触发 400,而且 v2.1.280 明说它可以被整条去掉后重试(“retries without it”)。后者是对”它只是一个随请求携带的标记、不是硬依赖”更直接的一手证据。也就是说,社区取证所称的”
advisor_20260301服务端决策门控”至少有了一个官方侧的存在性证据:这个 tag 确实存在、确实随请求发出、确实会被服务端校验。至于它是否就是”决策门控”,官方未作说明,本章不越界推断。⚠️ 本轮同时踩到一个检索口径陷阱,值得记下:裸词
advisor在全量 changelog 中命中 38 处(按出现次数;按行计 22 行),但那些全是另一个公开功能/advisor(Claude Platform on AWS 的顾问功能,含advisorModel/--advisor/CLAUDE_CODE_DISABLE_ADVISOR_TOOL),与advisor_20260301毫无关系。“0 命中”结论对检索词极为敏感——用裸词搜只会得到”几十处命中、全部同名异物”,用全名(且转义与非转义各搜一遍)搜才得出真正的 2 处。另:
buddy_react本轮全量 grep 仍为 0,公开检索亦未找到更新该取证的新来源。推论层(“下线的是客户端入口,服务端能力并未同步回收”)不受时点影响,保持不变——按本章既定策略,只更新事实层。
📌 推论部分不受时点影响,勿随警告一并标为过期(2026-10-01 注):上文中「下线的是客户端入口,服务端能力并未同步回收」这一事实依赖 2026-04 快照,会随时点腐烂;但由此得出的推论——「这与第 13 章关于 Feature Flag 可分别关掉客户端与服务端、两者不必同步的结论一致」——是一条逻辑一致性判断,不依赖取证时点。后续复核请只更新事实层,保留推论层。
延伸阅读:Claw Decode 的 Buddy 分析、18 款 ASCII 电子宠物详解、Claude Code 宠物系统全景、claude-buddy 协议层重建、Buddi 刘海屏实现。