ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

caveman 的 /caveman-stats:opencode 插件中的会话 Token 节省统计命令实现详解

caveman 的 /caveman-stats:opencode 插件中的会话 Token 节省统计命令实现详解 caveman 的 /caveman-statsopencode 插件中的会话 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 的 opencode 插件中/caveman-stats是一个由纯 Markdown 提示词模板驱动的斜杠命令它不执行任何脚本而是让模型读取 caveman 的终身历史日志输出一张包含总节省 token、会话数与平均压缩比的简短统计表。读完本文你将理解这条命令在 opencode 插件体系中的完整定义、它所依赖的历史日志数据格式、与之对应的 Claude Code 端caveman-stats.js脚本的源码级实现细节以及测试如何保证每一个数字都可验证、不夸大。命令定义文件frontmatter 与提示词正文/caveman-stats的完整定义位于 caveman-stats.md全文如下--- description: Show caveman lifetime token-savings stats --- Show caveman stats — total tokens saved, sessions, average compression ratio. Read the lifetime history log at ~/.config/caveman/.caveman-history.jsonl (or wherever the caveman-stats script writes it). Output: total saved, sessions counted, avg ratio. One short table.这份文件由两部分构成YAML frontmatterdescription字段供 opencode 的命令补全/列表展示声明该命令的用途是显示 caveman 终身 token 节省统计。提示词正文这才是命令的真正逻辑。opencode 在用户输入/caveman-stats时会把命令文件中的正文替换进消息发给模型plugin.js 源码注释中明确说明opencode 会在chat.message钩子看到消息之前把输入的斜杠命令替换为命令文件的提示词文本。也就是说这段文字本质上是一份给模型的执行指令包含三个明确约束做什么展示 caveman 统计——总节省 token 数total tokens saved、会话数sessions、平均压缩比average compression ratio从哪读终身历史日志默认路径为~/.config/caveman/.caveman-history.jsonl括号内的补充说明承认实际路径取决于 caveman-stats 脚本的写入位置输出形式total saved、sessions counted、avg ratio 三项数据且要求压缩成一张简短表格One short table符合 caveman 自身的简洁风格。这与 caveman 在 Claude Code 端的实现形成对照Claude Code 中/caveman-stats是通过 caveman-mode-tracker.js 这个UserPromptSubmit钩子拦截后直接执行caveman-stats.js子进程2.5 秒超时并把脚本输出以additionalContext的形式要求模型逐字转述而 opencode 端没有等价的脚本执行通道因此 README 中明确列出该插件不提供 statusline 徽章等限制统计能力退化为模型读文件 汇总的提示词方案。数据来源终身历史日志.caveman-history.jsonl命令提示词指向的~/.config/caveman/.caveman-history.jsonl是 caveman 的终身累计统计账本。从源码 caveman-stats.js 看脚本实际写入的路径是$CLAUDE_CONFIG_DIR未设置时为~/.claude下的.caveman-history.jsonl——这正是模板里 (or wherever the caveman-stats script writes it) 这句留白的原因路径随宿主与安装布局而变命令让模型自行寻找。每次运行 stats 且会话已有至少一个回合时脚本会向该文件追加一行 JSON 快照main 函数{ ts: 1725000000000, session_id: s, mode: full, model: claude-sonnet-4-7, output_tokens: 350, turns: 1, est_saved_tokens: 650, est_saved_usd: 0.00975 }各字段的写入逻辑与语义字段来源说明tsDate.now()快照时间戳用于时间窗过滤与每会话取最新去重session_id钩子转发或 transcript 文件名会话标识终身聚合的主键mode.caveman-active标志文件当前 caveman 模式如full非 active 则为nullmodel会话 JSONL 中首个带usage的 assistant 消息用于查输出 token 单价output_tokens/turns会话日志解析输出 token 总量与助手回合数est_saved_tokens按模式归属后的估算见下文按模式归属est_saved_usdtoken 数 × 模型输出单价未知模型时为 0追加写入走 caveman-config.js 提供的appendFlag该写入器是符号链接安全的拒绝 symlinked 目标、原子 temprename、0600 权限这一点有专门测试appendFlag is symlink-safe (refuses symlinked target)test_caveman_stats.js守护。同一会话内多次运行/caveman-stats会写入多行但聚合时只保留每个session_id时间戳最新的一行——aggregateHistory 用Map按session_id覆盖实现无 session_id 的旧行归入_桶。测试--all aggregates latest entry per session验证了这一点两个会话、其中一个会话有两条快照时只计最新一条185 371 556。底层脚本会话解析、模式归属与节省估算虽然 opencode 端由模型直接读历史文件但同一套数据的生产端是 caveman-stats.js约 680 行理解它才能理解历史日志里每个数字是怎么来的。会话日志解析parseSession 逐行解析 Claude Code 的会话 JSONL只统计type assistant且带message.usage的条目累计output_tokens、cache_read_input_tokens与回合数turns同时记录每条消息的{ts, outputTokens}供后续时间对齐。无--session-file参数时findRecentSession 会在$CLAUDE_CONFIG_DIR/projects下深度优先搜索 mtime 最新的.jsonl文件。按模式归属#601不把整段会话算给当前模式统计中最容易出错的是整段会话的 token 都记在 stats 时刻 flag 所显示的模式下——会话中途开启 caveman 会虚增节省中途关闭则归零。attributeByMode 采用三级证据链解决log最精确模式追踪钩子caveman-mode-tracker.js 中的recordModeChange在每次真实模式切换时向.caveman-mode-log.jsonl追加{ts, mode, prev}行stats 把这些时间戳与会话消息时间戳对齐每条消息的 token 记在其生成时刻实际激活的模式名下。会话隔离由--session-id参数保证其他窗口的切换行会被丢弃readModeLog。flag-mtime无切换日志但 flag 文件在会话中途被写入时只有写入之后的 token 可归属之前的 token 标记为 unknown 并排除而非猜测源码称之为 no-fake-savings 原则。whole-session既无日志也无中途变更证据时才按当前模式覆盖整段会话处理#601 之前的行为仅在模式从未变化时正确。测试attributes tokens to the mode active when each message happened (#601)test_caveman_stats.js构造了开启前 300 verbose token 开启后 350 token的会话正确结果是只有 350 个 full 模式 token 产生 650 的节省估算而旧的全会话算法会虚报 1,207。压缩比与金额估算节省估算的核心是一张模式→压缩比表第 81 行const COMPRESSION { full: 0.65 };目前只有full模式有 benchmarks/ 目录中 10 个任务、sonnet-4 的实测均值 65% 支撑lite/ultra/wenyan等模式在跑过基准并提交结果前不产生任何估算值——对ultra模式直接输出No savings estimate for ultra mode — only full has benchmark data.。估算公式deriveSavings已知有 caveman 时输出为T、压缩比为r则无 caveman 时的等效输出约为T / (1 - r)节省即两者之差。测试用例验证350 个 full 模式 token →350 / 0.35 1000→ 节省 650约 65%。金额换算由 MODEL_OUTPUT_PRICE_PER_M 这张按前缀匹配的输出单价表完成覆盖 Claude 5 系列Fable/Mythos $50/M、Opus 5 $25/M、Sonnet 5 $10/M到 Claude 3 系列的各档且最具体的前缀必须排在前面因为priceForModel返回首个命中。未知模型如gpt-4返回null此时只保留 token 估算、省略 USD 行——测试omits USD line when model is unknown守护了该行为。规则开销与净额不藏起负收益caveman 的规则每回合都会注入约 1,000–1,500 个输入token约 5 KB 的 SKILL.md 加每回合的强化提醒详见 HONEST-NUMBERS.md。脚本用每回合 1,250 token 的默认值第 89 行可用环境变量CAVEMAN_RULE_OVERHEAD_TOKENS覆盖计算开销deriveNet 输出Est. net 节省输出 − 规则输入开销。关键设计净额为正时显示Est. net: 1,536 (net saving after rule overhead)净额为负时直白提示caveman cost more than it saved for this workload — consider turning it off——测试session shows a NEGATIVE net and tells the user to consider turning caveman off (#145)专门验证了这条文案若节省区间本身无法归属unknown tokens或模式无基准数据则干脆不输出净额行避免用猜测的数字拼出净额。CAVEMAN_RULE_OVERHEAD_TOKENS的输入校验同样有测试非数字、0、负数、小数一律回落到默认 1250而不是产出无意义的开销。输出缩减比例只敢说输出占比outputReductionPct 计算的唯一比例是saved / (saved used)即 caveman 避免了多大比例的本会产生的输出 token。源码注释明确说明agentic 会话中 input cache token 占绝对大头且计入 Pro/Max 限额而 caveman 并不减少它们所以这个数字绝不能被标榜为会话用量占比或预算占比。测试session view never claims a % of usage/budget — only output reduction甚至用正则断言输出中不得出现budget/of your usage等字样也不得凭空编造 Anthropic 配额尺寸。命令行接口脚本可直接运行的完整参数在 Claude Code 之外脚本本身是一个可独立运行的 CLImain/caveman-stats斜杠命令的参数会被模式追踪钩子原样转发参数行为验证测试--session-file path指定要解析的会话 JSONL钩子用transcript_path传入保证读的是活跃会话而非最新 mtime 文件reads --session-file directly and sums output tokens--session-id id按会话过滤模式切换日志避免其他窗口的切换行污染本会话时间线#601 系列测试--share输出单行可分享摘要如 Saved 650 output tokens (~$0.0098) across 1 turns this session — caveman.sh无基准数据时退化为 1 turns, 200 output tokens this session--share prints single-line tweetable summary--all输出终身聚合视图Sessions、Output tokens、Est. tokens saved、Est. output reduction、Est. saved (USD)及净额块无历史时提示No sessions logged yet--all aggregates latest entry per session--since Nh\|Nd时间窗过滤如7d、24h非法格式如sometime以退出码 2 报错--since takes Nh or Nd (e.g. 7d, 24h), got: ...--since rejects malformed durations此外脚本还有两个副作用输出statusline 后缀文件每次运行后把终身节省总量渲染成⛏ 2.8k形式写入.caveman-statusline-suffix供 caveman-statusline.sh / caveman-statusline.ps1 直接cat而无需解析 JSONL写入同样经过 symlink 安全通道且测试验证了 statusline 会对该文件做控制字节剥离防止 ANSI 转义注入终端。记忆文件压缩检测findCompressedPairs 扫描$CLAUDE_CONFIG_DIR与当前工作目录下的*.original.md备份对/caveman-compress留下的原件若压缩版更小则按约 4 字符/token 折算输出Memory compressed: N files, ~X tokens saved per session start (approx)压缩版不小于原件的伪压缩对被跳过。测试矩阵从端到端到纯函数tests/test_caveman_stats.js 用真实子进程调用覆盖了整条链路运行方式即文件头注释node tests/test_caveman_stats.js。代表性用例端到端脚本直跑造一个.claude/projects/p/s.jsonl假会话 临时CLAUDE_CONFIG_DIR断言Turns/Output tokens/Cache-read tokens求和正确端到端经模式追踪钩子向 caveman-mode-tracker.js 喂{prompt: /caveman-stats --share, transcript_path: sess}断言输出 JSON 的hookSpecificOutput.additionalContext含统计块且运行 stats 不改变模式 flagmode tracker preserves caveman flag when /caveman-stats fires纯函数级priceForModel前缀匹配含带[1m]后缀的模型 id 与 null 输入、humanizeTokens2786 → 2.8k、1_250_000 → 1.3M、outputReductionPct的边界0 节省返回 null 而非 0%、deriveNet与开销覆盖值。skill 侧的交付说明见 skills/caveman-stats/SKILL.md该 skill 由hooks/caveman-stats.js交付模型在 skill 触发时无需做任何事——钩子直接以格式化好的统计作为回复上下文用户立即看到数字。opencode 插件侧的运行前提与边界把/caveman-stats放进 opencode 使用时需要理解 opencode 插件 的整体形态package.json 标记为 ESM 的caveman-opencode-plugin插件由session.created事件写入默认模式到~/.config/opencode/.caveman-active通过chat.message拦截/caveman命令与自然语言切换通过experimental.chat.system.transform注入每回合强化行安装布局与文件角色见 src/plugins/opencode/README.md。commands/目录下共六个斜杠命令模板/caveman、/caveman-commit、/caveman-compress、/caveman-help、/caveman-review、/caveman-stats全部以提示词展开方式工作因此/caveman-stats在 opencode 中的实际效果是模型按模板指令读历史文件并生成一张表而不是像 Claude Code 端那样由脚本生成确定性数字。相应地opencode 端没有 statusline 徽章TUI 未暴露插件可写的 statusline若想在 shell 中查看模式只能自行读取~/.config/opencode/.caveman-active标志文件。历史文件路径的差异也随之而来模板写的是~/.config/caveman/.caveman-history.jsonl而脚本生产端写在CLAUDE_CONFIG_DIR默认~/.claude下——若你的环境从未跑过 Claude Code 端的 stats 脚本历史文件可能尚不存在此时 opencode 端的命令应如实报告暂无统计而不是编造数字。诚实数字边界统计输出能声称什么stats 的所有输出都受 docs/HONEST-NUMBERS.md 约束值得随命令一并理解caveman 的响应 skill只压缩输出不压缩输入、上下文、文件与思考 token本地引擎与代理是独立组件skill 每回合新增约 1–1.5k 输入 token 的规则成本若输出节省低于该成本即为净亏简短编码问答、按请求计费的平台如 Copilot 是典型场景官方规则是对同一任务开/关 caveman 各跑一次以服务商账单总额对比为准A/B 结果为净负时直接关掉。这也是为什么caveman-stats.js的输出措辞如此克制节省一律标注 est. 与 output tokens only; input/cache usage is unchanged比例只称 output reduction未知模型不报金额无法归属的 token 不猜。小结/caveman-stats在 opencode 插件里只是一段三行提示词caveman-stats.md但它背后的数据链是完整的模式追踪钩子记录带时间戳的模式切换.caveman-mode-log.jsonlstats 脚本解析会话 JSONL、按模式归属 token、用唯一有基准支撑的full模式 65% 压缩比估算节省、按模型前缀查价折算美元、再减去每回合 1,250 token 的规则开销给出净额最后把每会话最新快照追加进.caveman-history.jsonl终身账本。opencode 端的命令模板则负责在宿主没有脚本执行通道时让模型基于这份账本输出total saved / sessions / avg ratio三要素的简短表格——数字的生产与呈现被分离在两个宿主上而口径估算、仅输出 token、不夸大由同一套源码与 tests/test_caveman_stats.js 中的数十个断言共同保证。【免费下载链接】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),仅供参考
返回列表