DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

Pingze-github /

Pingze-github/dsh-cost-audit

Verified

This plugin has no description yet.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: master@71653cb7

中文 | 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/start → turn/end
模型用时 step/start → assistant/message,带调用次数
首 token 平均(TTFT) step/start → 第一个输出 token
生成阶段 首 token → 结算,带 tok/s
工具用时 tool/call → tool/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-half 的 0.5,而且插件本来就读不到宿主的压缩配置。现在它只讲取舍(阈值越低, 每次摘要要回放的历史越短、单次越便宜,但压得越勤),而"要改去哪改"交给那条手动说明。

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

采纳一条建议

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

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

采纳之后

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

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

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

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

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

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

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

全账号报表

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

分母只留两个,都在产出侧 —— 不拿 agent 自己的流程当工作量:

行 为什么用它
每产出编辑 每 write / edit / present 一次多少钱 —— 交付物的分母;纯聊天、纯调研的日子没有产出,显示 —
每 1K 回答 token 产出 1000 token 回答要付多少(不含思考)—— 输入是回答的很多倍时它就高,缓存和上下文的问题都在这里显形

「每步」和「每回合」已经删掉:步数是 agent 自己的过程(把零碎调用合并成一个脚本会让它合理地上升), 回合数是你的习惯(说一句「你好」和一整个大任务都算一回合)—— 两个都不是工作量。四个读数里有两个会误导, 不如只留两个对的。曲线也只画这两条。 | 重读 / 冷输入 / 输出 | 三项加起来才是总额;只看总数看不出"为什么动了" | | 其中压缩摘要 | 是上面三项的子集,不是第四项 —— 摘要调用的 token 本来就是缓存重读或未命中输入 | | 高峰占比 | 只报数字,不做建议 |

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

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

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

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

细粒度视图

日粒度回答不了"我 11 点改的那个设置有没有用" —— 一天里混着好几种策略,而一个会话和下一个会话干的根本不是 同一件活。所以账单卡片里还有第三档「细粒度」,把同一批事件按分钟/小时折开:

  • 一行一个量度(¥ / 次、命中 tok / 次、冷输入 tok / 次、输出 tok / 次),全都除以调用次数 —— 桶里的工作 量不一样,画总量只会跟着工作量涨。
  • 窗口即粒度:2 小时=1 分钟桶、24 小时=5 分钟桶、7 天=1 小时桶。要两个开关才能表达一件事,就只做一个。
  • 标记:改思考档位、换模型、起子 agent、/compact、压缩摘要、切 preset / sandbox / approval,都画成竖虚线, 最近几条列在下面(带时刻)。
  • 两个能控制的变量做成开关:上下文档位(<100K / 100–200K / 200–350K / ≥350K)和并发(只有本会话 / 有并行)。曲线只有在同一档位内比较才说明策略优劣 —— 否则你量到的是上下文变重,不是策略变差。

边界写清楚:任务类型(写代码 / 调研 / 聊天)不是任何人能定的变量,所以这里不提供跨任务类型的对比;标记全部 从日志推出,因此在会话外改配置(编辑 preset、改 settings.yaml)不会留痕,只会表现为"下一个会话以不同档位 开始"。某个会话折不动时会在卡片上写出来,不会假装序列是完整的。

价格

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

模型族 缓存命中(空闲 / 高峰) 缓存未命中(空闲 / 高峰) 输出(空闲 / 高峰)
deepseek-flash、deepseek-v4.1-flash、deepseek-v4-flash 0.02 / 0.04 1 / 2 4 / 8
deepseek-v4-pro、deepseek-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 把所有会话的按日桶合并成一份日历,/api/dsh-cost-audit.fine 把同一批 事件按分钟/小时折成每次调用的均值并标出策略改动的时刻(改档位、换模型、起子 agent、压缩、切 preset / sandbox)。按需折叠存在的原因是:投影管线 只会在一个会话已经有物化单元之后才把它发给客户端 —— 持久投影检查点早于本插件的会话没有 dshCostAudit 那一行,而这条路由用同一个单元定义把这个缺口补上。报表路由要折叠一百多个会话,所以它缓存 60 秒。
  • 客户端半边(client.js)注册进 harness 的 conversation.chat.assistant-actions 与 conversation.composer.dock 两个插槽。它没有构建步骤:是一个手写的 window.__ModuleLoader__.load({ id, factory }) 形式的 bundle,所以这个包可以直接从 checkout 装。
  • 按日花费按本地日历日折叠(宿主的时钟,也是浏览器的时钟),保留最近 90 天,于是一个跨了几个月还在 用的会话不会让检查点无限膨胀。每个日桶带三套互不混淆的口径:token 轴(重读 + 冷输入 + 输出)等于当日总额, 费率轴(高峰 + 非高峰)也等于当日总额,而压缩摘要是 token 轴的子集、不是并列的第四项。
  • 会话行的位置是量出来的,不是写死的,并且两个胶囊整体保持居中。输入框 dock 是堆叠它的插槽条目的,而 官方统计行是一个本插件并不拥有的居中 flex 行,所以要量三件事:整行按官方行的高度上提、内容缩进到官方内容 结束的位置、官方行再向左平移本胶囊宽度的一半(用本插件设置和清除的 translateX,绝不改布局),这样两个才 读起来像一个居中的整体。官方标签变长、字号变了、窗口缩放,都会自动落在对的位置;当整组一行放不下时,本行 回退成自己的一行居中,官方行保持 harness 画的原样。

目录

index.js             宿主半边:dshCostAudit 投影 + balance / report / fine 三条路由
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。

—/ 5

No ratings yet

Verified DSH bundle

Commit 71653cb7bfb5

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout