最近我把 Claude Code 的接入方式从官方 API 切到了第三方 API 服务,本想省点成本,结果发现两个特别头疼的问题:推理响应明显变慢,token 用量呼呼往上涨。跑了不到两天,一个本来很简单的代码库扫描任务,账单比官方直连还贵,速度还慢了一倍不止。
这个现象在社区里其实挺常见,很多人一遇到就怪第三方服务不稳定,但实际排查下来,问题往往出在 Claude Code 自身的调用策略和第三方 API 的兼容层上。我花了两天时间把整个链路重新梳理了一遍,从网络请求到会话上下文管理,再到本地推理引擎(localai、LMStudio 这类)的配置,最后总算是把速度拉了回来,token 消耗也降到了原来的三分之一左右。
这篇文章不打算讲官方文档里那些套话,只想把踩过的坑、排查的思路、以及最后真正有效的配置改动都摊开说,希望能帮到正在用 Claude Code 接非官方 API 的朋友。
1. 先从根上理解:为什么第三方 API 会同时拖累速度和 token
1.1 Claude Code 的调用机制,和你想的可能不太一样
很多人以为 Claude Code 就是一个把聊天窗口搬到终端里的工具,每次提问就发一次请求,然后等结果。实际不是这样。Claude Code 是一个编码代理(coding agent),它的工作方式是:你给它一个任务,它会自己规划步骤,然后反复调用工具(读文件、跑测试、执行命令),每一步都可能触发一次完整的 API 请求。
这意味着一个简单的“找出项目里所有遗留的 TODO 并汇总”任务,可能产生 5-10 次 API 往返。每次往返都会把当前会话的完整上下文重新发一遍——系统提示词、工具定义、历史消息、文件内容片段,全都要跟着请求走。这就是 Claude Code 的 API 请求模式:不是单次对话,而是多轮、大上下文、高频的序列请求。
明白了这一点,再看第三方 API 变慢和 token 暴涨就顺理成章了。任何影响“单次请求响应速度”或“单次请求上下文计费规则”的因素,都会被放大 5 倍、10 倍。
1.2 第三方 API 的三种常见形态,问题各不相同
我梳理了一下,大家常用的第三方接入无非这三种:
- 本地推理引擎:localai、LMStudio、ollama 这类,跑在自己机器上,通过兼容 OpenAI 或 Anthropic 协议的接口给 Claude Code 用。
- 统一接入服务:企业或者个人自建的一层聚合入口,背后接多个模型,按路由规则分发请求。
- 模型服务商提供的兼容接口:本身不是 Anthropic 官方,但提供了 Anthropic 协议兼容的 endpoint。
这三种形态各有利弊。本地推理引擎的好处是数据不出本机,但硬件算力有限,slow 是常态;统一接入服务方便多模型切换,但如果它的兼容层实现得不完整,各种诡异问题就来了;第三方兼容接口通常最便宜,但上下文缓存、流式传输这类细节往往支持不全。
我这次遇到的典型组合是:Claude Code 默认走官方协议,但接到本地推理引擎(localai)上,同时某些请求又被路由到了第三方兼容接口。两边行为不一致,token 统计和服务端缓存的逻辑全乱了,看起来就像是“API 让推理变慢、token 暴涨”。
1.3 慢和贵,其实是两个独立的问题,但会互相强化
先说慢。推理慢的本质是请求在网络上多绕了几跳,加上服务端排队、模型 prefill 和 decode 的时间。第三方 API 如果支持流式输出,Claude Code 可以在第一个 token 生成时就拿到数据,体感上就不会太差;但如果不支持流式,或者网关把流式响应缓存成了完整 JSON 再一次性返回,那么你等到的就是“全部生成完+网络传输完”的时间,体感差距会非常大。
再说贵。token 暴涨的根源几乎都出在上下文重发上。Claude Code 的会话上下文本来就大,官方 API 会利用 prompt caching 让重复发送的前缀打折扣;但第三方 API 如果不支持缓存,每一轮请求都按完整 token 数全额计费,多轮会话一累积,token 用量就会爆炸式增长。
更麻烦的是,慢和贵还会互相强化。因为响应慢,用户往往会让 Claude Code 重试或者重复提交;每次重试都是一次新的上下文重发,token 继续涨。token 涨多了之后,上下文接近模型窗口上限,又会触发压缩或截断,导致信息丢失、模型重新生成不必要的内容,又更慢。这就是一个恶性循环。
2. 推理变慢:别急着甩锅给 API,先按这条路排查
2.1 先把“慢”拆开:TTFB 和生成速度是两码事
我调试这类问题有个习惯,先把一次请求拆成两个阶段看:第一个阶段是“首 token 等待时间”(TTFB),也就是你发出请求到收到第一个 token 的时间;第二个阶段是“生成阶段”,也就是第一个 token 到最后一个 token 的时间。
这两个阶段慢的原因完全不同。TTFB 慢,通常不是模型本身的问题,而是网络链路、服务端排队、以及请求的 prefill 处理慢。生成阶段慢,才是模型推理算力的问题。
怎么拆?很简单,用 curl 直接打第三方 API 的接口,开流式,把时间戳打出来看。我试过用一个固定 prompt(比如“写一首关于秋天的诗”),先测官方 API 的 TTFB 和总耗时,再测第三方 API 的。两者一对比,问题在哪一段就清楚了。
2.2 第三方 API 慢的真正原因:prefill 耗时、流式关闭、并发排队
从我的实测来看,第三方 API 变慢最常见的原因有三个。
第一个是 prefill 阶段太慢。LLM 处理请求时,要先把你发来的所有输入 token 算一遍注意力,这个过程叫 prefill。上下文越大,prefill 越慢。Claude Code 的请求动不动就几万 token,第三方服务如果架构上对长上下文支持不好,prefill 时间可能占据整个请求的 70%。你可以把 prefill 类比成考试前把整张卷子从头读一遍,如果题目有 5 万 token,读题就要读半天,还没开始写答案呢,时间已经过去不少了。
第二个是流式传输被吞掉了。有些第三方接入层为了做计费统计或者日志记录,会把模型的流式输出攒成完整一段再返回给 Claude Code。表面上你调的是支持流式的接口,实际上拿到的是整个 JSON 一次性返回。Claude Code 本身是流式渲染的,一旦变成非流式,它必须等全部内容到达才能开始显示,体验自然就特别拖。
第三个问题是并发排队。Claude Code 的很多操作是并发的——比如同时读多个文件、同时跑多个搜索。第三方 API 如果限制了并发数,后面的请求就得排队。排队久了,Claude Code 会超时重试,重试又加剧排队,恶性循环。
2.3 实测排查清单:五分钟定位卡点
我整理了一份自己的排查顺序,照着走基本能定位到问题层:
- 先裸测接口:用 curl 直接请求第三方 API,加上
--no-buffer参数观察流式输出是否正常,记录 TTFB 和总耗时。 - 换一个极小的上下文测试:用一个只有几个 token 的 prompt 请求相同模型,看 TTFB 是否明显下降。如果上下文小的时候很快、上下文大的时候突然变慢,说明瓶颈在 prefill/上下文处理,不在网络。
- 看服务端日志:localai 和 LMStudio 都会打印请求处理时间,重点看 prefill 时间和 decode 时间分别用了多少。
- 用
/status查看当前上下文占用:如果上下文已经用了 80% 甚至 100%,先/compact压缩会话再继续测试,排除上下文过满导致的重试和截断。
我遇到的实际情况是:本地推理引擎的 prefill 占了总耗时的 80% 以上,而且因为显存带宽不够,长上下文处理特别吃力。后来我把上下文从“无限”手动限制到 32k 以内,速度立刻提升了一个档次。
3. token 暴涨的元凶:上下文重发、缓存缺失和工具调用开销
3.1 为什么同一个任务,官方 API 便宜,第三方 API 就爆
token 暴涨这事,我第一次意识到严重性是在跑了一个 30 分钟的小任务后,看了一眼统计,震惊了——消耗的 token 量竟然是任务里实际生成内容的一百多倍。问题就出在“重复发送的上下文”上。
Claude Code 是多轮代理式调用,每执行一个工具调用,就要把到目前为止的整个对话历史重新发给模型。如果一次任务产生了 20 次工具调用,而对话历史在不断增加,那么最终消耗的 token 大体等于“每一次请求的累计上下文之和”,而不是“最终那一次请求的上下文”。
我举个例子,假设任务开始时上下文是 60k token,之后每轮新增 5k,一共 20 轮。总消耗大约是每轮上下文之和,大概是 20×60k + 5k×(1+2+...+19),等于 1.2M + 950k,合计约 2.15M token。也就是说,你只写出了大约 100k 的内容,账单上却是两百万 token。
官方 API 之所以便宜,是因为它对重复的前缀做了 prompt caching,缓存的输入 token 计费大约只有非缓存价格的十分之一。一个连续多轮的会话里,大量前缀是重复的,命中缓存就是省钱。但第三方 API 如果没实现 prompt caching,这些重复前缀全都按全价计费,这就是 token 暴涨最直接的元凶。
3.2 工具定义和系统提示词也是一个隐藏大户
我一度以为是历史消息撑大了上下文,后来用/cost一查,发现工具定义的开销同样惊人。Claude Code 自带的工具非常多——文件编辑、搜索、执行命令、网页搜索,每个工具都有完整的 JSON Schema 描述。这些工具定义是每轮请求都要发的,加起来就有 3-5k token。
系统提示词也一样。Claude Code 每次启动都要加载系统提示词,如果你配置了 CLAUDE.md 和自定义指令,系统提示词会更长。在 20 轮请求的任务中,光系统提示词+工具定义就要重发 20 次,积少成多,3k token 也会变成 60k。
这还不算一些第三方 API 会在服务端额外注入自己的系统提示词,比如“你是某某模型的翻译器”这类说明。这些注入的隐藏 token 不会显示在你本地的 cost 统计里,但会算在消费里,导致你看到用量和实际计费对不上。
3.3 怎么算清楚一笔 token 账:手动拆解一个实战案例
光说理论太虚,我拿一个真实任务拆给你看。任务内容是“扫描当前项目所有 Python 文件,找出没有类型注解的函数定义”。
这个任务看起来很小,但 Claude Code 的运作方式是:
- 先发送一次请求,包含系统提示词、工具定义、用户任务(初始上下文约 65k token);
- 然后调用工具
Grep搜索文件,工具结果返回(约 2k token),此时上下文变成 67k,连续请求; - 接着调用
Read读取某个文件,文件内容返回(约 8k token),上下文变成 75k; - 又读第二个文件(累计 83k);
- 最后汇总结果写回复(累计 85k)。
一共 5 轮请求,实际生成的内容只有最后那一段回复,约 1.5k token。算一下总消耗:
- 第 1 轮:65k
- 第 2 轮:67k
- 第 3 轮:75k
- 第 4 轮:83k
- 第 5 轮:85k
合计大约 375k token。如果官方 API 带缓存,重复前缀可以打一折,实际计费可能只有纯新增部分的 token,大约 30-40k;而第三方 API 没有缓存的话,就是 375k 全额计费。同样一个任务,差距 10 倍。
我后来用/cost查了一下,这个任务实际消耗是 38 万 token 出头,和估算吻合。如果你也有“任务明明很小,token 却大得离谱”的困惑,十有八九就是上下文重发没有缓存的问题。
4. 实操优化:把第三方 API 的配置调成“省钱省时”模式
4.1 先检查环境变量:接入地址和模型路由别搞错
很多时候慢和 token 暴涨,其实是环境变量配置不规范。我整理了一份推荐配置,放在 Claude Code 的settings.json里:
{ "env": { "ANTHROPIC_BASE_URL": "http://127.0.0.1:8080/anthropic", "ANTHROPIC_AUTH_TOKEN": "local-dev-token", "ANTHROPIC_MODEL": "local-model", "ANTHROPIC_SMALL_FAST_MODEL": "local-model" }, "apiKeyHelper": "local-dev-token" }说几个容易踩的坑。ANTHROPIC_BASE_URL一定不要加多余路径,具体对接的是/v1/messages还是/anthropic/v1/messages,要以第三方服务的文档为准。路径差一层,请求直接 404,然后 Claude Code 会无限重试,看起来像是“API 变慢”,其实根本没通。
ANTHROPIC_MODEL也要和第三方服务的模型列表对齐。我遇到过一个报错,提示llm-deepseek: no api key for provider route "deepseek-official",查了半天,原因是我把模型名填成了服务商内部的 provider 路由名,但接入层找不到对应的 API key 配置。正确做法是填你在该服务里实际创建的模型别名。
4.2 限制工具爆炸:减少无效往返就能省大量 token
上一节算过账,工具调用轮次是最主要的 token 消耗驱动者。那么为了省 token,核心手段就是减少无效的工具调用。
我试过几个有效办法。第一是清理不必要的工具。Claude Code 支持在settings.json里配置允许的工具白名单,比如我只让它用Read、Grep、Glob和Bash,把网页搜索、文件编辑这类在这个项目里用不到的工具全部关掉。工具定义少了,每轮请求的 token 就少了,模型也不容易瞎调用。
第二是在 CLAUDE.md 里写清楚约束。比如写上“先使用 Glob 和 Grep 搜索,再决定是否读取文件;不要一次性读取整个目录;不要用 Bash 运行项目无关命令”。模型会遵守这些约定,减少很多无意义的工具调用。
第三是检查第三方服务端的注入逻辑。localai 这类引擎通常是中立的,但有些统一接入层为了保证下游兼容性,会额外往请求里塞系统提示词。你可以在服务端日志里看到实际转发给模型的完整请求体,检查里面有没有你不需要的注入内容。
4.3 流式传输和超时参数:让慢请求变成可容忍的普通请求
推理慢的体验问题,很大程度可以通过调流式传输和超时来缓解。
第三方 API 如果支持流式,要确保 Claude Code 请求时带了stream: true。有些服务商的 Anthropic 协议兼容层默认把流式关掉,你需要到服务端配置里打开。以 localai 为例,安装 Anthropic 兼容层后,需要在它的配置里明确启用STREAMING选项,否则收到的是非流式响应。
超时设置也同样讲究。Claude Code 默认的请求超时时间是 60 秒还是 10 分钟?不同版本不太一样,但如果你接的是本地推理引擎,生成长文本时一次请求可能超过 3 分钟。我建议把超时时间加大到 300 秒或更长,同时让 Claude Code 等待响应的重试次数降下来——因为重试一次就是一次完整的上下文重发,token 消耗直接翻倍。
4.4 压缩会话和拆分任务:细水长流的省 token 技巧
最后一个手段是改变使用习惯。这里有几个体感明显的小技巧:
- 定时
/compact:上下文到了七八成的时候就手动压缩,把历史摘要化,而不是等它自动触发。自动触发压缩时往往上下文已经爆满,压缩本身还会产生一次额外的大上下文请求。 - 任务拆分:一个大型重构任务不要一个会话从头跑到尾,让 Claude Code 先输出方案和文件清单,你确认后再让它分批执行。这样能显著降低单会话的上下文天花板。
- 在
/status里观察上下文用量变化趋势,如果增长太快,说明模型在反复读取和重写同一个大文件。这时候给它更明确的指令,例如“修改函数体时只读取该函数所在的 50 行,不要读取整个文件”。
5. 常见报错速查与排查实录
接第三方 API 时,报错基本集中在认证、上下文长度、路由配置这三类。我把最近遇到的几个整理成了一张速查表。
| 报错信息 | 原因 | 排查方法 |
|---|---|---|
no api key for provider route "deepseek-official" | 模型路由到了某个 provider,但没配对应 key | 检查模型别名与接入层 provider 映射,确认该 provider 的 key 已设置 |
token exchange failed: error sending request | 认证服务器网络不通或地址错误 | 检查 auth endpoint 配置、DNS 解析、证书是否正确,确认请求能到达认证服务 |
token endpoint returned status 403 forbidden | 账号或服务区授权校验不通过 | 确认账号是否具备该服务访问权限,检查服务方对调用区域或组织策略的限制,联系服务商处理 |
maximum context length is 1048576 tokens | 请求总 token 超过了模型窗口,或模型上下文设置过大 | 用/compact压缩会话,检查第三方模型实际支持的 context 长度,对齐配置 |
invalid 'refresh_token': empty string | 本地持久化的凭据丢失或失效 | 重新执行登录流程,生成新的凭据,检查配置文件中的 token 字段 |
your organization has disabled claude subscription access | 组织策略禁止通过订阅方式使用 Claude Code | 改用 API key 方式认证,或联系组织管理员调整策略 |
sign-in failed: token exchange failed | 登录态过期且刷新失败 | 退出登录后重新登录,检查系统时间是否准确,时间偏移会导致 JWT 校验失败 |
逐个展开说。权限和地区策略出现 403 时,我踩过几次坑——本以为是网络问题,反复刷接口都没用,后来发现是账号在服务商那里的授权范围没覆盖当前调用来源。这个一般需要联系服务商解决,不是你在本地改几行配置能绕过的,安全合规优先。
上下文超限是另一个高频问题。有时候模型窗口显示 1M token,但第三方服务实际处理不了那么长的上下文;有时候是 Claude Code 的会话已经膨胀到极大,再发一次请求就超限。处理方式都是先/compact压缩,再检查模型服务端的 context 设置。本地推理引擎的话,还要看显存够不够,显存不足半途会 OOM,Claude Code 那边表现为请求被切断、下一轮重发全部上下文,token 又消耗一波。
凭据失效这类问题,我在用统一接入服务时遇到过几次。具体表现就是刷完登录状态之后,过几小时又报refresh_token失效。这通常是服务端的 refresh token 有效期设得太短,纯粹的认证策略问题,你只能重新登录,顺手检查系统时间是否准确——时间偏移会导致 token 签名校验直接失败,出现莫名其妙的token exchange failed。
在实际操作中的几个体会
这类问题排查到最后,我的体会是:不要把第三方 API 当成官方 API 的“平替”来对待,它的行为方式不一样,需要主动适配。如果发现慢和 token 暴涨同时出现,先怀疑流式传输和缓存支持,再怀疑上下文管理,最后才考虑是不是模型本身不行。
另外,建议平时开一个终端专门跑claude --cost或者用/cost看单次任务的 token 分布统计。很多问题刚发生的时候看统计就能看出端倪——举个例子,如果输入 token 和输出 token 的比值超过 100:1,那基本就是上下文重发太频繁了,而不是模型输出太多。
用第三方 API 和本地推理引擎图的是成本可控和数据可控,但前提是上面这些参数都对齐了,否则省下来的钱会被无效 token 慢慢吃回去。至少我现在这套配置已经跑了一周,速度和 token 消耗都稳定在可接受范围,希望这篇文章也能帮你少走几步弯路。