DeepSeek Harness 插件

Pingze-github/dsh-cost-audit

Star 数 ★ 0 分类 用量与计费 收录于 2026-09-20

以 harness 自己的统计形态显示每轮与会话的 token 与人民币花费,提供 1/7/30 天窗口的全账号账单与「单位工作量花费」趋势,并给出会在你采纳后重新测量效果的建议。

安装

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:Pingze-github/dsh-cost-audit

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWEDERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yamlallowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

中文 | English

DSH Cost Audit

一个 DeepSeek Harness 插件,只回答一个问题: 钱花到哪去了,照它说的做到底有没有用?

它把人民币花费放进 harness 本来就在用的两个统计位置 —— 每一轮下面整个会话下面;同时算了一些 别处都算不到的东西,首先是上下文压缩那次摘要调用自己的账单(并且把你手动压的和系统自动压的分开算)。 在这之上才是让它成为「审计」而不是「看板」的部分:一个建议引擎,会指出到底是什么在花钱、给一个一键采纳的 动作,然后在你采纳之后重新测量那个指标 —— 于是「我照做了」变成一个数字,而不是一种感觉。

所有界面都用 harness 自己的统计形态渲染:同一个图标胶囊、同一个随锚点定位的 dt/dd 面板、同一套设计 token、同一套几何。官方胶囊一个像素都不动,这个插件只是把自己的加在旁边。

它加了什么

每轮 —— 助手动作行里的一个胶囊,位于复制按钮和分支按钮之间,紧挨官方的"消耗"和"耗时"胶囊。它显示 ¥0.01,点开是:

含义
Model 这一轮实际走的模型路由
缓存命中 提示词输入里走缓存的比例,绝不四舍五入成假的 100%
缓存读取 走缓存的输入 token(缓存输入)
未命中输入 按未命中价计费的输入 token
缓存写入 写入缓存的输入 token(非零时才显示)
总输入 三个互不重叠的输入桶之和
输出 输出 token,含推理内容
本轮费用 人民币
耗时分布 本轮耗时去向 —— 见下

每会话 —— 一个与官方会话统计同一行的胶囊(1 turns 297 steps · 237 tok/s · 73.2M tok · Cache hit 99.7%), 就在它们右边:¥2.72 · today ¥0.41 · Account balance ¥113.45 —— 会话总额、其中今天花了多少、以及 实时账户余额。隔几天又捡起来的会话,今日花费从零开始算,而不是拿生命周期数字糊弄你。点开是整个持久日志 的同一套拆解,加上耗时分布,以及从 DeepSeek 账单接口实时读取的余额:

含义
会话总费用 人民币
today 今日 —— 这个会话在本地日历日上的花费
其中缓存重读 账单里那部分"同一份上下文又读了一遍"
其中压缩摘要 摘要调用自己的账单 —— 没有任何别的显示会统计它
缓存命中 / 读取 / 未命中 / 写入 / 总输入 / 输出 整个会话的 token 桶
耗时分布 见下
账户余额 实时
赠送 / 充值 余额构成

耗时分布

两个面板的用量部分都以"时间到底去哪了"结尾,工具行按自己的名字排序:

含义
总耗时 turn/startturn/end
模型用时 step/startassistant/message,带调用次数
首 token 平均(TTFT) step/start → 第一个输出 token
生成阶段 首 token → 结算,带 tok/s
工具用时 tool/calltool/result,带调用次数
其他开销 上面两项没覆盖的墙钟时间
工具明细 最忙的 6 个工具,其余合并成一行

省 Token 建议

只在真的有话可说时才出现第四个胶囊 —— 健康的会话不为它付任何空间。点开是一串有数据支撑的建议,每条带 严重程度、一行修法、以及一个按会话记忆的"忽略":

代号 触发条件 一键做什么
context-reread 缓存重读 ≥ 会话花费的 35%(且模型调用 ≥ 30 次) 立即压缩本会话 —— 提交 /compact
fragmented-tools 某个工具调用 ≥ 30 次,其中 ≥ 60% 不到 2 秒 让 agent 把那一批合并成一个脚本
repeated-target 同一个工具对同一目标调用 ≥ 4 次 让它读一次就记下结论,之后用 grep 定位
idle-grinding 连续 ≥ 30 步没有 write / edit / 交付物 要一份进度汇报,而不是继续摸
tool-failures 同一工具连续失败 3 次 让它停下来把错误读完
cache-hit-drop 50 次以上调用里命中率低于 85% 让它查是什么在每轮改请求头
compaction-churn 系统自动压缩 ≥ 3 次,或那些摘要花掉 ≥ 会话 10% ——(宿主配置项)
model-retries 模型重试 ≥ 5 次 ——
balance-low 按当前烧钱速度,余额撑不过五个会话 ——(充值)

你自己压的那次不算"频繁"。 上面那条重读建议推荐的就是 /compact,所以把紧随其后的那次压缩也算进去, 会让顾问跟自己吵架:它让你压,压完又嫌你压得太勤。计数门槛一开始是 2 —— 意思是"一次系统自动 + 一次本面板 请求的"就已经算频繁了。现在只有 harness 自己决定的压缩会喂给这条规则(从摘要前面那个 command/run 归属出来),计数门槛提到 3,成本门槛只看它们那一份。这不是纸上谈兵 —— 这台机器上就有三个会话分别是 53 / 35 / 17 次自动压缩,手动触发零次。

这条建议的正文也不再引用任何 thresholdRatio 数值了。它曾经写着"从 0.8 降到 0.3",错了两次:这台机器的 preset 早就是 standard-half0.5,而且插件本来就读不到宿主的压缩配置。现在它只讲取舍(阈值越低, 每次摘要要回放的历史越短、单次越便宜,但压得越勤),而"要改去哪改"交给那条手动说明。

金额一律渲染成两位小数 —— 万分之一元不是一个有人会据此行动的数字。唯一的例外是真花了钱却小到过不了 这个四舍五入的,显示 <¥0.01,而不是假装它免费。

采纳一条建议

每条可执行的建议都有一个按钮,通过输入框自己的动作面(setDraft + submit)提交进本会话 —— 走的是 发送按钮同一条路,所以消息会落在对话记录里,agent 在下一步就会读到(正在跑的轮次会排队作为"引导")。 没有诚实自动修法的建议会带上自己那一行说明该做什么 —— 要改哪个 agent preset 键、去控制台看什么 —— 因为原来那句通用的"这条需要你手动处理"没说出任何动作,读起来像耸肩。

两道护栏,都是刻意的:输入框里还有内容时按钮是禁用的,因为"执行"意味着写输入框,一次点击绝不能丢掉 人已经打的东西;每条建议发出后自己禁用。忽略是按会话记在这个浏览器里的。

采纳之后

被采纳的建议离开胶囊里的计数、但留在列表里,带一条会随会话继续更新的判定:

判定 含义
已采纳 · 有改善 指标往好的方向动了,超过它的门槛
已采纳 · 基本持平 动得比门槛小 —— 这次改变没被量出来
已采纳 · 反而变差 往反方向动了,超过门槛
已采纳 · 还在观察 采纳之后的样本还不够判;面板会告诉你还差多少

判定块从不只印一个状态。它总会说明实际执行了什么已执行 /compact已发出合并指令……),因为 单独一句"已采纳 · 还在观察"和"点了一下什么也没发生"完全没法区分 —— 而第一次上线时读起来正是后者。样本还 不够时它同时印出基线读数还差多少证据;对 /compact 还会在摘要调用落地后补上这条命令自己的 花费本次花费 ¥0.42)。最后这行需要点击那一刻就把压缩计数快照下来,所以更早的采纳记录没有它。

读数是自采纳以来的,不是会被历史冲淡的生命周期平均:浏览器在你点击的那一刻快照累计计数器,之后用新 读数相减。每条建议量的是它自己关心的那个指标 —— 每请求上下文 token、短调用占比、重复调用占比、工具失败 占比、缓存命中率 —— 而每个门槛都是基线的比例,这样 token 计数和比率能在同一把尺上判。这里没有任何地方 调用模型;它只是在胶囊已经读的那份折叠结果上做算术。

判定是一次测量,不是承诺:指标可能因为跟这条建议毫无关系的原因变好。请把"基本持平"当作诚实的默认值, 把数字当作证据。

每一条都是从持久日志里折叠出来的 —— 建议引擎从不调用模型,因为一个靠烧 token 来省 token 的功能是自相 矛盾的。门槛刻意保守,每条规则都要一个持续成立、而不是一次倒霉的模式:会喊狼来了的顾问很快就没人读了。

界面跟随 harness 的语言设置:zh 下简体中文,en 下英文。

全账号报表

会话级数字回答的是"这次对话花了多少",回答不了"我是不是比以前花得少了" —— 一个会话就是一件活,两件活 没法比。所以还有第二层读数:一个路由把所有会话的按日桶合并成一份日历,成本面板底部多出一段 「全账号 · 最近 7 天」

分母是特意挑的,让建议没法给自己刷分

为什么用它
每回合 分母是你自己发的消息数 —— 我们的建议改不动它,所以看趋势最公平
每产出编辑 每 write / edit / present 一次多少钱 —— 真正的"工作量"分母;纯聊天、纯调研的日子没有产出,显示 —
每 1K 输出 token 输入是输出的很多倍时它就高 —— 缓存和上下文的问题都在这里显形
重读 / 冷输入 / 输出 三项加起来才是总额;只看总数看不出"为什么动了"
其中压缩摘要 是上面三项的子集,不是第四项 —— 摘要调用的 token 本来就是缓存重读或未命中输入
高峰占比 只报数字,不做建议

每一行都自带一句人话解释,中英双语。一个没人看得懂的分母比没有数字更糟:这个面板收到的第一个问题就是 「这几个里到底哪个才是工作量」。

三条边界会直接印在面板上,别处也请记住:

  1. 金额按配置里的列表价计算。
  2. web/deepseek-search-llm-requestsession/title-llm-request 这两个调用的日志里没有用量, 所以这是下界,不是精确值。
  3. 报表能显示花费变了,但不能证明是你采纳的建议带来的。它把分母选成建议改不动的量、把成本拆到可解释; 归因永远要你自己把采纳的时间点和趋势对齐。

因为整份表是从持久日志折叠出来的,历史会回填 —— 不用等一周才能看到一周(上限是最近 90 天)。

价格

金额用的是 DeepSeek 官方人民币列表价,单位:元 / 100 万 tokenapi-docs.deepseek.com),按计费时段分开。 高峰是北京时间(UTC+8)周一至周五 09:00–12:00 与 14:00–18:00;其余时段以及整个周末都是半价

模型族 缓存命中(空闲 / 高峰) 缓存未命中(空闲 / 高峰) 输出(空闲 / 高峰)
deepseek-flashdeepseek-v4.1-flashdeepseek-v4-flash 0.02 / 0.04 1 / 2 4 / 8
deepseek-v4-prodeepseek-pro 0.15 / 0.30 4.5 / 9 13.5 / 27

一个既不带 v4 也不带 deepseek 标记的模型名会被计数但永不计价 —— 面板给它的费用显示 ,并说明有 多少 token 未计价,而不是拿 DeepSeek 的价目表去给一个国外模型计费。

费用是估算:它由供应商回报的用量算出,不是从账单对回来的。但账户余额不是估算 —— 它是实时读取的, 所以拿它去校准估算。

配置

每个字段都是可选的;覆盖写进同 id 的 profile 补丁层。

- id: dsh-cost-audit
  config:
    baseUrl: "https://api.deepseek.com"   # 账单接口的源
    credentialRef: "DEEPSEEK_API_KEY"     # 经 ctx.credentials 解析的引用
    balanceCacheMs: 60000                 # 一次余额读取复用多久
    requestTimeoutMs: 8000                # 上游超时
    pricing:                              # 元 / 100 万 token
      flash:
        peak: { cacheHit: 0.04, cacheMiss: 2, output: 8 }
        off:  { cacheHit: 0.02, cacheMiss: 1, output: 4 }
      pro:
        peak: { cacheHit: 0.30, cacheMiss: 9, output: 27 }
        off:  { cacheHit: 0.15, cacheMiss: 4.5, output: 13.5 }

安装

dsh plugin --profile web add github:Pingze-github/dsh-cost-audit

然后刷新浏览器页面以加载客户端 bundle。如果你是在自己改的 checkout 里,用实时链接装:

dsh plugin --profile web add link:/path/to/dsh-cost-audit

link: 让 checkout 保持实时,改 index.js / client.js 不需要重装。装了 dsh-hotswap 的话,它会根据写进 dsh.profile.bundles 的新条目热挂载 —— 不需要重启 dsh;这一点很重要,因为重启 dsh web 会杀掉正在 承载它的那个会话。

scripts/ 下的脚本是对着正在运行的部署验证的,不是对着夹具:check.sh 是离线闸门,smoke.sh 通过实时 路由扫过这台机器上的每一个会话,gui-probe.mjs 用无头 Chromium 渲染真实界面。smoke.sh 需要 DSH_HOME 和 一个带认证的 URL(它会从 /var/log/dsh-web.log 里读一个,或者用 DSH_STATS_URL)。

⚠️ 重命名一个 link: 安装的插件会留下一个卸不掉的开机条目,而新旧两个名字都指向同一个 client.js,浏览器 会把同一个 bundle 执行两次并报 duplicate factory registration,整个插件列表都会加载失败。补救办法是把 bundle 从 profile 清单里摘掉再加回去(每条条目会重新解析自己的路径),不是重启 dsh web

它是怎么工作的

  • 宿主半边index.js)注册一个会话投影 dshCostAudit,把整份持久日志折叠成"每轮"和"整会话"的计费桶 及其人民币费用。它走的是 harness 自己的 tokenUsage / sessionStats 同一条管线,所以客户端翻了多长的 历史,数字都是完整的。重试记账对齐 token-meter:一次助手结算替换它自己那个 (turn, step) 槽位,而 llm/retry-started 会先把槽位关掉,于是重试那次是相加
  • 宿主半边还注册两条 exact Connection Fetch 路由:/api/dsh-cost-audit.balance 提供账户余额和任意会话的 按需折叠,/api/dsh-cost-audit.report 把所有会话的按日桶合并成一份日历。按需折叠存在的原因是:投影管线 只会在一个会话已经有物化单元之后才把它发给客户端 —— 持久投影检查点早于本插件的会话没有 dshCostAudit 那一行,而这条路由用同一个单元定义把这个缺口补上。报表路由要折叠一百多个会话,所以它缓存 60 秒。
  • 客户端半边client.js)注册进 harness 的 conversation.chat.assistant-actionsconversation.composer.dock 两个插槽。它没有构建步骤:是一个手写的 window.__ModuleLoader__.load({ id, factory }) 形式的 bundle,所以这个包可以直接从 checkout 装。
  • 按日花费按本地日历日折叠(宿主的时钟,也是浏览器的时钟),保留最近 90 天,于是一个跨了几个月还在 用的会话不会让检查点无限膨胀。每个日桶带三套互不混淆的口径:token 轴(重读 + 冷输入 + 输出)等于当日总额, 费率轴(高峰 + 非高峰)也等于当日总额,而压缩摘要是 token 轴的子集、不是并列的第四项。
  • 会话行的位置是量出来的,不是写死的,并且两个胶囊整体保持居中。输入框 dock 是堆叠它的插槽条目的,而 官方统计行是一个本插件并不拥有的居中 flex 行,所以要量三件事:整行按官方行的高度上提、内容缩进到官方内容 结束的位置、官方行再向左平移本胶囊宽度的一半(用本插件设置和清除的 translateX,绝不改布局),这样两个才 读起来像一个居中的整体。官方标签变长、字号变了、窗口缩放,都会自动落在对的位置;当整组一行放不下时,本行 回退成自己的一行居中,官方行保持 harness 画的原样。

目录

index.js             宿主半边:dshCostAudit 投影 + balance / report 两条路由
index.d.ts           公开类型 + SessionProjectionMap 的模块增强
client.js            浏览器半边:两个插槽条目
cordis.patch.yml     bundle 补丁(挂载宿主条目)
scripts/check.sh     本项目唯一的成功标准
scripts/check.mjs    宿主半边行为:计价、重试记账、路由、折叠
scripts/smoke.sh     一次调用做完运行时验证(闸门 + 全机会话不变式 + 可选渲染)
scripts/link-deps.sh 把 node_modules 指向正在运行的 harness,供 check.sh 用
scripts/gui-probe.mjs 真实界面的无头 Chromium 探针

授权

MIT。

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →

社区评论

评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。