
这两天 anyrouter 发了一条公告,很多人第一眼看完会有点懵:Claude Code 最新版本对 Tool Search 功能做了限制,要求 API 地址必须是 api.anthropic.com;如果你走中转域名,Tool Search 可能就不工作了。公告接着又说,npm 版本可以改代码绕过去,bun 版本不行,建议用 npm 版本。
问题来了。现在不少人装 Claude Code,看到的已经不是传统意义上的 npm 脚本入口了,而是一个独立可执行文件,也就是大家口中的“二进制版”。那这时候再看到“npm 可以、bun 不行”这种说法,很容易脑子里打结:
- 不是都已经新版安装方式了吗?
- 不是都成二进制了吗?
- 为什么公告还在区分 npm 和 bun?
- 二进制到底算 npm、算 bun,还是都不算?
如果这几个概念没拆开,后面判断自己该不该改、该不该慌、该不该切换安装方式,基本都会出偏差。
这篇文章就把这件事彻底讲清:这条公告到底限制了什么,Tool Search 为什么重要,npm / bun / native / 二进制这几个词到底各自指什么,以及你现在看到“独立二进制”时应该怎么理解它。
先说结论:这不是“安装命令”的区别,而是“可修改性”的区别
很多人误以为公告在说:
- 用 npm 安装的能用
- 用 bun 安装的不能用
这理解并不准确。
更准确的说法是:公告关心的不是你当初用什么命令装,而是你手上的 Claude Code 最终产物还能不能被直接修改。
如果你手里的 Claude Code 是那种典型的 npm 结构,比如本地能找到:
node_modules/@anthropic-ai/claude-code/cli.js
那它本质上还是一份可以直接打开、替换字符串、重新运行的 JS 入口。Tool Search 的 host 校验如果写死在这类文件里,就可以粗暴地通过字符串替换绕过去。
但如果你手里拿到的是一个已经被打包、编译好的产物——无论它表面上叫“bun 版”、还是你感知到的是“独立二进制版”——情况就变了。因为这时你面对的已经不是一个方便编辑的 JS 文件,而是一个打包后的可执行体。它可能仍然包含某些字符串,也可能内部确实是 Bun 编译出来的,但对使用者来说,它已经不属于那类“随手 sed 一下就能改”的 npm 版了。
也就是说,这条公告真正想表达的是:
能改源码入口的那类版本,可以 patch;不能直接改源码入口的那类编译产物,就不适合这么 patch。
这和“你看到的是不是一个二进制”并不冲突。
Tool Search 到底是什么,为什么这次限制会有人紧张
先别急着讨论 npm 和 bun,先把 Tool Search 本身讲清楚。
Tool Search 的价值,不在于“多了一个按钮”,而在于它能显著改善 Claude Code 在复杂工具环境下的上下文利用效率。尤其是你接了很多 MCP 工具之后,工具定义本身会占掉相当多的上下文。工具越多、schema 越长,模型越容易在上下文里背着一大坨工具说明书工作,表现自然也会受到影响。
Tool Search 这类能力,本质上是在做一件事:让模型不用每次都把全部工具定义完整带进来,而是按需搜索和调用。
所以对工具多、MCP 多、上下文敏感的用户来说,Tool Search 不是可有可无的小优化,而是会直接影响:
- 工具定义占用的 token
- 会话上下文的有效空间
- 模型是否更容易聚焦在任务本身
- 多工具环境下的稳定性和表现
也正因为它很实用,一旦它被域名限制卡住,大家才会这么在意。
anyrouter 这条公告到底在说什么
把原话抽象一下,其实就是三层意思。
第一层:Anthropic 新版本把 Tool Search 绑到了 api.anthropic.com
也就是说,如果 Claude Code 在判断 Tool Search 能不能开的时候,看见你的 API host 不是官方域名,而是中转域名、反代域名或者第三方网关域名,它可能直接把这项能力关掉。
从公告给出的提示看,这个检查不是“你能不能正常调用模型”,而是针对 Tool Search 这项能力额外加了一层 host 限制。
所以这件事和“模型能不能用”不是一回事。你可能照样能聊天、照样能跑任务,但 Tool Search 不一定还能触发。
第二层:npm 版可以改代码,把 host 替换掉
如果本地 CLI 仍然是 JS 源码入口,你就可以通过一个脚本,把内部写死的 api.anthropic.com 替换成你自己的域名,例如:
anyrouter.top- 或其他中转 host
这样 Tool Search 的条件判断就会误以为“你正在访问的就是允许的 host”,从而继续启用。
第三层:bun / 编译产物不适合这么做
因为你已经拿不到一个好改的 cli.js 了,能 patch 的入口消失了。公告里说“bun 版不行”,说的其实不是某个品牌化的安装命令,而是:对已经打包好的产物,不存在一个稳定、公开、可维护的文本入口让你替换。
所以 anyrouter 最终才会建议:如果你强依赖 Tool Search,又要用非官方 host,最好切到 npm 版 CLI。
为什么“二进制版”和“bun 版”并不冲突
这里是最容易混的地方。
很多人脑子里的分类是这样的:
- npm 版:脚本
- bun 版:bun install 出来的版本
- native 版:原生二进制
看起来像是三选一,但现实不是这么分的。
更合理的拆法是:
1. 分发形式
也就是最终发给你的是什么。
比如:
- 一个 shell wrapper
- 一份 JS 入口脚本
- 一个独立可执行文件
当你看到:
- ~/.local/bin/claude
- file 显示是 Mach-O
这说明你拿到的是二进制分发形态。
2. 内部构建方式
也就是这个产物是怎么做出来的。
它可能是:
- Node / npm 的源码结构直接运行
- 用 Bun 打包/编译
- 用别的打包器做成单文件产物
所以“bun”很多时候说的是构建链和运行产物的性质,不是表面安装命令。
3. 可修改性
这是这次公告最关心的。
- 如果你能直接改
cli.js,那就是“npm 可 patch 那类” - 如果你面对的是编译产物,那就是“不适合直接 patch 那类”
换句话说:
二进制是你拿到的样子;bun/npm 更像是它内部怎么做出来、以及你还能不能方便改它。
所以一个产物完全可能同时满足:
- 它是二进制
- 它内部有 Bun 痕迹
- 它不属于 npm 可直接 patch 的类型
这三件事不打架。
我们实际排查时,怎么判断当前环境属于哪一类
光靠猜没意义,最稳的方式还是直接看本机的 claude 到底是什么。
排查时可以看三件事:
1. which claude
看它实际指向哪。
如果它只是一个 npm 安装出来的入口,通常能顺着路径看到 node_modules 结构;如果它是新版安装器管理的版本化产物,往往会落在某个版本目录里。
2. file $(which claude)
看它是不是原生可执行文件。
如果输出是:
- Mach-O 64-bit executable arm64
那就很明确了:你手上拿到的是一个二进制,而不是普通 JS 文件。
3. 用 strings 看内部特征
这一步不是必须,但很好用。
你可以看两类信息:
- 有没有
api.anthropic.com - 有没有明显的
bun相关痕迹
如果二进制里既能搜到:
- api.anthropic.com
又能搜到:
- build/release/tmp_modules/bun/...
- bun/sqlite
- 类似 Bun runtime 的片段
那基本可以判断:你现在的 Claude Code 是独立二进制分发,但内部更像 Bun 打包/编译产物。
这正是很多人误解的根源。因为从用户视角看,它已经不是“bun install”那种显式体验了;但从产物可修改性看,它又更接近公告里说的“bun / 编译版那类不方便 patch 的对象”。
为什么公告里的 patch 脚本不一定适合你当前环境
anyrouter 给的脚本核心思路是:先找到 Claude Code 实际运行的 cli.js,然后把里面的 api.anthropic.com 替换掉。
这套做法有一个前提:你的 claude 最终能回溯到 npm 的 JS 入口。
比如脚本里会去 grep:
node_modules/@anthropic-ai/claude-code/cli.js
如果你的当前安装形态根本不是那套结构,而是一个原生二进制文件,那这个前提就不成立。
最常见的问题有两个:
第一,根本找不到可 patch 的 JS 文件
脚本设计时假设你本地存在 cli.js 这类文本入口,但二进制版通常没有这种暴露出来的结构。
第二,误把二进制当文本替换
有些人会看到二进制里确实包含 api.anthropic.com 这段字符串,就动了直接替换的念头。理论上,字符串确实可能存在;但工程上,这不是一个稳妥的修复方案。因为你操作的已经不是普通文本文件,而是 Mach-O 可执行体。
哪怕替换后还能启动,也不代表它内部所有偏移、封装逻辑、校验行为都还正常。这个风险和改 cli.js 不是一个量级。
所以这条公告真正应该翻译成一句对使用者有用的话:
如果你当前的 Claude Code 已经是独立二进制 / 编译产物,就别把 npm patch 脚本生搬硬套过去。
现在最关键的问题:如果我还没升级,是不是就先不用慌
这是绝大多数人真正想知道的。
答案是:大概率可以先不慌。
前提是:
- 你当前没有升级到触发新限制的版本
- 你现在实际使用时,Tool Search 还没有失效
- 你暂时也不打算重装或覆盖当前 CLI
这种情况下,公告更像是在提示未来风险,而不是告诉你“你今天立刻就坏了”。
也就是说,如果你手上的版本当前还正常、工作流没断、Tool Search 没报废,最稳的策略反而是:
- 不要着急动环境
- 不要看到脚本就上手 patch
- 不要因为公告吓到自己先把 CLI 切来切去
先观察,先确认自己的实际状态,再决定要不要迁移。
这一步很重要,因为很多工具链事故不是“官方公告导致的”,而是用户看完公告以后自己先折腾坏了。
那能不能只把 Tool Search 单独换成 npm 版
不能。
这是另一个常见误区。
Tool Search 不是一个单独可插拔的小模块,不存在“把这一个功能切到 npm 版,其他部分继续沿用原生二进制”的简单做法。它是 Claude Code CLI 内部能力的一部分。
所以如果你真的决定要走 anyrouter 说的 npm patch 路线,本质上做的不是:
- “把 Tool Search 改成 npm 版”
而是:
- 另装一个 npm 版 Claude Code CLI,并在需要时用这套 CLI 工作
这两者差别很大。
前者听起来像小修小补,后者其实是安装形态的切换。
所以从决策角度讲,大家先要接受一个事实:
不存在“只改 Tool Search”的轻量开关。要么继续用当前这套,要么换一套更可 patch 的 CLI。
对大多数人,当前最合理的策略是什么
如果你问我一个更落地的问题:
“我现在看到这条公告,下一步该怎么办?”
我的建议很简单。
第一种情况:你现在没遇到问题
那就先别动。
尤其是:
- 当前 CLI 正常
- Tool Search 还在
- 工作没被影响
这时候最好的策略通常是:
- 暂停升级
- 保持现状
- 观察社区后续验证
第二种情况:你未来升级后,Tool Search 真失效了
再决定要不要切 npm 版。
这里的核心不是“看到公告就改”,而是:
- 你是否真的依赖 Tool Search
- 你是否真的被 host 限制影响
- 你是否愿意接受并行维护两套 CLI
第三种情况:你本来就不怎么用 Tool Search
那更没必要为这件事制造额外复杂度。
很多人看到“功能受限”就本能焦虑,但得先问一句:这功能是不是我生产流里的关键路径。
如果不是,那这件事的优先级可能根本没你想象得高。
把这件事压缩成一句人话
如果你只想记住一句,记这个就够了:
二进制是分发形式,npm / bun 更像内部实现和可修改性分类;你现在看到的独立二进制,很可能本质上更接近公告里说的“bun/编译产物那类不方便 patch 的版本”。
所以面对 anyrouter 这次公告,正确姿势不是马上找脚本硬改,而是先判断三件事:
- 我当前是不是已经受影响了?
- 我手上的 CLI 是不是 npm 可 patch 那类?
- 如果真要修,我是不是愿意换成并行的 npm 版 CLI?
只要把这三件事想清楚,这条公告其实没有看上去那么玄。
最后一句更务实的建议
这次争议本质上不是 API 调不调得通,而是某个高级能力被 host 判断限制住了。这类问题最怕的不是限制本身,而是用户脑子里把“安装方式”“分发形态”“运行时”“可修改性”全混成一团,最后一顿操作把自己环境搞乱。
真要做判断,顺序应该反过来:
- 先确认当前版本是否正常
- 再确认自己手上的 CLI 是哪一类产物
- 最后才决定是否值得为 Tool Search 单独准备一套 npm CLI
别先 patch,先分类。很多技术问题,一旦分类正确,情绪就会先稳定一半。