跳到主要内容

dsh-llm-stats

已验证

@aiwayds/dsh-llm-stats · v0.8.0 · MIT

dsh plugin: persistent whole-machine LLM usage ledger with a markdown /llm-stats report (GFM tables + emoji: tokens, cache hit, model/tool time, per-day bars)

安装

dsh plugin add @aiwayds/dsh-llm-stats

用 dsh --profile default --dump-config 确认 layer 已生效 —— 参见安装指南。

源码

标签

说明文档

@aiwayds/dsh-llm-stats

English | 中文

DeepSeek Harness 的持久化 LLM 用量账本插件,提供 /llm-stats 斜杠命令,以 markdown 报告(GFM 表格 + emoji)呈现用量。插件把每个结束的 agent step 折叠成一行持久化记录——token 四桶(provider 报告)、模型耗时、首 token 延迟、解码吞吐、工具耗时——追加写入 $DSH_HOME/llm-stats/ 下本进程私有的分片文件。本机所有挂载了本插件的 dsh 进程共用这份整机账本,/llm-stats 在任意 surface 上按滚动日历窗口渲染:

要求 dsh >= 0.2.0-rc.2 — 本插件只跟随 dsh RC/stable 线(CI 与发版在运行时解析 latest/next 中更新的 dist-tag)。不再支持 alpha 线。

📊 LLM stats · last 30 days (Aug 3 – Sep 1)

⚡ Sessions 💬 Turns 📡 Requests 👣 Steps
132 196 2710 2742
📥 In 🔥 Cache hit 📤 Out 🧮 Total
141M 93% 2.5M 144M

⏱ Model 13h15m · 🔧 Tools 18h35m · 🚀 TTFT 4.5s · ⚡ 69.2 tok/s

🤖 By model

Model 📥 In 📤 Out 🔥 Cache 📡 Req
glm-5.3-flash 46.8M 930K 90% 1053
deepseek-flash 78.1M 1.1M 94% 1304
glm-5.3 14.6M 369K 93% 301
MiniMax-M3 186K 15.3K 45% 7
kimi 393K 6.8K 79% 10
minimax/minimax-m3:free 1.2M 14.2K 96% 35

📈 Activity

📅 Date 📊 Tokens 📈
Aug 28 168K ▇
Aug 31 4.6M ▇▇▇▇▇▇▇▇▇▇▇▇▇▇
Sep 1 8M ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇

dsh-tui-pi 会识别表格分隔行,把报告经 markdown 组件渲染成框线表格;其他 surface(如 headless)显示原始 markdown。

安装

dsh plugin add @aiwayds/dsh-llm-stats

然后重启 dsh。想让哪些 profile 的用量计入,就把插件装进哪些 profile(账本整机一份,但只有挂载了插件的进程才会记账)。

卸载

dsh plugin --profile <name> remove @aiwayds/dsh-llm-stats

宿主会自动收敛(bundles 条目移除、patch 层随包消失)。~/.dsh/llm-stats/ 的账本(baseline.jsonl、records.*.jsonl 分片、回填文件)有意保留 —— 这是用量历史,重装后继续累计。0.5.1 起插件启动时会清扫遗留的 compact.lock.stale-* 接管目录和已死进程的 .baseline.jsonl.tmp-* 暂存文件。彻底清除:先备份,再 rm -rf ~/.dsh/llm-stats。

用法

命令 含义
/llm-stats 帮助:用法、当前配置、账本覆盖情况
/llm-stats day|week|month|3m|6m|12m 以现在为终点的滚动日历窗口
/llm-stats d|w|m day / week / month 的短别名
/llm-stats backfill 从落盘会话日志回填历史用量

范围是滚动语义:week = 最近 7 个本地日历日(含今天),输出标注的实际日期区间与口语「最近七天」一致。3 个月及以上的长档,逐日条形自动折叠为周一取齐的逐周条形。

配置

- id: dsh-llm-stats
  config:
    mode: on              # off 停止记账;/llm-stats 与清理照常工作
    retentionDays: 365    # 超过该天数的记录在 compaction 时清除(最小 7)

工作原理

  • 一个 step 一条记录。 折叠以 step/end 为锚点(step 生命周期的权威事件:完成、失败、取消、max-tokens 的步都恰好落一个),语义对齐上游 @deepseek-ai/dsh-session-stats projection——即 dsh web 聊天统计条背后的那份折叠。token 字段可空:没有 provider usage 的步照样计入 Steps 与 Turns,只是不计入 Requests。
  • 分片 append-only 账本。 每个 dsh 进程只追加自己的 records.<boot-id>.jsonl 分片,活着的进程绝不重写共享文件——TUI + headless + bot 并发互不践踏。死进程的分片在锁保护下于 compaction 时并入 baseline.jsonl,retentionDays 的过期清理也在同一时机执行。记录是计费旁路事实而非会话真相:写入尽力而为,失败的行直接丢弃,绝不影响会话。
  • 重叠安全的聚合。 聚合按 (sid, turn, step) 去重(last-wins),日志重放或(将来的)历史回填都不会重复计数。
  • 不记内容。 账本里只有数字、模型 id 和会话 id——没有 prompt、没有工具名、没有结果。

回填

账本从插件启动才开始记;之前的历史跑一次:

/llm-stats backfill

它会扫描 $DSH_HOME/sessions/(全部项目),解码每个落盘日志(拼接 zstd 帧的生产格式,含打包 chunk 行),用与实时记账完全相同的 step 语义折叠,然后把记录并入账本。全程遵守 retentionDays(最后写入早于窗口的会话整体跳过);fork/subagent 的种子历史按 header seedLength 跳过,父会话的用量绝不会被重复计入;已处理的会话记入 done-ledger,重复执行很快;中途被打断也可以续跑。

已知局限

  • 进程在 step/end 前崩溃的步实时记账不会记录;下一次 backfill 会从会话日志补回。
  • 子代理子会话只有在其事件冒泡到 host 监听时才被实时计入;漏掉的由 backfill 兜底。

开发

npm install                          # devDependencies 解析 @deepseek-ai/* 类型闭包
node scripts/link-dsh-closure.mjs    # 把本地 @deepseek-ai/* 重新指向全局闭包(每次 install 后重跑)
npm run check                        # tsc --noEmit
npm test                             # 构建 + node --test(fold / aggregate / render / store / 插件接线)

@deepseek-ai/* 只进 peerDependencies(devDependencies 仅供本地构建);把第二份闭包打进 dsh profile 会破坏 cordis 服务同一性。仓库以 link 挂进 live profile 时,正是上面这步 link 保证插件与 profile 解析到同一份闭包——不要跳过。

许可

MIT