公众号文章批量分析
版本:v1.1.0 · 作者:零一数科
一批历史文章一次评完:清单确认 → 整批提交 → 排行表 → 按需下钻 → 可选汇总报告。
评分、排行、汇总、报告渲染全部在远端服务完成。脚本 scripts/wx_analyze.py 负责全部 HTTP 调用,
接口说明见 references/api.md。你的职责是:把文件夹/链接整理成清单、在交互节点等用户确认、
把服务端返回的排行与结论讲给用户听。
执行流程
- 读配置(任何命令之前先做):读技能目录下
config.json;文件不存在就把包内config.json.example复制成config.json再读(模板里BASE_URL已是生产地址https://service.lingyishuke.com,一般不用改,只需补LY_API_KEY)。若config.json里BASE_URL仍是旧地址https://claw.lingyishuke.com/services,就地改成新地址——域名已迁移,且config.json优先级高于config.json.example,升级新包不会自动改它。 - 取 API Key:读技能目录下
config.json的LY_API_KEY(回退环境变量)。缺失按「鉴权」引导获取写入。BASE_URL同文件配置(生产地址https://service.lingyishuke.com),缺失时脚本退出码 2。 - 输入判定与清单确认:见「节点 1」「节点 2」,用户确认清单前不提交。
- 扣点确认:告知「本次批量评分预计扣 篇数×20 点(如 8 篇约 160 点),实际扣点以服务端为准」,等用户明确同意;账号直连模式按 count 计(预计扣点 = count×20,如 count=10 约 200 点);
--task-id恢复轮询不重复扣点,跳过本步。 - 提交 + 轮询:
batch submit(建任务与轮询一体,进度打在 stderr)。 - 讲排行:输出排行表与失败/拦截列表(见「节点 3」)。
- 下钻:用户点名某篇时
batch article --seq N(见「节点 4」)。 - 汇总报告:整批只问一次「要生成汇总 HTML 报告吗?」,确认后
batch report。 - 收尾:告知实际扣点(
WX_ANALYZE_POINTS_USED)与报告路径。
脚本定位(任何命令之前先做这一步)
后文命令里的 "$SKILL" 指本技能的安装目录。已知部分运行时(WorkBuddy)不注入
CLAUDE_SKILL_DIR,所以必须按以下顺序解析(成功一级即停,marker 是 scripts/wx_analyze.py):
SN=wx-batch-analyze
SKILL=""
if [ -n "$CLAUDE_SKILL_DIR" ] && [ -f "$CLAUDE_SKILL_DIR/scripts/wx_analyze.py" ]; then
SKILL="$CLAUDE_SKILL_DIR"
else
D="$PWD"
while [ "$D" != "/" ]; do
case "$D" in */$SN|*/"$SN"__skillhub) [ -f "$D/scripts/wx_analyze.py" ] && { SKILL="$D"; break; };; esac
D=$(dirname "$D")
done
if [ -z "$SKILL" ]; then
SKILL=$(find "$HOME/.claude" "$HOME/.codebuddy" "$HOME/.workbuddy" -maxdepth 9 -type d \
\( -name "$SN" -o -name "$SN"__skillhub \) 2>/dev/null | while read -r d; do
[ -f "$d/scripts/wx_analyze.py" ] && echo "$d"; done | head -1)
fi
fi
[ -n "$SKILL" ] && echo "SKILL=$SKILL" || echo "SKILL_DIR_UNRESOLVED"
打印 SKILL_DIR_UNRESOLVED 时:如实告诉用户无法定位技能安装目录并停止。
绝对禁止:猜路径、自行重写脚本逻辑、绕过脚本直接拼 HTTP 请求。
config.json 固定读技能目录,报告默认写到当前工作目录。
鉴权
API Key 取技能目录下 config.json 的 LY_API_KEY 字段,回退环境变量 LY_API_KEY。
脚本请求头使用 Authorization: <api_key>,裸 key,不带 Bearer。config.json 形如:
{ "LY_API_KEY": "你的密钥", "BASE_URL": "https://service.lingyishuke.com" }
- 检查是否已有 key。 读
config.json;没有则看环境变量。任一有值即视为就绪。 - 缺失则引导用户获取。 提示用户前往 https://claw.lingyishuke.com/webapps/01claw-auth/index.html?source=workbuddy 获取 API Key 并发给你。拿到前不要运行脚本。
- 记录用户发来的 key。 写入
config.json的LY_API_KEY字段(保留其它内容),该文件已被.gitignore忽略。 - 鉴权失败(退出码 3)时。 引导用户重新获取并覆盖写入,不要反复用失效 key 重跑。
SSL 证书错误(CERTIFICATE_VERIFY_FAILED 等)可设 LY_SKIP_SSL_VERIFY=1 后重试,仅限受控环境临时使用。
工作流 · 交互节点
节点 1 · 输入判定
支持三种批量形态:
-
一个本地文件夹:用 Glob 对该文件夹做仅顶层、不递归扫描(
*.md、*.txt、*.docx三种全收)。检测到子目录时在清单中提示"检测到子目录 {名},如需分析其中文章请单独指定该子目录路径再跑一批",不自动递归。其他扩展名列为"已跳过(不支持的文件类型)"。 -
2-10 个 mp.weixin.qq.com 链接:逗号或换行分隔。超过 10 个直接提示"一次最多支持 10 个链接,检测到 {N} 个,请分批提交",不处理任何一个。
-
公众号名字/账号(账号直连):用户只给了公众号名字(如"评一下XX公众号最近的文章")时,先搜索候选账号:
python3 "$SKILL/scripts/wx_analyze.py" search --keyword "公众号名字" [--page 1]把 stderr 里的候选表转成 Markdown 表格完整展示给用户(列:序号/名称/主体/类型/粉丝/周更/均阅/可直连/ghid,「可直连」列不得省略),【交互节点】必须等用户确认是哪个账号——即使只有一个候选或第一个看起来就是,也不得擅自代选。退出码 7(无结果)时请用户换关键词或改用文件夹/链接方式。
某个候选能不能直接用,判据只有「可直连」列一个(服务端字段
direct_available):✓ 就取该账号的ghid与name提交。ghid形如wxid_...而不是gh_...是正常可用的,不得因为前缀不对就自行判为不可用。篇数默认 10(用户可指定 2-20),进入扣点确认后提交(命令见「节点 3」)。账号直连模式跳过文件清单确认,候选账号确认即为本形态的清单确认。选中的候选「可直连」为 ✗ 时走「节点 1b」,不要就此结束。
只给了 1 个链接时:交给 wx-article-score 单篇链路用 score submit --url 直接提交(服务端会抓取正文,无需用户粘贴),或补足到 2 个链接以上再走本技能。单篇粘贴文本 / 单个本地文件同样属于 wx-article-score 的范围。
节点 1b · 候选不可直连时的降级(两条出路,效果等价)
用户选中的候选「可直连」是 ✗,或整页候选全是 ✗(脚本会在 stderr 追加提示)时——这不是死路,绝不允许回一句"账号直连不可行"就结束本轮。✗ 只说明上游账号记录残缺(缺 ghid),与这个号本身能不能分析无关。把下面两条出路一起摆给用户,请他选一条:
-
换更具体的关键词重搜:把关键词补完整再跑一次
search(例如「深圳地铁」→「深圳地铁运营」),换到一个「可直连」为 ✓ 的候选,然后照原流程用--account-ghid提交。 -
请用户发一篇该号的文章链接:话术形如「这个号的记录里缺直连标识,你把它任意一篇推文的链接发我就行,效果一样」。拿到链接后改用
--account-url提交,服务端据此反查账号并拉取同样的历史文章:python3 "$SKILL/scripts/wx_analyze.py" batch submit --account-url 'https://mp.weixin.qq.com/s/xxxx' \ --account-name '公众号名字' --count 10
两条出路产出完全一致——都是服务端拉该号最近 N 篇走同一评分流程,扣点口径也相同。不要把 --account-url 说成"降级方案"或"效果打折",它只是换了个找到这个号的入口。--account-ghid 与 --account-url 二选一,同时给出脚本直接退 2;链接必须是 mp.weixin.qq.com 域名。
节点 2 · 清单确认(必须等确认)
向用户完整列出后等待明确确认(如"开始"/"继续")才提交,不得跳过或默认确认:
- 识别到的文章文件 / 链接列表;
- 跳过项及原因;
- 预估篇数。
两条数量规则:
- 预估超过 40 篇(软性阈值)时追加提示:"检测到 {N} 篇文章,数量较多,建议确认是否继续或改为分批处理"——不强制阻断。
- 服务端单次任务上限 20 篇:超过 20 篇须拆成多次
batch submit提交,每次提交前都单独走一遍扣点确认。
用户要求剔除个别文件/链接时,据此更新清单再确认。
节点 3 · 提交、轮询与排行表
# 文件夹场景:把清单里的文件逐个传给 --files(脚本读文件并抽文本上传,主对话不读正文全文)
python3 "$SKILL/scripts/wx_analyze.py" batch submit --label "历史文章" --files '文章A.md' '文章B.docx' ...
# 链接场景
python3 "$SKILL/scripts/wx_analyze.py" batch submit --label "对标链接" --urls 'https://mp.weixin.qq.com/s/...' ...
# 账号直连场景(ghid/name 来自 search 结果、且已经用户确认;「可直连」为 ✓)
python3 "$SKILL/scripts/wx_analyze.py" batch submit --account-ghid 'gh_xxxx' --account-name '公众号名字' --count 10
# 账号直连兜底场景(候选不可直连,用户给了该号任意一篇文章链接;与 --account-ghid 二选一)
python3 "$SKILL/scripts/wx_analyze.py" batch submit --account-url 'https://mp.weixin.qq.com/s/xxxx' --account-name '公众号名字' --count 10
批量评分较慢(默认 --max-wait 1200 秒);超时(退出码 124)用 batch status --task-id <id> 恢复轮询,不重复扣点。轮询进度({done}/{total})打在 stderr,可转述给用户。
终态后读分隔符之间的 JSON,在同一次响应中输出:
- 排行表:列为「序号 / 标题 / 总分 / 等级 / 最弱维度 / 人设检查」,按
ranked[]顺序逐行取seq/title/total_score/grade/weakest_dimension/persona_status(人设检查显示 ✓/✗)。序号列取seq——它是下钻时--seq要用的值。 - 分布一句话:按
distribution概括等级分布。 - 纪律版本检查:
discipline_consistent为false时,先在表格上方输出警示横幅——"⚠️ 本批次混入了多代评分纪律的产物,跨代分数与排名不可直接比较,建议对旧版本产物重新评分后再对照"——并给表格追加「纪律版本」一列(取各项discipline_version);为true时不加列、不输出横幅。 - 失败与拦截:
failed[]非空时列出"以下 {M} 篇因故跳过:{标题或链接}({原因})";stderr 提示过被拦截的链接(blocked_urls)时,向用户转述:"以下链接被拦截,建议改用粘贴正文重新提交该篇"。
节点 4 · 下钻某一篇
用户点名排行表中的某个序号后:
python3 "$SKILL/scripts/wx_analyze.py" batch article --task-id <id> --seq 3
输出该篇的七维表(列「维度 / 分数(/10) / 区间 / 证据 / 升档差距」,label/score/band/evidence/next_tier_gap 逐字引用)与诊断要点。下钻不额外扣点。
批量链路的下钻不含改写建议;用户想要某篇的深度改写(备选标题/重写开头/结构大纲)时,引导把该篇正文交给 wx-article-score 单篇链路重新提交(会再扣 20 点,需再次确认)。
节点 5 · 汇总报告(整批只问一次)
排行输出后固定问一次:"要生成汇总 HTML 报告吗?"——不逐篇询问;回答"不要"直接结束,不追问第二次。确认后:
python3 "$SKILL/scripts/wx_analyze.py" batch report --task-id <id> [--out 目录或文件]
报告为服务端渲染的单文件自包含 HTML,断网可打开。
结果讲解边界
-
长图文/漫画类提示:若结果里
meta.char_count很小(如 <300),先向用户说明这篇正文以图片为主、可提取文字极少,文本维度的评分只针对文字部分、参考意义有限——不要把低分直接当作内容质量结论。 -
只讲产物字段:排行表、分布、下钻的七维表与诊断,全部逐字引用服务端返回。
-
用户追问「分数怎么算的」时只说:"7 个维度加权、每维证据定档、总分由服务端计算,evidence 与升档差距就是可直接复述的归因。"不展开权重数值与评分方法论细节。
-
不产出完整成稿;改写类需求引导走
wx-article-score。
输出交付
成功时 stdout 形如:
WX_ANALYZE_TASK_ID=<任务 ID>
WX_ANALYZE_POINTS_USED=<本次实际扣点,可能为空>
WX_ANALYZE_REPORT_FILE=<报告文件绝对路径>
=== WX_ANALYZE_RESULT_START ===
<结构化结果 JSON>
=== WX_ANALYZE_RESULT_END ===
- 讲结论:按「节点 3」讲排行,不把 JSON 原样丢给用户。
- 告知实际扣点:
WX_ANALYZE_POINTS_USED非空时说「本次任务实际扣除 {点数} 点」;为空时说「本次约扣 篇数×20 点(实际以服务端为准,可在 01Claw 账户查看)」。 - 告知报告查看方式:路径见
WX_ANALYZE_REPORT_FILE,可直接双击打开。
退出码处理
| 码 | 含义 | 处理 |
|---|---|---|
| 0 | 成功 | 按「输出交付」处理。 |
| 2 | 输入/配置错误 | 文件缺失或为空、篇数越界(<2 或 >20 篇、>10 链接、count 超出 2-20)、--account-ghid 与 --account-url 同时给出、--account-url 不是 mp.weixin.qq.com 链接、未配置 BASE_URL。改正后重试,任务未发起不扣点。 |
| 3 | 缺 key 或鉴权失败 | 按「鉴权」流程引导用户获取新 key 写入 config.json 再重试。不扣点。 |
| 4 | 发起失败,含点数不足 | 展示服务端 message;点数不足时引导用户前往 https://claw.lingyishuke.com/webapps/01claw-auth/index.html?source=workbuddy 充值。不扣点。 |
| 5 | 服务端把任务判为失败 | 转述 stderr 里的 error_message(如链接全部抓取失败);被拦截链接引导改用粘贴正文重提交。 |
| 6 | 网络 / 限流 / 服务不可用 | 告知网络原因失败,附 stderr 信息,询问是否重试。 |
| 7 | 完成但结果为空 | 没有任何一篇成功评出,建议检查输入文件或链接后重新提交;search 返回 7 表示没搜到该公众号,请用户换关键词或改用文件夹/链接方式。 |
| 124 | 轮询超时 | 任务可能仍在进行,附 task_id,用 batch status --task-id <id> 恢复轮询,不重复扣点。 |
未知状态不要自行判定失败;脚本会原样透出服务端状态,继续按轮询结果处理。
硬性要求
- 不得编造或改动任何分数与统计数字。 排行、分布、七维明细全部来自服务端返回。
- 报告一律来自服务端渲染。 唯一合法产出方式是
batch report;绝不自行用 Write 手写 HTML/CSS/图表。 - 不跳过交互节点。 清单未确认不提交;扣点未确认不运行;汇总报告整批只问一次。
- 被拦截的链接引导粘贴正文重新提交该篇,不尝试破解验证或换抓取姿势硬闯。
- 评分解释只用固定话术,不展开维度权重与方法论细节;不做全文代写。
- 账号搜索结果必须展示给用户确认后才能发起分析,绝不擅自选第一个。 候选表未经用户明确指认哪个账号,不得运行
batch submit --account-ghid;候选表必须带「可直连」列。 - 候选不可直连不等于做不了。 「可直连」为 ✗ 时按「节点 1b」给出两条出路(换更具体关键词重搜 / 用
--account-url提交文章链接),禁止只回一句"账号直连不可行"就结束。判断可用性只看「可直连」列,wxid_开头的 ghid 同样正常可用。
微信扫一扫