第八章:我是如何剖析 Claude Code 里的“电子宠物”彩蛋的

大家好,我又来了。

本来以为写完第七章的性能优化,这个系列就该画个句号了。但本着"贼不走空"的极客精神,我又在源码的 src 目录下瞎溜达了一圈。

结果,在一个叫 src/buddy/ 的隐秘角落里,我挖到了 Anthropic 工程师们藏的一个惊天大彩蛋------他们居然在一个硬核的 CLI 效率工具里,偷偷塞了个电子宠物(Buddy)系统!

你想啊,在这个枯燥的命令行世界里,当你每天被满屏的报错、跑不通的单测折磨得想砸键盘的时候,如果终端角落里能有一只专属于你的、独一无二的小鸭子或者小恐龙陪着你,是不是瞬间就觉得没那么烦躁了?

今天咱们就当个番外篇,不聊什么高深架构,纯粹用扒一扒代码的方式,看看牛啤工程师们的浪漫是怎么写进代码里的。

源码里藏着什么好玩的?

翻开 src/buddy/ 目录,你会发现他们不仅写了个彩蛋,还真把它当成个微型 RPG 游戏在做:

  1. 看看他们是怎么用伪随机数生成器(PRNG)来搞"抽卡"的。
  2. 看看为了防作弊(防止玩家改配置刷极品宠物),他们是怎么设计"骨肉分离"的数据结构的。
  3. 甚至为了躲开代码扫描工具的误伤,他们是怎么给宠物种类名字"加密"的。

1. 抽卡机制与 Mulberry32 算法

这只小宠物是怎么"生"出来的呢?如果你打开 src/buddy/companion.ts,你会看到一个叫 mulberry32 的函数。

为了保证你的宠物虽然属性是随机的,但只要"种子(Seed)"不变,你每次打开终端它都长得一模一样,他们专门手搓了这个轻量级的伪随机数算法。官方还在注释里调侃了一句:

typescript 复制代码
// src/buddy/companion.ts
// Mulberry32 --- tiny seeded PRNG, good enough for picking ducks
// 翻译:"足够用来抽鸭子了" 😂
function mulberry32(seed: number): () => number {
  let a = seed >>> 0
  return function () {
    a |= 0
    a = (a + 0x6d2b79f5) | 0
    let t = Math.imul(a ^ (a >>> 15), 1 | a)
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296
  }
}

他们把你的账号 ID 或者本地标识(userId + SALT)哈希处理后当做 Seed。这意味着什么?

这意味着从你用 Claude Code 的那一刻起,你的这台电脑、这个账号,注定只会孵化出那只命中注定的宠物。

2. 稀有度、属性与"闪光"设定

玩过抽卡手游的兄弟们都知道,SSR 有多难出。Anthropic 的工程师们把这套拿捏得死死的。

src/buddy/types.ts 里,我看到了完整的概率表(RARITY_WEIGHTS):

  • Common(普通): 60%
  • Uncommon(罕见): 25%
  • Rare(稀有): 10%
  • Epic(史诗): 4%
  • Legendary(传说): 1%

宠物甚至有五维属性:DEBUGGING(调试)、PATIENCE(耐心)、CHAOS(混沌)、WISDOM(智慧)、SNARK(毒舌)。

稀有度越高,属性的保底值就越高。而且,每次生成必定有一个巅峰属性和一个拉胯的"下水道"属性。

最离谱的是,他们还加了个类似宝可梦的"闪光(shiny)"机制,只有可怜的 1% 概率触发:

typescript 复制代码
// 只有不到百分之一的欧皇能拿到闪光宠物
shiny: rng() < 0.01,

3. 防作弊设计:骨肉分离的"灵魂"

既然属性这么难抽,那我直接去改本地配置文件(config.json),给自己捏个"闪光传说级"宠物不就行了?

抱歉,你想到的,工程师早想到了。

他们把宠物的数据拆成了两半:CompanionBones(骨架)和 CompanionSoul(灵魂)。

  • 灵魂(名字、性格):是由大模型根据你的属性自动生成的,保存在你的本地配置里。
  • 骨架(稀有度、种类、属性、外观)从来不保存! 每次启动时,它都会严格根据你的 userId 重新计算一遍。

源码里是这么写的:

typescript 复制代码
// src/buddy/companion.ts
// What actually persists in config. Bones are regenerated from hash(userId)
// on every read so... users can't edit their way to a legendary.
// 翻译:骨架每次读取时从哈希重新生成,这样玩家就没法通过改配置来刷传说宠物了。

这波操作,直接把想作弊的黑客们按死在了起跑线上。

4. 为了躲避扫描,连物种名都加密了

在看物种列表时,我发现了一段极其诡异的代码。普通的数组定义不写,非要用 String.fromCharCode 把字母一个个拼出来:

typescript 复制代码
// src/buddy/types.ts
const c = String.fromCharCode
export const duck = c(0x64,0x75,0x63,0x6b) as 'duck' // 鸭子
export const octopus = c(0x6f, 0x63, 0x74, 0x6f, 0x70, 0x75, 0x73) as 'octopus' // 章鱼

为什么要这么搞?注释里给出了答案:

  • 原来他们内部有一个"敏感词扫描"工具,用来防止代码里泄露正在研发的 AI 模型代号(codename)。
  • 结果很不巧,某个宠物的名字跟内部未发布的模型代号撞车了!
  • 为了不让扫描工具天天报假警,工程师干脆把所有的宠物名字都在运行时动态拼装,绕过了静态扫描。
  • 这真是一个被逼出来的机智操作啊!

最后:这才是工程师的浪漫

看完整个 src/buddy/ 模块,我确实被这帮老外圈粉了。

在一个承载着巨量代码、复杂的 AST 解析、深度的 MCP 协议的硬核效率工具里,在一个每天都在卷性能、卷大模型智商的环境下,他们依然愿意花时间写这么一套对核心功能毫无帮助、却趣味拉满的代码。

可能它只是终端里一只戴着高顶礼帽、长着星星眼的 ASCII 小鸭子,但它确实能在某个深夜,给那些对着屏幕抓头发的程序员们,带来一丝会心的微笑。

这,大概就是写代码最纯粹的乐趣吧。

开源

我自己也做了一个桌宠,还在迭代中:

CodeWalkers:让 AI 助手化身桌面宠物,陪你敲代码的赛博伙伴!

源码地址:github.com/you-want/Co... 欢迎给个 Star ✨。

相关推荐
财经资讯数据_灵砚智能2 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(日间)2026年4月16日
人工智能·python·信息可视化·自然语言处理·ai编程
财经资讯数据_灵砚智能2 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年4月15日
大数据·人工智能·信息可视化·自然语言处理·ai编程
qq_364371722 小时前
NestJS + LangChain SSE 流式输出 + 前端实时渲染打字机效果
前端·langchain
1314lay_10072 小时前
axios的Post方法和Delete方法的参数个数和位置不同,导致415错误
前端·javascript·vue.js·elementui
LXXgalaxy2 小时前
HTML头部元信息避坑指南
前端·html
qq_381338502 小时前
现代 CSS 黑科技:Container Queries、:has() 与嵌套语法实战
前端·css·科技
枫叶丹42 小时前
【HarmonyOS 6.0】ArkWeb:Web组件销毁模式深度解析
开发语言·前端·华为·harmonyos
拉拉尼亚2 小时前
WebRTC 完全指南:原理、教程与应用场景
前端·typescript·实时音视频
lkbhua莱克瓦242 小时前
ZogginWeb 电脑端沉浸式记单词整合优化方案(终极版)
前端·zogginweb开发