DeepSeek Harness Hub
← 返回列表

成本账本suimi8/dsh-cost-ledger

DeepSeek Harnessspec-screened在 GitHub 查看 ↗
未验证

记录每次 token 用量并查询预算开销

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/8/14 · 已提供中文文档

DeepSeek Harness 的跨会话持久化成本账本:将每次 LLM token 使用记录到 SQLite,并暴露 record/query/budget 工具。内置 DeepSeek 定价,可通过配置覆盖。

综合分
27.4
GitHub 分
27.4
用户评分
★ Stars
1
周下载量
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add suimi8/dsh-cost-ledger
该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-runtime@deepseek-ai/dsh-client-ui-settings@deepseek-ai/dsh-client-ui-slots@deepseek-ai/dsh-settings
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

dsh-cost-ledger

用于 DeepSeek Harness 的跨会话持久化成本账本。
自动将每个 LLM token 用量事件记录到 SQLite,并暴露 record_cost / query_cost / set_budget 智能体工具。内置 DeepSeek 定价,可通过插件配置覆盖。安装即用,无需额外接线。

状态

阶段 1(宿主侧)——已完成并在 DSH 0.1.0-rc.6 中实机验证(最后验证于 2026-08-13)。 28 项数据层检查通过(pnpm selftest);该插件在真实的 dsh web 配置中加载并运行。

token 用量来源和工具注册 API 已从 DSH 0.1.0-rc.6 源码确认,并已真实接线:

| 集成 | API | 状态 |
|---|---|---|
| Token 用量捕获 | ctx.on('llm/stream', (options, next) => AsyncIterable) —— 包裹每次模型调用的 Cordis waterfall | ✅ 已接线 |
| 工具注册 | ctx.tools.register(ToolDefinition) —— 真实的 { name, description, parameters, output:{schema,render}, execute(args, exec) } | ✅ 已接线 |
| 持久化存储 | 通过 better-sqlite3 使用 SQLite(预构建 win32 二进制,无需编译) | ✅ |
| 定价 | DeepSeek 官方(人民币/百万 token),感知缓存;可通过配置覆盖 | ✅ |
| 在 dsh web 中实机加载 | 通过 dsh plugin --profile web add . 安装,宿主加载该 bundle,apply() 运行,SQLite 打开 | ✅ 已验证 |
| 端到端 token 捕获 | dsh --profile headless "..." → 真实 LLM 调用 → llm/stream 监听器触发 → 采集用量 chunk → 写入 SQLite 行 | ✅ 已验证 |

实机验证: 一次性的 dsh --profile headless "reply with exactly: hi" 在 ledger.db 中产生了真实行({model:"glm-5-2", inputTokens, outputTokens, cacheReadTokens})——完整的 llm/stream → 用量 chunk → SQLite 流水线可对真实宿主工作。

模块加载使用 .ts 扩展名说明符(./store.ts)——Cordis 加载器会重写这些并直接加载 TypeScript,因此无需构建步骤;该插件安装后即可从源码运行。

在实机集成期间发现并修复了两个问题:
- ctx.on('llm/stream') 上的 { global: true } —— 没有它,监听器只能看到来自自身 fiber 的调用;智能体循环从不同的作用域派发。(与宿主自身的 invariant.js 用法一致。)
- 不能未注入访问服务 —— 除非在 inject 中声明,否则 ctx.session/ctx.workspace 会抛出 "cannot get property without inject"。会话 id 现在改为来自 llm/stream 事件的 options.sessionId。

阶段 2(WebUI 仪表盘面板)——已调研,未实现。 参见 阶段 2。

功能

- 自动记录 token 用量:订阅 llm/stream waterfall,并按每次真实提供商调用(包括重试)写入 {timestamp, session, project, model, inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens, cost}。
- 计算成本:内置 DeepSeek 定价(deepseek-chat / deepseek-reasoner,人民币元/百万 tokens)。inputTokens 是未缓存的输入;计费输入 = input + cacheRead + cacheWrite,各自按其费率计价。可通过配置覆盖或添加模型。
- 三个 agent 工具:
- record_cost — 手动记录一条用量条目(回填/测试)。
- query_cost — 在某个范围内(today/week/month/all/ISO)统计总支出 + 按模型细分;报告当前每日预算状态。
- set_budget — 创建/更新/删除支出预算(daily/weekly/monthly/never 窗口,按标签限定范围:daily、model:、project:)。

安装(社区 / 标准)

dsh plugin --profile web add

宿主从 package.json(dsh.bundle.patch)发现插件——无需绝对路径,无需手动接线。prepare 脚本从源码构建 lib/,因此 git checkout 安装即可自包含。安装后重启 dsh web。

Git 安装注意事项: pnpm ≥10 会阻止 git 依赖的 prepare 脚本,直到被允许为止。如果第一次 add 失败,将 pnpm 打印的确切包键复制到 profile 的 pnpm-workspace.yaml(allowBuilds: dsh-cost-ledger: true)并重新运行——正如官方文档所述。

本地开发

pnpm install
pnpm selftest              # verify the data layer (28 checks)
pnpm typecheck
pnpm build                 # build host (lib/.js) + client (lib/client.js)

load into a running dsh web via the patch (absolute path, this machine):
dsh web --patch ./cordis.patch.yml

定价——内置官方费率

内置模型定价(元/百万 tokens,来自各平台官方定价页):
- deepseek-v4-flash — 输入 0.10 / 输出 3.0 / cacheRead 9.0(高峰档)
- deepseek-v4-pro — 输入 0.30 / 输出 9.0 / cacheRead 27.0(高峰档)
- deepseek-chat (V3) / deepseek-reasoner (R1) — 旧版别名
- glm-5-2 — 默认 0(在仪表盘 ⚙️设置 标签页或配置中覆盖;从智谱定价填入)

未知模型仅记录 tokens(成本 = 0),直到你设置价格。可随时通过仪表盘中的 ⚙️设置 标签页 或 WebUI 设置卡片覆盖——更改立即应用于新调用。

配置

在仪表盘 ⚙️设置 标签页(运行时,重启后不持久化)或 WebUI 插件配置卡片(持久化)/ cordis.patch.yml 下编辑:

config:
dbPath: 'dsh-cost-ledger/ledger.db'      # relative to DSH cwd
defaultDailyBudget: 0                     # CNY; 0 = no limit
pricing:
deepseek-chat:                          # override or add any model
input: 2
output: 8
cacheRead: 0.5
cacheWrite: 8

架构

src/
pricing.ts   built-in DeepSeek price table + computeCost()
store.ts     SQLite ledger: insert + summaryByModel + spentSince + budgets
tools.ts     three ToolDefs (pure handlers over store + config)
config.ts    Schema (schemastery) config
index.ts     apply(ctx):llm/stream 监听器 + registerTools + 清理
client/      第二阶段 WebUI 入口(占位)
cordis.patch.yml   本地开发配置补丁(绝对路径)
scripts/selftest.ts   独立数据层验证

Token 捕获(已确认的 API)

llm/stream 是一个 Cordis 瀑布流(waterfall),包裹每一次流式模型调用(包括重试)。监听器在透传底层流的同时采集 usage 数据块:

ctx.on('llm/stream', (options, next) => (async function () {
let usage: TokenUsage | undefined
for await (const chunk of next()) {
if (chunk.type === 'usage') usage = chunk.usage
yield chunk
}
if (usage) record(options, usage)   // 持久化一行记录
})())

关键计费事实(来自官方 TokenUsage):
- inputTokens = 仅未缓存输入。计费输入 = input + cacheRead + cacheWrite。
- reasoningTokens 已包含在 outputTokens 中——切勿重复计算。
- usage 不保证存在(提前中止/出错)——缺失时以 debug 级别记录日志。

TokenUsage / StreamChunk / GenerateOptions 类型位于 @deepseek-ai/dsh-llm(一个未发布的、由宿主注入的包)。本插件声明了最小化的本地类型以便独立进行类型检查;一旦宿主包可解析,就替换为真正的 import type。

第二阶段(WebUI 面板)

针对 dsh-web-ui 参考实现进行了调研。关键发现:DSH 没有为外部插件暴露通用的侧边栏面板插槽。sidebar.workspaces / sidebar.settings 是单一占用且已被外壳占用。可选方案:

- DOM 层面绕过(dsh-task-board / dsh-ssh 的做法):MutationObserver + createRoot 注入到 [data-pane="sidebar"] / [data-pane="conversation"]。最灵活。
- 设置卡片,通过 web-ui.plugin.item(最轻量——设置 → 插件下的一个摘要卡片)。
- 生态中没有图表库先例。推荐:内联 SVG,或内置 recharts(严格 CSP,无 CDN)。

兼容性

- DSH 版本: 已针对 0.1.0-rc.6 验证(API 表面——ctx.on('llm/stream')、ctx.tools.register、ctx.inject、agentDefaultModel——已从 DSH 0.1.0-rc.6 源码确认)。
- 最后验证: 2026-08-13。
- 配置文件: 在 dsh web(完整 UI + HTTP API + 仪表盘)和 dsh --profile headless(仅 Token 捕获 + 工具;HTTP API 和仪表盘仅限 web 配置文件,会被静默跳过)下均可加载。
- 操作系统: SQLite 后端通过 better-sqlite3 提供预构建的 win32 二进制文件;其他平台在安装时从源码构建(需要 C++ 工具链)。已在 Windows 11 / Node 22 上验证。
- 预发布注意事项: DSH 处于开发者预览阶段,预计会有破坏兼容性的变更。Token 用量来源和工具注册 API 已针对 rc.6 确认;未来主线版本可能会重命名它们,届时需要更新插件。

安装

dsh plugin --profile web add
宿主从 package.json(dsh.bundle.patch)中发现该插件——无需绝对路径,无需手动接线。prepare 脚本会从源码构建 lib/,因此通过 git 检出安装即可自包含。安装后重启 dsh web。

Git 安装注意事项: pnpm ≥10 会阻止 git 依赖的 prepare 脚本,直到被允许为止。如果首次 add 失败,请将 pnpm 打印出的确切包键复制到配置文件的 pnpm-workspace.yaml 中(allowBuilds: dsh-cost-ledger: true)并重新运行——正如官方文档所述。

卸载

Remove the bundle from the profile, then restart dsh web
dsh plugin --profile web remove dsh-cost-ledger

这会从配置文件的 dsh.profile.bundles 列表中移除该 bundle,并解除该包的链接。账本数据库(dsh-cost-ledger/ledger.db)以及 cordis.patch.yml 中的任何配置覆盖不会被自动移除——如果你想要彻底清理,请手动删除它们:

Remove-Item -Recurse -Force dsh-cost-ledger   # the data dir created under the DSH cwd

若要临时禁用而不移除:在配置文件的 cordis.yml 的 bundles 列表中注释掉 dsh-cost-ledger 并重启。

快速开始

1. Install into your web profile (see Install above)
dsh plugin --profile web add .

2. Restart dsh web, then just use the agent normally
dsh web

现在每次模型调用都会被自动记录。经过几次提示后,让 agent 查询花费:

查一下今天花了多少钱(query_cost today)

或者打开 Web UI 中的仪表盘面板(cost-ledger 标签页),查看实时摘要、按模型细分以及预算/预算设置——无需额外接线。

权限与数据

- 写入的文件: 一个位于 dsh-cost-ledger/ledger.db 的 SQLite 数据库(路径可通过 dbPath 配置,相对于 DSH 工作目录)及其 WAL/SHM 附属文件。除此之外不触碰文件系统。
- 网络: 无。该插件不进行任何出站网络调用。(parse-prices 端点调用的是宿主自身的 ctx.llm.stream()——它复用你已配置的模型调用路径,而非新建连接。)
- 凭据: 不读取、不存储、不传输任何凭据。该插件从不触碰你的 API 密钥;它只读取宿主已在 llm/stream 事件中发出的 token 计数和模型名称。
- 每次模型调用记录的数据: {timestamp, sessionId, project, model, provider, inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens, cost}。提示内容或补全内容永远不会被存储——只存储聚合的 token 计数和元数据。
- HTTP API: 在 dsh web 下运行时,该插件在 /api/cost-ledger/ 下注册了大致只读的 JSON 端点。它们绑定到宿主的 Web 服务器,可从与 Web UI 相同的源访问。cleanup 和 parse-prices 端点是供仪表盘 UI 使用的写入/POST 端点。

故障排除
- Cannot find module './store.ts' / git pull 后加载错误: Cordis 加载器会直接解析 .ts 说明符,但陈旧的 lib/ 可能会干扰。运行 pnpm build(或 pnpm install 以触发 prepare)并重启 dsh web。
- better-sqlite3 在 macOS/Linux 上安装失败: 预编译二进制文件仅适用于 win32;其他平台需从源码编译。安装 C++ 工具链(build-essential / Xcode CLT)并重新运行 pnpm install。
- 没有出现成本记录行: 确认模型调用确实发出了 usage 数据块(提前中止/出错时可能不会)。Token 捕获是尽力而为的——缺失的 usage 会以 debug 级别记录。同时确认 dbPath 可写。
- parse-prices 返回 503 / “default model not configured”: agentDefaultModel 服务尚未解析完成,或 Agent 设置中未设置默认模型。设置一个默认模型并重试。
- pnpm 在 git 安装时阻止 prepare 脚本: 在配置文件的 pnpm-workspace.yaml 中添加 allowBuilds: dsh-cost-ledger: true,然后重新运行 dsh plugin add。
- 日志: 插件诊断信息会输出到宿主日志(dsh web 控制台 / dsh-run.log);SQLite 账本本身是成本数据的记录系统。
- 回滚: dsh plugin --profile web remove dsh-cost-ledger + 重启;可选地删除 dsh-cost-ledger/ 数据目录(参见 Uninstall)。

开发

pnpm install
pnpm selftest              # 验证数据层(28 项检查)
pnpm typecheck
pnpm build                 # 构建宿主(lib/.js)+ 客户端(lib/client.js)

通过补丁加载到正在运行的 dsh web 中(绝对路径,本机):
dsh web --patch ./cordis.patch.yml

react / react-dom 以及 @deepseek-ai/dsh-client-* 运行时包对客户端 bundle 而言是外部依赖(在运行时由宿主的模块加载器解析),因此它们被正确地声明为 devDependencies / peerDependencies,而非 dependencies。唯一的运行时 dependency 是 better-sqlite3。

许可证与安全

MIT — 参见 LICENSE。

安全报告: 此插件没有网络暴露面,也不存储任何凭据,但如果你发现了漏洞(例如不安全的 SQL 处理、通过 dbPath 进行的路径遍历),请不要公开提交 issue。请通过 GitHub Security Advisories 私下报告(在仓库中依次点击 Security → Report a vulnerability)。所有 SQL 均使用参数化语句(@named 绑定参数),所有文件系统访问都限制在配置的 dbPath 内。

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

同作者(suimi8)的其他插件

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群