# Loop Weekly Report

> 一个每周自动生成工作周报的定时 loop 的设计与参考实现。每周一读上周所有 Claude Code session，用 headless claude 归纳成分类周报云文档，链接自动归档进汇总索引，再推一条通知。适合想用「定时 + headless AI + 从自己的工作痕迹里自动写周报/月报/汇总」的人参考。触发词：自动周报、session 汇总、headless 定时生成文档、工作痕迹归纳、周报自动化、cron + claude -p 写文档。

- Skill: `igoingdown/loop-weekly-report` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add igoingdown/loop-weekly-report`
- Raw SKILL.md: https://api.skillmd.com/api/skills/igoingdown/loop-weekly-report/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: igoingdown (https://skillmd.com/u/igoingdown)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/igoingdown/loop-weekly-report

---


# loop-weekly-report

> 这是一个 **loop skill**（自动化循环），沉淀的是「怎么用定时 + headless AI 把自己一周的工作痕迹自动写成周报」的设计与去敏参考实现。真实运行需按 `config.example.sh` 填本地配置，并把文档/通知层换成你自己的工具。

一句话：**每周一自动读我上周和 Claude 的所有对话，归纳成一篇分类周报，建成云文档、归档进索引、把链接发我手机。** 我不用再手写周报。

## 为什么值得自动化

周报的原始素材其实全在你一周的工作痕迹里（每个 session 干了什么、解决了什么、结论是什么），只是散、且回忆有偏差。让 AI 从结构化摘要里归纳，比人凭记忆写更全、更省时，还不容易漏掉长会话里真正的重头戏。

## 架构：三步流水线

1. **提取（digest.py）**：扫过去一周 `[上周一, 本周一)` 窗口内所有 session transcript，每个 session 压成一条结构化摘要——项目、时间、PR/issue 号、**按首/中/末采样的多条用户消息**、**助手正文里的高信号行**、**子代理关键词命中**、最终结论。
2. **归纳（headless claude）**：`claude -p` 通读摘要，按固定大类（需求承接 / 稳定性排查 / 用户反馈 / 架构设计 / 基础组件 / 研发效能）归纳成 1000~1500 字周报 + 「下周重点」，创建云文档，并把 URL 用固定格式 `WEEKLY_DOC_URL=<url>` 打到 stdout 供脚本捕获。
3. **归档（archive-to-index.sh）**：把这周的链接插到「汇总索引文档」锚点段落之后（最新在最上），再推通知。

## 关键设计决策与踩过的坑

- **采样别只取首条消息**：早期 digest 只取「首条用户请求 + 末条助手回复」，结果**续接会话和长会话的主线全丢**——一个 session 聊了 5 个话题，只看到第一个。改成对去重后的真实用户消息按位置（首/中/末）采样，才抓得住主线。
- **子代理命中兜底话题漂移**：真正的重活常常 fan-out 到 subagent 里做，主线程摘要看不到。所以额外扫每个 session 关联的 `subagents/` 目录，统计领域关键词命中次数——命中高的关键词往往才是这个 session 的重头戏。这些关键词要**按你自己的业务领域定制**（脚本里给的是通用工程词）。
- **高信号行摘取**：助手正文里含「上线/合入/事故/验收/压测…」这类里程碑词的行单独摘出，避免归纳时漏掉关键成果。同样建议按业务补词。
- **URL 用固定标记回传**：headless claude 建完文档后，约定用 `WEEKLY_DOC_URL=<url>` 单独一行输出，外层脚本用 `grep -oE` 抓，比让模型「告诉我链接」稳定得多。这是**让 headless AI 和外层脚本可靠交接结果的通用技巧**。
- **锚点按关键词定位，不硬编码 block-id**：归档时在索引文档里按锚点关键词找插入位置，而不是记死某个段落 id——文档结构一变，硬编码就失效。
- **数字必须来自素材、不许编造**：prompt 里明确要求所有数字/结论/PR 号来自摘要文件；元操作类 session（讨论周报本身）和测试 session 不计入工作量。
- **单次喂给 headless 的输入必须有上界，体量涨了会静默炸**：digest 随 session 数增长（观测：一周从约 200 KB 涨到约 310 KB 后，headless 在读文件阶段连续三次自动压缩后放弃——没建文档、没归档，只剩一条失败通知）。两层修法：① digest 先过噪声过滤——跳过 headless/自动化入口的会话、0 条真实用户消息的会话、只有几行的空壳（这些是 jsonl 里的结构化字段，判定确定）；② 脚本改 **map-reduce**：外层按固定大小（如 ≤60 KB）切块，每块一次 `claude -p` 只做"提炼成结构化工作项清单"，再把几 KB 的条目拼起来喂最后一次 `claude -p` 写周报。上界由 shell 保证，不靠 prompt 里让模型"分块读"的自觉——炸掉那次就是模型自己选的块大小。仓库里的参考脚本仍是单次归纳版，切块与拼接按这个思路自行加。
- **换模型档位（省成本）时要同时核上下文窗口，并用真实体量复跑一次**：把归纳阶段切到更便宜的模型后，第一次真实运行就在 reduce 阶段撑爆——输入没变，变的是新模型的上下文窗口更小，往期都过只因为往期跑的是大窗口模型。选档看三个维度：**任务复杂度**（巡检/播报类走轻量档，跨源推理与写代码保留强档）、**输入体量**（digest 大的选大上下文档位，或先把输入切小）、**时效**（loop 里内嵌的外部评审步骤按等待预算选快档，最强的那个往往最慢）。换档不是改一行配置就完，要拿最近一次真实大小的 digest 复跑通过才算切换完成。
- **确定性副作用收回 shell 层，模型的活到 `Write` 为止**：建文档 / 推通知 / 归档索引是确定性操作，放在 headless 会话尾部意味着模型只要在最后一步前炸掉，前面写好的正文就全丢。改成模型只负责把正文写成本地文件，shell 检测到文件即接手建文档、通知、归档——会话后半段再炸也不影响交付，失败时留下的正文还能人工补发。
- **headless 会话的起步窗口要体检：不用的 MCP 工具定义会白占大半上下文**：定位第二次撑爆时才发现，会话第一轮还没读任何文件，系统提示 + 挂载的 MCP 工具定义就吃掉了 200K 窗口的三分之二（两个与周报无关的 MCP server 合计约 88K token）；再读几十 KB 条目、再让模型现场"学一遍"文档 CLI 的用法，必炸。周报这类流水线根本不用 MCP。规矩：① 定时 headless 任务默认以**空 MCP 配置**启动（`claude -p` 加 `--strict-mcp-config --mcp-config '{"mcpServers":{}}'`），真要用哪个再显式挂哪个；② 用"只回一个字"的空跑看首轮 cache 体量，就是起步成本，换模型、加输入之前先看它还剩多少；③ 固定不变的用法（文档 XML 格式、通知命令）写死进 prompt 或收回 shell，不让模型每周重学一遍。同一套 cron 家族（日报复盘、各类盯守）都背着同样的起步成本，只是还没炸——修一处时顺手把全家改掉。
- **"换便宜模型省成本"要以网关/账单侧的实际应答模型核实，别信 CLI 回显的键名**：切档五天后查代理请求日志才发现，请求的便宜模型被上游网关**静默路由回了原来的强模型**——几十条请求无一例外——所谓省 20 多倍一分钱没省；当初对比出的成本差其实是两次探测的 cache 体量差，不是单价差。带大窗口后缀的模型名同理：CLI 侧按大窗口推迟自动压缩，上游真实窗口没变，输入一超就不是压缩而是硬失败。规矩：验模型看代理/账单日志里"实际应答模型"那一列（或响应头），成本对比按**同一 cache 体量**做；切档后至少一次真实运行用这个方法核过才算切成。
- **定时交付物已知坏了，下次触发前必须闭环，与拍板无关的必做修复不等拍板**：周报连续两个周一失败。第一次失败当天就诊断清楚、修了一半；第二天把剩余修复清单连同"用哪个模型"的选择题一起发给用户等拍板，清单里已经标了"这条独立于模型选择，必做"——但整份清单都跟着选择题一起等了六天，第二个周一到点又以同一个报错失败，用户在开会前发现"今天的周报没有成功生成"。规矩：① 必做且与待决问题无关的修复**当天落地**，拍板请求里只留真正需要用户选的那一项；② 修完用**最近一次真实体量**的 digest 跑一遍 `DRY_RUN`（不建文档、不推通知），各阶段零自动压缩、产物结构自检通过才算修好；③ 有硬消费时刻（周一开会）的交付物，把失败发现时刻往前挪：正式触发前一晚先跑一次 `DRY_RUN` 校验（或把正式触发提前到消费时刻前几小时），脚本支持手动指定窗口补跑，失败通知里直接带补跑命令与诊断入口——两次失败当天都推了 ❌ 通知，但通知到达时用户已经在要用它的那一刻，余量为零。

## 脱敏红线

- **署名、租户域名、文档 ID** 全部外置到 config，仓库里只有占位符。
- **业务领域关键词**（gems/coins/内部功能名之类）不进仓库——脚本里只放通用工程词，你在本地 config 化的 digest 里自己加。
- 周报正文由 AI 从你的私有 session 生成、发到你自己的云文档，**不经过这个公开仓库**；仓库里只有生成它的脚本骨架。

## 需要你自备/替换的东西

- **云文档 CLI（`$DOC_CLI`）**：创建/更新文档、按 block 插入内容。参考实现依赖一个私有 CLI，未随仓库分发——`archive-to-index.sh` 里用伪代码 + TODO 标出了你要补齐的 4 步。
- **通知渠道（`$NOTIFY_CMD`）**：把链接推到你的 IM/邮件。
- **索引文档**：一篇带锚点段落的「周报汇总」文档，新链接往锚点后插。

## 安装与自检

```bash
./install.sh init-config     # 生成 ~/.config/loop-weekly-report.sh
$EDITOR ~/.config/loop-weekly-report.sh
./install.sh doctor          # 自检依赖与配置
./install.sh install-cron    # 装 crontab（每周一 11:00）
```

## 与其他 skill 的边界

- 本 skill 管「每周归纳」。要按天做「日记 + 自我改进项」复盘，见 `loop-daily-retro`；要让 skill 库自己进化，见 `loop-skill-optimizer`。三者共享「cron + headless claude + digest 提取 + 去敏配置外置」的同一套范式，但产物和窗口不同。

