7.3 KiB
7.3 KiB
调研结论:cc-web 使用统计看板
用户要求
- 当前只需要可执行计划,不实施产品代码。
- 看板必须不影响现有聊天、会话、检索和工具调用功能。
- 指标必须有明确口径,不能使用含糊的“活跃会话”。
- Skill 只统计显式
$skill使用,不宣称能够监控实际读取或执行。 - 用户已授权开始实施,并要求先完成整体功能,再适配所有现有主题。
- 用户指定统计入口位于侧栏底部:会话列表下方、现有
CC-Web设置入口同一区域,而不是会话列表内部。 - 入口参考图为
sessions/_attachments/750cb7a2-a109-44a9-ae3d-6ca352d4aba0.jpg;图中底部操作区在会话列表滚动区域之外。
现有数据能力
- 会话数据保存在
sessions/*.json。 - 用户消息可持久化
composerMentions,可识别显式$skillmention。 - 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.jsWebSocket 分发已有独立消息类型模式,可新增统计查询类型而不改变现有协议。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 根看板使用实色背景,避免下层聊天视觉透出。