工具大全
踩坑实录作者:Coocon2026年8月24日7 次阅读约 4 分钟阅读

ANTHROPIC_BASE_URL 设了却不生效

现象

给 Claude Code 挂第三方中转站(one-api / new-api 那类 API 网关),配置写得规规矩矩,~/.zshrc 里三行齐全:

export ANTHROPIC_BASE_URL="https://xxxx.example.com"
export ANTHROPIC_AUTH_TOKEN="sk-..."
export CLAUDE_CODE_USE_VERTEX=0

新开终端,claude 启动,顶部写着:

Fable 5 · Google Vertex AI

Vertex。中转站的 base URL 像是根本没被看见。

同一天还有第二件事:CloudCLI(claudecodeui 改名后的 Web UI,用来远程控制本机 claude)由 macOS launchd 拉起,登进去一直让选 provider,提示未认证。可命令行里 claude 明明已经能走中转站了——同一个用户,同一台机器。

两个现象,两个独立的坑,共同点是:环境变量你以为设上了,进程里其实不是那么回事。

坑一:settings.json 的 env 比 shell export 大

先查环境变量本身有没有生效。echo $ANTHROPIC_BASE_URL 是对的,echo $CLAUDE_CODE_USE_VERTEX 也是 0。shell 这层没问题。

那就翻 Claude Code 自己的配置。~/.claude/settings.jsonenv 块里躺着三行测试残留:

{
  "env": {
    "CLAUDE_CODE_USE_VERTEX": "1",
    "ANTHROPIC_VERTEX_PROJECT_ID": "hello",
    "CLOUD_ML_REGION": "global"
  }
}

ANTHROPIC_VERTEX_PROJECT_ID 值是 hello——一眼就知道是当初试 Vertex 时随手填的,试完忘了删。

根因清楚了:settings.jsonenv 字段是「强制注入」,优先级高于 shell 里的 export。 你在 zshrc 里写的 CLAUDE_CODE_USE_VERTEX=0,进程启动时被这里的 "1" 盖掉。Claude Code 检测到 Vertex 配置齐活,就走 Vertex 通道去了,ANTHROPIC_BASE_URL 从头到尾没人问津——它压根不在那条代码路径上。

修复就一件事:把这三行删掉。

claude -p "1+1"
# 正常出结果,走的是中转站

这里值得单独强调一句env 的优先级,和 model 字段的优先级链(--model > ANTHROPIC_MODEL > settings.json > 默认,实测过)是两回事。model 那条链上 settings.json 排在环境变量后面,是「你没设我才用」;env 这个子字段反过来,是「我设了就盖你」。它还藏在 JSON 文件里,不像 shell 配置那样天天能看见——这才是它比 model 优先级更容易吃亏的地方。

坑二:launchd 启动的服务不读你的 shell 配置

命令行修好了,CloudCLI 那边还是未认证。

打开它的 plist:

<!-- ~/Library/LaunchAgents/com.xxxx.claudecodeui.plist -->
<key>EnvironmentVariables</key>
<dict>
    <key>PATH</key>
    <string>/usr/local/bin:/usr/bin:/bin</string>
    <key>HOME</key>
    <string>/Users/xxxx</string>
</dict>

只有 PATHHOME。没有 ANTHROPIC_BASE_URL,没有 ANTHROPIC_AUTH_TOKEN

根因:launchd 不读 ~/.zshrc 它跟 Linux 上的 systemd 是一个道理——服务进程不是从交互 shell 里 fork 出来的,你在 .zshrc / .bashrc 里写的任何 export,对它统统不可见。CloudCLI 自己环境是空的,透传给 claude 子进程的自然也是空的。

修复不是往 plist 里塞环境变量(那等于把 token 写进一个 XML,还要多维护一处),而是把中转站配置落到 ~/.claude/settings.jsonenv 块:

{
  "env": {
    "ANTHROPIC_BASE_URL": "https://xxxx.example.com",
    "ANTHROPIC_AUTH_TOKEN": "sk-..."
  }
}

写在这儿,两条路都能读到

  • Claude Code CLI 每次启动都读 settings.json 的 env,不依赖父进程给了什么;
  • CloudCLI 的认证逻辑专门读这个文件——它 loadSettingsEnv 的注释写得明明白白,「即使服务进程 env 为空也能用」。

同一个坑,坑一里 env 是加害者,坑二里它是解药。

验证:用 env -i 模拟服务环境

改完别急着重启 launchd 再登一次 Web UI 试——那一轮反馈太长。直接在终端里把环境清空,模拟服务进程的裸环境:

env -i HOME="$HOME" PATH="/usr/local/bin:/usr/bin:/bin" claude -p "1+1"

env -i 丢掉所有继承来的环境变量,只留你显式给的那两个——launchd 给什么,这里就给什么。这条命令能出结果,说明配置确实落在了「工具自己读得到」的地方,而不是靠 shell 喂进去的。

这个手法对付一切「命令行能跑、服务里跑不了」都好使:cron、systemd、Docker entrypoint,都是同一类环境断裂。

带走的教训

  1. 排查「环境变量设了却不生效」,第一站是 ~/.claude/settings.jsonenv 有同名键就是它赢,shell 里 export 多少遍都没用。这跟 model 的优先级链方向相反,别拿一套记忆套两处。
  2. 服务管理器不读 shell 配置。 launchd、systemd、cron 启的进程都看不见你的 .zshrc。依赖环境变量的工具一旦交给它们启动,配置就得落到「工具自己读得到的地方」——settings.json、服务的 EnvironmentVariables、独立 env 文件,三选一。
  3. env -i 是模拟干净服务环境的最快验证手段。 不用重启服务、不用重登,一条命令就知道配置落点对不对。
  4. 测试残留必须清。 ANTHROPIC_VERTEX_PROJECT_ID: "hello" 这种一看就是临时填的值,试完当场删。它不会报错,只会在几个月后跟你的新配置打架,而你完全想不到往那儿看。

相关文章

蜗牛在你点开的瞬间原地调头:一帧的时钟误差,被取模回绕放大成了最大误差

SwiftUI 里用 TimelineView 驱动一张吉祥物场景卡,两个毛病:第一次点开音色时蜗牛原地镜像翻转一下,停止播放时背景硬切。前者查了两轮——第一轮以为是 timeline 暂停导致时间源错位,改完仍在;真正的根因是相位取模时那句 `raw < 0 ? raw + 1 : raw`,它把「timeline.date 比 Date() 早了一帧」这个几十毫秒的误差,回绕放大成了 0.9999 的相位,而朝向恰好是相位在 0 处的不连续函数。这篇复盘讲清楚为什么在 TimelineView 里不能用 .transition、怎么把动画状态写成时间的纯函数、以及交叉淡化为什么要设计成「只有淡入没有淡出」。

bug-复盘swiftui+4
pitfalls2026年8月20日8 min
114

AI 视频的字幕越到后面偏得越多:别再修对齐算法了,问题出在「先生成整段音频」这一步

用 TTS + 自动字幕做科普视频,字幕前半段完美、越往后漂移越大,尾部时间戳甚至退化成 00:00:00。第一反应是修对齐算法——归一化数字、调相似度阈值——都是打补丁。这篇复盘给出根因:「整段 TTS + whisper 转写 + 事后匹配」这类方案在结构上必然漂移,因为它把本该由生成过程直接产出的时序信息,交给了一个会出错的事后重建环节。解法是逐句 TTS + 采样级拼接:字幕时间戳等于每句真实 wav 采样数的累加,句边界天然重置误差,物理上不存在漂移。附完整切句规则、缓存设计与适用边界。

ttsbug-复盘+3
pitfalls2026年8月20日4 min
117

Claude 没有写那个打印机驱动:14KB 胶水代码、一个 Linux 容器,和 HP 自己的二进制

一条「Claude 给只支持 Windows 的 HP 打印机写了 macOS 驱动」的推文拿到 262 万阅读。把仓库拉下来一看:Shell 6497 字节、Python 7638 字节、Dockerfile 550 字节,没有一行 C,真正做编码的是 HP 官方 Linux 驱动里的 rastertospl 二进制,跑在 Mac 上的 Linux 容器里。HN 上一群人指出了这件事。但这篇文章想说的不是拆台——四小时会话里真正有含金量的部分(读打印机吐出的错误页、绕过 CUPS 沙箱、libusb 直写),以及那个决定性转折点是人提出来的、不是 Claude 想到的,才是 AI 干脏活能力边界的准确刻度。

claude-code开源+6
claude2026年8月19日11 min
149

MCP Server 把 CPU 吃满 100%:一次 Cloudflare MCP 失控进程的排查与止血

Mac 风扇狂转、CPU 100%,定位到元凶是 Cloudflare 的 stdio MCP server:两个进程各吃满一个核,背后还堆着一排历史会话残留的僵尸实例。本文复盘现象、定位过程、stdio MCP 的进程模型缺陷,以及为什么低频运维操作用 REST API 比挂一个常驻 MCP 更合理。

mcpclaude-code+2
pitfalls2026年8月18日4 min
216