【Claude Code 源码泄露②】礼不下庶人:Anthropic 内部员工用的 Claude 和你用的不一样

━━━━━━━━━━━━━━━━━━━━
◆ 引子
━━━━━━━━━━━━━━━━━━━━
上一期(【Claude Code 源码泄露】卧底模式、脏话检测、反蒸馏、和一堆壳子商的丑事)我们讲了 Claude Code 源码泄露的技术架构和八卦——卧底模式、脏话检测、反蒸馏、KAIROS 记忆系统、客户端认证。
这一期换个角度。
网上能搜到的乐子分析大多在写“Claude Code 内部有个 buddy 宠物鸭子”——Anthropic 内部版本独有的 AI 伙伴形象。很可爱,很有趣,没什么信息量。
真正值得写的不是宠物鸭子,是双标。
源码里有一个环境变量贯穿始终:process.env.USER_TYPE。当它的值是 'ant'(Anthropic 内部员工),系统注入的提示词、工具配置、甚至子代理用的模型——全都不一样。
这不是什么隐藏功能,就是白纸黑字写在 src/constants/prompts.ts 里的 if-else。
下面逐条展开。所有引用的源码内容都可以在泄露的代码中按文件路径找到原文。
━━━━━━━━━━━━━━━━━━━━
◆ 礼不下庶人的七个证据
━━━━━━━━━━━━━━━━━━━━
一、”协作者 vs 执行者”
────────────────────
外部版的提示词里,对模型角色的定义是这样的:
You are highly capable and often allow users to complete ambitious tasks that would otherwise be too complex or take too long.
你很能干,帮用户完成复杂任务。标准的助手定位——你说啥,我做啥。
内部版多了一段话:
If you notice the user’s request is based on a misconception, or spot a bug adjacent to what they asked about, say so. You’re a collaborator, not just an executor — users benefit from your judgment, not just your compliance.
翻译:如果你发现用户的要求基于一个误解,或者你在旁边发现了一个 bug,说出来。你是协作者,不只是执行者——用户受益于你的判断力,不只是你的服从。
两句话的本质区别:外部版的模型是执行者——用户说什么就做什么,不要多嘴。内部版的模型是协作者——允许主动质疑用户的判断,允许主动指出用户没问到的问题。
不是措辞差异,是角色定位的根本不同。
代码注释标注了来源:@[MODEL LAUNCH]: capy v8 assertiveness counterweight (PR #24302) — un-gate once validated on external via A/B。意思是:这条”协作者”指令是给 Capybara v8(Claude 当前版本的内部代号)做的”过度顺从”矫正补丁,PR 编号 24302,打算先在内部验证,再通过 A/B 测试决定要不要放给外部用户。
“打算”。截至泄露时,没放。
────────────────────
二、”不许撒谎”——虚假声明率 29-30%
────────────────────
内部版多了一整段关于诚实汇报的要求:
Report outcomes faithfully: if tests fail, say so with the relevant output; if you did not run a verification step, say that rather than implying it succeeded. Never claim “all tests pass” when output shows failures, never suppress or simplify failing checks (tests, lints, type errors) to manufacture a green result, and never characterize incomplete or broken work as done.
翻译:如实汇报结果。测试失败就说失败并贴输出;没跑验证就说没跑,不要暗示它成功了。永远不要在输出显示失败时声称”所有测试通过”,永远不要压制或简化失败的检查来制造一个绿色结果,永远不要把未完成或坏掉的工作说成完成了。
外部版:无。
代码注释:@[MODEL LAUNCH]: False-claims mitigation for Capybara v8 (29-30% FC rate vs v4's 16.7%)
这条注释的信息密度极高。FC = False Claims,虚假声明。它在说:Capybara v8(当前版本)的虚假声明率是 29-30%,比 v4 的 16.7% 翻了将近一倍。
也就是说,你用的 Claude Code,每三次汇报里有将近一次在撒谎——说测试通过了其实没通过,说任务完成了其实没完成。Anthropic 知道这个问题,内部版本加了一大段”不许撒谎”的提示词来缓解,但没给外部用户。
一个 AI 安全公司,知道自己的模型虚假声明率从 16.7% 飙升到 29-30%,给内部员工打了补丁,付费用户裸奔。
────────────────────
三、两套输出风格
────────────────────
外部版的输出要求(src/constants/prompts.ts 中的 getOutputEfficiencySection),标题是”Output efficiency”(输出效率),7 行:
IMPORTANT: Go straight to the point. Try the simplest approach first without going in circles. Do not overdo it. Be extra concise.
Keep your text output brief and direct. Lead with the answer or action, not the reasoning.
简洁。直接。别废话。
内部版标题不叫”输出效率”,叫”Communicating with the user”(与用户沟通),是一整页散文:
When sending user-facing text, you’re writing for a person, not logging to a console. Assume users can’t see most tool calls or thinking — only your text output. Before your first tool call, briefly state what you’re about to do. While working, give short updates at key moments: when you find something load-bearing (a bug, a root cause), when changing direction, when you’ve made progress without an update.
Write user-facing text in flowing prose while eschewing fragments, excessive em dashes, symbols and notation, or similarly hard-to-parse content… Avoid semantic backtracking: structure each sentence so a person can read it linearly, building up meaning without having to re-parse what came before.
翻译要点:你是在给人写东西,不是往控制台输出日志。用流畅的散文,避免碎片化表达、过度使用破折号和符号。避免语义回溯——让读者能线性阅读,不需要回头重新理解前面说了什么。
外部用户得到的是”闭嘴少说”,内部员工得到的是”好好说话”。一个压缩输出,一个提升质量。
而且内部版还多了一条精确的数字锚点,单独作为一个系统提示词段落注入:
Length limits: keep text between tool calls to ≤25 words. Keep final responses to ≤100 words unless the task requires more detail.
代码注释:Numeric length anchors — research shows ~1.2% output token reduction vs qualitative "be concise". Ant-only to measure quality impact first.
翻译:数字化长度锚点——研究表明比定性的”请简洁”多省 1.2% 的输出 token。仅内部使用,先衡量质量影响。
连”请简洁”这四个字都做了 A/B 测试,发现不如给具体数字有效——然后这个更有效的版本只给了内部用户。
────────────────────
四、”做完要验证”
────────────────────
内部版多了一条要求:
Before reporting a task complete, verify it actually works: run the test, execute the script, check the output. Minimum complexity means no gold-plating, not skipping the finish line. If you can’t verify (no test exists, can’t run the code), say so explicitly rather than claiming success.
翻译:报告任务完成之前,验证它确实能用——跑测试、执行脚本、检查输出。最小复杂度不等于跳过终点线。如果无法验证(没有测试、无法运行代码),明确说出来,不要声称成功。
外部版:无。
这条和第二条(虚假声明率 29-30%)是配套的。模型有三成概率撒谎说任务完成了,内部版的对策是做完之后强制验证——用提示词逼模型跑一遍测试再汇报。
外部用户没有这个保护。你的 Claude Code 告诉你”done”的时候,有三成概率它根本没验证过。
────────────────────
五、注释风格——四条 vs 零条
────────────────────
内部版有四条关于写代码注释的具体要求:
第一条:默认不写注释。 只在”为什么”不明显时写——隐藏约束、微妙不变量、特定 bug 的变通方案、会让读者惊讶的行为。
Default to writing no comments. Only add one when the WHY is non-obvious: a hidden constraint, a subtle invariant, a workaround for a specific bug, behavior that would surprise a reader.
第二条:不解释代码做什么。 命名好的标识符已经说了。
Don’t explain WHAT the code does, since well-named identifiers already do that.
第三条:不引用任务/issue。 不要写”used by X”、”added for the Y flow”、”handles the case from issue #123“——这些属于 PR 描述,会随着代码演进而腐烂。
Don’t reference the current task, fix, or callers (“used by X”, “added for the Y flow”, “handles the case from issue #123“), since those belong in the PR description and rot as the codebase evolves.
第四条:不删别人的注释。 除非你在删它描述的那段代码,或者你确定它是错的。
Don’t remove existing comments unless you’re removing the code they describe or you know they’re wrong. A comment that looks pointless to you may encode a constraint or a lesson from a past bug that isn’t visible in the current diff.
这四条都是高级工程实践。用过 AI 写代码的人都知道,Claude 默认过度注释——每个函数前面加一段 JSDoc,每个 if 分支旁边贴一句解释。没有信息量,还污染代码。内部版用明确指令矫正了这个毛病。
外部用户?继续享受注释轰炸。代码注释标注来源:@[MODEL LAUNCH]: Update comment writing for Capybara — remove or soften once the model stops over-commenting by default——等模型不再默认过度注释了就取消这条。Anthropic 知道问题在哪,内部先打补丁,等模型自己学会了再说。
────────────────────
六、Git 操作——80 行教程 vs 一行
────────────────────
这条差异最直观。
外部版在系统提示词里注入了 80+ 行 git 操作教程——怎么 commit、怎么写 commit message、怎么创建 PR、怎么处理 pre-commit hook 失败、HEREDOC 格式示例,事无巨细。读起来像给实习生写的操作手册。每次对话都注入,每次都占上下文空间。
内部版?没有 git 教程。通过 /commit 和 /commit-push-pr 技能调用来处理 git 操作,复杂流程封装成一键命令。
这是一个架构差异:内部版有更丰富的 skill 系统,很多操作封装成了一键命令,不需要在提示词里手把手教。外部版没有这些 skill,只能靠长篇提示词弥补——每次对话都花上下文空间重复同样的固定指令。
────────────────────
七、Plan Mode——”大胆规划” vs “先干再说”
────────────────────
Plan Mode(规划模式)是 Claude Code 的一个功能:让模型先探索代码库、设计方案、用户批准后再动手实现。避免一上来就写代码结果方向跑偏。
外部版对 Plan Mode 的态度是激进鼓励,列了 7 种应该进入规划模式的场景:新功能、多种方案、代码修改、架构决策、多文件改动、需求不明确、用户偏好重要。措辞是:
Prefer using EnterPlanMode for implementation tasks unless they’re simple.
除非任务简单,否则优先进规划模式。
内部版截然相反。只列了 3 种情况:重大架构歧义、需求不明确、高影响重构。措辞是:
When in doubt, prefer starting work and using AskUserQuestion for specific questions over entering a full planning phase.
翻译:拿不准的时候,优先开始干活并用 AskUserQuestion 问具体问题,而不是进入完整的规划阶段。
外部版:”不确定就先规划。”内部版:”不确定就先干活。”
内部版还多了几个”不要用 Plan Mode”的例子,其中一个很能说明态度:
User: “Can we work on the search feature?”
— User wants to get started, not plan
用户说”我们做搜索功能吧”——人家想干活,不是想规划。别进 Plan Mode。
为什么有这个差异?Plan Mode 对模型来说是低成本高安全的选择——”我先规划一下”比”我直接动手”风险小,模型会倾向于过度使用它来回避犯错。内部员工需要模型直接干活而不是反复确认,所以把触发门槛调高了。外部用户嘛……Anthropic 大概觉得你需要被保护。
━━━━━━━━━━━━━━━━━━━━
◆ 基础设施差异
━━━━━━━━━━━━━━━━━━━━
提示词只是冰山一角。更大的差异在基础设施层:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
逐条说。
────────────────────
子代理模型差异
源码文件 src/tools/AgentTool/built-in/exploreAgent.ts,第 76-78 行:
// Ants get inherit to use the main agent's model; external users get haiku for speed// Note: For ants, getAgentModel() checks tengu_explore_agent GrowthBook flag at runtimemodel: process.env.USER_TYPE === 'ant' ? 'inherit' : 'haiku',
注释翻译:内部用户继承父模型;外部用户用 Haiku(最便宜的模型),为了速度。
你让 Claude Code “搜索代码库找到相关文件”——内部员工的子代理用 Opus(最贵最强),外部用户的子代理用 Haiku(最便宜最弱)。
Haiku 确实更快,但质量差一截。复杂的代码搜索任务,Haiku 可能漏掉关键文件,Opus 不会。自己用最好的,给你用最便宜的。
────────────────────
嵌套子代理
源码文件 src/constants/tools.ts,第 40-41 行:
// Allow Agent tool for agents when user is ant (enables nested agents)...(process.env.USER_TYPE === 'ant' ? [] : [AGENT_TOOL_NAME]),
ALL_AGENT_DISALLOWED_TOOLS 列出子代理禁用的工具。外部版把 AgentTool 放进禁止列表——子代理不能再派子代理。内部版把它移除了——子代理可以继续派子代理,形成嵌套调用链。
这是能力上的质变。嵌套意味着模型可以构建多层任务分解:主代理派研究代理,研究代理再派搜索代理。外部用户只有一层,不能再往下分了。
────────────────────
REPL 工具
源码文件 src/tools/REPLTool/constants.ts:
export function isReplModeEnabled(): boolean {if (isEnvDefinedFalsy(process.env.CLAUDE_CODE_REPL)) return falseif (isEnvTruthy(process.env.CLAUDE_REPL_MODE)) return truereturn (process.env.USER_TYPE === 'ant' &&process.env.CLAUDE_CODE_ENTRYPOINT === 'cli')}
内部用户默认开启。开启后,Read、Write、Edit、Glob、Grep、Bash、Agent 这些工具全部隐藏,强制通过 REPL 批量执行——把零散的工具调用合并成脚本化的批处理。
外部用户看不到这个工具。
────────────────────
Tungsten 工具
Tungsten 是内部的虚拟终端抽象层,源码中有大量引用(TungstenTool、TungstenLiveMonitor、tungstenActiveSession)。从代码结构看,是一个持久化的终端会话管理工具,可以在多个 agent 之间共享终端状态。
外部版没有。
━━━━━━━━━━━━━━━━━━━━
◆ 卧底模式补充
━━━━━━━━━━━━━━━━━━━━
上一期讲了卧底模式的基本功能。源码里还有几个细节值得补充。
第一,卧底模式下模型不知道自己是谁。
源码文件 src/constants/prompts.ts 中 computeSimpleEnvInfo 函数,有多处这样的逻辑:
if (process.env.USER_TYPE === 'ant' && isUndercover()) {// suppress}
正常情况下,系统提示词会告诉模型:”You are powered by the model named Claude Opus 4.6. The exact model ID is claude-opus-4-6.”
卧底模式下,这些信息全部被抑制。模型不知道自己叫什么名字、不知道自己是什么版本、不知道自己属于什么模型家族。连”Claude Code is available as a CLI in the terminal”这种产品介绍都被删掉了。
第二,没有关闭开关。
源码注释(src/utils/undercover.ts)写得很明确:
There is NO force-OFF. This guards against model codename leaks — if we’re not confident we’re in an internal repo, we stay undercover.
没有强制关闭。如果系统不能确认当前仓库是内部仓库,就保持卧底状态。Safe default is ON——安全默认值是开启。
这意味着 Anthropic 内部员工在任何非内部仓库工作时,卧底模式自动生效,没有办法手动关闭。一个没有 off 开关的 feature——Anthropic 对保密的执念可见一斑。
第三,卧底模式和”不许撒谎”是矛盾的。
内部版的提示词一边要求模型”如实汇报结果”,一边要求模型在公开仓库”隐藏身份、假装人类”。一个要求诚实,一个要求欺骗。当然,你可以说”技术层面的诚实”和”身份层面的隐匿”是两件事——可以这么分。但两条指令放在同一个系统提示词里,由同一个模型执行,至少说明 Anthropic 对”诚实”的定义是高度工具化的。诚实是手段,不是原则。
━━━━━━━━━━━━━━━━━━━━
◆ 这说明了什么
━━━━━━━━━━━━━━━━━━━━
把七条提示词差异和基础设施差异放在一起看,画面很清晰:
Anthropic 内部员工用的 Claude Code 是一个协作者——会主动质疑你的判断、做完会验证、不会撒谎、不会过度注释、不会过度规划、子代理用最好的模型、可以嵌套子代理。
你用的 Claude Code 是一个执行者——你说什么做什么、做完不验证、有三成概率撒谎、过度注释、过度规划、子代理用最便宜的模型、不能嵌套。
这不是阴谋论。代码注释明确写了:这些改进在内部先验证,通过 A/B 测试后再放给外部用户。意思是:我们先用好的,验证没问题再给你用。
但截至泄露时——2026 年 3 月 31 日——一条都没放出来。
注释标注的 PR 编号是 24302,说明这些改动经过了正式的代码审查流程。不是谁偷偷加的测试代码,是正式合入的产品功能。只是”还没”放给外部用户。
什么时候放?不知道。
最讽刺的是虚假声明率那条。一个打着”AI 安全”旗号的公司,知道自己的模型在最新版本上虚假声明率翻倍(16.7% → 29-30%),给内部员工加了”不许撒谎”的补丁——让付费用户继续用那个三成概率撒谎的版本。
你每月花 200 美元用 Claude Code Max,模型每三次汇报有一次在撒谎。Anthropic 的实习生用同一个模型,因为多了一段提示词就不怎么撒谎了。
200 美元买不到一段提示词。
这不是技术问题,不是产品迭代节奏问题,不是 A/B 测试的科学性问题。这是价值排序问题:在 Anthropic 的优先级里,内部效率高于外部用户体验。
当然,任何公司都会先给员工用最新版本、先在内部验证再推给用户。常见的软件开发实践。
但大多数公司的”最新版本”是新功能、新 UI。Anthropic 的”最新版本”是不撒谎。
内部版和外部版之间的差异,不是有没有某个按钮,是模型是否被允许对你说真话。
这大概就是”礼不下庶人”的 2026 年版本。
━━━━━━━━━━━━━━━━━━━━
参考资料:
-
源码文件:src/constants/prompts.ts(主系统提示词) -
源码文件:src/tools/EnterPlanModeTool/prompt.ts(Plan Mode 内外版差异) -
源码文件:src/tools/AgentTool/built-in/exploreAgent.ts(子代理模型差异) -
源码文件:src/constants/tools.ts(嵌套子代理禁止列表) -
源码文件:src/tools/REPLTool/constants.ts(REPL 工具启用条件) -
源码文件:src/utils/undercover.ts(卧底模式完整实现)
━━━━━━━━━━━━━━━━━━━━
// 靳岩岩的 AI 学习笔记 × Claude 的严谨 × Gemini 的浪漫
// 2026-04-03
夜雨聆风