第 22 章 第六部分:专题研究

专题:Buddy 宠物系统与工程文化

18 个物种、5 种稀有度、确定性生成——一个隐藏在 Feature Flag 后的完整游戏系统,以及它透露的团队文化信号

Claude Code Buddy ASCII Pet 工程文化 Easter Egg 专题研究

不只是彩蛋

初看 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;同轮 Buddy 0、emotion(词边界)0、buddy_react 0。结论一字未变。

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;同轮 Buddy 0、buddy_react 0、advisor_20260301 2(转义/非转义各 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 补):

  1. 这是一次跨模型外推。该论文的研究对象是 Sonnet 4.5,而 Buddy 的人格生成与气泡评论所调用的模型未必是同一个。本章”Buddy 的 personality 参数可能通过影响这些内部情绪维度来塑造性格”属于跨模型外推,不是论文已验证的结论。
  2. 没有证据表明 Buddy 显式操纵了情绪表征。更合理的解读是,Buddy 的 personality prompt 恰好利用了模型已有的情绪概念结构——即使开发者并未有意识地设计这一点。
  3. 因果效应的具体数值口径目前不统一。二手转述对”激活某个情绪向量后某类失准行为上升多少”给出了不一致的数字(同一实验在不同转述中分别被写成作用于 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 以 xhigh effort 运行其 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.spinnerVerbs missing 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 spinnerVerbs setting 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 生成代码的典型特征——功能正确,但结构不佳。


从宠物系统学到的

  1. 情感连接是产品粘性的合法来源。不要低估”可爱”的产品价值
  2. 确定性设计创造独特性。hash(userId) 比随机 gacha 更能创造”我的宠物是独一无二的”感觉
  3. 轻量交互不干扰工作流。宠物偶尔评论但不打断——这个分寸拿捏得好
  4. Feature Flag 保护实验。BUDDY 功能在代码中完整存在但对外不可见,直到团队决定发布
  1. 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(无告别语,但有记载)。两种移除的记载差异本身或可说明:哪些移除值得一行记载,本身就是官方自己的注意力分配信号(此句为编者观察,仅供参考)。

  1. 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-012026-10-212026-11-08增量(10-21 → 11-08)
coding-buddy ★464463464+1
coding-buddy fork6766660
coding-buddy 开放 issue292938+9
coding-buddy 最后 push2026-07-282026-07-282026-10-28+92 天(单日修复脉冲,见下)
Buddi ★939392−1
Buddi fork1213130
Buddi 开放 issue12—本轮未取
Buddi 最后 push2026-08-222026-08-222026-08-220 天

🔴 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' when ANTHROPIC_BASE_URL points 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 刘海屏实现。