--- name: daily-agent-review description: | 跨 agent/渠道的每日复盘。读取 owner 在飞书 agent、微信 agent(及未来更多 agent)当天的聊天记录, 归一化、去重、跨渠道合并成一份当日对话档案,并基于可追溯的证据生成今日计划、完成情况、未决事项、 关键决策、风险与次日建议。支持手动与定时(默认 23:30 本地)触发。输出以 JSON 为主,同时给人类 可读 TXT;可参数选择只输出其一。当用户说“复盘今天 / 今日总结 / 跨渠道日报 / 每日回顾 / daily review / agent review / 生成今天的复盘”等时使用。 allowed-tools: - Read - Write - Edit - Bash metadata: version: 1.0.0 author: 2100chen --- # Daily-Agent-Review:每日多 Agent 对话汇总与计划复盘 把散落在飞书 agent、微信 agent(及未来更多 agent)里**某一天**的聊天收拢成一份当日对话档案,并基于**可追溯证据**复盘:今天计划了什么、完成了什么、还悬着什么、拍板了什么决定、有什么风险、明天打算干什么。**独立运行,不依赖任何其它 skill,也不调用任何模型 API——所有分析由 OpenClaw agent(你,自带模型)按本文件的【分析规范】完成。脚本只做采集/归一化/组装/渲染/校验这类机械活。** ## Outcome Contract - **Outcome**:`data/reviews/.json` + `data/reviews/.txt` —— 一份证据可追溯的每日复盘。 - **Done when**:覆盖已如实记录(含失败/缺失渠道)、JSON 通过 `validate_output.py`、TXT 已渲染、用户已看过一句话总结。 - **Evidence**:每个「已完成」事项、每个决策/承诺/风险,都必须挂至少 1 条 `evidence_refs`,且 ref 能解析到 `messages[]`(或独立保存的原始消息档案)。 - **Output**:先跑脚本产出 bundle,你(agent)分析后写 review JSON,再渲染 TXT、跑校验,最后回报给用户;**不要默默覆盖既有 review**(除非 `overwrite:true`)。 ## 核心工作流(你严格执行) 1. **Pre-flight(先确认参数)**:`date`(默认当地当天)、`timezone`(默认 `Asia/Shanghai`)、`sources`(默认全部已启用)、`output_format`(`json`/`txt`/`both`,默认 `both`)、`include_raw_messages`(默认 true)、`include_private`(默认 false)、`overwrite`(默认 false)、`language`(默认 `zh-CN`)。`overwrite=false` 且当日 review 已存在 → 先停下问用户。 2. **采集(你负责渠道调用)**:对每个 source 用 OpenClaw 的渠道工具(如飞书 `feishu_chat`)拉取当日消息,写到 `data/raw///`;某个渠道插件未暴露历史查询工具(微信/QQ 常见)→ 让用户导出/粘贴近期对话,再跑: ```bash python scripts/collect_messages.py --source feishu --date --timezone Asia/Shanghai \ --file <原始txt或json> --conversation-id <会话标识> --conversation-name <会话名> \ [--agent-id ... --agent-name ...] [--include-private] ``` - 支持多会话:每个会话单独跑一次,给不同 `--conversation-id`。 - **绝不假装拉到了拉不到的消息**:某渠道拉不到,就让它缺着,后续如实标 `coverage` 缺口。 3. **归一化**: ```bash python scripts/normalize_messages.py --date --timezone Asia/Shanghai \ [--sources feishu,wechat] [--owner-aliases 主人昵称1,主人昵称2] [--include-private] ``` - `--owner-aliases` 很关键:主人本人可能在不同群用不同昵称,务必传全,否则会把主人的话误判成「他人请求」。 - 产出 `data/normalized/.json`:统一 14 字段、去重、时区换算、按日期过滤、角色/类型/隐私分类。 4. **组装 bundle**: ```bash python scripts/build_daily_review.py --bundle --date ``` - 产出 `data/bundles/.json`:按 (source,agent,conversation) 分组 + 表层线索(`owner_statements` / `external_requests` / `questions_to_owner` / `deadlines_mentioned` / `recall_or_edit_markers` / `owner_commitments`)+ `coverage` + `all_message_ids`。 5. **分析(你用自带模型,本步是核心)**:Read `data/bundles/.json`,**以其中 `messages` 与 `surface_signals` 为唯一依据**,按下方【分析规范】产出 review JSON,写到 `data/reviews/.json`(schema 见 `references/output-schema.md`)。 - `include_raw_messages=true` 时,把 `bundle` 里所有标准化消息原样放进 `messages[]`(这样 evidence_refs 才能被校验解析)。 - 没有当日任何可分析消息 → 仍写一份 review,`coverage.status=failed`、`one_line_summary="无可分析记录"`,各数组留空。 6. **渲染 + 校验**: ```bash python scripts/build_daily_review.py --render --review-json data/reviews/.json python scripts/validate_output.py --review-json data/reviews/.json --bundle data/bundles/.json ``` - 校验不过 → 用 Edit 改 review JSON 对应问题(通常是 evidence_refs 指错/缺失、缺必填键、状态枚举非法),重渲染重校验,直到通过。 - `output_format=txt` → 只产出 TXT;`output_format=json` → 只产出 JSON(跳过渲染)。 7. **回报**:一句话总结、覆盖状态(哪个渠道缺了)、完成/未决/决策/风险条数、两个文件路径。 ## 分析规范(给 agent,第 5 步执行) 以 `bundle.messages` 与 `bundle.surface_signals` 为唯一依据。**`surface_signals` 只是线索,不是结论**——你要逐条回到真实消息文本确认后再下判断。 - **任务抽取**:优先从 `owner_statements`、`external_requests`、`owner_commitments` 三类线索里识别任务;任务 `title` 用 owner 原话改写(不改义),保留 `evidence_refs`。他人对主人提的要求 → 任务 `origin: "external_request"`,**不可当作主人自己的计划**。 - **状态判定决策树(必须按证据判,不臆测)**: - `completed` ⟺ 能找到时间晚于任务起始、且语义上确认完成的消息(含「搞定/完成/已发/已提交/done」等),且 ≥1 条证据。 - `in_progress` ⟺ 有起始声明、当日内无完成证据。 - `partial` ⟺ 完成证据不充分,或 owner 自述「一部分/一半/差不多」。 - `delayed` ⟺ 含截止时间且已过、无完成证据。 - `cancelled` ⟺ 明确撤回/取消(`recall_or_edit_markers.kind==cancel` 或 owner 明说取消)。 - `unknown` ⟺ 证据不足;同时把该条加入 `analysis_notes.low_confidence_items`。 - **跨渠道合并**:当飞书与微信里两条消息指向同一事项(标题实体、时间、对象三要素一致)→ 合并成一个 task,`evidence_refs` 保留**两源** ref。**拿不准是否同一事项 → 保持分开,并标 `possibly_related: true`,绝不强行合并**(避免丢上下文或误并)。 - **四类内容严格分离(硬规则)**: - **事实(Facts)**:仅陈述发生了什么,挂在 `decisions`/`completed_today` 的 `evidence_refs`。 - **主人计划(Owner plans)**:仅来自 `sender_role==owner` 的陈述 → 进 `tomorrow.owner_stated_plans` 与任务的 `origin:"owner_plan"`。 - **外部请求(External requests)**:来自 `contact` → 任务 `origin:"external_request"`,不可混进主人计划。 - **系统建议(System suggestions)**:你(agent)推断的建议 → 进 `tomorrow.system_suggestions`,**必须带 `rationale` 解释**,且不得伪装成主人的意图。 - **证据强制**:每个 `completed_today`、每个 `status==completed` 的 task、每个 `decision`/`commitment`/`risk`/`pending_reply` 必须有 ≥1 条 `evidence_refs`,且 ref 能解析到 `messages[]`(或独立原始档案)。`validate_output.py` 会查。 - **覆盖诚实**:任一 source `status != ok` → `coverage.status` 设为 `partial`(部分失败)或 `failed`(全失败),并在 `analysis_notes` 列出影响范围;**绝不伪造补全缺失渠道的内容**。 - **去重**:同一任务被多渠道提到只计一次(证据合并),避免重复计入。 - **定时触发**:你可被 cron 触发(推荐每天 23:30 本地时区);定时模式下若所有渠道都失败,写一份只含 `coverage` 的空 review 并标记 `failed`,**不要报错中断**。 ## Hard Rules - **无证据不判定**:未命中证据链的状态一律 `unknown`,绝不臆测。 - **四类分离**:facts / owner plans / external requests / system suggestions 不可混入同一字段。 - **覆盖诚实**:拉不到的渠道如实标记,绝不假装完整。 - **隐私有效**:`privacy=="excluded"` 永不进 `messages[]`;`"private"` 仅在 `include_private=true` 时进入。 - **幂等**:同日重跑(相同原始输入)核心结果稳定;`overwrite=false` 时已有 review 不覆盖,先停下问。 - **无凭证**:review JSON/TXT 不得出现任何 API key/token/银行卡号;`validate_output.py` 会正则扫描。明显的密钥你写之前先脱敏。 - **日期独立**:回填历史日期产出独立文件 `.{json,txt}`,互不污染。 ## 文件结构 ``` ├── SKILL.md # 本文件(含分析规范) ├── agents/openai.yaml # 对外调用接口声明(不参与 OpenClaw 加载) ├── scripts/ │ ├── collect_messages.py # 解析单来源/单会话原始聊天 → 带采集状态的 parsed.json(不调模型) │ ├── normalize_messages.py # 跨渠道归一化、去重、时区转换、角色/类型/隐私分类(不调模型) │ ├── build_daily_review.py # --bundle 组分析 bundle / --render 渲染 12 段 TXT(不调模型) │ ├── validate_output.py # 校验 schema / 证据链 / UTF-8 / 凭证泄露(不调模型) │ └── requirements.txt # 无第三方依赖(纯标准库) └── references/ ├── source-adapters.md # 飞书/微信/未来渠道如何映射到统一消息结构 + 时区说明 └── output-schema.md # 完整 JSON Schema + 枚举说明 ``` 运行时数据(已 gitignore):`data/{raw///.parsed.json, normalized/.json, bundles/.json, reviews/.{json,txt}}`。 ## Gotchas | 发生过的问题 | 规则 | |---|---| | 某渠道拉取失败就假装完整、或整个任务卡死 | 拉取是「优先」非「必须」;拉不到走手动归一化,`coverage` 标 `partial`,绝不伪造 | | 把他人请求当成主人自己的计划 | 四类分离铁律:外部请求标 `origin:"external_request"`,不进 owner plans | | 「已完成」没挂证据,校验失败返工 | 每个 completed 必须有 ≥1 条可解析 `evidence_refs` | | 跨渠道合并太粗暴,把两件不同的事并了 | 拿不准就分开 + `possibly_related:true` | | `--owner-aliases` 没传全,主人的话被误判成他人 | 在不同群的昵称都要传;也可设环境变量 `DAILY_AGENT_REVIEW_OWNER_ALIASES` | | 时区没对齐,跨午夜会话归错日期 | 归一化严格按目标时区重算并保留 `original_timestamp`;跨午夜按消息实际时间归档 | | 回填历史日期覆盖了今天的 review | 历史日期产出独立文件;`overwrite=false` 默认不覆盖,先问 | | review 里混进了 API key | 写之前脱敏;`validate_output.py` 会扫描 sk-/ghp_/bearer/40位hex/银行卡号等 | ## 输出 复盘完,回报:日期、覆盖状态(哪个渠道缺)、消息总数、一句话总结、完成/未决/决策/风险各几条、JSON 与 TXT 文件路径。不要默默做完全程——尤其「已完成」与「明日建议」要让用户过目。