AI Coding 中如何节省 Token
- 文章分三大块:先讲清楚钱是按什么算的,再讲缓存这个省钱大头(缓存基础与缓存命中策略),最后是实操方法
- 参考来源以 DeepSeek 官方文档为主,以官方定价页为准。
计费标准
一次对话发生了什么
- 要省钱先得知道钱花在哪。一次对话到底发生了什么,从头拆一遍
- 一次对话落到工程上就是一次 HTTP 请求,客户端把一整段 messages 数组发过去,服务端算完把结果发回来
- 关键事实:模型是无状态的,每次请求都要把完整上下文重新发一遍
- “继续聊天”只是假象,每次请求都是把 system 消息、之前所有轮次的 user/assistant/tool 消息原样打包重发
- 上次聊了什么,模型不记得,全在请求里。对话越长,每次请求的输入越大,这是 token 开销的第一来源
- 服务端处理分两个阶段(DeepSeek-V3 技术报告里明确把这两个阶段分开部署):
- prefill(预填充):把输入整段一次性并行算完,产出第一个 token,同时把 KV cache 存下来
- decode(解码):从第一个 token 开始逐 token 生成,一次一个,靠 KV cache 复用前面算好的部分
- 请求返回两个东西:
- choices[0].message.content:最终答案(思考模式下还有 reasoning_content,思维链)
- usage:本次消耗的 token 明细,是计费依据,也是后面诊断开销的入口
- DeepSeek 官方 usage 字段(API Reference 里的定义):
| 字段 | 含义 |
|---|---|
| prompt_tokens | 输入 token 数,等于下面两个相加 |
| prompt_cache_hit_tokens | 输入中命中上下文缓存的 token 数 |
| prompt_cache_miss_tokens | 输入中未命中缓存的 token 数 |
| completion_tokens | 输出 token 数 |
| completion_tokens_details.reasoning_tokens | 输出中思考(思维链)部分的 token 数 |
| total_tokens | 输入加输出 |
- 费用 = 各分类 token 数 × 对应单价,所以想省钱,就是让 token 落在便宜的类里(比如命中缓存),或者干脆少用
输入的定义与组成
- 输入就是上下文,上下文就是 messages 数组里的全部内容,模型一次性读完,从头到尾
- 按角色分,输入由这几类组成:
| 角色 | 是什么 | 典型内容 |
|---|---|---|
| system | 系统提示词 | 角色、规则、输出风格,每次请求原样带着 |
| user | 你这次说的话 | 提问、任务、贴的代码、塞的文件 |
| assistant | 模型以前说过的话 | 对话历史、工具调用记录 |
| tool | 工具返回结果 | 命令输出、文件内容、API 响应 |
- 在 AI 编码工具里,输入基本是这几样拼起来的:
- 工具自身的 system prompt(Claude Code、Hermes 这类工具都内置一大段规则)
- 项目上下文(项目说明、文档、skills、被引用的文件)(有些工具默认就把一堆东西塞进来,你还未必知道)
- 会话历史(之前的对话轮次,包括模型输出的内容,甚至思维链)
- 输入受上下文窗口限制,DeepSeek V4 系列是 1M,够塞下一本书。但窗口大不等于该塞满,塞得越多每次请求越贵,而且上下文一多模型容易忘记或注意力不集中,实际有用高效的部分只占 30% ~ 40% 窗口大小,要经常做上下文管理
输出的定义
- 输出是模型这一轮生成的所有 token,主要有三类:
- content:最终答案正文
- reasoning_content:思维链
- 工具调用 JSON(请求带 tools 时)
- 思考模式默认开启:DeepSeek 默认 effort 是 high,也就是说每次回答前模型都会先输出一大段推理过程,这部分全是输出计费,单价还是最贵的那档。思考模式默认开启这件事,好多人是第一次看账单才知道的
- 这里有个省 token 的官方机制,很多人不知道:请求不带 tools 参数时,reasoning_content 不需要回传,即使传了也会被忽略、不会拼进上下文(官方文档原话)。但 AI 编码工具几乎都带 tools,所以思维链会进上下文,这是编码场景特有的开销来源
输入输出的分类
| 分类维度 | 分类 | 说明 |
|---|---|---|
| 按角色 | system / user / assistant / tool | 输入的不同来源 |
| 按内容 | 指令 / 数据 / 历史 / 推理 | 指令是任务,数据是材料,历史是对话,推理是思维链 |
| 按计费 | 命中缓存输入 / 未命中输入 / 输出 | 三类价格差最大能到几十倍 |
输入输出开销差异与原因
- DeepSeek 官方当前定价(每 1M tokens,空闲时段价,2026-09 抓的官方中文定价页,以官方页为准):
| 模型 | 输入(缓存命中) | 输入(未命中) | 输出 | 上下文长度 |
|---|---|---|---|---|
| deepseek-v4-flash | 0.05 元 | 1.5 元 | 4.5 元 | 1M |
| deepseek-v4-pro | 0.15 元 | 4.5 元 | 13.5 元 | 1M |
| deepseek-v4-flash-vision-exp | 0.05 元 | 1.5 元 | 4.5 元 | 1M |
- 顺带一提,deepseek-chat / deepseek-reasoner 这两个旧模型名已经在 2026-07-24 弃用,现在只有 V4 系列。网上还飘着旧价格表的文章,别信
- 看三个数字,得出三个结论:
- 缓存命中的输入约是未命中的 1/30(flash 的 0.05 vs 1.5 元),命中缓存是最大头的省钱手段
- 输出约是未命中输入的 3 倍(4.5 vs 1.5 元),输出是单价最贵的部分,思考模式的思维链还额外堆在这上面
- 输入即使全部未命中也比输出便宜,所以”多塞点必要上下文让模型少猜”在单价上划算,前提是别塞没用的
- 为什么输出最贵?回到 prefill 和 decode 的原理:
- prefill 处理输入,整段并行算,能吃满 GPU 并行度,单位 token 的算力成本低
- decode 生成输出,一次只能算一个 token,串行;每生成一个 token 还要读一遍越来越大的 KV cache,受内存带宽限制,单位 token 的算力成本高
- DeepSeek-V3 技术报告里写得很直白:decode 阶段每个专家只有很小的批量(通常 256 token 以内),瓶颈是内存访问而不是计算
- 说白了,输入可以批量打包处理,输出只能一个字一个字现写,贵是计算方式决定的
- 还有高峰 / 空闲时段计费(DeepSeek 官方规则,北京时间口径):
- 高峰:周一至周五 09:00-12:00 和 14:00-18:00(北京时间)
- 空闲:其他所有时间,价格是高峰的一半
- 对个人开发影响不大,但批量任务、CI 脚本挑空闲时段跑能省一半
token 的分类与开销差异
- 同一段内容,不同模型切出来的 token 数不一样,直接决定花多少钱
- DeepSeek 官方口径(Token & Token Usage 文档):
- 1 英文字符 ≈ 0.3 token
- 1 中文字符 ≈ 0.6 token
- 一个中文词、英文词、数字或符号通常算一个 token
- 注意口径差异:OpenAI 官方口径是 100 tokens 约 75 个英文单词、中文 1 字约 1-2 token。各家 tokenizer 不同,比例只能估算,实际以 usage 返回为准
- 按字符数比,中文的 token 数是英文的 2 倍;但表达同样意思,中文文本通常短得多,谁更省不能一概而论,别凭感觉,用官方给的离线 tokenizer(deepseek_tokenizer.zip)实测,网页端还有图片 Token 计算器
- 图片输入按尺寸换算 token(deepseek-v4-flash-vision-exp):
- 图片会自动缩放:小图放大、大图缩到约 800×800 的总像素
- 每张图上限 384 token,2000×2000 和 5000×5000 的图花的钱一样
- 多张图每张独立计,按输入价计费
- 一张截图 ≈ 384 token,按输入价计费(图片能否命中缓存,官方文档没明确说,别指望它享受文本缓存的折扣)
- 思维链 token:思考模式下 reasoning_content 按输出价计费,AI coding 里模型经常”想很久”,这部分开销不小
- 小结:token 开销差异来自四个维度,语言(中/英/代码)、类型(文本/图片)、阶段(输入/输出)、缓存(命中/未命中)。实操方法基本就是围绕这四个维度展开
缓存基础与缓存命中策略
缓存的概念
- 命中缓存的输入开销只要未命中的 1/30,这一章把它讲透:缓存是什么、怎么命中、怎么失效
- 上下文缓存(context caching)是什么:服务端把请求的前缀部分存下来,后续请求如果前缀相同,重叠部分直接从缓存取,不重新计算
- 为什么能缓存:模型处理输入时,相同前缀的计算结果是确定的,中间结果(KV cache)可以复用。上一轮算过的东西,下一轮不用再算一遍
- 省在哪:输入 token 按缓存命中价计费。flash 的命中输入 0.05 元/1M vs 未命中 1.5 元/1M(空闲时段),差了 30 倍
- DeepSeek 官方实现:Context Caching on Disk Technology(磁盘缓存),默认对所有用户开启,不用改任何代码(官方原话 “enabled by default for all users, allowing them to benefit without needing to modify their code”)
- 命中状态在 usage 里看:prompt_cache_hit_tokens(命中)和 prompt_cache_miss_tokens(未命中),加起来就是输入总数
缓存的分层架构
- 先纠正一个常见误解:缓存本身不分”系统 / 项目 / 会话”三层,这说法是拿应用层的上下文分类去套缓存
- 缓存的粒度只有一个:前缀。请求的 messages 数组从头开始,前缀越稳定,能命中的部分越多
- 那”系统 / 项目 / 会话”是什么?是编码工具在应用层拼 messages 数组时,上下文的三个来源。它们的稳定性,直接决定前缀稳不稳定:
| 上下文来源 | 内容 | 稳定性 | 对缓存的影响 |
|---|---|---|---|
| 工具/system 提示词 | 工具内置规则、你的角色设定 | 基本不变 | 前缀最前面,最稳定,最容易命中 |
| 项目上下文 | 项目说明、文档、skills、被引用的文件 | 较稳定 | 中间部分,改了会导致断点之后全 miss |
| 会话历史 | 对话轮次、工具结果、思维链 | 一直在变 | 尾部,每轮都在增长 |
- 所以”系统 / 项目 / 会话”是上下文的来源分层,不是缓存的机制分层。缓存眼里只有前缀匹配,没有这些概念
- 各家 API 的缓存机制对比(具体数字以各家官方文档为准):
| 维度 | DeepSeek | OpenAI | Anthropic |
|---|---|---|---|
| 生效方式 | 自动,无需改代码 | 自动,无需改代码 | 需要显式 cache_control 标记缓存点 |
| 缓存位置 | 磁盘缓存 | 服务端前缀缓存 | 标记点之间的前缀 |
| 命中输入价格 | 打折(约未命中 1/30) | 读取约 0.1×,写入 1.25× | 读取约 0.1×,写入 1.25×(官方公告) |
| 最小可缓存前缀 | 官方未给具体值 | 1024 token(GPT-5.6+) | 1024/2048 token(第三方资料) |
- 三家都能省钱,DeepSeek 和 OpenAI 是”你什么都不用做,保持前缀稳定就行”;Anthropic 要自己在代码里声明缓存点,多一步配置。也就是说 DeepSeek 和 OpenAI 是开箱即用的,Anthropic 需要你主动设计缓存策略
缓存写入机制:前缀匹配
- 先补一个概念:Sliding Window Attention(滑动窗口注意力,SWA)。普通注意力里,每个 token 要和序列里所有其它 token 算一遍注意力;SWA 把范围限制在固定窗口内,每个 token 只和它前面窗口大小内的 token 做注意力,窗口之外的历史不参与当前计算
- 用 SWA 的好处是长序列下计算量和显存可控:序列再长,每个位置都只看窗口内,这是 Mistral 这类模型用它的原因
- 它和缓存的关系:因为注意力只覆盖窗口内,缓存前缀的存储和匹配方式跟每个 token 依赖前面所有 token 的时代不一样了。官方文档的原话是:由于 SWA 机制,每条缓存前缀是一个独立的完整单元,后续请求只有在完整匹配缓存前缀单元时才能命中
- 通俗地说,缓存不是一条从头到尾连续依赖的链,而是按单元组织的一批积木;命中检查就是我的请求前缀能不能完整盖住某个已落盘的单元
- 这里和常见认知有个重要区别:不是任意前缀都能命中,必须是”缓存前缀单元”(cache prefix unit)的完全匹配
- 缓存单元什么时候被持久化(写入磁盘缓存)?官方给了三种时机:
- 请求边界持久化:每个请求会在 user 输入末尾和 model 输出末尾各产生一个缓存前缀单元
- 公共前缀检测持久化:系统检测到多个请求有公共前缀时,把该公共前缀单独持久化为一个单元
- 固定 token 间隔持久化:长输入、长输出按固定 token 间隔切出单元,避免长前缀因为永远到不了末尾而完全没法缓存
- 官方 Example 1(多轮对话):第一轮发 A+B,第二轮发 A+B+C,第二轮完全匹配第一轮的单元 A+B,命中
- 官方 Example 2(长文本问答):第一轮 A+B,第二轮 A+C,第二轮匹配不上(A+C 不能完全匹配 A+B),不命中;但系统检测到公共前缀 A,把它持久化;第三轮发 A+D,命中 A
- 从这两个例子能推出三个实用结论:
- 多轮对话天然吃缓存:system 和前面的轮次都不变,只有尾部在长,命中的部分随对话推进越来越大
- 中间改一条消息,断点之后全废:前缀从改动处断开,后面的内容全部 miss
- 系统提示词是前缀最前端,改一个字符,整条前缀从最前面开始全部 miss。这是 system prompt 必须保持稳定的直接原因
TTL 与过期
- DeepSeek 官方对缓存有效期的口径:
- 缓存是 best-effort 的,不保证 100% 命中率
- 缓存构建需要数秒(第一次请求时构建,所以第一次请求必然是 miss)
- 缓存不再被使用后会自动清除,通常在几小时到几天内
- 也就是说没有固定的 TTL 数字,是”用进废退”:你高频使用,缓存就一直在;隔几天不用,缓存可能已经被清了
- 对比一下别家:OpenAI 官方口径是最近一次写入/命中后至少 30 分钟(GPT-5.6+,旧模型约 5-10 分钟不活跃、最长 1 小时);Anthropic 默认 5 分钟、扩展档 1 小时。DeepSeek 不给具体数字,只说几小时到几天,更宽松
- 缓存只匹配输入的前缀部分,输出仍然是实时计算生成的,受 temperature 等参数影响,有随机性(官方原话,别以为命中缓存后输出也会被复用)
缓存失效的场景
| 场景 | 发生了什么 | 对策 |
|---|---|---|
| 系统提示词更换 | 前缀从最前端断开,几乎全 miss | system 保持稳定,要变的内容尽量放尾部 |
| 中间某条消息被改动 | 断点之后全部 miss | 会话历史只追加、不修改 |
| 上下文被压缩/清空 | 前缀整体变化,之前的缓存单元匹配不上 | 压缩时尽量保留公共骨架(system + 不变的背景) |
| 长期不用 | 缓存几小时到几天后自动清除 | 高频任务保持活跃;隔很久重开任务,直接开新会话更省 |
| 首次请求 | 缓存还没构建,必然 miss | 别指望第一次就命中,连续操作才有缓存可吃 |
| 切换模型 | 缓存与模型绑定(官方未细说,谨慎理解) | 别在任务中途换模型,换模型就当缓存清零 |
- 总结一句话:缓存命中的核心操作是”让请求的前缀尽量稳定”
实践方法
诊断先行:先知道钱花在哪
- 前两章是原理,这一章全是能上手做的事。先别急着优化,先把账算清楚
- 诊断入口有三个:
- usage 字段:每次请求返回的 prompt_tokens / prompt_cache_hit_tokens / prompt_cache_miss_tokens / completion_tokens,这是最细的账本
- 平台的用量账单页:能看到按天的 token 消耗和费用曲线
- 代理层统计:很多转发工具/网关自带用量日志,能看到每次请求的明细
- 具体做法:拿几个典型任务跑一遍,重点看两个比例
- 命中比例 = hit / (hit + miss):如果长期接近 0,说明你的使用方式根本没吃到缓存
- 输出占比 = completion / total:如果输出占大头,说明模型话太多
- 账算明白了再动手,别凭感觉优化
从缓存命中角度省钱:防止缓存失效
- 缓存吃的是前缀稳定性。这一节全是围绕”让前缀别乱动”的操作
- 保持 system 稳定:
- 系统提示词是前缀最前端,改一个字符全废
- 会变的内容(日期、当前任务、临时要求)放 user 消息或对话尾部,别塞进 system
- 工具自带的 system prompt 你管不了,但你自己加的角色设定、规则要克制,别动不动加一句
- 切任务就清理会话:
- 换个任务还在旧会话里继续,旧上下文全变成前缀的”历史包袱”,既占输入又破坏缓存
- 新任务开新会话,前缀从干净的 system 开始,缓存命中率高得多
- 不中途切模型:
- 切换模型缓存基本清零(官方未细说,但别赌)
- 一个任务从头到尾用一个模型,要换就换会话
- 会话历史只追加、不修改:
- 改中间一条消息,断点之后全部 miss
- 需要修正时,追加一条新消息说明,别回头改
- 缓存过期后,与其重新发送不如先压缩:
- 隔很久再继续旧任务,旧缓存大概率已被清除(几小时到几天自动清),原样重发等于全 miss
- 这时候不如先把旧对话总结成要点,用”总结 + 新任务描述”开新请求,输入更短、前缀更干净
- 压缩的正确姿势:把 system + 不变的背景留下,把过程性的来回删掉,只留结论
削减输入 token
- 输入即使全 miss 也比输出便宜,但积少成多,对话一长输入才是大头
- 写好文档和 skills,而不是每次现贴:
- 项目背景、技术约束、代码规范这类知识,沉淀成文档/skills,需要时让模型按需读取
- 每次把一大段背景贴进对话里,等于每轮都按原价付一次,还占上下文
- 知识放外面,用到才读,是编码工具里最省输入 token 的习惯之一
- 不引入不必要的上下文:
- 别把整个仓库、整份文件丢给模型,它只需要相关的那几段
- 引用文件时只给需要的部分,模型要更多再给
- 无关的日志、旧代码、聊天记录,能不给就不给
- 删重复内容:上下文里别让同一段信息出现两遍(比如文档贴了一遍,又口头描述了一遍)
削减输出 token
- 输出是单价最贵的部分(flash 输出 4.5 元/1M vs 未命中输入 1.5 元/1M),模型每多说一个字都是钱
- 不引入无端增加输出的 skills 和指令:
- 有些 skills/提示词会要求模型”详细解释每一步””给出多个方案对比”,这些都会放大输出
- 按任务需要给输出约束:要结论就别要解释,要代码就别要注释(除非你确实需要注释)
- 明确输出格式:指定”只返回 JSON / 只返回 diff / 只给结论”,模型就不会发散
- 控制思考模式的开销:
- DeepSeek 思考模式默认开启且 effort 默认 high,思维链按输出计费(usage 里的 reasoning_tokens 单独列着,能看见自己想了多少)
- 简单任务可以把 reasoning_effort 调低(low),复杂任务才开 high
- 思维链是不带 tools 时不会拼进上下文,但编码工具基本都带 tools,这部分省不掉,只能靠调 effort
- 检查 max_tokens 上限:输出截断会浪费一半生成量(生成了但没用上),该给的上限给够,不该给的别超
会话管理与文档持久化
- 单个会话别拖太长:
- 每次请求都重发全部历史,对话越长,每次请求越贵,输入呈线性增长
- 长对话末尾,即使缓存全命中,命中的也是”越来越长的前缀”,实际花费还是涨
- 总结并开新会话:
- 会话到一定长度(比如输入接近几千 token 时),让模型把关键信息总结成一份文档
- 开新会话,把总结作为新的上下文起点,前缀重新变得又短又干净
- 这招对”越聊越贵”的问题立竿见影,也顺便解决了长对话里模型注意力被稀释的问题
- 文档持久化:
- 把结论、决策、代码要点写进项目文档,会话清空后信息还在
- 下次需要时用文档代替”重新聊一遍”,输入更短、质量更高
- 必要时切换适合任务场景的模型:
- 简单任务(改个变量名、格式化、问个语法)用便宜小模型就够,别杀鸡用牛刀
- 复杂任务(架构设计、疑难 bug)才上贵的大模型
- 模型切换和会话切换一起做:新任务 + 新模型 + 新会话,三者配套
用工具动态监控开销
- 光省不算账等于白省,监控是长期保持低开销的手段
- 平台用量页:定期看 token 消耗曲线,异常飙升(比如某天突然翻倍)说明使用方式出了问题
- 代理层日志:如果请求走转发工具/网关,它的日志能看到每次请求的 hit/miss 明细,比平台粒度更细
- 自己写脚本:把 usage 字段落库,按项目/任务维度统计,能看出哪个项目在烧钱
- 监控发现的典型问题:
- 命中率骤降:多半是 system prompt 被改了,或者换了模型
- 单次输入暴涨:某个文件被整个塞进了上下文
- 输出暴涨:某个任务的要求让模型输出过多
提示词本身瘦身
- 提示词的长度直接决定输入 token,每句话都要有目的
- 删套话:请务必、非常重要、一定要认真,这类词不增加信息,模型也不会因为”务必”就更认真
- 控制 few-shot 示例数量:2~5 个够用,每个示例都是 token,还可能有偏差
- 指令和描述分开:任务指令写清楚,背景材料用分隔符标出来,别混在一起让模型读两遍
- 精简的提示词反而更好用:模型对长提示词末尾的注意力本来就弱,短而准的提示词命中率更高
减少请求次数
- 每次请求都有固定成本(上下文重发 + 输出),请求次数越少越省
- 一次说清需求:把任务背景、要求、期望输出一次讲明白,别挤牙膏式一问一答
- 挤牙膏 5 轮 = 5 次上下文重发 + 5 次输出,一次说清 = 1 次
- 合并小任务:连续的小修改、小问题合并成一次请求处理,不要一个文件一个请求
- 让模型批量产出:比如”把这三个函数都优化了”而不是”先优化第一个”
- 注意别矫枉过正:任务太复杂时硬合并,模型容易做不好,返工更费 token。批量要适量
模型选型降级
- 不同模型价格差好几倍,选型是最直接的省钱手段
- DeepSeek 当前定价对比(空闲时段未命中输入):flash 1.5 元 vs pro 4.5 元,差 3 倍;输出 flash 4.5 元 vs pro 13.5 元,差 3 倍
- 什么时候用贵的:
- 复杂推理、架构设计、疑难 bug:pro 的准确率值这个差价
- 简单任务(改代码风格、查语法、写文案):flash 完全够用
- 工具里一般都能按任务配置模型:日常小任务走便宜档,关键任务手动切贵档
- 选型降级和会话管理要配套:换模型就当缓存清零,别在一个会话里来回横跳
多模态输入开销
- 图片按输入 token 计费,deepseek-v4-flash-vision-exp 每张图上限 384 token(缩放后)
- 384 token 什么概念:按 DeepSeek 官方换算(1 中文字符 ≈ 0.6 token),约等于 640 个中文字,还享受不到文本缓存折扣
- 什么时候该贴图:
- 截图、UI 布局、图表、报错画面:图比文字描述准确,值得贴
- 能从文字/代码表达清楚的:别贴,直接给文本
- 一张图只算一次:同一张图在一个请求里只算一张的 token,多张图每张独立计
- 对编码场景:报错信息优先贴文本(错误信息、堆栈),需要看界面布局才贴截图
DeepSeek Harness 里的省钱实践
- 前面几节是通用做法,这一节拿 DeepSeek Harness(DSH)具体说一遍。DSH 是 agent harness 类的编码工具,官方文档里也在开发者预览阶段,用 DeepSeek 模型做后端,也就是这篇文章运行所在的这个环境
- 会话隔离:一个任务一个会话,任务做完开新会话。DSH 的会话可以切换工作目录、继续之前的对话,但别图省事在旧会话里开新任务,旧上下文全变成前缀的历史包袱,输入和缓存两头亏
- skills 按需加载:DSH 的 skills 不常驻每次请求,用到才加载完整内容。把反复要用的知识(项目规范、常用命令、代码风格)写成 skill,而不是每次手动贴一大段,能省下大量重复的输入 token
- 子代理隔离上下文:独立任务(调研、翻译、批量处理)派给 subagent 在后台跑,主会话只拿结果摘要,工具执行的细节输出不会全部回填主会话,上下文就不会被撑爆
- 文件按需读取:用 read / glob / grep 精准拿内容,别让模型把整个仓库读进上下文。DSH 里工具结果会回填到上下文,读多少花多少,一次整读目录和精准读取差的可能就是几千 token
- goal 管理长任务:跨轮的长目标用 goal 记录下来,后续轮次不用每轮重述任务背景;阶段产出写进文件而不是堆在对话里,需要时再读
- 开销监控:DSH 底层走 DeepSeek API,账单在 DeepSeek 平台的用量页看。如果发现某轮输入异常大,先查是不是有文件被整读、或者工具输出回填过多