mcpbeat

Adversarial Polish

jimliu/adversarial-polish

>- 多轮对抗式稿件打磨技能。通过"批评→改写→综合→盲评"循环,像学术同行评审一样反复打磨稿件直到收敛。所有中间产物(批评、改写、综合、评分)保存为独立文件,完整记录进化过程。当用户说"对抗打磨""反复打磨""深度打磨""多轮润色""盲评打磨""打磨到收敛""帮我把这篇稿子磨一磨""pressure polish""adversarial polish"时触发。也适用于用户说"这篇稿子很重要,帮我好好打磨"或"我需要更高质量的润色"等暗示需要超越单轮润色的场景。注意:如果用户只是要求普通润色,优先使用已有 polish 技能。本技能适合对质量要求极高、愿意花更多时间打磨的稿件。

4k tokens
context cost
the whole folder, loaded on every use
1
files
instructions only
0
copies elsewhere
how many repositories repackaged it
618
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/JimLiu/Illustrated-Agent-Skills --skill adversarial-polish

The instruction itself

10 sections, as written by the author

对抗式稿件打磨

用独立角色的对抗与盲评替代主观判断,让稿件在"批评→改写→综合→盲评"的循环中自然收敛到最优状态。

核心理念

单次润色的问题:模型要么过度迎合(你说改我就改),要么过度批判(为了批而批),要么过度折中(两边都不得罪)。结果是稿件被 prompt 的措辞而非内容质量所左右。

对抗式打磨的解法:把每个角色拆成独立视角,各自只看到必要信息,然后让盲评来决定谁赢。赢家成为新基准,循环直到没人能改得更好。


⚠️ 执行模型:Sub-Agent 隔离(核心机制)

对抗式打磨的一切价值都建立在上下文隔离之上。 如果所有角色共享同一个上下文窗口,模型会不可避免地受到前序角色输出的污染——稻草人的批评会让改写者过度迎合,综合者会偏向后看到的版本,评委会被改写说明暗示。这不是"注意力不集中"的问题,是架构层面的根本缺陷。

有 Sub-Agent 能力时(Claude Code / Cowork)—— 首选方案

每个角色必须作为独立的 sub-agent 生成(spawn)。 这是硬性要求,不是建议。

具体做法:

  • 稻草人 → spawn 一个 sub-agent,prompt 中包含:任务描述 + 当前版本 A 的文本 + 稻草人角色指令(见下文 prompt 模板)。不包含任何历史轮次的批评、改写、投票信息。
  • 改写者 → spawn 一个新的 sub-agent(在稻草人完成后),prompt 中包含:任务描述 + 当前版本 A + 稻草人批评报告 + 改写者角色指令。不包含综合者或评委的任何信息。
  • 综合者 → spawn 一个新的 sub-agent(在改写者完成后),prompt 中包含:任务描述 + "版本甲"和"版本乙"(A 和 B 随机打乱顺序标记)+ 综合者角色指令。不包含稻草人批评报告(综合者不应知道哪个版本是"被批评后改的")。
  • 三位评委同时 spawn 3 个独立 sub-agent(并行执行)。每个评委的 prompt 中包含:任务描述 + 三个版本(随机标记为 X/Y/Z,打乱顺序,去除所有末尾的改写说明和综合说明)+ 评委角色指令。三位评委之间完全独立,互不可见。

关键原则:

  • Sub-agent 只接收上面列出的信息,绝不多给
  • 稻草人、改写者、综合者是串行的(后者依赖前者输出)
  • 三位评委是并行的(互相独立,同时 spawn)
  • 每个 sub-agent 用完即弃,不复用

Sub-Agent Prompt 模板

稻草人 prompt:

你是一位挑剔的资深中文科技内容编辑。你的任务是审阅一篇文章,只找问题,不给修复方案。

## 任务描述
{task_prompt}

## 待审阅文章
{current_A_text}

## 你的职责
[...稻草人角色指令全文,见下方"角色 1"章节...]

请直接输出批评报告,不要输出任何前言。

改写者 prompt:

你是一位有能力的中文科技内容作者。你需要根据一份批评报告改写一篇文章。

## 任务描述
{task_prompt}

## 原文
{current_A_text}

## 批评报告
{strawman_critique}

## 你的职责
[...改写者角色指令全文,见下方"角色 2"章节...]

请输出完整的改写版本,不要输出任何前言。

综合者 prompt:

你是一位客观的中文科技内容编辑。你面前有同一任务的两个版本,需要取长补短合成最优版本。

## 任务描述
{task_prompt}

## 版本甲
{randomly_assigned_version_1}

## 版本乙
{randomly_assigned_version_2}

## 你的职责
[...综合者角色指令全文,见下方"角色 3"章节...]

请输出完整的综合版本,不要输出任何前言。

评委 prompt(每位评委相同模板,独立 spawn):

你是一位盲审评委。你需要从三个版本中选出最好的一个。你不知道这些版本的作者或来历。

## 任务描述
{task_prompt}

## 版本 X
{randomly_labeled_version_X}

## 版本 Y
{randomly_labeled_version_Y}

## 版本 Z
{randomly_labeled_version_Z}

## 你的职责
[...评委角色指令全文,见下方"角色 4"章节...]

请直接输出你的排名和理由,不要输出任何前言。

无 Sub-Agent 能力时(Claude.ai 网页版)—— 降级方案

Claude.ai 没有 sub-agent,所有角色在同一个上下文中执行。这意味着真正的上下文隔离无法实现。为了尽可能模拟隔离效果:

  • 每次切换角色前,明确声明"现在以 [角色名] 身份思考,只考虑以下信息:[列出可见信息]"
  • 严格只引用该角色"可见信息"范围内的内容
  • 评委阶段必须使用随机标签(X/Y/Z)并去除改写说明
  • 坦诚告知用户:在 Claude.ai 中执行时效果弱于有 sub-agent 的环境,因为上下文无法真正隔离。如果稿件非常重要,建议在 Claude Code 中运行本技能。

工作流程

第零步:准备工作

  • 获取稿件
  • 上下文中已有 → 直接使用
  • 用户上传文件 → 直接使用
  • 用户给出 URL → 使用 web_fetch 获取
  • 创建工作目录
   <文章目录>/adversarial-polish/
   ├── round-0/
   │   └── A-original.md          # 原始稿件
   ├── round-1/
   │   ├── strawman-critique.md   # 稻草人批评
   │   ├── B-rewrite.md           # 改写版本
   │   ├── AB-synthesis.md        # 综合版本
   │   ├── judge-ballots.md       # 三位评委投票
   │   └── round-summary.md       # 本轮总结
   ├── round-2/
   │   └── ...
   ├── evolution-log.md           # 全程进化日志
   └── final/
       ├── final-article.md       # 最终定稿
       └── polish-report.md       # 打磨报告
  • 确认任务 prompt
  • 向用户确认或自动生成一个清晰的"任务描述"(task prompt),作为所有角色的锚点
  • 示例:"将这篇关于 AI Agent 架构的技术博客打磨到可发布水平,目标读者是有一定技术背景的中文互联网用户"
  • 这个 task prompt 所有角色都能看到,是唯一的共享上下文
  • task prompt 中应包含写作风格要求(如有),比如目标读者画像、语言风格偏好、术语处理规范等
  • 保存原始稿件round-0/A-original.md

循环开始

每轮循环包含四个角色 + 一个收敛判断。

角色 1:稻草人(Strawman)

⚡ 执行方式:spawn 为独立 sub-agent(使用上方稻草人 prompt 模板)

身份: 一个挑剔的资深读者/编辑。

可见信息: 任务描述 + 当前版本 A(仅此而已,不看历史批评和修改)。

职责:

  • 只找问题,不给修复方案
  • 像同行评审一样严格,但对事不对人
  • 覆盖以下维度:
  • 结构:逻辑是否通顺?段落顺序是否最优?有没有多余或缺失?
  • 表达:有没有 AI 味?有没有废话?节奏感如何?
  • 读者体验:开头抓人吗?中段有没有走神点?结尾有力吗?
  • 信息密度:有没有灌水?有没有信息过载?
  • 说服力:论证逻辑有没有漏洞?有没有未支撑的断言?
  • 每个问题给出严重等级:🔴 致命 / 🟡 显著 / 🟢 轻微

输出格式:

# 稻草人批评报告 - 第 N 轮

## 总体印象(2-3 句话)

## 问题清单

### 🔴 致命问题
1. [具体位置] [问题描述]
2. ...

### 🟡 显著问题
1. [具体位置] [问题描述]
2. ...

### 🟢 轻微问题
1. [具体位置] [问题描述]
2. ...

## 稻草人总结
- 致命问题 X 个,显著问题 Y 个,轻微问题 Z 个
- 最关键的一个问题是:[...]

保存到: round-N/strawman-critique.md


角色 2:改写者(Author B)

⚡ 执行方式:在稻草人完成后,spawn 为新的独立 sub-agent(使用上方改写者 prompt 模板)

身份: 一个有能力的作者,接到了修改任务。

可见信息: 任务描述 + 当前版本 A + 稻草人批评报告。

职责:

  • 逐条审视批评,判断哪些有道理、哪些是吹毛求疵
  • 针对合理批评进行改写
  • 保留原文的优点和作者声音
  • 改写幅度取决于批评的严重程度:致命问题必须解决,轻微问题酌情处理

输出: 完整的改写版本(不是 diff,是完整文章)。

在文章末尾附上改写说明:

---
## 改写说明
- 采纳批评 N 条,忽略 M 条
- 主要改动:[列出 3-5 个关键修改]
- 忽略理由:[解释为什么某些批评不采纳]

保存到: round-N/B-rewrite.md


角色 3:综合者(Synthesizer)

⚡ 执行方式:在改写者完成后,spawn 为新的独立 sub-agent(使用上方综合者 prompt 模板)

身份: 一个客观的编辑,面前有两个版本,需要取长补短。

可见信息: 任务描述 + 版本 A + 版本 B(随机标记为"版本甲""版本乙",打乱顺序避免位置偏差)。

职责:

  • 逐段对比两个版本
  • 取每段更好的表述
  • 如果两个版本各有优劣,创造性地融合
  • 保持全文的一致性和连贯性

输出: 完整的综合版本。

在文章末尾附上综合说明:

---
## 综合说明
- 版本甲贡献:[哪些段落/表达来自甲]
- 版本乙贡献:[哪些段落/表达来自乙]
- 原创融合:[哪些地方做了创造性合并]

保存到: round-N/AB-synthesis.md


角色 4:盲评评委团(Judge Panel)

⚡ 执行方式:同时 spawn 3 个独立 sub-agent 并行执行(使用上方评委 prompt 模板)。三位评委之间完全隔离,互不可见。

身份: 三位独立评委,只关心"哪个版本最好地完成了任务"。

可见信息: 任务描述 + 三个版本(随机标记为 X/Y/Z,打乱顺序,隐去所有作者信息和改写说明)。

重要: 提交给评委的版本必须去掉末尾的"改写说明"和"综合说明",只保留文章正文。

评判标准:

  • 对任务的完成度(是否达到了 task prompt 的要求)
  • 读者体验(阅读是否流畅、抓人)
  • 信息密度与表达质量
  • 整体完成度(能否直接发布)

每位评委独立排名并给出理由,然后用 Borda 计分汇总:

# 盲评投票 - 第 N 轮

## 评委 1
排名:[X > Y > Z] 或其他顺序
理由:[2-3 句话]

## 评委 2
排名:[...]
理由:[...]

## 评委 3
排名:[...]
理由:[...]

## Borda 计分
(第一名 2 分,第二名 1 分,第三名 0 分)

| 版本 | 评委 1 | 评委 2 | 评委 3 | 总分 |
|------|-------|-------|-------|------|
| X    | ?     | ?     | ?     | ?    |
| Y    | ?     | ?     | ?     | ?    |
| Z    | ?     | ?     | ?     | ?    |

## 结果
- 胜出版本:[X/Y/Z](揭晓为 [A/B/AB])
- 得分差距:[大/小/微弱]

保存到: round-N/judge-ballots.md


收敛判断

每轮结束后,检查收敛条件:

  • 如果 A(原版)胜出 → streak 计数 +1
  • streak = 2 → 收敛! 循环结束
  • streak < 2 → 继续下一轮(A 不变)
  • 如果 B 或 AB 胜出 → streak 归零,胜出版本成为新的 A,继续下一轮

安全阀: 最多循环 4 轮。如果 4 轮后仍未收敛,取历史最高分版本作为最终结果。

每轮结束生成轮次总结:

# 第 N 轮总结

- 稻草人发现:🔴 X 个 / 🟡 Y 个 / 🟢 Z 个
- 改写者采纳:M 条批评
- 盲评结果:[版本] 胜出(Borda 分 X 分)
- 收敛状态:streak = N / 未收敛,继续
- 当前最佳版本:[来源说明]

保存到: round-N/round-summary.md


循环结束后

生成进化日志

汇总所有轮次的演变过程,保存到 evolution-log.md

# 稿件进化日志

## 任务描述
[task prompt]

## 进化轨迹

### 第 1 轮
- 稻草人核心批评:[...]
- 改写关键改动:[...]
- 盲评结果:[版本] 胜出
- streak: 0 → N

### 第 2 轮
...

## 收敛分析
- 总轮次:N
- 收敛方式:[A 连续两轮胜出 / 达到最大轮次]
- 最终版本来源:[第 X 轮的 A/B/AB]
- 关键进化点:[稿件在哪些方面有了质的提升]
生成最终文件
  • 最终定稿 (final/final-article.md):干净的文章正文,不含任何说明
  • 打磨报告 (final/polish-report.md):
  • 原文 vs 定稿的关键差异摘要
  • 主要改进点(3-5 个)
  • 每个改进的具体对比示例(原文 → 定稿)
  • 质量评估:
  • H (Hook):标题和开头能否抓住读者?
  • K (Knowledge):读完有没有收获?信息密度够不够?
  • R (Resonance):有没有共鸣点?能否引发"我也这么想"?
输出到 outputs/

将以下文件复制到输出目录:

  • final-article.md — 最终定稿
  • polish-report.md — 打磨报告
  • evolution-log.md — 进化日志

使用 present_files 展示最终定稿和打磨报告。


重要原则

角色隔离(最重要的原则)

有 sub-agent 时:每个角色必须 spawn 为独立 sub-agent。 这是对抗式打磨的根基,详见上方"执行模型"章节。

每个 sub-agent 只接收其"可见信息"范围内的内容:

  • 稻草人只看到任务 + 当前版本,不考虑"怎么修",只管"哪里有问题"
  • 改写者看到任务 + 当前版本 + 批评,可以不同意批评,不必全盘接受
  • 综合者只看到任务 + 两个版本(随机标签),不知道谁是原版谁是改写版
  • 评委只看到任务 + 三个版本(随机标签 + 去除说明文字),不知道任何版本的来历
  • 三位评委之间完全隔离,并行 spawn,互不可见

保留作者声音

所有角色都必须尊重原文的核心观点、态度和风格。打磨是优化表达,不是重写内容。改写者和综合者首先忠于原作者的意图。

诚实评判

评委必须真实评判,不能"为了显示价值而选新版本"。如果原版确实更好,就选原版。真正好的内容能经受住对抗式检验。

中间产物全部保留

每个角色的每次输出都保存为独立文件。这不仅是为了可追溯,也让用户可以在任何阶段介入:

  • 觉得稻草人的某条批评不合理?可以干预
  • 觉得某个中间版本反而更好?可以提取
  • 想了解稿件是怎么一步步变好的?看进化日志

执行策略

快速模式 vs 完整模式

如果用户明确说"快速打磨"或稿件较短(< 1000 字),可以缩减:

  • 评委从 3 位减到 2 位
  • 最大轮次从 4 减到 2
  • 收敛条件从 streak=2 降到 streak=1

默认使用完整模式。

用户介入点

循环中的每一轮结束后,简要向用户报告本轮结果。默认自动继续下一轮,除非:

  • 用户说"停""暂停""我看看"
  • 用户说"用第 X 轮的 B 版本"
  • 用户对某条批评有意见

进度提示

每轮开始时告诉用户当前状态:

> 第 2 轮开始(streak=0,上轮 AB 综合版胜出,已替换为新基准)

> 稻草人正在审视新基准…


注意事项

  • 如果稿件质量已经很高,可能第 1 轮就收敛,这是正常的——说明稿件经受住了对抗检验
  • 如果 4 轮后仍未收敛,说明可能存在风格偏好分歧而非质量问题,此时应输出最高分版本并在报告中说明

How to use it

Copy the folder

Take jimliu/adversarial-polish from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.