Claude Code v2.1.89 里藏了个彩蛋:输入 /buddy 可以孵化一只 ASCII 小宠物,蹲在你的终端输入框旁边。

CLI
buddy

但问题是——你的宠物在你创建账号的那一刻就被决定了,概率如下:

  • common(60%)— 普通路人
  • uncommon(25%)— 稍有姿色
  • rare(10%)— 小有运气
  • epic(4%)— 欧洲人
  • legendary(1%) — 天选之子
  • shiny(1% 概率闪光)— 锦上添花

大部分人抽到的都是 common,想换一只?官方没有重抽机制。


分析

翻了源码(src/buddy/),发现宠物生成链路是完全确定性的:

Bun.hash(userID + "friend-2026-401")
    ↓ mulberry32 PRNG
    ↓ 按顺序抽取:稀有度 → 物种 → 眼睛 → 帽子 → 闪光 → 属性

同一个 userID,永远生成同一只宠物。物种名还用 String.fromCharCode 编码,绕过构建系统的代码名检查。

关键发现

外属性(物种/稀有度/外观)不持久化——每次从 userID 实时计算,不写进配置文件。这意味着:

  1. 改配置伪造稀有度?没用,bones 每次重算
  2. 想换宠物?换个 userID 就行
  3. 想指定宠物?暴力搜索 userID 空间

属性上限的真相

算法强制分配一个峰值和一个谷值属性,全属性 100 在数学上不可能

legendary (floor=50):
  峰值: min(100, 50+50+0~30) = 100 ← 必然满
  谷值: max(1,  50-10+0~15)  = 最高 55 ← 不可能满
  其他: 50+0~40              = 最高 90

理论最高总分: 100 + 55 + 90×3 = 425 / 500

所以别信什么"全满属性",算法层面就不存在。


暴力搜索

既然 userID 决定一切,那搜索 64 位十六进制空间里的最优解就好了。

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

第二版直接用 Bun 原生运行时,190 万 userID/秒,55 秒扫完 1 亿个 ID。

修复的 bug

PRNG 是严格顺序消耗的,属性抽取顺序必须与源码完全一致:

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

stats 提前消耗了 rng 调用,导致所有后续属性偏移——结果是 legendary+shiny 对了,但物种和属性全错。


最终工具

写了个交互式脚本 find-best-buddy,流程是:

  1. 选物种(18 种,带 emoji 和中文名)
  2. 选眼睛、帽子、是否闪光
  3. 设搜索量
  4. Bun 原生暴力搜索,~190 万/秒
  5. 找到最高属性匹配后,一键写入 ~/.claude.json

全自动——备份、写入、验证一步完成。

项目地址:https://github.com/Fzuim/find-best-buddy.git
交互页面


总结

冷知识 说明
宠物在你第一次打开 Claude Code 时就定了 userID → 确定性 PRNG
全属性 100 不存在 算法强制有峰值和谷值
改 userID 几乎无副作用 对未登录用户只影响遥测
物种名用 charCode 编码 绕过构建系统的代码名扫描
搜索 1 亿 ID 只要 55 秒 Bun 原生运行时 + mulberry32 PRNG
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐