WorkBuddy 用量统计(v1.2)
Overview
自动统计 WorkBuddy 本机使用数据。许多用户想复盘「自己这段时间用 WorkBuddy 干了啥、花了多少时间/积分,我自己又在上面忙了多久」,但 WorkBuddy 默认不提供这类汇总。
本 skill 直接读取本机存储(非联网),把一次「任务」对应到一个会话(session),并算出以下核心指标:
- 任务类型:新建(
created_at在窗口内)/ 继续(created_at早于窗口、last_activity跨进窗口)。两者在表格里分块呈现。 - 对话轮次:以「用户开启一次话题」切分的应答轮;连续多次追问并入同一轮(3 问 1 答 = 1 轮)。合计中标注「含 X 复合」表示其中有 X 轮是含多次追问的复合轮。
- 用户提问:用户实际发出的消息条数(含追问)。
- 模型耗时:Σ(本轮末条用户消息 → 本轮末条模型回答),仅计窗口内事件。剔除用户自身思考/补问间隙,仅计模型实际响应段。
- 用户耗时:Σ(下轮首问 − 上轮末答),即用户两轮之间的真实在场时间。默认仅计入 ≤30 分钟的间隔,超过该阈值的间隔大概率为用户离开任务,不计入。
- 消耗积分:从
session_usage.credit_json求和得到真实扣费;限免模型(如 hy3)的credit_json为空,记为「限免0」(实付 0)。
When To Use
- 用户要求统计 WorkBuddy 自身用量:「统计本周任务」「我这周花了多少时间」「看看我用了多少积分」「统计今天的用量」。
- 用户想复盘任务清单:「我这段时间的任务有哪些」「上周做了什么」。
- 用户想了解自己在某次/某段任务中的投入:「我这次在任务里忙了多久」「用户耗时多少」。
- 需要按时长/积分/轮次排序查看。
- 「今天没新建任务但有真实用量」 这种继续任务主导的场景——v1.2 明确区分新建/继续、继续任务只算窗口内部分。
不要用于统计「某外部项目/代码库」的用量——本 skill 只统计 WorkBuddy 自身对话数据。
Workflow
1. 确定时间窗口
默认统计本周(北京时间周一 00:00 至今)。如用户指定其他区间,转换为 --start / --end(格式 YYYY-MM-DD,含起始日、不含结束日的次日 00:00):
- 「上周」→ 计算上周一至上周日。
- 「今天」→
--start YYYY-MM-DD --end YYYY-MM-DD(同日)。 - 「8 月 15 到 8 月 21」→
--start 2026-08-15 --end 2026-08-21。 - 「这个月」→ 本月 1 号至今。
2. (可选)调整用户耗时阈值
--max-gap 45:仅计入 ≤45 分钟的间隔(放宽)。--max-gap 0:不过滤,所有相邻轮次间隔都计入。
3. (可选)切换 playground 行为
- 默认排除
is_playground=1的会话(开发者用 playground 模式调试的)。 --include-playground:把 playground 也算进来。
4. (可选)列出孤儿 jsonl
--list-orphans:把projects/下有日志但sessions表里没记录的 jsonl 全部打印(默认只显示数量)。
5. 运行统计脚本
python3 "<skill_dir>/scripts/stats.py" [--start YYYY-MM-DD] [--end YYYY-MM-DD] [--max-gap N] [--include-playground] [--list-orphans]
<skill_dir> 为本 skill 所在目录。脚本会输出:
- 顶部摘要:窗口范围、新建/继续/已排除 playground/孤儿 jsonl 计数。
- 两个分块表格:新建任务、继续任务。
- 各自的「小计」+ 全局「合计」行。
- 默认按「用户耗时」降序排列。
6. 呈现结果 & 关键口径说明
把脚本输出的表格直接交给用户,务必附带以下口径说明(避免被误读):
- 任务类型分两类:新建 vs 继续。继续任务的耗时只算窗口内部分,不重复计入历史时段。
- 模型耗时是「逐轮累加的真实活跃耗时」,不是会话挂机跨度。 取「本轮末条用户消息 → 末条模型回答」,剔除用户在轮内的补问/思考间隙。
- 用户耗时衡量「用户自己的投入」,默认剔除 >30 分钟间隔。 用
--max-gap可自定义阈值。 - 限免模型实付 0。 只有非限免任务才在
credit_json留下真实积分。 - 时间窗口为北京时间(UTC+8)。 跨日/跨周任务按毫秒时间戳落入窗口来判定。
- 孤儿 jsonl(projects/ 下有日志但 sessions 表里没记录,可能是 cleanup 残留)会被扫描并提示,不计入统计。
算法定义
| 指标 | 定义 |
|---|---|
| 任务类型 | 新建:created_at ∈ [start, end);继续:created_at < start 且 last_activity ∈ [start, end) |
| 对话轮次 | 以「用户开启一次话题」切分的应答轮;连续多次追问并入同一轮 |
| 用户提问 | Σ 各轮用户消息条数(含追问) |
| 模型耗时 | Σ(本轮末条用户消息 → 末条模型回答),仅统计窗口内事件;跨窗口边界的轮次按窗口边界截断 |
| 用户耗时 | Σ(下轮首问 − 上轮末答),仅计入 ≤ --max-gap 的间隔;跨窗口边界剔除 |
| 消耗积分 | Σ session_usage.credit_json 各值;空则记为限免 0 |
Resources
scripts/stats.py
核心统计脚本。逻辑要点:
- 会话清单来自
workbuddy.db的sessions表,过滤窗口:created_at或last_activity_at落在[start_ms, end_ms)。 - 任务分类:先看
created_at是否在窗口,是则「新建」;否则看last_activity_at是否进入窗口,是则「继续」。 - 每个会话的逐轮耗时来自
projects/<目录>/<sessionId>.jsonl:解析type=="message"且role in (user, assistant)的行,按timestamp排序后切分「轮次」,再用窗口边界裁剪——只保留timestamp ∈ [start, end)范围内的事件;轮次若跨窗口边界(如上轮末答在窗口外、下轮首问在窗口内),按截断规则处理。 - 积分来自
session_usage.credit_json(JSON 各值求和);为空则记为限免 0。 - 找不到 jsonl 的会话(如纯后台自动化)跳过时间累加,仅计入会话数。
- 孤儿 jsonl:扫描
projects/**/*.jsonl,与sessions.id取差集,仅作提示。 - 默认排除
is_playground=1的会话;可用--include-playground切换。
如需调整排序字段、增减列(如增加 token 用量 used)、或导出 CSV,直接改该脚本即可。
Scan to join WeChat group