Tallyhook 发布:按客户统计 Claude Code 与 Codex 日志开销
Show HN: Tallyhook – price Claude Code and Codex logs per client you bill
Tallyhook 是一个无依赖的 Node.js 单文件工具,读取本机 Claude Code 和 Codex CLI 已写入的会话日志并按公开 API 价格计算开销,示例中 30 天 266 个会话合计 2740.96 美元。
你的 AI 编程代理实际花费了多少——按仓库,以及按你计费的每个客户。
一个无依赖的 Node.js 文件。它读取你机器上 Claude Code 和 Codex CLI 已经写入的会话日志,并为其定价。无需账户,无需注册,不上传任何内容。
npx tallyhook
AI coding-agent usage on this machine, last 30 days (public API list prices)
REPO SESSIONS OUTPUT LIST COST
github.com/acme/storefront 118 10.8M $1,450.59
github.com/acme/patient-portal 100 7.2M $867.84
github.com/globex/intranet 44 3.1M $402.17
local:scratch 4 96.2k $20.36
TOTAL 266 21.2M $2,740.96
Previous 30 days: $1,602.11 across 186 sessions — up 71%.
其他本地工具都做不到的部分:该开什么发票
如果你用代理处理需要向他人计费的工作,你需要的数字不是“这个仓库花了多少”——而是“这个月我该在 Acme 的发票上写多少”。所以把仓库分组并设定费率:
npx tallyhook clients add "Acme Corp" acme/storefront acme/patient-portal --rate 20 npx tallyhook clients add "Globex" globex/ --rate 35 npx tallyhook --by client
CLIENT SESSIONS OUTPUT LIST COST BILLABLE
Acme Corp 218 18.0M $2,318.43 $2,782.12
Globex 44 3.1M $402.17 $542.93
TOTAL 262 21.1M $2,720.60 $3,325.05
Not counted: $20.36 in repos no client claims. `tallyhook clients` lists them.
这个映射保存在你机器上的 ~/.tallyhook/clients.json 中,它仍然免费,仍然不上传任何内容。单独运行 tallyhook clients 会打印出该映射,外加所有尚无客户认领的仓库,按费用从高到低排列——这就是挡在你和完整发票之间的工作清单。
可计费总额是按四舍五入到分的行相加得出的,这是刻意的:客户把你展示给他们的各行加起来,必须等于你开出的总额。
命令
npx tallyhook # spend per repo, last 30 days npx tallyhook --by client # roll repos up into the clients you bill npx tallyhook --by model # the same spend per model npx tallyhook clients # the billing map, and which repos nobody claims npx tallyhook mcp # MCP server, so an agent can ask what its own work cost
| 标志 | 作用 |
|---|---|
--days 90 |
更长的时间窗口。趋势线始终与紧邻其前、长度相同的窗口进行比较,因此 --days 7 是将本周与上周比较。 |
--by client|model|repo |
如何分组。跨越两个模型的会话,其费用会在两者之间拆分,而不是整体归给其中一个。 |
--markup 20 |
试用一个费率而不保存它。对于那一次运行,它会胜过任何已存储的费率,因此绝不会悄无声息地失效。 |
--json |
同样的数字,不带说明文字,供脚本使用。任何无法定价的内容都不会被猜测:如果价格表无法访问,每个费用都是 null,而 priced 是 false。使用 --by client 时它还会带上 counted 和 not_counted_cost_usd,它们始终加起来等于 total_cost_usd,这样脚本就能知道客户行实际覆盖了机器的多少部分。 |
以上所有内容都完全在你的机器上运行。唯一的网络调用是 GET 获取公开价格表(https://tallyhook.dev/api/prices)。想先读一读再运行?它是本仓库中的一个文件,tallyhook.js——下载它,读一读,然后 node tallyhook.js。
它做对了什么
这个文件的大部分工作都在于不出错:
- 流式行:Claude Code 为每个内容块写入一行 JSONL,每行都携带相同的
usage对象。行按message.id去重,否则相同的 token 会被多次计数。 - 子代理:分叉出的子代理记录会复制父级的助手行。去重覆盖一个会话的每个文件,包括
subagents/*.jsonl。 - 缓存定价:缓存读取、5 分钟缓存写入(1.25× 输入)和 1 小时缓存写入(2× 输入)分别定价。快速模式消息按快速模式费率定价。
- Codex:读取
~/.codex/sessions/**/*.jsonl,以及 Codex 在七天后压缩的.jsonl.zst文件(需要 Node 22.15+;更旧的 Node 会跳过它们而不是猜测)。 - 按仓库,而非文件夹:会话按 git remote(
host/org/repo)分组,因此同一个仓库在两个检出中只算一行。没有 remote 则归为local:<folder>。 - 按文件,而非仅 cwd:一个在三个仓库中编辑过文件的会话,会归因于这些文件所属的仓库,而不是代理恰好启动时所在的目录。
- 诚实的数字:费用是来自供应商公开 API 定价的标价等价物。在订阅制下,这是你所使用内容的价值,而不是账单。没有已知价格的模型会报告为未定价,而不是猜测。
问问你的代理它刚刚花了你多少钱
claude mcp add tallyhook -- npx -y tallyhook mcp
一个基于 stdio 的 MCP 服务器,因此 Claude Code(或任何 MCP 客户端)可以回答关于其自身工作的费用问题。无需账户,无需令牌,不上传任何内容——它读取与报告相同的本地日志。或者手动,在 .mcp.json 中:
{ "mcpServers": { "tallyhook": { "command": "npx", "args": ["-y", "tallyhook", "mcp"] } } }然后问它“这个仓库这个月花了我多少钱?”、“哪些会话是昂贵的?” 或者“我比上个月花得更多吗?”
| tool | answers |
|---|---|
usage_by_repo |
按 git 仓库分组的过去 N 天支出 |
usage_by_model |
同样的支出按模型分组——跨两个模型的会话会在两者之间拆分,因此总额一致 |
expensive_sessions |
花费最高的单个会话,用于发现失控的 agent 循环 |
usage_summary |
总计和会话数,与紧邻之前的等长窗口对比 |
解析每个本地日志是慢的部分,因此每个进程缓存一分钟:在繁忙的机器上第一个
问题需要几秒钟,其余都是即时的。在
~/.tallyhook/config.json 中设置 "privacy": true,并且 expensive_sessions 也会省略提示片段。
将其安装为 agent 技能
npx skills add tallyhook/tallyhook-collector
一次性为 Claude Code、Codex、Cline、Amp 以及其他二十多个 agent 安装 agent-cost-report,
这样 agent 本身就能回答“这个项目花了多少钱”和“这个月我该向 Acme 开多少账单”,
而无需被告知如何操作。该技能包含防止答案出错的规则:这些是
标价等价物而非账单,客户报告只涵盖已映射的仓库,并以金额说明其排除了什么,
以及无法访问价格表意味着报告 token 数而非猜测美元金额。
专门针对 Claude Code 还有一个插件,带有 /tallyhook:cost 和 /tallyhook:clients
以及上面的 MCP 服务器。
当一台机器不够用时
以上所有内容只读取本磁盘上的内容,这也是它的局限:它看不到你 同事的会话,一旦 Claude Code 轮转其日志它就会忘记历史,也无法向 客户交付任何东西。Tallyhook 是面向这三点的托管层: 每个开发者的会话汇总为一个总数,历史比日志更长久,每个 客户有预算和警报,以及一个无需登录即可发送给客户的报告链接。有一个 实时演示,无需注册。
npx tallyhook install <token> # registers Claude Code hooks (SessionEnd, and Stop at most every 10 min), uploads history npx tallyhook sync [--dry-run] # upload anything new now; --dry-run prints a summary and never touches the network npx tallyhook status # what is configured npx tallyhook uninstall # remove the hooks and ~/.tallyhook
无论哪种方式,本地命令都保持本地且无需账户;安装 token 不会改变它们 读取的内容,也不会额外发送任何东西。
按会话上传(仅安装/同步时):按模型的 token 数、开始和结束时间、工具和
版本、git remote 和分支、编辑文件所属的仓库、来自 git config 的开发者身份、
机器主机名、轮次和工具调用次数、编辑文件的路径,以及第一个提示的前
160 个字符(用 "privacy": true 关闭此功能)。
绝不上传:转录、代码、差异、工具输出、环境变量。
Node.js 18+。macOS 和 Linux;Windows 自 0.4.2 起新获允许,但尚未验证。许可证:MIT。
来源:Hacker News · github.com