Skip to content

fix(token-stats): 会话复制导致的 Token 重复统计 - #32

Merged
changexbc merged 1 commit into
changexbc:mainfrom
1565115013a-lang:fix-bug
Sep 15, 2026
Merged

changexbc merged 1 commit into
changexbc:mainfrom
1565115013a-lang:fix-bug

Conversation

@1565115013a-lang

@1565115013a-lang 1565115013a-lang commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

问题

复制/派生会话会把原会话完整历史(含 usage 记录、原始时间戳)落盘到新会话的 jsonl,而 source() 逐行累加且无跨文件去重,同一次请求会被计入 N 份。

实测本机 324 个 jsonl:

  • 67% 的 usage 记录存在多份拷贝,单条最多 49 份
  • 历史累计重复计入约 104 亿 token
  • 某日统计虚高 22.7 倍(显示 11.62 亿 vs 去重后 5,113 万),与积分消耗方向严重背离

修复

  • source() 改为按文件 mtime 升序处理,原始会话先于 fork 副本
  • 全局 HashSet<(timestamp, input, output, cacheRead, cacheWrite, model)> 指纹去重,重复记录跳过,usage 归属原始会话
  • fork 会话只统计自身新产生的请求;无时间戳的记录保持原逻辑
  • 新增测试 source_deduplicates_copied_session_history

验证

  • cargo test -p wb-switch-core --lib modules::token_stats:10 个测试全过(gnu 工具链)
  • 修复后 dashboard 历史数字回落到真实值,与积分消耗方向一致

Fixes #28

复制/派生会话会把原会话完整历史(含 usage 记录、原始时间戳)落盘到
新会话的 jsonl,而 source() 逐行累加且无跨文件去重,同一次请求会被
计入 N 份。实测本机 324 个 jsonl 中 67% 的 usage 记录存在多份拷贝,
单条最多 49 份;历史累计重复计入约 104 亿 token,某日统计虚高
22.7 倍(11.62 亿 vs 去重后 5113 万),与积分消耗方向严重背离。

修复:
- source() 改为按文件 mtime 升序处理,原始会话先于 fork 副本
- 全局 HashSet<(timestamp, input, output, cacheRead, cacheWrite,
  model)> 指纹去重,重复记录跳过,usage 归属原始会话
- fork 会话只统计自身新产生的请求;无时间戳的记录保持原逻辑
- 新增测试 source_deduplicates_copied_session_history

注:修复后 dashboard 历史数字会回落到真实值。
wh-1 added a commit to wh-1/workbuddy-switch that referenced this pull request Sep 12, 2026
新增 projects_anchor.rs(本地专属,上游零冲突):
- 同步项目侧栏:切号时目标账号项目集合对齐到源账号——缺的项目补
  空白占位会话(INSERT + 最小空 JSONL),多余项目会话软删
- 会话瘦身:每项目保留最近 N 条存活会话,其余软删(JSONL 保留,
  Token 统计不受影响)
- 级联误删防护:源项目清单清零或较快照骤减 30% 时中断(force 放行),
  快照存 ~/.wb-switch/project_set_snapshot.json(路径注入可测)
- JSONL workspace 目录编码实测反推:盘符小写 + : 删除 + \/ → -
- 6 个单测全绿;dry-run 全程支持

语义定稿(不再复制/搬运会话正文):
- 切号连续性 = 设置同步(配置/画像/主题) + 项目占位(侧栏可见) + 空锚点可续聊
- 规避上游 changexbc#32 Token 重复统计与 changexbc#9 侧栏副本雪球

更名与归并:
- L4 数据文件一致性同步 → 「设置同步」,主题跟随(L6)并入报告 settings.theme
- L3 自动化归属对齐 → 「定时任务迁入」
- L3 会话归属对齐 → UI 下线(代码保留防回退),报告键 files→settings
- post_close_sync 返回值合并为单一 align_report,switch.rs 适配

前端:切号弹窗新增「同步项目侧栏」(默认开)、「会话瘦身」(默认关),
预览报告含项目补删/瘦身明细
@changexbc
changexbc merged commit 9701628 into changexbc:main Sep 15, 2026
changexbc added a commit that referenced this pull request Sep 15, 2026
复制会话去重用例的两个 fixture 连续写出,mtime 截断到毫秒后可能并列;
sort_by_key 是稳定排序,并列时退化为文件系统目录遍历顺序(readdir 无序),
副本可能先被处理并认领共享记录,原会话记录数归 0 后被 push_session 丢弃,
导致 sessions.len() == 2 与 forked.input == 7 断言随机失败
(macOS APFS 实测 8 次跑 6 次失败)。

改用 File::set_modified 把 original 固定到 60s 前、fork 固定到 now,
处理顺序确定后连跑 10 次全绿;复制会话去重的产品逻辑不变。

Refs #32
@changexbc

Copy link
Copy Markdown
Owner

合并后我做了一次实测核对与一处测试稳定性修复,记录在这里备查。

1. 修复了新增用例的 flaky(commit 1224058

source_deduplicates_copied_session_history 的两个 fixture 是连续写出的,mtime 截断到毫秒后可能并列;sort_by_key 是稳定排序,并列时退化为文件系统目录遍历顺序(readdir 无序)。此时副本会先被处理并认领共享记录,原会话记录数归 0 后被 push_session 丢弃,sessions.len() == 2token_stats.rs:1005)与 forked["input"] == 7 随之随机失败。macOS APFS 上实测 8 次跑 6 次失败。改用 File::set_modified 把 original 固定到 60s 前、fork 固定到 now 后连跑 10 次全绿,产品逻辑未改动。

2. 去重逻辑在真实数据上的表现(本机 183 个 jsonl / 4858 条 usage 记录)

  • 有 2 对整份复制的会话(41 条与 17 条,记录集 Jaccard = 1.00),去重后 input 减少约 1.0%(4.98M / 485M,共 58 条),总量口径正确,去重与 cutoff 的先后顺序也正确
  • 副本与原文件逐字段比对:139 个记录 id 同时出现,只有 sessionId 被改写,id / timestamp / usage 完全一致 —— 与 session.rstext.replace(cid, new_cid) 复制方式吻合
  • PR 描述里的 67% / 104 亿 token / 22.7 倍属作者本机复制次数的特例(换账号复制次数多),建议按"幅度取决于本机复制次数"表述

3. 发布说明会写明:升级后历史统计数字会回退(去重生效),不是数据丢失。

感谢这个修复,去重方向是对的。

wh-1 pushed a commit to wh-1/workbuddy-switch that referenced this pull request Sep 16, 2026
fix(token-stats): 会话复制导致的 Token 重复统计
wh-1 pushed a commit to wh-1/workbuddy-switch that referenced this pull request Sep 16, 2026
复制会话去重用例的两个 fixture 连续写出,mtime 截断到毫秒后可能并列;
sort_by_key 是稳定排序,并列时退化为文件系统目录遍历顺序(readdir 无序),
副本可能先被处理并认领共享记录,原会话记录数归 0 后被 push_session 丢弃,
导致 sessions.len() == 2 与 forked.input == 7 断言随机失败
(macOS APFS 实测 8 次跑 6 次失败)。

改用 File::set_modified 把 original 固定到 60s 前、fork 固定到 now,
处理顺序确定后连跑 10 次全绿;复制会话去重的产品逻辑不变。

Refs changexbc#32
wh-1 pushed a commit to wh-1/workbuddy-switch that referenced this pull request Sep 16, 2026
fix(token-stats): 会话复制导致的 Token 重复统计
wh-1 pushed a commit to wh-1/workbuddy-switch that referenced this pull request Sep 16, 2026
复制会话去重用例的两个 fixture 连续写出,mtime 截断到毫秒后可能并列;
sort_by_key 是稳定排序,并列时退化为文件系统目录遍历顺序(readdir 无序),
副本可能先被处理并认领共享记录,原会话记录数归 0 后被 push_session 丢弃,
导致 sessions.len() == 2 与 forked.input == 7 断言随机失败
(macOS APFS 实测 8 次跑 6 次失败)。

改用 File::set_modified 把 original 固定到 60s 前、fork 固定到 now,
处理顺序确定后连跑 10 次全绿;复制会话去重的产品逻辑不变。

Refs changexbc#32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

【BUG】Token统计异常,为什么4号比3号消耗积分更少,却Token统计异常多

2 participants