用编码记录自动整理工时与站会汇报
文章将分支、提交和编码 Agent 会话串成时间线,按任务归集工时并生成站会记录。其规则包括超过 15 分钟的间隔视为空闲、仅计入人在场时的 Agent 工作,以及按刻钟取整。
AI 深度解读
作者用两周 Claude Code 活动记录估出了 61 小时工作时间,而每天第一次到最后一次活动的跨度合计是 120.5 小时。按后者报工时,几乎会多报一倍。但 61 小时也不是经过核验的真实工时,它只是按一组公开规则算出的估计值。
这篇最有用的地方,是把工时表变成一份有依据、能修正的草稿:从 Git、Agent 会话和终端记录重建时间线,再分配到工单,顺带生成站会笔记。对按小时结算的开发者,这比周五凭记忆补表更值得借鉴。
为什么一天在线十二小时,不能报十二小时
开发者已经留下了不少工作线索。分支 fix/ABC-142-login-timeout 指向工单,Git reflog 能追踪分支切换;提交消息有时间戳,也可能包含工单编号;Claude Code 或 Codex 会话记录了提示词及所在项目;带时间戳的 shell 历史则能补上 npm test、git push 等操作。
问题是,这些记录都是离散的点。早上 9:10 发出提示词,晚上 6:40 提交代码,中间虽然跨了九个半小时,却不能证明一直在工作。午饭、外出,以及 Agent 独自运行的时间,都可能混在里面。
作者拿自己的两周 Claude Code 记录做了比较:按规则估计为 61 小时,首尾跨度为 120.5 小时。样本里,即使某天首尾相隔十二小时,估计活动时间也没有超过约七小时。

这里必须分清比较对象。作者没有用人工计时器校验结果,只是比较了两种算法。样本也只包含 Claude Code 活动,没有纳入 Agent 之外的终端操作和 Git 活动,更无法完整覆盖思考、阅读与会议;当天的数据还只是尚未结束的部分。
所以,这组数字能说明首尾跨度容易虚高,却不能证明 61 小时就是正确答案。作者自己也把它定位为键盘活动时间的下限估计。
工时算法最重要的是规则能解释
作者最终采用四条规则,优先考虑的是能向客户解释清楚。
第一,每个活动点获得到下一个点之间的时间。10:00 输入提示词,10:07 运行测试,就把七分钟归给前一个活动。
第二,间隔超过 15 分钟,视为空闲,前一个点只计 5 分钟。15 分钟用于容纳看 diff、短暂思考等间隙;超过阈值,则不再把整段时间算进去。作者承认,阈值设成 10 或 20 分钟也有讨论空间,关键是每天一致执行。
下面这段原文代码负责分配相邻活动之间的时长,属于完整脚本的局部:
hours = defaultdict(float)
for i, (when, project) in enumerate(present):
gap = (present[i + 1][0] - when).total_seconds() if i + 1 < len(present) else IDLE_GAP + 1
hours[(when.date(), project)] += gap if gap <= IDLE_GAP else CREDIT
要看最后一行:IDLE_GAP 是 15 * 60 秒,CREDIT 是 5 * 60 秒;最后一个活动点没有后继,也按 5 分钟计入。因此,「超过 15 分钟不计入」只是简写,实际规则仍保留了前一个点的少量时间。
第三,Agent 活动必须靠近人的输入。自动回复、执行命令都有时间戳,但不能据此把机器独自运行的一小时报成人工工时。作者只保留距离人工活动 15 分钟以内的 Agent 事件,两周内因此排除了 724 个事件。
这里还有一个实现细节:示例脚本用的是与人工提示词时间戳的绝对距离,既可能靠近此前输入,也可能靠近此后输入。它证明的是时间接近,并不能确认人一直在场。
第四,结果按最近的 15 分钟取整,并明确标注为估计。用户补录电话、修改单元格后,要保留修正标记,重新计算时也不能覆盖。
自动估算负责起草,人负责补齐记录之外的工作。
原文提供的 hours_check.py 默认统计最近 DAYS = 14 天,读取 ~/.claude/projects/*/*.jsonl 中的时间戳、目录及事件元数据,不读取消息正文来分析内容;其中也会检查消息结构,排除工具结果和上下文压缩摘要,避免把它们当成人工输入。
保存完整脚本后运行 python3 hours_check.py,加上 --mask,即 python3 hours_check.py --mask,可以把输出项目名替换成 Project A、Project B、Project C。这只遮蔽输出里的项目名,不代表整份记录都经过匿名化。
时间归到哪个工单,比求和更考验规则
有了每日小时数,还得回答客户真正关心的问题:每个工单用了多久。
作者采用的是从现有记录中寻找归属线索。分支 fix/ABC-142-login-timeout 对应 ABC-142;会话标题 ABC-150 export to CSV 对应 ABC-150。提交消息 ABC-142: handle expired tokens 则可以把此前未标记的活动归到该工单,回溯范围止于上一笔提交或最近一次超过 15 分钟的停顿。
终端命令没有自己的分支信息,就借用同一项目内、15 分钟以内最近活动的分支。比如两次 ABC-142 提示词之间的 git push,归给 ABC-142。
这些都是归属推断,并非确定事实。作者因此还加了限制:在 main 上的活动,以及存活超过 30 天的分支,归到项目层级,不直接归到某张工单。长期分支通常不足以代表一个具体工作项。
工单格式也不能写死。ABC-123、INC0012345、#1234 都可能出现,作者建议从分支和提交中寻找反复出现的编号模式,再请用户确认。
同一条时间线还可以生成站会草稿:提交、创建分支和合并记录回答昨天做了什么;失败测试、未推送提交、待评审分支提供后续事项。固定模板已经能完成基础整理,AI 只负责润色,并被明确禁止编造工作、数字、人员或工单。
作者把这些规则做进了自己的 Mac 应用 L2Cache。Worklog 汇总 Git、Agent 会话和终端命令,支持人工改单元格、补会议记录;Copy as Table 用于粘贴到表格,Export CSV 用于导出,Today 页面可以生成站会。按作者描述,数据留在 Mac 本地,不连接 Jira 或其他服务。

我的判断
我赞同它把依据和人工修正一起保留。比起只交一个小时数,能展示当天的活动顺序、计算规则和补录原因,更便于核对;也比单靠 Git 提交重建工作更细,因为提交经常隔很久才出现。
但 15 分钟空闲阈值、5 分钟保底、30 天分支限制,都是作者的经验选择,没有对照数据证明它们适合多数团队。持续阅读源码、纸上推演或结对讨论,都可能长时间没有输入;频繁给 Agent 发消息,也不能自动证明持续投入。
活动密度可以帮助回忆工作,不能直接代表工作价值。
与手动计时器相比,这套方法省去了开始、暂停的操作,却增加了推断误差。与日历相比,它更容易找回编码细节,却容易漏掉会议和沟通。合理的使用方式是相互补充,再由人确认可结算范围。原文也没有交代多项目并行、跨午夜活动和同名仓库如何处理,不能把示例脚本直接当成成熟的计费系统。
站会同样需要校正。失败测试未必是阻塞,未推送提交也未必是今天的计划。这些记录适合触发回忆,最终安排仍要由开发者确认。
能拿来做什么
- 如果你按小时承接前端或 Node 项目,可以先用原文完整脚本检查最近 14 天记录,对照首尾跨度与活动估计,再用会议记录补齐缺口;先确认差异来自哪里,再决定报工时规则。
- 在日常 AI 编程中,把工单编号放进分支名、提交消息和会话标题,并保持一致,让后续归属有据可查;无法确定的活动保留在项目层级。
- 生成工时草稿时保留「自动估计」和「人工修正」状态,补录电话或评审时写清原因,重新计算也保留这些修改。
- 生成站会时先用固定模板整理提交、分支和测试事实,再让 AI 润色;发出前逐项确认今天计划与阻塞,删掉记录无法支持的判断。