Files
cc-web/.planning/usage-statistics-dashboard-plan/findings.md

103 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 调研结论:cc-web 使用统计看板
## 用户要求
- 当前只需要可执行计划,不实施产品代码。
- 看板必须不影响现有聊天、会话、检索和工具调用功能。
- 指标必须有明确口径,不能使用含糊的“活跃会话”。
- Skill 只统计显式 `$skill` 使用,不宣称能够监控实际读取或执行。
- 用户已授权开始实施,并要求先完成整体功能,再适配所有现有主题。
- 用户指定统计入口位于侧栏底部:会话列表下方、现有 `CC-Web` 设置入口同一区域,而不是会话列表内部。
- 入口参考图为 `sessions/_attachments/750cb7a2-a109-44a9-ae3d-6ca352d4aba0.jpg`;图中底部操作区在会话列表滚动区域之外。
## 现有数据能力
- 会话数据保存在 `sessions/*.json`。
- 用户消息可持久化 `composerMentions`,可识别显式 `$skill` mention。
- Codex App 的 MCP 调用会规范化到 assistant message 的 `toolCalls[]`,包含 `server`、`tool`、`status`。
- 现存 MCP 工具调用没有独立时间戳;历史统计只能暂时使用所属 assistant 消息完成时间。
- 会话持久化有消息数和每条消息工具调用数上限,因此看板只能统计“当前保留数据”,不能声称是永久全量审计。
- 当前会话主创建字段为 `created`;134 个会话均有 `created/updated`,当前 2,226 条保留消息均有 `timestamp`。
- 当前扫描得到 1,745 次 MCP 调用,`completed=1645`、`failed=100`;失败调用同样可能 `done=true`,失败口径必须读取 `meta.status`。
- 显式 Skill mention 的稳定判定是 `composerMentions[].kind === 'skill'`,不能扫描消息正文中的 `$xxx`。
- `crossConversation` 可区分跨会话自动消息;界面使用“直接发送消息”和“跨会话消息”,避免把前者绝对命名为人工消息。
## 已有数据扫描结果
- 134 个会话 JSON,总量约 82 MB。
- 1,678 次 MCP 调用,`server/tool` 解析率 100%。
- MCP 状态:`completed=1578`,`failed=100`。
- 显式 Skill mention 共 7 次。
- 一次全量扫描约 0.93 秒,峰值 RSS 约 116 MB。
## 架构判断
- 82 MB 数据量下,全量扫描可以用于一次性回填或维护操作。
- 不应让每次看板刷新都全量解析所有会话文件,否则数据增长后会和聊天服务争用 CPU、内存和磁盘 IO。
- 最稳妥的结构是:独立索引文件、异步更新、独立查询协议、独立前端工作区。
- 统计是旁路只读能力,不进入消息发送和会话写入的同步关键路径。
- 统计索引采用懒加载:第一次打开看板才加载/回填,未使用看板时不增加服务启动成本。
- 索引初始化后可防抖增量更新;调度与删除必须内层 `try/catch`,不能让统计异常进入 `saveSession` 或删除会话的主错误分支。
- 统计响应只返回聚合值、工具名、Skill 名和会话元数据,不返回消息正文、MCP 参数或工具结果。
## 页面范围
- 顶部:时间范围、本周、本月、自定义范围、刷新。
- 首行指标:新建会话、发送消息、MCP 调用、MCP 失败、Skill 显式使用。
- 中部:按日趋势;MCP 工具使用明细。
- 下部:MCP 状态分布;Skill 显式使用排行;最近会话明细。
- MCP 工具明细行可进入该工具的调用明细;该交互属于网页实现,不需要在生图提示词中逐字描述。
- 看板作为 `.chat-main` 内局部覆盖工作区,聊天 DOM 保持挂载;高级检索与看板互斥打开。
- 入口必须使用独立 `.usage-dashboard-open`,不能复用 `.settings-btn`,否则 Wasteland 的齿轮伪元素会污染统计按钮。
- 当前共有 11 个主题 ID;基础样式使用语义 token,专属修正只需要 coolvibe、共享暗色组、gilded 和 wasteland。
## 代码落点依据
- `public/index.html` 已有 sidebar 与 `main.chat-main`,看板可以作为 chat-main 内独立工作区,而不必重做应用外壳。
- `server.js` WebSocket 分发已有独立消息类型模式,可新增统计查询类型而不改变现有协议。
- `scripts/regression.js` 已覆盖高级检索的独立入口和独立状态模式,统计看板可沿用相同隔离策略。
- codebase-memory 项目 `home-cc-web` 索引状态为 ready(4,455 nodes / 9,320 edges)。
- `saveSession()` 是高入度核心写入函数,统计逻辑不得直接接入其同步调用链;旁路索引应在看板查询或独立后台任务中刷新。
- 用户和 assistant 消息均有 `timestamp`;Codex App steer 用户消息也会持久化 `composerMentions`。
- MCP 调用继续从 assistant message 的 `toolCalls` 读取,`ensureToolCall()` 负责归一化名称、kind、meta 和状态更新。
## 风险与控制
| 风险 | 控制方式 |
|---|---|
| 看板查询拖慢聊天服务 | 使用增量索引;请求限时;禁止请求时全量扫描 |
| 索引与会话数据不一致 | 保存源文件指纹;可重建;界面显示统计更新时间 |
| 历史 MCP 时间不准确 | 明示按 assistant 消息时间归属;不展示伪精确耗时 |
| Skill 指标被误解 | 指标名称固定为“Skill 显式使用” |
| 前端状态污染聊天 | 独立状态对象、DOM 根节点、样式命名空间和关闭恢复流程 |
| 新功能引入回归 | 功能开关、合同测试、现有完整回归、灰度启用 |
| 现有文件已有未提交修改 | 只在精确区块追加,不重排或覆盖高级会话检索改动;以任务开始时 diff 为基线 |
## 计划审查记录
- 第一次审查发现原计划缺少“全部现有主题逐一适配”的独立阶段。
- 已新增 Phase 5 和硬性主题验收门槛,第二次审查通过。
- 复审确认现有会话主创建字段为 `created`;实施以此为主,`createdAt` 只作历史兼容兜底。
- 统计响应需携带 `schemaVersion`,性能验收已补充明确阈值。
## 资源
- 参考图:`sessions/_attachments/67a5f5ae-ea62-4c12-b723-deb9adb98c2f.png`
- 会话存储与 WebSocket:`server.js`
- Codex App 工具调用归一化:`lib/codex-app-runtime.js`
- 页面外壳:`public/index.html`
- 现有前端状态与交互:`public/app.js`
- 回归测试:`scripts/regression.js`
## 实施与验收结论
- 统计索引在第一次打开看板时才构建;未初始化时保存会话不会安排统计更新。
- 查询响应包含 `schemaVersion` 和 `[from,to)` 语义,不包含消息正文、MCP 参数或结果。
- `usage_stats_query` 使用独立 requestId,真实协议回归确认不会新增 `session_list`。
- `CC_WEB_USAGE_STATISTICS=0` 会关闭鉴权 feature flag,并让查询返回 `disabled`,不影响服务其他能力。
- 真实数据最终性能:83,335,652 字节、134 个会话,回填 1,146.68 ms,查询 P95 51.79 ms,峰值 RSS 119,476 KB,缓存 394,629 字节。
- 浏览器验收:Chrome Headless 151.0.7922.71,视口为 1440×900、1024×768、768×1024、390×844、360×800;11 个主题共 55 组。
- 页面级横向溢出均为 0;窄屏 MCP 表格按设计在 `.usage-dashboard__table-wrap` 内局部滚动。
- Wasteland 的 `.usage-dashboard-open` 没有继承 `.settings-btn::before`;移动端入口为 44×44,桌面为 34×34。
- 浏览器动态状态已覆盖 loading、MCP 明细、空态和错误态;Wasteland 根看板使用实色背景,避免下层聊天视觉透出。