
caveman 的 /caveman-stats基于会话日志的真实 Token 用量统计与诚实的节省核算【免费下载链接】caveman why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman项目地址: https://gitcode.com/GitHub_Trending/caveman1/caveman本文围绕 caveman 仓库中的 skills/caveman-stats/SKILL.md 展开讲清/caveman-stats这条斜杠命令背后的完整机制它如何直接读取 Claude Code 的 JSONL 会话日志得到真实 token 用量、如何用基准数据估算若不用 caveman 会多花多少 output token、又如何在Est. rule overhead与Est. net两行中如实呈现规则注入的输入成本与净收益甚至直接告诉你这个工作负载下建议关掉 caveman。读完本文你能完整理解该技能的 hook 契约、数据流、命令行参数、环境变量覆盖项以及源码中按模式归因per-mode attribution的三层回退策略。技能定位与 hook 契约caveman-stats的核心承诺是真实会话 token 收据不经过模型估算。它由 src/hooks/caveman-stats.js 实现在 Claude Code 中通过UserPromptSubmit阶段的caveman-mode-trackerhook 被触发当用户输入/caveman-stats时src/hooks/caveman-mode-tracker.js 用正则/^\/caveman(?::caveman)?-stats(?:\s(.*))?$/匹配提示词识别后不再走模式解析逻辑而是直接把该 prompt 转发给 stats 脚本并注入统计结果。SKILL.md 原文描述的契约是模型在这个技能触发时不需要做任何事——hook 会把格式化好的统计结果作为拦截决策的理由返回用户立刻看到数字。当前实现的具体形式可以从源码中确认mode-tracker 以同步子进程方式执行caveman-stats.js2.5 秒看门狗超时超时或脚本缺失时降级为提示could not run stats script然后把输出包进hookSpecificOutput.additionalContext并附带一条指令要求模型把这段统计块原样打印在代码块里不要说别的见 src/hooks/caveman-mode-tracker.js。也就是说模型只是传声筒所有数字都来自磁盘上的日志解析而非模型自己心算——这一点由 tests/test_caveman_stats.js 中mode tracker delivers /caveman-stats via additionalContext等用例直接验证。斜杠命令本身的注册见 commands/caveman-stats.tomldescription Real session token usage lifetime savings USD. Tweetable line via --share.prompt /caveman-stats {{args}}{{args}}允许把尾部参数透传给脚本。数据从哪来会话 JSONL 日志stats 脚本的所有数字都来自 Claude Code 的会话 transcriptJSONL 文件会话目录process.env.CLAUDE_CONFIG_DIR或默认的~/.claude会话文件位于claudeDir/projects/下定位会话hook 集成时 Claude Code 会提供transcript_pathmode-tracker 通过--session-file path显式传入保证读的是当前活跃会话而不是最近被修改的某个 JSONL不带该参数直接运行时脚本会递归扫描projects/目录取 mtime 最新的.jsonlsrc/hooks/caveman-stats.js解析规则parseSession()逐行解析 JSONL只统计type assistant且带message.usage的条目累加usage.output_tokens与usage.cache_read_input_tokens每计一次 usage 记一个 turn并取第一条记录的message.model作为计费模型标识src/hooks/caveman-stats.js。测试用例 tests/test_caveman_stats.js 验证了最基本的行为给脚本一个包含两条 assistant 消息output 10050、cache_read 20050的合成会话文件输出必须包含Turns: 2、Output tokens: 150、Cache-read tokens: 250。此外输出里还有Cache-read tokens一行它本身不算被节省的部分只是如实展示缓存命中的输入规模为读者理解整个会话的 token 结构提供参考。节省量的估算只用有基准数据的模式估算逻辑集中在 src/hooks/caveman-stats.js 的常量表与 deriveSavings()压缩比表COMPRESSION { full: 0.65 }。源码注释说明 65% 来自benchmarks/results/*.json中 10 个任务的 per-task 均值sonnet-4-20250514lite/ultra/wenyan等模式尚无基准数据输出会明确写No savings estimate for mode — only full has benchmark data而不是给一个拍脑袋的数字。换算公式estNormal round(outputTokens / (1 - ratio))estSaved estNormal - outputTokens。即若正常风格应输出 X token而实际只输出了 Y则节省了 X − Y。测试中 350 output tokens、full 模式的断言是Est. without caveman: 1,000、Est. tokens saved: 650 (~65% of output)tests/test_caveman_stats.js。美元换算脚本内置一张按 model id 前缀匹配的 output 定价表MODEL_OUTPUT_PRICE_PER_M如claude-sonnet-4→ $15/M、claude-opus-4→ $25/M、claude-3-5-haiku→ $4/M 等最具体的前缀必须排在最前取第一个匹配。模型不在表内如未来的新模型时美元行被省略token 估算仍会输出——测试 tests/test_caveman_stats.js 专门验证了unknown model 时不出现 Est. saved (USD)。输出比例措辞源码注释强调从 output token 能诚实计算的比例只有output reduction绝不能标成usage/budget 占比因为 input 与 cache token 在 agentic 会话中占大头且不受 caveman 影响详见 docs/HONEST-NUMBERS.md。Est. rule overhead 与 Est. net把隐藏成本摆到台面上这是 SKILL.md 强调的重点也是该技能区别于只看毛节省的关键。只要上方节省量估算无歧义单一有基准的模式、已知 turn 数输出就会多出两行Est. rule overhead: 58,750 (input, ~1,250/turn over 47 turns) Est. net: -51,394 (caveman cost more than it saved for this workload — consider turning it off)上例取自 skills/caveman-stats/README.md 的示例输出。规则开销caveman 每轮会往上下文注入 SKILL.md 规则约 5 KB加上 mode tracker 的逐轮强化提示docs/HONEST-NUMBERS.md 承认这是每轮约 1–1.5k 输入 token 的固定成本。脚本将其量化为DEFAULT_RULE_OVERHEAD_TOKENS_PER_TURN 1250src/hooks/caveman-stats.jsoverhead turns × 1250。环境变量覆盖CAVEMAN_RULE_OVERHEAD_TOKENS可以覆盖每轮开销ruleOverheadPerTurn()只接受正整数garbage、0、-100、12.5等非法值一律回落到默认 1250——tests/test_caveman_stats.js 覆盖了这些边界如设为500后断言Est. rule overhead: 500 (input, ~500/turn over 1 turn)。净额与直白结论net estSavedTokens − overheadTokens。净值为正时输出N (net saving after rule overhead)为负时不回避直接写caveman cost more than it saved for this workload — consider turning it off。这正是 SKILL.md 所说的不把净亏区间藏在毛节省数字背后的实现。注意节省量是 output token、开销是 input token两者属于不同计费桶但源码注释指出把它们相减是唯一的诚实全预算口径src/hooks/caveman-stats.js。何时不出 net 行混合模式或部分 token 无法归因的会话源码有意不输出 net 行宁可缺省也不猜src/hooks/caveman-stats.js。按模式归因绝不用当前 flag冒充整个会话如果会话中途切换过 caveman 级别把整场 token 全记在统计时刻的 flag 名下会高估或归零节省量。源码用三层策略解决attributeByMode()log最精确mode tracker 与 SessionStart hook 在每次真实模式切换时往~/.claude/.caveman-mode-log.jsonl追加{ts, mode, prev}行src/hooks/caveman-config.js 定义文件名。stats 把这些时间戳与会话 JSONL 中每条 assistant 消息的timestamp做 join每段输出 token 记在生成当时生效的模式名下。readModeLog()还会按--session-id丢弃其他窗口的切换行避免跨窗口交织污染时间线。flag-mtime没有切换日志、但 flag 文件在会话中途被写过——只有写入点之后的 token 可归因给当前模式之前的记为 unknown 并明确排除no-fake-savings原则。whole-session兜底既无日志也无中途变更证据则当前模式覆盖全会话模式从未变时这是正确答案也是 #601 之前的旧行为。输出格式也随之变化非 uniform 会话会打印逐模式分解如full: N tokens (est. X saved)、caveman off: N tokens (no benchmark estimate)、unattributed: N tokens (mode unknown — excluded from estimate)页脚注明只有模式已知的区段才套用基准估算。命令行参数与运行方式脚本既可被 hook 调用也能手动直接运行node src/hooks/caveman-stats.js # 自动找最近会话 node src/hooks/caveman-stats.js --session-file path.jsonl # 指定会话文件 node src/hooks/caveman-stats.js --all # 全生命周期汇总 node src/hooks/caveman-stats.js --since 7d # 最近 7 天支持 Nh / Nd node src/hooks/caveman-stats.js --share # 单行可转发摘要--session-filehook 集成必传防止读错会话--session-idhook 转发用于过滤模式日志中属于其他窗口的行缺省时回退到 transcript 文件名Claude Code 按 session id 命名 transcript所以这不是猜测而是既有约定--all/--since走生命周期聚合路径短路的无需活跃会话——aggregateHistory()从~/.claude/.caveman-history.jsonl中每个 session 只取最新一条快照再求和src/hooks/caveman-stats.js--since只接受Nh/Nd格式非法值报错退出--since takes Nh or Nd (e.g. 7d, 24h)。生命周期视图同样只对记录了 turns 字段的行计算 net——旧格式行缺turns混入会歪曲开销因此只计入毛总量--share输出单行摘要如 Saved 650 output tokens (~$0.0098) across 1 turns this session — caveman.sh测试断言见 tests/test_caveman_stats.js无基准比例的模式退化为 1 turns, 200 output tokens this session — caveman.sh。在 Claude Code 内则直接输入/caveman-stats支持/caveman:caveman-stats命名空间写法及--share/--all/--since尾部参数mode-tracker 会逐一透传。附带写入历史快照与 statusline 徽章每次运行时若turns 0脚本还会产生两个副作用src/hooks/caveman-stats.js生命周期历史向~/.claude/.caveman-history.jsonl追加一行快照ts、session_id、mode、model、output_tokens、turns、est_saved_tokens、est_saved_usd。同一会话多次调用会追加多行--all聚合时按 session 取最新一条statusline 后缀聚合后的终身毛节省量经humanizeTokens()1.2M / 12.4k 风格渲染成⛏ 12.4k写入.caveman-statusline-suffix供状态栏直接 cat 显示。SKILL.md 特别说明该徽章故意保持毛节省口径——它是一眼可读的摘要而非完整核算要看净收益就运行/caveman-stats。另外脚本会扫描~/.claude与当前目录下的*.original.md备份对caveman-compress 压缩记忆文件留下的原件若压缩版更小则按约 4 字符/token 估算每次会话启动的输入节省并在输出中单独列出Memory compressed: N files, ~M tokens saved per session start (approx)。健壮性设计安装不完整时给可操作的信息skills/caveman-stats/SKILL.md 提到该技能由hooks/caveman-stats.js提供、被hooks/caveman-mode-tracker.js读取而 src/hooks/caveman-stats.js 开头一大段防御代码正是为此契约服务强制兄弟模块caveman-config.js缺失时不抛裸的MODULE_NOT_FOUND堆栈而是打印一行可操作提示the install is incomplete. Run/plugin update caveman, or rerun install.sh并以非零码退出——stats 没有降级输出可言它打印的每个数字都依赖 config 模块管理的 flag/history宁缺毋滥针对 opencode 的目录布局插件目录是type: module兄弟文件被改名为.cjs做了条件重试且只在错误确为找不到./caveman-config时才重试避免把兄弟模块内部的MODULE_NOT_FOUND误报成配置文件缺失加载成功但导出形状不对插件缓存漂移场景也会被 shape check 拦截报install is inconsistent依赖readFlag/appendFlag/readHistory/safeWriteFlag/VALID_MODES等导出per-session 新导出resolveActiveMode等则逐个回退到旧行为保证旧版 config 模块下仍能出正确的机器级数字而不是直接报错。验证依据以上机制均有测试覆盖tests/test_caveman_stats.js约 900 行包括token 求和、full 模式 65% 换算、非 full 模式不出估算USD 行随模型定价表出现/省略、priceForModel前缀匹配跨点发布版本claude-opus-4-20250101→ $75/M 而claude-opus-4-7→ $25/M--all每 session 取最新快照、--since时间窗过滤历史快照追加内容逐字段断言net 行为正值、负值、CAVEMAN_RULE_OVERHEAD_TOKENS覆盖及非法值回落mode-tracker 触发时不改变.caveman-activeflagstats 命令不得顺带切模式。小结/caveman-stats体现的是 caveman 项目诚实数字的产品原则真实数字output/cache token、turns直接来自会话 JSONL估算数字65% 压缩比、每轮 1250 规则开销都标注来源并可被环境变量校准净亏场景直接建议关闭而不是美化。理解这套核算口径后你可以把它当作 A/B 的参照基线——而 docs/HONEST-NUMBERS.md 仍建议以供应商账单上的同任务 A/B 对比作为最终裁决依据。【免费下载链接】caveman why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman项目地址: https://gitcode.com/GitHub_Trending/caveman1/caveman创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考