2940 words
15 minutes
blog-update skill 改进计划

blog-update skill 改进计划#

本文记录一次对 blog-update skill 的完整改进过程:从 implement-agent 过度压缩的根因诊断,到 prompt 重写方案,再到全文件回归检查与多张力修复。这是一套可复用的「单点修复 → 回归防漂移」方法论。

背景与症状#

blog-update skill 是为 fuwari 框架博客生成文章的 pi skill,主流程 8 步,三个 background 子代理分工:

Agent职责
implement-agent从 session context 生成纯 markdown 正文
merge-agent新内容 + 现有文件做多粒度合并
review-agent内容质量 + 格式门禁

症状:implement-agent 总是把对话信息压缩。一篇多步调试 + 代码 + 命令的技术长文,产出却退化成「这是解决方案」式的摘要。

前置确认:压缩发生在哪一环#

SKILL.md Step 3 的措辞是 “Extract content from the session related to the topic”。主会话直接从原始会话里 extract 相关片段透传给 implement-agent,没有预先摘要化。所以 implement-agent 是第一个有损环节,改它有效。如果 Step 3 本身就在压缩,那改 implement-agent 也白搭——这个前置假设必须先确认。

根因诊断:三个叠加信号把任务框成了”过滤+压缩”#

不是模型能力问题,是 prompt 本身把任务框成了「filter」而非「reconstruct」。三个信号叠加:

信号 1:任务框架是 “filter”,不是 “reconstruct”

prompt 通篇用 “Content to Preserve / Content to Filter” 二分法,模型读到的潜台词是「我的活儿是删东西」,于是倾向多删。更致命的是 Filter 清单里有几条恰恰是技术文最值钱的内容:

  • Error retry processes(错误重试过程)—— 调试叙事的核心
  • Temporary exploration attempts(临时探索)—— dead-end 路径有教学价值
  • Repeated explanations(重复解释)—— 常常是递进式澄清,不是冗余

把这些删掉,「我怎么把 bug 修好的」就退化成「这是解决方案」。

信号 2:Length recommendation: 500-3000 words 是硬天花板

有明确上限,模型一靠近就开始概括。技术长文(多步调试 + 代码 + 命令)忠实转录轻松破 3000。

信号 3:没有任何反压缩指令

没一句话说「不要概括/不要省略」。模型默认 summarization 行为就启动了。再加上 Output Format 示例只有两行 Content paragraph... More content...,进一步暗示「简短是常态」。

修复方案:A+B+C+D + 两条用户约束#

核心思路:把任务从「过滤压缩」重写成「忠实叙事重建」,只删纯噪声,其余全留。具体改 4 处,外加用户提的两条约束。

A. 重写任务定义(开头)

把「生成符合规范的博客」改为「忠实重构成可读技术正文,任务=叙事重建而非摘要压缩」,明确保留所有技术实质——代码、命令、配置、错误与排查过程、关键决策及其理由,只剔除纯社交噪声。

B. 砍窄 Filter 清单

Preserve 新增「临时探索/dead-end」「递进式澄清」「决策理由」——这三类原来在 Filter 里,是压缩的最大帮凶。Filter 从 6 条砍到 4 条;debug output 加了「但错误信息与关键诊断必须保留」的边界,避免一刀切删堆栈。

C. 删掉长度上限,改成无上限 + 反压缩硬约束

删掉 500-3000 words 上限,明确「无字数上限,完整保留所有技术实质是唯一标准,技术长文常见 3000–10000 字属正常」。列 4 条禁止压缩硬约束:禁止把多段解释压成一句话;禁止省略任何代码块/命令/错误信息;禁止用「等」「……」概括列表;禁止把不同步骤的讨论合并成一段。

D. 加输出前自检清单(强制穷举,防漏)

7 条逐项清单,含两条对称的反向检查:「有没有概括成一句话?(应为否)」vs「有没有为不压缩而塞进客套/离题?(应为否)」。模型在自检时同时面对两个方向的否命题,跑偏任一侧都会被自己否决。

用户约束 1:安全信息去敏

新增 “Desensitize — Mandatory” 段:key/token/密码/私有数据/真实用户名路径/邮箱手机 → 占位符;并约束「去敏不得导致删整段技术内容」——只替换字段值,不删段落。这条解决了去敏(改写敏感字段)和保真(不增删事实)的潜在冲突。

用户约束 2:反矫枉过正

不能为了避免压缩而走向另一个极端——照抄社交客套、保留离题、堆栈原样转储。把「反矫枉过正」落到 4 个具体行为上:不照抄客套、不保留离题、堆栈只摘关键行、可调整顺序补过渡句。「重建」≠「原始 chat-log 转储」。

两个平衡点的设计说明#

「去敏」和「保真」的冲突:去敏要求改写敏感字段,保真要求不增删事实。去敏段末加了「不得因去敏而删除整段技术内容」——只替换字段值,不删段落,两个约束不冲突。

「反压缩」和「反矫枉过正」的冲突:这是最容易跑偏的点。没有把「不要矫枉过正」写成一句泛泛警告,而是落到 4 个具体行为上。自检清单里做成对称对照,跑偏任一侧都会被自己否决。

语言一致性回归#

上一轮把 implement-agent.md 改成了中文。用户指出「语言一致 LLM 可以更好地理解,需要所有都用英文」。SKILL.md、merge-agent.md、review-agent.md 本就是英文,只有 implement-agent.md 是中文版,转回英文,保留全部 A+B+C+D + 去敏 + 反矫枉过正结构,同步到 ~/Blog-Update-Skill

全文件回归检查:避免漂移#

只改一个文件不够。改 implement-agent 后,review-agent / SKILL.md 之间可能产生新的张力。对全部 5 个文件做回归检查,发现 4 个真实问题 + 1 个文档漂移,按严重度分级。

🔴 C1 — review-agent 与 implement-agent 直接矛盾(诊断输出)#

文件表述
implement-agent Must Preserve”error messages and the full troubleshooting process”; “Tentative exploration / dead-end paths (have teaching value)“
review-agent Filter EffectivenessDebug Output | No test results or debug logs

implement-agent 被要求保留诊断输出和 dead-end 路径,review-agent 却把「有 debug logs」判为该过滤的残留 → review 会把 implement 正确保留的内容 FAIL 掉,触发 Step 4–6 无效循环。

修法:review-agent 这一行改为 Diagnostic Output,从「删除项」翻转为「存在项」:删除冗长堆栈垃圾,但关键错误信息和诊断行必须存在(do not treat troubleshooting narrative as noise)。

🔴 C2 — review-agent 的输入机制自相矛盾#

  • review-agent.md ## Inputcontent: <content to be reviewed>(内容作为入参传入)
  • SKILL.md Step 6:review-agent reads the file(读文件验证,这是「先写后 review」顺序约束存在的唯一理由)

两处对 review-agent 怎么拿内容描述不一致。如果 review 真是读文件,Input 里不该有 content 字段;如果 content 真传进去了,「先写后 review」的硬约束就失去意义(content 和文件可能不一致)。

修法(选前者,更符合现有「先写」约束的设计意图):review-agent.md Input 改为 file_path,加注「读 file_path 的磁盘实际内容,这是唯一真相源;不要 review 文本传入的内容」。

🟡 G1 — 去敏检查缺口(上轮改动未传播到 review-agent)#

implement-agent 现有 “Desensitize — Mandatory” 段,但 review-agent 的三个维度(Content Quality / Markdown Format / Filter Effectiveness)没有任何一项检查敏感信息是否泄漏。一个漏网的 API key 能过 review。SKILL.md Red Flags 只提到「File path contains sensitive information」(路径敏感),不覆盖内容泄漏。

修法:review-agent Filter Effectiveness 加一行 Sensitive Info:无泄漏的 key/token/密码/私有路径/个人数据,占位符一致使用。

🟡 D1 — --yes 非交互模式在 SKILL.md 中完全未文档化#

  • CLAUDE.md(mini-agent 项目说明):/blog-update --yes <topic_name>,“--yes flag enables non-interactive mode — skips Step 2 confirmations and writes through validator warnings instead of stopping”,mini-agent 的 handle_topic 自动调用依赖此行为
  • SKILL.md:grep 全文 零命中 --yes / non-interactive / validator warning

调用方(mini-agent)依赖一个 skill 文件里没写的契约。如果有人按 SKILL.md 实现,--yes 会被当成未知参数丢掉,Step 2 仍会停下来等确认,handle_topic 的自动流程就卡死。

修法:SKILL.md 新增 ## Non-Interactive Mode (--yes) 独立小节,用对比表明确 3 处差异:

StepInteractive default--yes mode
Step 2Pauses to ask user for tags/category, or to confirm auto-inferred topic/tags/categorySkips all confirmations; infers tags/category directly and proceeds
Step 6 review FAILLoops Step 4–6 (max 3 times)Still runs review-agent (for diagnostics/logging), but FAIL no longer triggers a revision loop — the last written content is kept as-is and the flow proceeds to Step 7. Review findings are reported to the user in Step 8 instead of blocking
Validator warningsStops on warningsWrites through warnings instead of stopping

关键设计决策:--yes 模式下 review-agent 仍然执行(输出在 Step 8 报告中呈现给用户),但 FAIL 不再触发 Step 4–6 循环——保留最后一次写入的内容直接进 Step 7。这样既不会让自动调用方卡死,又不丢质量信号。Step 6 主流程文本加了内联交叉引用 → Non-Interactive Mode,防止线性阅读者漏掉豁免语义造成漂移。同时在 Quick Reference 加了 Non-interactive 行。

次要项(不阻塞,记录备查)#

  • M1:review-agent PASS case 允许 [Optional: a brief one-line comment],SKILL.md Step 6 靠解析 PASS/FAIL 字符串做分支。若主会话用严格 == "PASS" 匹配,带注释的 PASS 会被误判 FAIL。建议明确「前缀匹配」或禁止注释。低风险。
  • M2:implement-agent 输出模板首行 ## Article Title(H2),而 frontmatter 的 title 才是文章标题;正文首段重复标题作 H2 在 fuwari 里略冗余。和 merge-agent 的 ## <section> 语义也混。非错误,可不改。
  • M3:merge-agent 无去敏意识。因 implement-agent 已预去敏,merge 只是重组现有内容,风险低;但若 existing_file 含历史未去敏内容,merge 不会发现。优先级低于 G1。

已确认无漂移的项#

  • 语言一致性:5 个文件全英文
  • Step 3 session_context 透传:SKILL.md 明确 “Extract content from the session related to the topic”,无预摘要化
  • 长度上限:implement-agent 已删 500-3000 words,merge-agent “More detailed preferred” 与之同向
  • frontmatter 生成权:SKILL.md Step 7 主会话生成,implement/merge/review 均声明不碰 frontmatter
  • 写操作归属:SKILL.md + 三个 prompt 均一致「写操作只在主会话」

修复落地与同步#

修复顺序:先改 review-agent.md(C1 + C2 + G1 一次性),再改 SKILL.md(D1)。修 SKILL.md 时一度把 Quick Reference 段落整个替换掉丢了表格——读回确认后补回,并在 Quick Reference 加 Non-interactive 行。给 Step 6 加了内联交叉引用,避免线性阅读时漏掉 --yes 的豁免语义。

验证两个文件最终状态后同步到 ~/Blog-Update-Skill,diff 确认两处文件完全一致。

同步收尾发现一个漂移隐患:~/Blog-Update-Skill/ 里同时存在 skill.md(旧文件,6412 字节,6 月 7 日)和 SKILL.md(当前文件,7747 字节)。源目录只有 SKILL.md,dest 却同时有大小写两份且内容不同——这正是刚做完回归检查要防的「漂移」。删除残留的小写 skill.md,dest 与源目录结构对齐。README.md / LICENSE / .git 是 repo 级文件(源 skill 目录本就没有这些),不算漂移,不动。

方法论小结#

这次改进的关键不在单点修复,而在两步:

  1. 先确认有损环节在哪一环——前置确认 Step 3 是否预摘要化,否则改 implement-agent 无效。
  2. 单点修复后必做全文件回归——改 implement-agent 后,review-agent 与它的矛盾(C1)、review-agent 自身输入机制矛盾(C2)、去敏缺口未传播(G1)、调用方契约未文档化(D1)都是单点改动的外溢。不回归就会留下新的隐性矛盾,比原问题更难查。

去敏与保真、反压缩与反矫枉过正,这两对天然冲突不能靠一句泛泛警告解决,必须落到具体行为清单 + 自检对称否命题,让模型在两个方向上同时被约束。

blog-update skill 改进计划
https://sgjki547.top/posts/blog-update-skill-improvement-plan/
Author
SGJki
Published at
2026-07-19
License
CC BY-NC-SA 4.0