Claude Code换用DeepSeek V4:400万Token成本从26美元降到2美元 我前阵子把一个批量迁移任务丢给 Claude Code断断续续跑了差不多一周到月底一看用量明细累计消耗 400 万 Token费用 26 美元。当时第一反应不是“我提示词写得不够好”而是“这钱花得有点冤”。后来我把执行模型切到 DeepSeek V4用一套兼容配置继续跑完剩下的任务账单直接掉到 2 美元上下代码该改的也都改了工具调用该跳的也都跳了。这篇文章就是这次接入的完整过程怎么把 Claude Code 的默认后端换掉、400 万 Token 是怎么烧出来的、中间踩了哪些坑以及最后我为了控制成本到底动了哪些习惯。适合那些还在用 Claude Code 跑大批量任务却被 Token 消耗搞得肉疼的同行。1. 先看看这 400 万 Token 到底是怎么花出去的1.1 一个你以为很小的任务为什么能吃这么多量这次接的活说简单也简单把一套内部系统的 300 多个页面文案从旧格式统一成新格式再顺手修正一批不规整的组件命名。听起来就是个“复制粘贴微调”的活儿但用 Claude Code 跑的时候问题完全不是这样。Claude Code 每轮对话并不是只把你输入的那句话发给模型。它会把系统提示、工具定义、历史消息、上一轮工具执行后的输出全部打包发给模型。你让它“读取某个文件”它就先要发一条Read请求把你指定的文件内容作为上下文塞进去你让它“改一个变量名”它要先读一遍相关文件再发起一次Edit然后还要执行一次Bash来跑编译或搜索。每一个动作背后都是几千甚至几万 Token。我这批页面文件大部分是 300 到 600 行左右的 Markdown 和组件文件每次完整读写一个文件就能消耗 8000 到 15000 Token。再算上多轮对话里反复追问、上下文越堆越长一个看起来没多复杂的批次任务跑下来轻松就是 20 万到 40 万 Token。300 多个文件分几轮处理400 万 Token 很快就来了。我后来统计了一下用量分布。四百万 Token 里输入部分占了绝大多数大概是 360 万左右输出只有 40 万上下。这说明 Claude Code 这种“工具调用驱动”的工作方式真正吃预算的不是让模型写多少字而是让模型循环读取、修改、验证所产生的大量输入上下文。1.2 官方 API 的成本结构决定了这笔钱省不下来用官方默认模型跑的时候计费是输入和输出分开算的。输入部分每百万 Token 大概是 3 美元输出部分每百万 Token 一档是 15 美元缓存读取又会低一些但也不是免费。拿我这批任务来说360 万输入加上 40 万输出按官方计费口径粗略算一下就是接近 17 美元。但实际账单是 26 美元出头原因很简单会话越往后历史消息被反复携带早前读过的文件内容在后续每一轮都会被再次计费再加上中间有一段时间我没有使用缓存同一个大文件在相邻几轮里被反复完整读取费用自然会往上翻。这里得说清楚官方默认模型本身的输出质量是非常好的尤其擅长复杂的代码重构和不知道前后逻辑的多文件修改。但当你跑的是“批量格式化、批量改名、按模板重写”这类体力活时它的质量优势体现不出来成本劣势反而暴露无遗。一个需要持续 200 轮工具调用的任务十有八九比想象的更贵。1.3 换到 DeepSeek V4 的本质是一场“任务匹配”把模型换成 DeepSeek V4 之前我先做了一次简单的任务拆解这个项目里有多少比例的任务真正需要顶级推理能力结论是大概只有两成。剩下八成是“读文件—按规则替换—验证结果”的机械流程完全不需要最贵的模型来兜底。Claude Code 本身是一个调用模型的客户端框架它可以被配置成使用其他兼容接口。DeepSeek 提供了兼容 Anthropic 格式的端点调用方式可以基本对齐因此 Claude Code 不需要做太多改动就能切换后端。这样替换之后同一批剩余任务继续跑最后的费用大概是 2 美元出头。输入和输出按 DeepSeek 的单价重新算一遍刚好是官方价格的十分之一左右。这个“十分之一”并不是模型变笨了而是这类任务的固定属性大量输入、少量输出、重复模式多恰好是低价模型的甜区。2. 接入 DeepSeek V4 前先把这几个配置想清楚2.1 三个环境变量就决定了请求往哪里走Claude Code 默认情况下会把所有请求发给官方接口但只要在启动它之前设置几个环境变量请求就会被重定向到兼容端点。我用的是这三个export ANTHROPIC_BASE_URLhttps://api.deepseek.com/anthropic export ANTHROPIC_AUTH_TOKENsk-你的密钥 export ANTHROPIC_MODELdeepseek-v4ANTHROPIC_BASE_URL是接口地址所有对话和工具调用都会发到这里。ANTHROPIC_AUTH_TOKEN是鉴权用的密钥替换成你在 DeepSeek 后台创建的密钥即可。ANTHROPIC_MODEL指定要使用的模型名我当时的配置是deepseek-v4具体模型名要以模型服务商的官方文档为准。这里有一个新手很容易忽略的点这三个变量必须在你输入claude命令之前设置好。如果你是在已经打开的 Claude Code 会话里临时补了环境变量当前进程不会自动重新读取必须退出重启。我最初就是在会话内设置了环境变量然后继续跑结果所有请求还是发去了默认端点白白跑了几十分钟才发现。如果你不想每次开终端都手动 export可以直接写进 Claude Code 的配置文件~/.claude/settings.json这样每次启动它都会自动带上。2.2 用 settings.json 固化配置避免换模型时手忙脚乱settings.json是 Claude Code 的全局配置文件。我在换用 DeepSeek V4 之后是把环境变量和模型参数一起放在这个文件里的方便团队里其他人使用时直接参考。一个最小可用的配置大概是这样的{ env: { ANTHROPIC_BASE_URL: https://api.deepseek.com/anthropic, ANTHROPIC_AUTH_TOKEN: sk-你的密钥, ANTHROPIC_MODEL: deepseek-v4 }, model: deepseek-v4, permissions: { allow: [Read, Edit, Bash, Glob] }, maxTokens: 8192 }其中permissions控制的是 Claude Code 可以直接执行哪些工具操作。我在批处理任务里只开放了读取、编辑、执行命令和文件检索把不需要的工具全部关掉。这里的效果前面也提到了工具定义本身会作为上下文的一部分反复发送权限列表越短每轮的 token 消耗越低。maxTokens是单次响应输出上限。我建议不要开太大通常 4096 到 8192 就够用了。输出太多之后系统会把长输出当成下一次输入的一部分重新发送如果输出里面有大量不需要的内容等于变相增加成本。2.3 配置完先做三件事避免“白跑一趟”换完配置之后别急着直接跑大批量任务先花五分钟验证三件事。第一确认模型身份。启动 Claude Code输入/status查看当前使用的模型名应该是deepseek-v4而不是默认模型。第二验证一次最简调用。用一行命令直接跑一个打印任务echo 请用一句话介绍当前环境 | claude -p如果它能正常返回结果说明接口地址、鉴权密钥和模型名三者都配对了。如果返回报错优先检查密钥有没有复制错、模型名是否和官方文档一致。第三验证工具调用。让 Claude Code 读取一个小文件并替换一个字符串然后再读回来检查替换是否生效。这一步非常关键。很多人第一次切换后普通对话没问题但真正跑起 Claude Code 的核心功能“工具调用”时就报错原因大多是模型与工具格式兼容性没对齐。提前用最小命令确认后面跑大批量任务时会安心很多。3. 400 万 Tokens 的完整实战清单3.1 先把任务切成可以回滚的小块我不建议把 300 个文件一次性全塞给 Claude Code 处理。原因很简单一旦在中间某个环节出现理解偏差它会带着这个偏差污染后面的所有文件。我这次的做法是先按目录把任务切成 10 到 20 个文件一批每批用一个独立会话跑。每一批都先让 Claude Code 列出一个处理计划我再快速过一眼计划是否正确正确就让它继续不正确就立刻改提示词。这样即使某批跑偏了损失的 token 也只有几万而不是几十万。这里还有个细节每一批跑之前我都会清空一下当前工作区里那些临时生成的输出文件。因为 Claude Code 在读取文件时如果发现同目录下多出来一些上次生成的文件它会把它们也读进上下文。上下文一旦变乱模型判断就容易出错。3.2 关键参数我是怎么定的不是拍脑袋在跑大批量任务时启动参数直接影响成本。我最后用的是这一套启动方式claude --continue --max-turns 30 --allowedTools Bash,Read,Edit,Glob--continue是接续上一个会话而不是每次都从零开始。这样能避免每次启动时重复加载系统提示和工具定义省下不少输入 token。--max-turns 30限制了单次会话最多执行 30 轮工具调用。这个限制很重要没有它同一个会话会一直运行到任务自己结束一旦模型进入一个重复循环Token 就会以非常快的速度烧掉。--allowedTools限定了允许工具的范围这个我前面提过核心意义是减少工具定义占用的上下文空间。工具列表越长提交给模型的工具 schema 越大每轮都会重复计费。另外我把超时时间调得比较保守。默认情况下如果某次调用执行时间过长Claude Code 可能会因为等待过久出现幻觉式的“重试”行为导致同一段代码被反复处理。把超时控制在 5 分钟左右配合--max-turns能保证任务在可控节奏下推进。3.3 每 10 万 Token 做一次检查点比拼命跑到底有用跑大约 10 万 Token 之后我会主动踩一次刹车。具体做法是用/compact把当前会话的历史摘要压缩然后让 Claude Code 基于摘要继续后续任务。为什么不继续带着完整历史跑因为上下文越长后续每一轮计费就越高。一个跑了 50 轮、上下文里塞了 8 万 Token 历史消息的会话之后光是发送这些历史就要花掉大量输入预算。/compact的意义在于把已经有定论的内容压缩成一段摘要同时保留关键文件路径、规则和还没完成的任务清单。执行/compact之后模型可能会丢失一些细节记忆。为了补偿这一点我通常在关键规则处单独写一个RULES.md放在项目根目录每次新会话开头让 Claude Code 读一遍。这个文件本身会花一些 token但相比无休止的历史消息重发性价比高得多。3.4 看账单不要只看总数否则你会误判成本比例一次任务结束我会去后台把 usage 数据拉出来。重点看三个字段输入 token、输出 token、缓存命中数。我见过不少人看账单时只看到了“400 万 Token”这个总数然后惊呼“模型太能吃”。其实输入和输出的单价差别很大如果输出只有一点点费用大头就在输入如果缓存命中高费用也会明显下降。不分开看就没有办法判断后面的优化到底该往哪儿使力。我自己的统计方式是每跑完一个批次就在配套的统计表格里记录一组数据文件数、轮数、输入、输出、缓存命中、费用。这样后面任何一次调整只要对比前后两批的数字就能清楚判断改动是正向还是负向而不是凭感觉。4. 中途踩到的坑和排查记录4.1 工具调用报错响应格式不符合预期第一次切换之后跑了大概 5 轮对话突发情况就来了。Claude Code 向我报告某次编辑没有生效提示“工具执行出现异常”。我直接查看日志发现是模型的工具调用返回格式和 Claude Code 的解析器没对齐。这不是说接口不兼容而是模型在极端情况下会生成一个“伪工具调用”比如它把工具名称写错了或者把参数当成普通文本输出。解决方式分两步第一步确认当前模型版本确实支持完整的 Claude 工具调用格式如果模型文档里写明只兼容部分能力就需要升级到支持完整工具调用的版本第二步在项目里跑一个最小编译调用就是让模型“读取某个文件并把某个字符串替换掉”观察它是否严格按照工具调用规范执行。这类问题其实是所有跨模型接入里最常见的说到底是模型和框架之间的协议版本不完全一致。解决办法没有捷径只能通过最小复现代码来验证模型的行为是否符合框架预期。4.2 长上下文被截断模型开始“失忆”跑到一个比较大、接近 5000 行的文件时Claude Code 提示上下文长度超限而且后面几轮明显开始“忘记”前面约定的规则。准确的讲并不是模型真的失忆而是上下文被内部截断系统只保留了关键部分把中间的一些指令挤掉了。我当时的处理办法是把大文件拆分成更小的片段只让 Claude Code 处理其中相关的那一两百行而不是把整个文件丢进去。后来我发现在 prompt 里可以让 Claude Code 先用Glob检索定位关键代码段再用Read读取该文件的起始部分和末尾部分分段处理比一次全读要省 Token也不容易触发上下文截断。另外遇到特别大的文件时我会先让 Claude Code 用Bash执行一段脚本把文件里需要关注的“关键行号”提取出来之后只读取这些行附近的代码。这个方法的好处是明显减少无意义的上下文填充缺点是要求我对文件结构有一定了解不能完全把判断甩给模型。4.3 限流与响应卡住不是模型坏了切换后的第二天出现了一批 429 限流报错同一个密钥的并发请求太多API 直接拒绝了部分调用。Claude Code 在这种情况下会自动重试但重试期间如果任务本身还在继续发请求就会造成更多的 429形成恶性循环。我的解决方式是降低并发。刚接入时我习惯开着多个终端窗口同时跑任务后来改成每次只跑一个会话并且把每次启动之间的时间间隔拉长到 5 秒以上。对于不急于完成的批量任务这个延迟完全可接受。响应卡住的情况也要单独说。有些时候模型思考时间很长界面看起来像没反应。我当时差点 CtrlC 杀掉进程后来才明白那只是模型在纠结某个步骤。解决方式是给单次响应设一个合理的输出上限并耐心等一个完整的工具调用结果。如果是真的超时我再手动中断这时我会把一个会话内记录关键进度的小文件更新到磁盘方便后面重新接入时模型能迅速恢复状态。4.4 缓存命中带来的价格误判切换之后我注意到一个有意思的现象DeepSeek 的计费里缓存命中价格非常低。如果某个系统提示、历史片段在短时间内被重复使用后续调用会命中缓存费用按“缓存命中”档位计算。这本来是好事但问题在于它会让人误判任务的实际成本。举个例子一批任务里有 30 个文件每个文件的处理逻辑相同只是数据内容不同。前几个会话会把“系统提示规则说明工具定义”完整加载并计费后面的会话只要系统提示内容没变就会被缓存命中价格低了一大截。这时候如果你只看总体费用会觉得任务很便宜但一旦调整了系统提示缓存全部失效下一批任务费用突然又涨回去了好像模型变贵了一样。这其实不是模型变贵是缓存命中率波动导致单价变化。我现在的做法是任何一次任务费用对比都要在同一套系统提示和规则文件前提下进行。不然你比较出来的“优化效果”很可能只是缓存命中的变化而不是真实的任务消耗变化。5. 这次接入之后我顺手调整的几个习惯5.1 把每轮都要发的那部分上下文压到最薄切换模型之后最大的收获其实不是省了几十美元而是我开始认真审视 Claude Code 每次调用到底发出去多少“固定开销”。系统提示、工具定义、历史消息这些都是固定的重复内容每一轮都要计费。以前用官方默认模型时我对这些开销并不敏感因为任务跑完就完这次因为全程盯着 token 消耗才发现这些固定开销在一个长任务里能占到相当大的比例。我后来做的调整有几个一是不再让 Claude Code 自动加载所有工具只保留当前任务必要的三个二是把系统提示写成精简的指令列表去除所有客套和重复解释三是规定自己在同一个会话里不反复上传同一个大文件如果第二次还要读取就让 Claude Code 先去查询文件修改时间确认变了再读。这三件事叠加起来单轮消耗能降低 30% 左右。5.2 核心任务和重复体力活分开用模型这次之后我完全没有“以后全用 DeepSeek V4”的想法。模型选择始终是一个任务匹配问题。做多文件重构、写全新模块这类需要强推理的任务我还是会切回官方默认模型格式统一、批量改名、规则替换这类高度重复的活才用 DeepSeek V4 来跑。这样做的好处不只是成本节省更是避免低价值任务占用高价值模型的输出配额。对一个需要反复修正迭代的核心模块来说模型质量直接决定交付质量这时候省钱意义不大。反过来那些一次性的批量处理任务用便宜模型跑通了再把结果人工抽检一遍性价比确实高出很多。你完全可以在同一个项目里准备两套配置一个默认配置指向官方模型用于核心开发另一个通过环境变量切换到 DeepSeek V4用于脚本化的批处理。启动时用不同的 shell 脚本切来切去并不会增加多少麻烦。5.3 每批任务留一个“决策记录”比日志好用跑这种大 token 任务最大的隐性成本不是钱而是“重跑”——因为没有记录当时的决策下一次进入会话时模型又从头开始判断时间和 token 双重浪费。我现在习惯在每个批次的任务目录下生成一个DECISIONS.md把每批的关键决策、已确认的规则、尚未完成的事项按时间顺序写进去。这比我之前用的日志方案更好用因为日志记录的是“模型做了什么”而决策记录写的是“为什么这么做”。新会话启动时让 Claude Code 读一遍DECISIONS.md相当于给它装了一份有效记忆。虽然读文件本身要花一点 token但和省下来的重跑成本比代价完全可以忽略。5.4 别让“便宜”成为你乱跑任务的借口最后想多说一句。把成本降到十分之一之后很容易产生一种幻觉既然 token 便宜了那我是不是可以让 Claude Code 随便跑、反复试我试过结果并不好。便宜模型在低难度任务上和经济模型差异不大但在反复出现的“模糊上下文”上它的稳定性会比顶级模型稍弱。一旦任务本身定义不清便宜模型会把错误实时固化到代码里你后面要花大量时间清理。所以我的经验是接入便宜模型之后反而要把任务拆得更细、提示词写得更准。因为你付的低价只代表“执行单价低”不代表“试错成本低”。试错成本一旦堆起来几十美元的差价根本不够看。那次 400 万 Token 的经历算下来真正教会我的不是怎么把成本从 26 美元降到 2 美元而是让我把“模型调用”这一件事彻底看清楚哪些开销是可避免的、哪些任务是可以用低配模型完成的、哪些环节必须花大价钱买质量。如果你手上也有一个长期在跑的 Claude Code 任务我建议你也做一次同样的拆解——算一笔账把所有 token 消耗来源列清楚再决定切换还是不切换。这个动作本身花不了多少时间回报却远比省下一顿饭钱要大。