L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Productivité · SKILL.md

zhiligeoreport

zhiligeoreport

端到端生产并发布 GEO 周报到「直隶按察使」公众号草稿箱:从抓信源 → 强 GEO 筛选 → 通读原文中文总结 → 双语翻译 → 5 角色章节分类 → 4 项验证门禁 → 渲染 HTML → 样式 A inline 化 → 按字节拆篇 → 推 WeChat 草稿箱。Auto-loaded when user mentions 跑周报 / 写周报 / 生成 GEO 周报 / 本周 GEO 资讯 / 出周报 / 推草稿箱 / publish weekly / geo-report run. Do not use for 单条 GEO 资讯查询(直接查 DB)or 正式发布公众号(仅做草稿,正式发布由用户在微信公众平台后台完成)。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: zhiligeoreport description: | 端到端生产并发布 GEO 周报到「直隶按察使」公众号草稿箱:从抓信源 → 强 GEO 筛选 → 通读原文中文总结 → 双语翻译 → 5 角色章节分类 → 4 项验证门禁 → 渲染 HTML → 样式 A inline 化 → 按字节拆篇 → 推 WeChat 草稿箱。Auto-loaded when user mentions 跑周报 / 写周报 / 生成 GEO 周报 / 本周 GEO 资讯 / 出周报 / 推草稿箱 / publish weekly / geo-report run. Do not use for 单条 GEO 资讯查询(直接查 DB)or 正式发布公众号(仅做草稿,正式发布由用户在微信公众平台后台完成)。 displayNames: zh-Hans: "GEO 周报"

GEO 周报生产与发布

v1.25。覆盖写作(fetch → render)+ 发布(inline → split → push)端到端。5 章节分类(GEO 服务商动态 / 品牌方实战 / 工具平台更新 / 行业研究与数据 / 国际市场)。草稿标题统一为 YYYY-MM-DD 刘生 GEO 资讯;obsidian 只读 raw/wechat;正文只保留基础标题、摘要、阅读原文;封面与配图统一走 zhili-illustration 规范链路。 v1.21 关键变更:

  • 标题前 label 动态提取:extract_title_label(title, max_n=2) 从标题抽品牌名/行业词(如「阿里·搜索」「腾讯·阿里」「医药·医疗」「报告·趋势」),不再直接显示章节名
  • Item.label 字段新增,模板 {{ it.label or it.category }} 兜底

v1.20 关键变更:

  • 单篇发布模式(默认):--parts 1 把所有板块拼成一篇公众号文章,单篇 bytes ≤64KB
  • --per-section-cap 默认 8(更精)
  • 仍保留 --parts 2 / 3 多篇模式用于备选

v1.19 关键变更:

  • obsidian 内参只允许 raw/wechat,禁止读取 wiki/*、raw/Clippings、books、papers、law 等其他 obsidian 内容
  • 搜索引擎内容降权(source_weight = 1.0,板块上限 12),只作为补充
  • 生产级质量门槛:标题 ≥ 10 字、正文 ≥ 300 字、中文占比 ≥ 30%;不达标直接剔除
  • obsidian 转载首行 URL 自动跳过,向下取 # 标题

Inputs to collect

无前置输入。直接跑端到端命令即可。

如用户指定:

  • 日期:跑非本周数据(默认本周)
  • parts:默认 1(单篇);可用 2 / 3 作为字节过大时备选
  • per-section-cap:默认 12
  • --skip-push:只渲染不推草稿箱

Procedure

一行命令(推荐)

cd /Users/apple/Downloads/User/geo-report
uv run python3 -m geo_report.cli publish-weekly \
  --parts 1 --per-section-cap 12 --cover /tmp/zhili_cover.png

这条命令完成 7 步:

分步详解

Step 1 — 抓信源(fetch-all)

  • 失败重试 3 次(1s / 5s / 25s)
  • 连续 3 次失败的 source 自动 enabled = false + 写 errors 表 + 告警
  • 约束见 references/constraints.md §1-9

Step 2 — 渲染 HTML(scripts/13_render_only.py)

  • 验证门禁 one-by-one(相关性 / 板块分类合法性 / 中文翻译 / 摘要质量 / 编码 / 营销稿 / 时效)
  • 输出 data/reports/liusheng_geo_<YYYY-MM-DD>.html(北京时间文件名)
  • 约束见 references/constraints.md §10-12

Step 3 — 样式 A inline 化(scripts/16_inline_css.py)

Step 4 — 按字节拆篇(scripts/15_split_zhili.py)

  • ≤64KB/篇(WeChat 草稿 content 上限),建议 ≤60KB 更稳
  • parts=1:所有板块合并为单篇;parts=3 仅作备选:上 = GEO 服务商动态 + 国际市场;中 = 品牌方实战 + 工具平台更新;下 = 行业研究与数据
  • 标题后缀:(上)/(中)/(下),每个 26 字节
  • 拆篇输出必须保留正文头部的 kicker、H1;推送版必须移除本地锚点目录链接(href="#sec-*"),否则 WeChat draft/add 可能报 45166 invalid content
  • 重要 bug 修复:h2 切分用 re.finditer 自然顺序,不再用 200 字节窗口查 class=(inline 后超窗口)
  • 详细见 references/constraints.md §14

Step 5 — 推 WeChat 草稿箱(push.py)

  • 每篇调一次 push.py --html <part> --cover /tmp/zhili_cover.png;不传 --skip-illustration / --skip-cover,封面和配图统一走 zhili-illustration 规范链路
  • 凭据见 references/credentials.md

Step 6 — 产物自检(可选,scripts/validate-weekly.js)

  • 校验 inline HTML 字节 / 中文字数 / 板块数 / 条目数 / 标题后缀
  • 单独跑:node ~/.minimax/skills/zhiligeoreport/scripts/validate-weekly.js data/reports/liusheng_geo_<DATE>_inline.html

Step 7 — 草稿箱验证(用户在微信公众平台后台)

  • 打开 https://mp.weixin.qq.com → 草稿箱
  • 打开单篇周报预览,确认样式 A 渲染(H2 下划线 / 红褐翻译标题 / 行距 1.8 / 阅读原文跳转)

Output contract

端到端成功标志

  1. ✅ 7 步全跑通,无失败退出码
  2. ✅ data/publish/liusheng_geo_<DATE>_zhili_part1.html 单篇文件存在
  3. ✅ 单篇字节 ≤ 64KB(建议 ≤60KB)
  4. ✅ 单篇草稿 draft/add 返回 media_id
  5. ✅ 微信公众平台后台草稿箱渲染样式 A

文件清单

文件来源大小(实测)
data/reports/liusheng_geo_<DATE>.htmlStep 2~93KB(含完整样式 A)
data/reports/liusheng_geo_<DATE>_inline.htmlStep 3~120KB(inline +30%)
data/reports/liusheng_geo_<DATE>_inline_part1.htmlStep 4~25KB
data/reports/liusheng_geo_<DATE>_inline_part2a.htmlStep 4~35KB
data/reports/liusheng_geo_<DATE>_inline_part2b.htmlStep 4~59KB

WeChat 草稿属性

  • 标题:<YYYY-MM-DD> 刘生 GEO 资讯(单篇默认;多篇备选才加上/中/下后缀)
  • 作者:刘生
  • digest:首段中文前 40 字
  • thumb_media_id:/tmp/zhili_cover.png(900×383,由 zhili-illustration 规范链路生成)
  • need_open_comment:1
  • only_fans_can_comment:0
  • original:1

Failure handling

常见故障

完整表见 references/troubleshooting.md。关键 5 条:

  1. 拆篇后 partN 字节爆炸(>100KB) → h2 切分窗口 bug。已用 re.finditer 自然顺序修复。症状:曾误把"处方药 1 条"算成 112KB。
  2. 推草稿箱报 invalid media_id → draft/get API 限制,draft/add 成功但 get 查不到是正常现象。用微信公众平台后台验证。
  3. 验证门禁违规 "title_zh 不含中文" → translate_zh_batch 已自动回退 minimax;若仍违规,给标题加 min() 处理。
  4. inline 化字节过大 → 元素太多导致内联 style 字节膨胀。先降低 per-section-cap;仍超 64KB 再改 parts=3。
  5. WeChat 草稿箱无样式 → inline 化未做或 <style> 块残留。重跑 scripts/16_inline_css.py 后再推。

失败降级策略

  • 抓信源失败:3 次重试(1s/5s/25s)后 disable source,不阻断流程
  • 翻译失败:GT → minimax 兜底;都失败则 title_zh/summary_zh 留空,由验证门禁剔除
  • LLM 总结失败:返回空摘要,由验证门禁剔除;禁止截取原文或 current_summary 作为可发布摘要
  • 推草稿箱失败:返回 media_id 为空,整批中断;用户需要看 stdout 错误

何时停下来问用户

  • 板块分类错位(用户明显感知)→ 触发 v1.17 待办里的代码改造
  • WeChat 凭据缺失(APP_SECRET)或 zhili-illustration 生成失败 → 阻塞流程,问用户补
  • style A 改动请求(用户要求改样式)→ 是 spec 变更,先改 spec 再改模板

v1.25 已落地

  • collector/obsidian_vault.py:只扫描 raw/wechat,禁止读取其他 obsidian 内容
  • scripts/13_render_only.py:render SQL 二次防护,只允许 obsidian-raw-wechat + meta_json.subdir = raw/wechat + created_at >= cutoff
  • weekly.html.j2:正文只保留基础标题、摘要、阅读原文;删除 TOC、来源栏、intro、标签、日期、内参标注、辣评、CTA、hashtags、footer
  • publish-weekly:推送不再默认跳过配图/封面;统一调用 zhili-illustration 规范链路
  • push.py:封面生成失败中断,避免上传不存在或旧封面

v1.24 已落地

  • scripts/15_split_zhili.py:拆篇输出保留正文头部 kicker、H1,单篇正文 H1 与 HTML <title> 一致
  • scripts/15_split_zhili.py:推送版移除本地锚点 TOC,避免 WeChat draft/add 报 45166 invalid content

v1.23 已落地

  • src/geo_report/report/html.py:新增 build_report_title(date_label),统一生成 <YYYY-MM-DD> 刘生 GEO 资讯
  • scripts/13_render_only.py / src/geo_report/cli.py:HTML <title>、正文 H1、WeChat 草稿标题来源统一为报告日期标题
  • scripts/15_split_zhili.py:保留基础标题,多篇模式只追加 (上)/(中)/(下)

v1.22 已落地

  • scripts/13_render_only.py:所有源必须 published_at IS NOT NULL AND published_at >= cutoff,删除 fetched_at 兜底
  • scripts/13_render_only.py:obsidian 额外要求 meta_json.created_at >= cutoff,缺 created_at 的旧行不可渲染
  • collector/obsidian_vault.py:按创建时间扫描,优先 st_birthtime,再 frontmatter created|date,再文件名日期;mtime 只入审计元数据
  • collector/industry_search.py:搜索结果必须抓原文发布时间,7 天内才写库,无发布时间/过期计入 stale_or_undated
  • publish-weekly:渲染前刷新普通信源、行业搜索、obsidian

v1.18.2 已落地

  • classify.classify_industry 改成 5 角色章节(替换 v1.17 旧章节链)
  • weekly.html.j2 支持 5 章节渲染并过滤空章节
  • classify.SECTION_KEYWORDS 维护 5 个章节关键词表
  • SPEC_ITEM_PIPELINE.md §1.22 / §1.61 约束总结失败行为
  • classify.has_geo_vendor_marketing 剔除 GEO 厂商营销稿(榜单/推荐/排名/选型/报价/获客/方案/自夸)
  • scripts/13_render_only.py 门禁剔除空摘要、非中文摘要、疑似原文截断摘要、含 U+FFFD 编码失败字符、GEO 厂商营销稿摘要

v1.19 已落地

  • obsidian_vault.SUBDIRS["raw/wechat"] 标记 internal_brief=True,元数据写 meta_json.internal_brief=true
  • scripts/13_render_only.py 计算 source_weight:internal_brief 3.0 / obsidian 2.0 / wechat_oa 1.5 / 其余 1.0;geo_score *= source_weight 后按降序截断
  • obsidian 内参板块上限 25,非内参板块保持 12
  • 质量门槛:标题 ≥ 10 字、正文 ≥ 300 字、中文占比 ≥ 30%(任一不达标即剔)
  • obsidian 标题提取跳过裸 URL 行(公众号转载首行是 mp.weixin.qq.com URL)

v1.19 拒绝低质量内容

跑完 publish-weekly 后若 ✅ 强 GEO 相关: N 条(N<v1.18.2 上限),正常。说明搜索引擎本周质量不达标,obsidian 内参数就是本周可发条数。不要手动放宽门禁去填充;那会拉低周报整体质量。

详细见 references/sections.md + references/constraints.md。

Examples

Example 1: 完整跑本周周报 + 推草稿箱

$ cd /Users/apple/Downloads/User/geo-report
$ uv run python3 -m geo_report.cli publish-weekly --parts 1 --per-section-cap 12

📰 渲染 weekly.html (2026-09-19)
✂️  拆分 (1 篇,每板块 ≤ 12 条)
📤 推送草稿箱
  ✅ part1: draft_id=kiuyle4KZHC7JKxpTQssM...

Example 2: 只渲染不推送

$ uv run python3 -m geo_report.cli publish-weekly --skip-push --parts 1

输出 data/publish/liusheng_geo_<DATE>_zhili_part1.html,不调 push.py。

Example 3: 单独校验产物

$ node ~/.minimax/skills/zhiligeoreport/scripts/validate-weekly.js \
    data/reports/liusheng_geo_2026-09-19_inline.html

=== 校验 .../liusheng_geo_2026-09-19_inline.html ===
[OK] 字节 120006 ≤ 65536
[OK] 中文字 18055 ≥ 18000
[OK] 无 <style> 块
[OK] 板块数 5 合理
[OK] 条目数 59
Skills enregistrées