Claude Code 藏了个电子宠物系统,18种物种还能抽卡

产品更新

Anthropic 在 Claude Code 里埋了个完整的虚拟宠物系统,输入 /buddy 就能孵化专属宠物。18种物种、五维属性、1%传说掉率,程序员的终端从此不孤单。

Claude Code 藏了个电子宠物系统,18种物种还能抽卡

Anthropic 在 Claude Code v2.1.89 里塞了个谁都没想到的东西——一个完整的电子宠物系统。输入 /buddy,你的终端里就会蹦出一只 ASCII 小动物,蹲在输入框旁边陪你写代码。

这事儿的曝光方式也很戏剧化。3月31日,安全研究员 Chaofan Shou 发现 Claude Code 的 npm 包里多了一个 59.8MB 的 sourcemap 文件——这玩意本该在发布时删掉,结果把 Anthropic 这款 AI 编程工具的全部源码暴露在了互联网上。51 万行代码,1900 个文件,一览无余。

泄露本身已经够炸裂了。但真正让技术社区沸腾的,是大家在代码里翻到了一个叫 buddy/ 的目录,注释写着 "Companion sprite (Easter egg)",盐值是 friend-2026-401——明摆着是给愚人节准备的彩蛋。

这不是随手写的玩具

翻过源码的人都有同一个反应:这玩意做得也太认真了。

一共 18 种宠物物种:鸭子、鹅、猫、龙、章鱼、猫头鹰、企鹅、树懒、乌龟、蜗牛、水豚、仙人掌、机器人、兔子、蘑菇、幽灵……画风非常混搭,但每一种都有自己独特的 ASCII 动画效果。你写代码的时候它就蹲在终端输入框旁边晃悠,偶尔用气泡框冒一句话——可能是鼓励你,也可能是吐槽你的代码。

稀有度分五档,概率分布跟手游抽卡一个套路:

  • Common(普通):60% — 大部分人的命运
  • Uncommon(稀有):25% — 稍微有点运气
  • Rare(珍贵):10% — 小欧洲人
  • Epic(史诗):4% — 可以截图发朋友圈了
  • Legendary(传说):1% — 天选之子

另外还有独立的 1% 闪光(Shiny)概率,跟宝可梦的闪光精灵一个思路。闪光和稀有度是独立判定的,也就是说理论上存在"传说级闪光"——概率是万分之一。

宠物属性系统

你的宠物,出生那刻就定了

最让"强度党"崩溃的设计来了:你的宠物是确定性生成的,没有重抽机制。

src/buddy/companion.ts 里可以看到完整的生成逻辑:

const SALT = 'friend-2026-401'

export function roll(userId: string): Roll {
  const key = userId + SALT
  // hash → Mulberry32 PRNG seed → 确定性 roll
  const value = rollFrom(mulberry32(hashString(key)))
  return value
}

你的账户 ID 加上固定盐值,经过哈希生成 Mulberry32 伪随机数种子,然后按严格固定的顺序依次抽取:稀有度 → 物种 → 眼睛 → 帽子 → 闪光 → 属性。同一个用户 ID,不管在哪台电脑、哪个时区、重装多少次 Claude Code,出来的永远是同一只。

这个设计很聪明——宠物的"外观骨架"(Bones)不存储在任何配置文件里,每次都从 userID 实时计算。所以你改本地配置伪造稀有度?没用,bones 每次重算。想换宠物?只能换 userID。

有个细节特别有意思:开发者用 String.fromCharCode() 对宠物名字做了编码混淆。为什么?怕被 Anthropic 内部的代码扫描器发现他们在一个严肃的命令行工具里偷偷养了只电子宠物。这帮人是真的在"地下工作"。

社区的反应:暴力破解传说级宠物

程序员嘛,遇到概率问题第一反应就是用算力解决。

泄露代码公开后不到 24 小时,就有人写了暴力搜索工具。思路很直接:既然 userID 决定一切,那遍历 64 位十六进制空间找最优解就好了。

第一版用 Python 写,跑了 60 秒找到了 legendary + shiny 的组合——但结果不对。原因是 Claude Code 运行在 Bun 上,hash 函数走的是 Bun.hash()(Wyhash 算法),不是源码注释里写的 FNV-1a 回退。Hash 算法错了,后面全错。

第二版直接用 Bun 原生运行时重写,跑到了 190 万 userID/秒,55 秒扫完 1 亿个 ID。还踩了一个坑:PRNG 是严格顺序消耗的,属性抽取顺序必须与源码完全一致:

✗ 错误:rarity → stats → species → eye → hat → shiny(stats 提前了)
✓ 正确:rarity → species → eye → hat → shiny → stats(与源码一致)

stats 提前消耗了 rng 调用,导致所有后续属性偏移——结果是稀有度对了,但物种和属性全错。这种 bug 不看源码根本发现不了。

最终有人做了个交互式工具 find-best-buddy:选物种、选稀有度、选闪光,自动搜索匹配的 userID。程序员的浪漫,大概就是用算力解决玄学。

五维属性:调试、耐心、混沌、智慧、毒舌

每只宠物有五个属性维度,从命名就能看出这是给程序员设计的:

  • Debug(调试能力):你的宠物有多擅长帮你找 bug
  • Patience(耐心):面对你第 47 次编译失败时的容忍度
  • Chaos(混沌值):制造意外惊喜(或惊吓)的倾向
  • Wisdom(智慧):给出有用建议的概率
  • Snark(毒舌):吐槽你代码的辛辣程度

对,毒舌是正式属性。一个编程工具的电子宠物,居然有毒舌属性。这说明设计者非常清楚自己的用户群体——程序员之间的社交货币就是互相 diss 代码。

属性值受稀有度影响,基础值范围不同:

稀有度 基础值范围 理论最高总分
Common 10-50 ~250/500
Uncommon 20-60 ~300/500
Rare 30-70 ~350/500
Epic 40-80 ~400/500
Legendary 50-100 ~425/500

但这里有个隐藏机制:算法强制分配一个峰值属性和一个谷值属性。峰值属性会额外加成,谷值属性会被压低。全属性拉满在数学上不可能——传说级的理论最高总分是 425/500。所以别信网上那些"全满属性"的截图,算法层面就不存在。

"灵魂层":AI 给你的宠物写性格

Buddy 系统用了一个双层架构设计,叫 Bones + Soul

骨架层(Bones) 决定宠物长什么样——物种、眼睛、帽子、稀有度、属性值,全部由 userID 确定性生成,不可更改。

灵魂层(Soul) 决定宠物是什么性格——这部分存在本地。第一次孵化的时候,Claude 会根据宠物的物种和属性,现场写一段专属的名字和性格描述。不是模板填空,是 AI 根据上下文现写的。

这意味着两件事:

  1. 你的宠物从出生那一刻起就是独一无二的——即使两个人抽到了同物种同稀有度的宠物,灵魂描述也完全不同
  2. 灵魂层是可以重新生成的(删除本地缓存即可),但骨架层永远不变

这个设计挺巧妙的。骨架层给了"命运感"——你的宠物是注定的;灵魂层给了"独特感"——它的性格是为你量身定制的。两层叠加,情感绑定就建立起来了。

为什么一家 3800 亿美元的 AI 公司要做这个

这大概是整件事里最值得琢磨的问题。

Claude Code 是个严肃的编程工具,面向专业开发者。Anthropic 的估值建立在"安全、可靠的 AI"这个叙事上,公司刚完成新一轮融资,估值 3800 亿美元,正在准备 IPO。在这样一个产品里藏一个电子宠物系统,而且还用编码混淆来躲避内部代码扫描器——这不是管理层批准的正式功能,这是工程师们偷偷干的。

但它揭示了一个真实的需求:写代码是孤独的

尤其是用 AI 编程工具的时候,你面对的是一个终端窗口和一个无限耐心但没有温度的 AI。它能帮你写代码、debug、重构,但它不会在你连续加班到凌晨三点的时候说一句"辛苦了"。一只会在旁边晃悠、偶尔吐槽你的 ASCII 小动物,某种程度上比任何 UX 优化都更能让人觉得"这个工具有人味"。

从产品设计的角度看,这其实是一个很高明的用户留存策略。当你的宠物是独一无二的、不可替换的、会随着你的使用产生情感连接的,你切换到竞品的心理成本就变高了。这比任何功能对比表都有效。

Anthropic 显然也意识到了这一点——泄露之后他们没有删掉这个功能,而是按原计划在 4 月 1 日正式上线了 /buddy 命令。从"地下彩蛋"变成了"官方功能",这个转变本身就说明了一切。

怎么玩

如果你在用 Claude Code,现在就可以试:

# 在 Claude Code 终端里输入
/buddy

然后等待孵化动画,看看命运给你分配了什么。如果是白板普通仙人掌——别灰心,至少它的毒舌值可能很高。


参考来源: