<table>
<tr>
<td width="42%" valign="top">

# dsh-meter

[English](README.md) | 中文

### DeepSeek 开始按时段计价了，这是配套的电表。

每天两段高峰，空闲时段半价。花费不再是事后翻账本才看的数字，而是**你此刻正站在里面的费率**。

输入框下面一行：这个会话花了多少、当前是哪一档、还有多久换档。悬停展开卡片，里面是时段表、缓存的经济账，以及账户余额。

[![site](https://img.shields.io/badge/site-dsh.works%2Fdsh--meter-00c2e9)](https://dsh.works/dsh-meter/)
[![ci](https://github.com/dshworks/dsh-meter/actions/workflows/ci.yml/badge.svg)](https://github.com/dshworks/dsh-meter/actions/workflows/ci.yml)
[![powered by dsh](https://img.shields.io/badge/powered__by-dsh-4D6BFE?logo=deepseek)](https://github.com/deepseek-ai/deepseek-harness)
[![license: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)

</td>
<td width="58%" valign="top">

<img src="https://raw.githubusercontent.com/dshworks/dsh-meter/main/docs/meter-light.png" alt="输入框下方的计价行与展开的卡片：会话总价、时段表、缓存与输入拆解、账户余额" width="420">

</td>
</tr>
</table>

## 安装

```sh
dsh plugin --profile web add @dshworks/dsh-meter
dsh --profile web
```

`dsh plugin` 转发给 pnpm，因此 PATH 里要有 pnpm。除此之外无需配置：会话产生第一次计费请求后，计价行就会出现在输入框下方。

## 那一行

```
2 turns · 2 steps | LLM 3.1s | TTFT avg 1.3s · 41 tok/s | Cache hit 50% | Input 44.3K tok
                    ¥0.0672  |  peak  |  off-peak in 48m
```

上面是 dsh 自带的统计行，原样保留；下面才是本插件。它**新增**一行，而不是抢占官方那一格——想在官方统计行里追加内容，只能用同 id 更低 priority 把它顶掉，那样每次上游改动都会跟着坏。

悬停或聚焦展开卡片。处在高峰时段时，档位用琥珀色标出，倒计时指向下一个空闲时段：

<img src="https://raw.githubusercontent.com/dshworks/dsh-meter/main/docs/meter-dark.png" alt="暗色主题下处于高峰时段的同一张卡片" width="620">

| 卡片里有什么 | 为什么值得占这个位置 |
|---|---|
| 会话总价、请求数、模型 | 这个数字只出现一次，用最大的字号 |
| 24 小时时段条，按**你所在时区**绘制，带实时游标 | 官方按 UTC 公布高峰窗口。深夜心算时区不如直接看一条 |
| 缓存命中 / 未命中输入 / 输出，各自的 token 与金额 | 命中价只有未命中的 **1/30**。这一行能看出前缀是否稳定 |
| 账户余额，以及其中多少是赠送额度 | 赠送额度会过期，充值余额不会 |
| 同样的 token 换到另一档要多少钱 | 调价前：看新价会让这个会话变成什么样；调价后：看等到空闲时段能省多少 |
| 缓存省下了多少 | 把每一次命中都按未命中重算出来的对照值 |

## 设置面板：花钱之前就能看

那一行需要一个会话，而且要这个会话已经产生过计费请求——于是这个插件本该回答的问题，
必须先付钱才问得出来。**设置 → 峰谷价**在没有会话的情况下直接回答。

<img src="https://raw.githubusercontent.com/dshworks/dsh-meter/main/docs/meter-settings.png" alt="dsh 设置里的峰谷价面板：当前档位与倒计时、七天时段网格、公开价目表、账号余额" width="620">

它刻意不是一张表单。两个配置项都在插件自己的配置里，harness 本来就有编辑插件配置的地方；
为两个字段再造一条写入路径，那是「设置页」的条件反射，不是内容。这里放的是仪表：

| 面板展示 | 为什么在这里 |
|---|---|
| **当前**档位，大字号，配倒计时和结束时刻 | 你打开这个面板的理由，在读到别的东西之前就已经回答 |
| **本周**——七个本地日 × 二十四小时，高峰为琥珀色，带实时游标 | 卡片上的条带回答「今天什么时候换挡」。周末转为空闲价之后这变成了一个按周的问题，168 格里 35 格琥珀色，是看清「高峰是每周 35 小时而不是 49 小时」最快的方式 |
| 按你账号计价币种显示的**公开价目表** | 按 DeepSeek 公布的精度显示——是 `¥1.5`，不是 `¥1.50`。价目是报价，不是账单 |
| 你的**余额** | 面板打开时读一次，走的是卡片用的同一条宿主路由 |

网格按你的日期排，不是按北京的日期排，而每一格都问那个给请求定价的同一个函数——
所以画面和账单不会不一致，你也不用自己做时区换算。

中文界面里，小时格子上藏了个彩蛋。峰、谷本来就是电力峰谷电价的老词，而「峰」那一半，
离卖 token 那家公司创始人的名字只差一个字。把鼠标放到格子上：文峰、文谷。


## 验证

2026-08-24 对 dsh `0.1.1-rc.2` 做过真实验证，DeepSeek-V4-Pro 与 V4-Flash 真实会话，不是 mock：

> **这次是重跑，因为只读源码不够。** 到 rc.8 为止，这一段一直用「rc.7 与 rc.8
> 的 `src/` 逐字节相同」来论证投影契约没动过。后来它动了：`0.1.1-rc.1` 把
> `schema` 改名为 `stateSchema`，并把面向客户端的 `view` 挪进了可选的 `wire`。
> 注册表是逐个字段去读定义的，从不校验，所以旧写法不会报错——它被理解成
> 「这个投影只留在宿主端」，于是在一个完全健康的 harness 上，那一行什么都不渲染。
> 一个会退化成沉默的契约，靠 diff 源码是查不出来的；下面这张表是重新跑出来的，
> 不是推出来的。

| 结论 | 怎么验的 |
|---|---|
| 能在标准 web profile 里加载 | `dsh --profile web --dump-config` 能列出 `@dshworks/dsh-meter`；`/plugins/@dshworks/dsh-meter/client.js` 返回 200 |
| 那一行渲染出来了 | 输入框下方的 `¥0.2185 \| off-peak \| peak in 14h`，直接从活的 DOM 里读出来——正是能抓住 rc.1 那次改名的检查 |
| 读数正确 | V4-Flash 与 V4-Pro 合计 36.1K 未命中输入 + 147 输出 = ¥0.2162 + ¥0.0023 = **¥0.2185**，与正上方 dsh 自己那行 token 统计一致 |
| 重启后仍在 | 重启服务、冷启动重开一个八天前的会话，投影从持久日志重放出同一个数 |
| 卡片能打开 | 分模型明细、缓存对照（全高峰 ¥0.2185 / 全低谷 ¥0.1093）、账号余额，页面无报错 |
| 币种自动识别 | 真实账号经 `/dsh-meter/balance` 返回 `{"currency":"cny", ...}`，整个界面无需配置直接切到 ¥ |
| 两种主题、两种档位 | 亮色/暗色、统一价/高峰，见上图，摄于 2026-08-15——那次早于 8/16 切换，其中的统一价读数是新会话已不会再出现的状态 |
| 130 个测试，CI 绿 | `pnpm test` — 折叠逻辑、时段时钟、价目表、省钱模式的提示语、余额读取、对着两代注册表替身跑的注册契约，外加生成产物的同步校验 |

## 两种货币，不做换算

DeepSeek 公布的是**两张互相独立的价目表**——国际站按美元，中国站按人民币。一个账号只按其中一张计费，两张表也不是彼此的汇率换算，所以用汇率去折算的插件会错两次。

`dsh-meter` 两张表都算，然后让账号自己决定用哪张。`GET /user/balance` 会返回该账号的计价币种（真实账号会同时列出两行，只有一行有余额），插件读有余额的那一行并按它显示。不需要配置，也不靠界面语言去猜。

余额请求跑在宿主侧，用的是 LLM adapter 同一套凭据接口；浏览器通过 `GET /dsh-meter/balance` 只拿到解析好的数字，拿不到 key。它只在计价行挂载和你展开卡片时发出，不做轮询——设 `balance: false` 可以整个关掉，计价功能不受影响。

## 价目表

原样写在 [`lib/core.js`](lib/core.js) 里，单位为每百万 tokens。

| | 缓存命中 | 缓存未命中 | 输出 |
|---|---|---|---|
| **flash** 空闲 | $0.003 / ¥0.02 | $0.15 / ¥1 | $0.6 / ¥4 |
| flash 高峰 | $0.006 / ¥0.04 | $0.3 / ¥2 | $1.2 / ¥8 |
| **v4-pro** 空闲 | $0.022 / ¥0.15 | $0.66 / ¥4.5 | $1.98 / ¥13.5 |
| v4-pro 高峰 | $0.044 / ¥0.30 | $1.32 / ¥9 | $3.96 / ¥27 |

高峰为 **周一至周五 UTC 01:00–04:00 与 06:00–10:00**（北京时间 09:00–12:00、14:00–18:00）。其余时间都是空闲时段，包括两个窗口之间那两小时和整个周末。周末自 UTC 2026-08-22 16:00（北京时间 8 月 23 日 0 点）起全天按空闲价，按*北京*日历算，所以周末在 UTC 16:00 翻转，而不是 UTC 零点。空闲价正好是高峰价的一半——v4-pro 仍高于它取代的统一价，输出约为 2.3 倍。

**`deepseek-flash` 即 DeepSeek-V4.1-Flash，自 2026-09-10 起。** 它取代了 V4 Flash 和 V4 Flash Vision Exp（视觉能力已内置），Flash 价格随之下调：空闲时段缓存未命中 ¥1.5 -> ¥1，输出 ¥4.5 -> ¥4，缓存命中 ¥0.05 -> ¥0.02。旧模型名仍可调用，由 V4.1 Flash 提供服务并按 Flash 价格计费，所以切换之后发出的 `deepseek-v4-flash` 请求，电表按 `deepseek-flash` 计费；切换之前的仍按旧价。API 返回的模型名只是回显你发出的名字，看不出实际由谁计费；发出时间可以。

新价格于 **北京时间 2026 年 9 月 10 日 12:00**（UTC 04:00）生效，见 DeepSeek 的[发布公告](https://api-docs.deepseek.com/zh-cn/news/news260910)，电表就在这一刻切换。价格页本身晚了好几个小时才更新，所以别用参考页面的变动时间去推断调价时刻。UTC 2026-09-11 17:03 的账单探测按新价结算，分毫不差。

<details>
<summary>已退役的统一价，保留用于回算历史</summary>

在 **UTC 2026-08-16 16:00** 之前全天按此计费。官方页面已不再列出它；电表保留它，是因为切换前记录的会话必须仍按当时真实的价格计算。

| | 缓存命中 | 缓存未命中 | 输出 |
|---|---|---|---|
| **v4-flash** 统一价 | $0.0028 / ¥0.02 | $0.14 / ¥1 | $0.28 / ¥2 |
| **v4-pro** 统一价 | $0.003625 / ¥0.025 | $0.435 / ¥3 | $0.87 / ¥6 |

相较于它，v4-pro 缓存命中输入涨到 6 倍（高峰 12 倍）、缓存未命中输入 1.5 倍（高峰 3 倍）、输出 2.3 倍（高峰 4.6 倍）。涨幅最陡的正是最便宜的那种 token，也正是 agent 发得最多的那种。

</details>

<details>
<summary>已退役的 V4 Flash 价目，保留用于回算历史</summary>

`deepseek-v4-flash` 与 `deepseek-v4-flash-vision-exp` 在 **UTC 2026-09-10 04:00**（北京时间 12:00）之前按此计费，之后均按 `deepseek-flash` 计费。

| | 缓存命中 | 缓存未命中 | 输出 |
|---|---|---|---|
| **v4-flash** 空闲 | $0.007 / ¥0.05 | $0.22 / ¥1.5 | $0.66 / ¥4.5 |
| v4-flash 高峰 | $0.014 / ¥0.10 | $0.44 / ¥3 | $1.32 / ¥9 |

Vision Exp 自 2026-08-21 上线起即按此价计费。

</details>

来源：<https://api-docs.deepseek.com/quick_start/pricing>，每天与中英文两份页面自动比对（见下节），最近一次确认一致为 2026-09-18——并且核对过真实账单：v4-pro 一次 188,542 缓存未命中 tokens 的调用，空闲时段实扣 ¥0.84，即每百万 ¥4.46，对应公布的 4.5。

## 价目表也是一份数据源

自己做用量估算？取这份数据，别抄上面表格里的数字。

```
https://dsh.works/dsh-meter/pricing.json
```

静态 JSON，无需 key，不限流。两种货币、两个档位、24 小时 UTC 档位表、用于回算历史的已退役统一价，以及三个计费桶的定义——由 [`scripts/build-feed.mjs`](scripts/build-feed.mjs) 从 [`lib/core.js`](lib/core.js) 生成，所以它不可能报出一个电表自己不认的价。

JavaScript 里可以跳过这次 fetch，直接调同一个模块：

```js
import { costOf, tariffAt } from '@dshworks/dsh-meter/core'

const tokens = { miss: 188_542, hit: 1_204_880, out: 9_310 }
costOf(tokens, 'deepseek-flash', tariffAt(Date.now()), 'cny')
```

`lib/core.js` 不依赖任何包。价目表、档位时钟、成本折叠都是纯函数，内部不读时钟，所以历史会话按它当时真实的档位回算。

### 现在是什么价？

这份数据**不包含「现在」**，却能回答这个问题：它发布的是 24 小时档位表，由你用当前 UTC 小时去索引。正因为如此，CDN 缓存十分钟、或者把它编进二进制里，都不会让「当前是哪个档位」变旧：

```sh
curl -s https://dsh.works/dsh-meter/pricing.json | jq -r '
  (now|gmtime|.[3]) as $h
  | .timeOfUse.scheduleUtc[$h] as $t
  | "\($t) · v4-pro 输出 $\(.models["deepseek-v4-pro"].rates[$t].usd.out)/1M"'
```

如果换成一个直接返回答案的接口，它在缓存存活期间就是错的——每天四次，而且恰好错在「差一倍」的那条边界上。

**两种会静默出错的写法：**

- **用本地小时索引。** `scheduleUtc` 按 UTC 小时索引，不会旋转到你的时区。`new Date().getHours()` 会返回一个看着合理、但对地球上大多数人来说是错的档位。
- **broken-down time 的下标。** jq 的 `gmtime` 是 `[年, 月, 日, 时, …]`，小时是 `.[3]`。写成 `.[2]` 取到的是「日」——而它同样是 24 元素数组的合法下标。写这一节时是 UTC 09:59，`.[2]` 给出 `offpeak`，真实档位是 `peak`。看上去毫无破绽。

档位表锚定在北京时间（UTC+8），而中国自 1991 年起不再实行夏令时——正是这个固定偏移，才让「一张 UTC 小时表」可以安全发布。数据里在 `timeOfUse.anchor` 写明了这一点；`verify-pricing` 会**分别**核对英文页的 UTC 表述与中文页的北京时间表述，再核对两者是否仍然一致。

有一件事任何数据源都救不了：`now` 用的是你自己机器的时钟。它要是漂了，你的档位也就漂了。

**为什么不直接用现成的价格源？** 因为没有一个是对的。2026-08-20 复核，也就是切换四天之后，做估算最常用的两个源仍然把 DeepSeek 已退役的统一价当作现价发布：

| 数据源 | v4-pro 缓存未命中输入 | 相对真实账单少算 |
|---|---|---|
| [models.dev](https://models.dev/api.json) | $0.435 | 空闲 1.5 倍，高峰 3.0 倍 |
| [LiteLLM](https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json) | $0.435 | 空闲 1.5 倍，高峰 3.0 倍 |
| 本数据源 | 空闲 $0.66 / 高峰 $1.32 | — |

在缓存命中输入这一桶——agent 发得最多的那一桶——models.dev 在高峰时段少算 **12 倍**。而且这不是他们补一次数据就能修的：两家的 schema 都是「每模型每桶一个固定单价」，根本没有放档位的位置。一个每天有七个小时是错的价格，在这两种结构里都表达不出来。

OpenRouter 的 `/api/v1/models` 是准的，但回答的是另一个问题——它报的是 **OpenRouter** 转售这个模型的报价，不是 DeepSeek 从你账户里扣的钱。

### 这些数字没有人手工敲

我们不敲，也不建议你敲。手工维护的价目表一定会烂掉，而最好的证据来自厂商自己：DeepSeek 官方的 [pi 集成文档][pi-guide]里那段 `cost` 配置，v4-flash 的缓存读取价是一个 10 倍的小数点错误（写成 `0.028`，实际是 `0.0028`），v4-pro 的数字则正好是价目表的 4 倍——那是 Azure 的转售价，被贴进了 DeepSeek 自己的文档，而这一页是给人直接复制到 agent 配置里的。

所以价目表由机器写、由人审：

| | | |
|---|---|---|
| **读** | `scripts/verify-pricing.mjs` | 抓取中英文两份页面——价格、高峰窗口、模型列表——与价目表逐项比对 |
| **写** | `scripts/apply-pricing.mjs` | 把抓到的数字写回 `lib/core.js`，然后**用校验脚本重新读一遍自己的输出**，读不通就回滚 |
| **发** | `npm run build` | 用改写后的价目表重新生成 bundle、站点和数据源 |
| **判** | 你 | 任务只开 PR，从不自己合并 |

[每天一次的定时任务](.github/workflows/pricing-watch.yml)把这四步跑完。本地：`npm run verify:pricing` 只看，`npm run sync:pricing` 才改。

**为什么只开 PR 不自动合并。** CI 能检查的全是结构性不变量——空闲价是高峰价的一半、输出比缓存未命中贵、当前请求不会按已退役的统一价计费——而一个「错得很合理」的解析结果能同时满足所有这些。没有任何测试能把「对的价格」和「像样的价格」区分开，但一个人看一眼 diff 可以。

上一次调价，我们盯着的任何渠道都没有收到通知——这是要装警报的理由；厂商自己那个 10 倍的手误，则是把键盘从所有人手里拿走的理由。

[pi-guide]: https://api-docs.deepseek.com/zh-cn/quick_start/agent_integrations/pi_mono

## 钱是怎么算出来的

| 行为 | 细节 |
|---|---|
| 数据来源 | 持久会话日志里由供应商上报的 token 数。不采样，不推测 |
| 每次请求的档位 | 按**发出**时刻（`step/start`）判定，而不是按回答结束的时刻。UTC 00:59 发出的请求即使流式输出跨进高峰窗口，仍按空闲价计；跨档会话的两侧各按各的档位算 |
| 计费桶 | `inputTokens` 按未命中价，`cacheReadTokens` 按命中价，`outputTokens` 按输出价。dsh 上报的是互不重叠的三个数（DeepSeek adapter 会从 `prompt_tokens` 里减掉命中部分），推理 token 已包含在输出里 |
| 缓存写入 | 并入未命中桶。DeepSeek 没有单独的写入价，首次进入缓存的 prompt 按未命中计；DeepSeek adapter 也从不上报这一项 |
| 失败的请求 | 某一步的 usage chunk 即使请求随后失败也会计入；最终 message 会**替换**这个样本而不是叠加，模型名与请求头不一致时同样如此 |
| 未知模型 | 只计数、只列名，绝不定价。没有公开价格的模型贡献 token 与请求数、金额为零，卡片会明说 |
| 持久性 | 一个会话投影（`costMeter`），从日志折叠而来。翻页、压缩、刷新、重启服务都不影响，走标准投影缓存 |

## 对模型的影响

默认没有。`dsh-meter` 不加工具、不加系统提示、不加消息、不发模型请求，完全不碰请求本身。花费是付钱的人该看的东西，不该占 agent 的上下文。唯一的例外要你自己打开：[省钱模式](#省钱模式--让电表开口说话)（`savingMode: true`）会贡献一段系统提示，说明当前处在哪个计费时段；这段文本渲染为空时，整节都不存在。

#### KV 缓存影响

默认无。开启省钱模式后，`meter:tariff` 这一节的文本在同一个计费时段内逐字节相同，所以提示前缀——以及它的缓存——能从一次请求保持到下一次；只有在时段切换的那一刻才变，因此切换后的第一次请求会错过前缀缓存，之后重新命中。

## 配置

以下都是校验过的配置项，写在 profile 的 `cordis.patch.yml` 里：

```yaml
- id: dsh-meter
  config:
    currency: cny        # 固定价目表，不再自动识别
    balance: false       # 完全不调用 /user/balance
```

| 键 | 默认值 | 含义 |
|---|---|---|
| `currency` | `auto` | 显示哪张价目表：`auto`（先看账号余额币种，再退到界面语言）、`usd`、`cny` |
| `balance` | `true` | 是否把账户余额提供给 Web UI |
| `apiKeyEnv` | `DEEPSEEK_API_KEY` | 存放 API key 的凭据引用 |
| `baseUrl` | `https://api.deepseek.com` | 读取余额的接口来源 |
| `balanceTtlMs` | `300000` | 展开卡片时重新拉取余额的最小间隔 |
| `balanceTimeoutMs` | `4000` | 单次余额请求的超时 |
| `savingMode` | `false` | 贡献一段系统提示，告诉模型当前处在哪个计费时段，好让它相应地调整行为 |
| `savingPeakPrompt` | 内置提示语 | 高峰窗口期间注入的文本 |
| `savingOffPeakPrompt` | `''` | 非高峰期间注入的文本；默认为空，意味着整节渲染为空、不花一个提示 token |

## 省钱模式 — 让电表开口说话

默认关闭，因为一个只读的仪表不该自己长进 agent 的上下文里。把 `savingMode` 打开，电表就不再只是旁观者：每次组装提示时，它会贡献一节 `meter:tariff`，告诉模型**下一次**请求将按哪个时段计费、以及在这个时段里该怎么做。

在高峰窗口内，这一节的内容是 `savingPeakPrompt`——默认是电表自己的提示语：点名高峰时段、说清账单翻倍、并要求模型答得简洁，优先用已有的上下文而不是新开工具调用，遇到昂贵又能等的任务就说出来、提议等窗口关掉再跑。窗口之外这一节渲染 `savingOffPeakPrompt`，默认为空，所以没有什么要提醒的时候，电表说话的成本是**零 token**。想让模型在低谷时段反而放开手脚？把 `savingOffPeakPrompt` 设成类似「现在是半价时段，可以放心多花 token」的文字。

有四点是刻意为之：

- **时段在组装时读取，用的是计费折叠同一个时钟。** 提示和账单永远不会对「下一次请求落在边界哪一侧」产生分歧——周末也一样：周末整天按低谷计费，因此完全不会触发提示。
- **提示语里的时段是推导出来的，不是手写的。** `peakHoursPhrase()` 从 `PEAK_WINDOWS_UTC` 和 `tariffSchedule()` 里读，所以排期一改，句子跟着改。一段告诉模型错误高峰时段的提示，就是插件在钱的问题上骗它。
- **同一个时段内文本恒定。** 在这里放倒计时会每分钟变一次，为了一句话滚掉整个会话的提示前缀缓存——这是一个成本插件所能想到的、最昂贵的省钱方式。它只在时段边界翻转（翻转后第一次请求会错过前缀缓存），之后保持不变。
- **这是提醒，不是限流。** 模型可以无视它；请求层面没有任何强制。需要硬上限的话，那是另一个插件。

## 开发

```sh
pnpm install
pnpm test                        # 先校验产物同步，再跑 vitest
pnpm run build                   # 改完 core/ui 后重新生成三份产物
pnpm run verify:pricing          # 与 DeepSeek 官方价格页逐项比对（需联网）
```

`lib/core.js` 是价目表、时段时钟和折叠逻辑，`lib/balance.js` 是账户读取，`src/ui.js` 是浏览器界面。三份产物都由这一份价目表生成——`lib/client.js`（dsh 实际分发的 bundle）、`docs/index.html`（站点）、`docs/pricing.json`（数据源）——价目表因此只存在于一个文件里，任何一份产物与源码不同步 `pnpm test` 就会失败。

`verify:pricing` 是唯一联网的脚本，并且刻意不放进 `pnpm test`：单元测试不该因为一个文档站点慢而失败，价格警报也不该因为这周没人提 PR 而沉默。它按自己的日程每天跑。

## 已知限制

- **这是估算，不是账单。** 官方价目乘以上报 token。优惠价格、以及任何挡在 API 前面的中转都看不到。
- **档位按发出时间戳判定**，用的是 dsh 这台机器的时钟。若 DeepSeek 实际在档位边界另一侧收到请求，可能差出一两秒。
- **非 DeepSeek 线路不定价。** 它们的 token 会被计数、模型会被列名，但卡片会标为未定价，而不是把 DeepSeek 的价格悄悄套到别人家的 API 上。
- **价目表是编译进去的。** DeepSeek 会调价；本插件带的是 2026-08-17 复核过的峰谷价目表，跟进下一次调价需要发新版本。
- **只有 Web。** 投影本身任何界面都能读，但读数是为 Web UI 做的，没有 TUI 版本。

## 参考与致谢

dsh 插件登记处已经收录了[约 50 个花费/用量插件](https://github.com/dshworks/awesome-dsh-plugins/blob/main/lists/usage-cost.md)，其中不少就出现在 DeepSeek 公布调价日期的那一周，读它们的实现影响了这一版的取舍。缓存节省的表述来自 [`deepseek-cli`](https://github.com/thevibeworks/deepseek-cli) 的本地用量账本。

## 许可

MIT
