[功能] /insights --project:将报告范围限定到单个项目目录
预检清单
- [x] 我已搜索现有请求,该功能尚未被请求过
- [x] 这是一个单一的功能请求(不是多个功能的组合)
问题陈述
/insights 会分析本机上的每一次会话,但没有提供将报告范围限定到某一个项目的方式。对于在多个代码仓库上使用 Claude Code 的用户来说,这份报告反映的其实是他们使用最多的那个项目,根本无法回答"我在这个项目上的进展如何?"。
在我本机上的实测数据(~/.claude/usage-data/session-meta/,v2.1.278,2026-09-19 重新测量):
- 4,294 条 session-meta 记录,分布在 634 个不同的
project_path值上 - 在这 634 个中:50 个真实项目目录、其下 158 个 git worktree,以及 426 个来自 hook 隔离测试的临时
/tmp/…目录 - 我今天想要查看洞察的那个项目:53 次会话 — 仅占总量的 1.23%
- 使用量排名前三的项目:占总会话数的 45.2%
该语料库的两个特性使得真实占比比 1.23% 看起来还要更低。
76.9% 的记录是零信号的。 4,294 条中有 3,301 条恰好只有 2 条"消息"、零助手轮次、零工具调用、零 token、零时长,并且 first_prompt: "No prompt"。它们的转录文件清楚说明了本质——一个只跑了一次本地斜杠命令、在任何模型轮次之前就退出的会话:
7f020908-….jsonl 10 lines {'queue-operation': 2, 'attachment': 4, 'user': 2, 'system': 1, 'last-prompt': 1}
| <command-name>/usage</command-name>
只有 945 条记录(22.0%) 包含任何助手轮次或任何工具调用。一次 /usage 调用被计为一次会话,分母中有它,采样池中也有它,与一个长达六小时的构建会话并列。在有实质内容的记录中,我的项目只占 8/945 — 0.85%。
会话数本身就不是正确的统计单位。 在那 53 次会话中,中位数是 2 条消息;53 次中有 45 次会话消息数 ≤5,合计只有 90 条消息 — 占该项目总量的 7.6% — 而单单一次会话就占 37.3%,前五次会话合计占 80.3%。整台机器上也呈现同样的形态:每次会话的中位数为 2 条消息,前 10% 的记录承载了 81.8% 的全部消息。因此,对会话做均匀采样,其实是在对空壳做采样,而真正蕴含设计决策和痛点的少数会话恰好被这种采样所遗漏。
叙述段落、痛点模式、工具使用画像与建议,全部是基于整个语料库生成的,因此没有项目专属的内容可供单独阅读——这份分析自始至终就与我的项目无关。
实际情况比占比所暗示的还要更糟,因为报告本身是采样的。我最近一次报告的头部是这样的:
4,956 sessions total · 490 analyzed · 6,764 messages · 2026-07-15 to 2026-09-19
4,956 个会话中分析了 490 个。如果该样本在记录上是均匀分布的,那么其中属于我项目的会话数的期望值为 5,再按上面 8/53 的实质内容比率折算,其中真正含有任何内容的期望值不到 1 个。关于那个项目的任何一句话都毫无依据地漂浮在那里,没有标签地与其他 489 条混合在一起,并且头部信息既没有说明包含了哪些项目,也没有说明各自有多少。读者根本看不出这是一份跨 50 个代码仓库的汇总报告。
这不是什么特殊的使用场景。它就是一台工作机器的常态:少数大型的、长期运行的项目,加上长长的、由小型项目组成的尾巴。洞察最有价值的恰恰是在这条长尾上——一个新项目、一个不熟悉的技术栈、一个出问题的代码仓库——而全局汇总恰恰把这条长尾淹没了。426 个 /tmp 临时目录则是第二个原因:没有人愿意在工作流分析里看到 hook 隔离的测试运行结果,而目前没有任何办法将它们排除。
数据其实已经被采集了。每一条 session-meta 记录都把 project_path 作为一等顶层字段:
{
"session_id": "…",
"project_path": "/home/me/projects/auxiliary/kanjin",
"start_time": "2026-09-02T09:48:20.173Z"
}
不需要再去采集、存储或计算任何新数据。语料库本来就是按项目为键组织的。缺少的只是一个过滤器。
提议方案
为 /insights 增加一个可选的项目范围限定。之前提出过该诉求的多个用户不约而同地几乎给出了同样的设计,因此作为方案来说已经得到了充分的验证:
/insights # 保持不变 —— 所有项目,沿用当前行为
/insights --project . # project_path 位于当前工作目录下的会话
/insights --project <path> # 对 project_path 进行前缀匹配
/insights --exclude <path> # 可选的反向排除 —— 例如 --exclude /tmp
默认行为必须保持不变。 不带任何参数的 /insights 依然分析全部会话。严格意义上的增量、可选功能:不需要迁移、不需要废弃,对不传该参数的任何人都毫无影响。
采用前缀匹配,而非完全相等。 在 git worktree 中启动的会话会把 /.claude/worktrees/ 记录为项目路径——在我本机上,覆盖 158 个 worktree 路径、共 331 次会话。对代码仓库根目录进行前缀匹配,会把这些会话归并到它们的父项目中,这正是用户说"这个项目"时的真实含义。如果采用相等匹配,这些会话就会被静悄悄地丢掉。
如果觉得上面这一组参数过多,最小可用版本是采用一个可选的位置参数路径,正如 #29844 所提议的:
/insights /home/me/projects/thing
实现上只需要在加载阶段、采样与 facet 生成之前增加一个谓词:
sessions.filter(s => s.project_path.startsWith(resolvedScope))
下游的所有环节——采样、facet 抽取、叙述生成、图表、HTML 报告——在过滤后的集合上照常运行,无需任何改动。
两处花不了多少成本的额外增强,能让效果显著改善:
-
在报告头部显式说明范围。 现在的头部只打印消息数、会话数与日期范围。还应该打印所包含的项目、范围之内的会话数,以及其中有实质内容(非零信号)的会话数。这样一份限定范围的报告就不会被误读为全局报告——而一份全局报告也应该如实说明它是一个跨 N 个项目的汇总。
-
在生成之前先打印范围内的会话数。 如果一次限定范围的运行只覆盖 4 个会话,应该明确告知用户,而不是默默地产出一份空洞的叙述。这也有助于解决一长串"报告为空"的问题(#64275、#83849、#83695、#81679 等等)——在这些 issue 中,输入量不足都会导致 AI 部分为空且没有任何解释。
备选方案
尝试过、或经过考虑后被否决的方案:
-
删除或移动其他项目的 session-meta 文件。 这是 #56334 提交者最终采取的做法。它为了获得一份限定范围的报告,必须销毁全局历史,而且每次都要重做一遍。
-
运行
/insights,然后绕过噪声自行阅读。 在面对一份 490 个会话的样本、信号占比仅 0.85% 的情况下,这是不可行的。叙述是基于完整语料库生成的,里面没有任何项目专属的内容可供单独阅读。 -
*自己解析 `session-meta/.json
。** 我做过这件事,才得到了上面那些数字。但这样做只能得到计数。/insights` 的价值在于定性的 facet 分析与叙述,而目前没有受支持的方式可以在一个子集上调用这些能力。 -
每个项目使用独立的机器或操作系统账户。 #41199 的提交者真的这样做了——后端跑在虚拟机上,UI 在另一台桌面上——并且报告说即便如此,当同一桌面有两个项目时仍然会失败。对于 51 个项目,这显然不现实。
-
用日期过滤(
--since/--until)作为替代。 对于一次只做一个项目的人来说,这能部分缓解。该功能也已被请求过九次,却至今仍未发布,因此整个过滤系列的需求都还没有得到响应。
没有任何一种变通方案能够保留该功能真正的价值。
优先级
高 - 对生产力有显著影响
功能分类
CLI 命令与参数