# Ielts Writing Coach

> Use when the user wants an IELTS essay corrected, graded, scored, or rewritten — Task 1 (Academic 图表/流程/地图, General 书信) or Task 2 (议论文). Triggers include: 雅思作文批改, 帮我改雅思作文, 雅思大作文, 雅思小作文, 作文估分/打分, IELTS Writing Task 1/2, band score, essay feedback, 雅思写作润色, 批改报告. Produces a criterion-by-criterion band estimate backed by sentence-level evidence, an error-pattern breakdown, targeted before/after rewrites, and a shareable Markdown report.

- Skill: `unrealinux/ielts-writing-coach` (Agent Skill, multi-file: 9 files)
- Install (CLI): `npx skillmds@latest add unrealinux/ielts-writing-coach`
- Raw SKILL.md: https://api.skillmd.com/api/skills/unrealinux/ielts-writing-coach/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- License: MIT
- Author: unrealinux (https://skillmd.com/u/unrealinux)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/unrealinux/ielts-writing-coach

---


# IELTS Writing Coach — 雅思作文批改

对雅思写作 Task 1 / Task 2 做**可复核、有证据、可执行**的批改：给出四项分项预估分与总分、逐句错误定位、定向改写、以及一份可分享的 Markdown 报告。

## 0. 核心原则（不可违背）

1. **证据优先**：每一条扣分和每一条表扬都必须引用原文的具体句子或短语（`§段落号` + 原文片段）。禁止"整体不错""词汇较丰富"这类无证据评价。
2. **不编造**：不得虚构题目要求、不得替考生补写他没写的论点、不得声称这是官方评分。报告开头必须写明 "预估分，非官方成绩"。
3. **分数要克制**：AI 评雅思作文最常见的失败是给分虚高。默认校准：未经专门训练的考生作文绝大多数落在 **5.0–6.5**；给出 Band 7 必须有明确证据；Band 8+ 在限时作文中属罕见，除非四项都达标。用 `references/band-descriptors.md` 的"该档位门槛"逐条核对，不要凭语感给分。
4. **批改 ≠ 代写**：改写只针对**问题句子和段落**，并说明改动理由。不要重写整篇后让用户照抄——那会掩盖他自己的错误模式。
5. **中英分工**：诊断、解释、建议用**中文**；原文引用、改写的英文句子、范文段落、词块保留**英文**。除非用户要求全英文。
6. **Task 1 与 Task 2 的评价体系不同**：Task 1 评的是 Task Achievement（概述 + 数据选取），不是"论证"；Task 2 评的是 Task Response（立场 + 论证）。不要交叉套用。

## 1. 流程

### Step 0 — 收集必要信息（缺什么问什么，一次问完）

必需信息：

| 项 | 说明 | 缺失时的处理 |
|---|---|---|
| 题目原文 | 完整题干 | **必须索取**，否则无法判断偏题与 Task Response |
| 作文正文 | 全文 | 必须 |
| 任务类型 | Task 1 Academic / Task 1 General / Task 2 | 从题干推断，推断后先声明"我按 Task 2 处理" |
| 目标分 | 如 6.5 / 7.0 | 缺失时默认按"从当前水平提到 0.5 分"给建议 |
| 是否限时 / 是否允许查词典 | 影响对错误的苛刻度 | 缺失时按限时作文处理（更宽容的 fluency 判断，更严格的时间管理建议） |

如果用户只给了作文没给题目：**先索取题目**。如果用户坚持不给，就按"无法评估 Task Response/Task Achievement"处理，只给 CC / LR / GRA 三项，并明确标注 TR/TA 未评。

如果用户一次性粘贴了作文和题目，**不要反问**，直接开始，在报告里列出你的假设。

### Step 1 — 客观预分析（先跑工具，再做判断）

把作文存成 `.txt` / `.md`，**并把题目也传入**，运行：

```bash
python3 scripts/analyze_essay.py <essay-file> --task 2 \
  --prompt <prompt-file-or-text> --out stats.md
```

> `--prompt` 不是可选项。**偏题（TR-OFF）无法从作文本身看出来**——一篇跑题的作文往往语言干净、论证充分（工具会显示"✅ 论证支撑度未触发警报"）。只有把题干传进去，工具才能比对题干的争议轴，检查题型要求的写作动作（是否给出立场、是否给出比较结论），并在关键词覆盖率过低时发出偏题警告。**没有题目时不要评 TR / TA。**

拿到客观数据：字数、句数、平均/最长句长、段落词数分布、词汇丰富度（TTR）、高频内容词、连接词使用与堆砌（**以连接词开头的句子占比**比总密度更能区分机械与自然）、口语化词、拼写/搭配启发式告警，以及两节专项：

- **第 7 节 论证支撑度**（证据标记 / 举例标记 / 模糊限制语 / 具体细节 / 空泛表达）
- **第 8 节 题目相关度**（题型识别 / 要求的写作动作 / 题干关键词覆盖与缺失词）

**第 7 节是任务相关的，必须用对**：

- **Task 2** → 第 7 节是「论证支撑度」（证据标记 / 举例 / 模糊限制语 / 具体细节）
- **Task 1 Academic**（`--task 1`）→ 第 7 节是「Task 1 专项检查（图表）」：overview 是否存在、纯报数比例、比较类表达、观点/原因泄漏、时态混用
- **Task 1 General Training**（`--task 1gt`）→ 第 7 节是「Task 1 专项检查（书信）」：称呼、结尾敬语、称呼与敬语是否匹配、语域

**书信不是图表，两者绝不能混用判据**：书信没有 overview 可缺，也没有数据可比。套用图表标准会告诉写信的人"TA 上限 5.0"，而那是假的——这是实测踩过的坑。书信最致命的失分点是**三个 bullet 是否全覆盖**，工具判不了，必须对照题干人工确认。

**在 Task 1 里绝不能套用论证支撑度**：数字就是任务本身（不是"证据"），而"没有举例、没有因果"恰恰是正确的。用错会得出与事实相反的结论——这是实测踩过的坑。Task 1 的硬性判据是 **overview 缺失 → TA 上限 5.0**。

三个轴必须分开读：

| 轴 | 看第几节 | 决定什么 | 典型失败模式 |
|---|---|---|---|
| **错误轴** | 第 5 节 | GRA、LR 的**下限** | 语法错误密集（样例：16 处/20 句） |
| **支撑轴 / Task 1 专项** | 第 7 节 | TR（Task 2）或 TA（Task 1）的**上限** | 论证空洞；或 Task 1 缺概述、机械罗列 |
| **相关轴** | 第 8 节 | TR 的**上限** | 语言与论证俱佳但答了另一个问题 |

三种失败模式互相独立，可以叠加。**如果错误轴干净但支撑轴或相关轴告警，不要因为语言好就抬高总分**——这恰恰是最容易被放过、也最可惜的情况。

这些数据**用于定位**（哪句 48 词过长、哪个词出现 9 次、连接词是否机械），**不用于直接给分**。字数不足是硬性扣分项：

- Task 1 < 150 词 → Task Achievement 直接降到 Band 5 以下区间
- Task 2 < 250 词 → Task Response 直接降到 Band 5 以下区间

### Step 2 — 逐项评分

四项各占 25%，各自独立打分（可到 0.5）：

- **Task 2**：Task Response (TR) / Coherence and Cohesion (CC) / Lexical Resource (LR) / Grammatical Range and Accuracy (GRA)
- **Task 1**：Task Achievement (TA) / CC / LR / GRA

总分 = 四项平均，**四舍五入到最近的 0.5**；恰好 .25 上进到 .5，恰好 .75 上进到下一个整分（例：6.5+7.0+6.0+6.5=26.0/4=6.5；6.5+6.5+6.5+7.0=26.5/4=6.625→6.5；7.0+7.0+6.5+7.5=28/4=7.0）。

每项打分必须走完"判定三问"，并在报告中写出：

1. **该档位的门槛是什么**（查 `references/band-descriptors.md`）
2. **本文达标与否的证据**（引用原文）
3. **离上一档差什么**（一条可执行动作，不是"多练习"）

详细评分流程与防虚高校准清单见 `references/scoring-protocol.md`。

### Step 3 — 建立错误清单

用统一错误代码标注（完整表见 `references/error-taxonomy.md`），逐条给出：位置 → 原文 → 代码 → 修改后 → 一句话原因。

```
GRA-SVA 主谓一致 | GRA-TENSE 时态 | GRA-ART 冠词 | GRA-PLU 名词单复数
GRA-PREP 介词 | GRA-FRAG 残句 | GRA-RUN 粘连句/逗号拼接 | GRA-WO 语序 | GRA-CLAUSE 从句
LR-COLL 搭配 | LR-WF 词形 | LR-WW 选词 | LR-SP 拼写 | LR-REG 语域/口语化 | LR-REP 重复
CC-REF 指代 | CC-LINK 连接词误用/缺失 | CC-PARA 分段 | CC-PROG 信息推进
TR-OFF 偏题 | TR-PART 漏答要点 | TR-UNDEV 论证不足 | TR-GEN 空泛
TA-OVER 缺概述 | TA-DATA 数据误读/错报 | TA-FEAT 关键特征遗漏
```

**每一处缺陷只归一个评分项**（`references/scoring-protocol.md` §七）。一个逗号拼接会同时表现为
标点错误、指代不清、逻辑被掩盖——如果三项都拿它当降档证据，一个错误被算了三次，
**四项各被压低一点，总分可能少 0.5**。这和高估一样有害，而且更隐蔽，因为报告看起来"证据充分"。

判断方法：对每处跨项引用问——**"把归属项的缺陷改对之后，另一项的指控还成立吗？"**
成立则属独立缺陷（同句多缺陷是允许的）；不成立则是同一缺陷，只能归一处。

凡被多项引用的引文，都要在报告的 `## 缺陷归属审计` 里声明归属；
交付前用 `python3 scripts/audit_report.py <报告>` 自查，未声明会返回非 0。

**注意审计的覆盖边界**：审计器只覆盖**成句引用**。如果报告的扣分证据主要是表格或短引文（例如「这个词一次都没出现」这类基于缺失的指控），审计会报「覆盖不完整」——**那是「没查」，不是「通过」**，必须在回复里说清并请用户人工核对。

批改顺序：**先分类，再计数，最后归因**。错误清单之后必须给出**错误模式小结**（例如："全文 11 处冠词错误集中在不可数名词和首次提及，说明是冠词系统问题而非笔误，建议按 `a/the/∅` 三类专项处理"）——模式比单点更有价值。

### Step 4 — 定向改写

只改**最影响分数的 3–6 处**，按优先级：

1. 导致失分的结构性句子（跑题句、无支撑的断言、粘连长句）
2. 四项评分标准各自最弱的一个点
3. 高频错误模式中的代表性句子

每组给出：

```
原文 (¶2)：The government should do something about this problem because it is very important.
问题：TR-UNDEV 空泛断言（do something / very important 无具体内容）；LR-WW 口语化
改写：Governments should therefore prioritise early-childhood nutrition programmes, since
      the cognitive gains they produce in the first five years translate into measurable
      improvements in later academic performance.
改动说明：把"应该做点什么"落到具体政策；把 very important 换成可验证的因果链；
         用 therefore 承接上句，避免另起炉灶。
```

如果用户希望看整篇高阶示范，**只示范一个主体段**（不是全文），并在示范前声明"这是演示目标分段的写法，不要背，要学结构"。

### Step 5 — 输出报告

按 `templates/report-template.md` 生成报告，写入文件（默认 `<workspace>/ielts-reports/<日期>-<任务类型>.md`），并在对话里给出**精简摘要**（分数卡 + 前三条最优先改进）。

报告是交付物：写完必须调用 `present` 让用户能直接打开分享。

**如果用户想"在原文上逐句看批注"**（学生常见需求：想在 Word 里点开批注、或打印给老师看），从**已有的报告**生成带真实 Word 批注的 `.docx`：

```bash
python3 scripts/report_to_docx.py --essay <作文.txt> --report <报告.md> --out <输出.docx>
```

它把「错误清单」变成**真实的 Word 批注**（锚定在原文词句上）、把「句子升级」的改写作为斜体段落插在对应段落后，并附评分页。**报告是唯一数据源——不需要重写任何内容。**

**Word 批注用「页边标签」而不是诊断句**：每条批注首行是短英文标签（`Articles · 冠词`、`Collocation · 搭配`），
第二行是修改（`→ pay attention to`），理由以小字放在最后。标签的价值在**可扫读**——页边扫一眼看到
`Articles` 出现五次，比读五句解释更能让人意识到这是系统性问题。评分页另附**标签统计表**（按批注数排序）。
映射由 `scripts/ielts_codes.py` 统一维护，**不要在报告里自造标签**。

注意：标签统计表数的是**已锚定的页边批注数**（同一处合并计一次、未锚定的不计入），
与报告里的「按代码统计」（错误总数）可能不同。这是有意的，docx 里已写明。

**输入自相矛盾会被拦下**：如果 `--task` 与题干不符（例如 `--task 1` 配一封 GT 书信题干），
分析器会在报告开头打出「⚠️ 输入自相矛盾」横幅，并声明第 7 节结论不可用。**此时不要采信该节，改用正确的 `--task` 重跑。**

**报告可以用英文写**：`Score Card` / `Error List` / `Sentence Upgrades` 及其字段标签都能解析。
但如果报告里出现了错误代码却一条错误行都没解析出来，脚本会 `BUILD FAILED` 而不是交付一个零批注的文档。

**配错文件会失败，不会静默交付**：如果报告里的引文在作文中一条都找不到（多半是报告与作文不是同一篇，或作文在批改后被改过），脚本会报 `BUILD FAILED`、删除半成品并返回非 0。**此时不要换一篇作文凑，要确认文件配对。**

三条约束（脚本已内建，不要绕过）：

- 逐字定位失败时**绝不把批注挂到别的位置**，而是列入「未锚定」清单并写在评分页上——挂错位置比不挂更糟。
- 同一段原文被两行错误引用时**合并成一条批注**；一处标注意见，而不是两条重叠。
- 生成后自动校验（批注 id 一致性、嵌套闭合、必备部件、评分页完整性）。校验失败会返回非 0，而不是产出一个 Word 会提示"修复"的文件。

**写"下一步 3 个动作"时必须做到两件事**（详见 `references/failure-modes.md`）：

1. **按修复成本排序，聚焦单一瓶颈**：跑题（2 分钟）→ 机械衔接（1–2 周）→ 空洞（2–4 周）→ 语法（数月）。**不要四项各给三条建议**——那等于没给建议。
2. **用跨档算术支撑提分判断**：跨半个档位需要四项总和增加多少**不是固定值，必须按公式算**：
   `增量 = 4 × (当前总分 + 0.25) − 四项总和`，取值为 **0.5 / 1.0 / 1.5 / 2.0** 之一（四者频率相当）。
   先算出增量，再据此判断"把哪一项从多少提到多少"才能跨档。
   **不要记成"跨档需要 +1.5"**——那只是四种情况之一。增量 ≤ 1.0 时单项小幅提升就可能够；
   增量 ≥ 1.5 时必须显著提升某一项或同时改两项。如果四项都很接近（如全部 6.0 上下），须说明**需要同时修两项**。

如果用户的强项与弱项差距很大（例如 GRA 8.0 而 TR 5.0），在报告里明确写出"**继续打磨强项是零收益**"——这是最容易被浪费的时间。

### Step 6 — 跨篇追踪（当报告目录里已有历史记录时）

单篇报告是写一次就不再被读的。写完新报告后，如果 `<workspace>/ielts-reports/` 里已经有其它报告，运行：

```bash
python3 scripts/track_progress.py <workspace>/ielts-reports --out <workspace>/ielts-reports/_趋势.md
```

它纯统计、不调用模型，输出四件单篇报告看不到的东西：

1. **分项趋势**——同一任务类型的首篇 → 末篇变化（Task 1 与 Task 2 分开算，因为 TA 与 TR 不可比）
2. **当前状态与跨档算术**——四项总和、距下一档还差多少、**若只靠某一项填平差距需要提到多少分**
3. **错误代码跨篇累计**——哪些代码反复出现、累计多少处
4. **持续性问题**——出现 ≥2 篇的错误代码。**跨篇重复才是系统性弱点的证据**，单篇里它可能只是笔误

**给用户的建议必须以第 4 项为准**：一个在历史记录里反复出现的模式，优先级高于新报告里偶然出现的新错误。

**两个诚实性约束**（脚本已内建，不要在报告里推翻它们）：

- **同一天的报告不构成趋势。** 顺序未知时脚本拒绝计算变化，改为输出各分项的分布区间。不要手工按文件名排个序就宣称"进步/退步"。
- **只认 `## 分数卡` 小节。** 没有该小节的 Markdown（例如你自己写的汇总文档）会被跳过并列在末尾。这是刻意的——汇总文档里的对比表格也含四项分数，全文扫描会把它们误当成批改记录。

输出文件名以 `_` 开头可避免它被下次运行的目录扫描当成报告（脚本同时跳过 `_` 与 `.` 开头的文件）。

### Step 7 — 校准记录（可选，只在用户想量「准不准」时）

工具的分是预估，而**它到底偏多少，只有用户的作文能量**。当用户问「这个准吗」「和你上次给的怎么对不上」，
或者你已经为他改过两篇以上时，**可以主动提一次**：

1. 从 `templates/calibration-log.md` 复制一份到 `<workspace>/ielts-calibration/<日期>-<题型>.md`
2. **你替用户填你已知的部分**：日期、题型、`工具总分`（从刚给的报告里取）。**不要替他填「你的总分」**
3. 问他一句：这篇有没有老师给的分或官方模考分？有就填上；没有就留空。再问他：报告里有没有**他核对原文后确认说错了的**、有没有**确实错了而报告没提的**
4. 攒够几篇后：`python3 scripts/calibrate.py <workspace>/ielts-calibration`

**四条约束，别越过**：

- **不要替用户编「你的总分」。** 留空是有信息量的（脚本会报「N 篇未判定」），编一个数字会让偏差统计变成假的。
- **误报只算「工具说错了」，不算「用户不同意」。** 判据是事实，不是偏好。用户说「我觉得这里没那么严重」不是误报。
- **`calibrate.py` 拒绝下结论时，不要替它下。** 少于 5 篇有对照它不给偏差方向，少于 3 条误报漏报它不排序——这是内建的诚实性约束，和同一天的报告不算趋势同一个道理。
- **不要宣称「验证过准确性」。** 校准记录量的是「工具对**这个人**准不准」，不是「工具准不准」。而且它不是盲测：用户先读了报告再判断，量到的偏差通常**小于**真实偏差。

## 2. 报告必备结构

```markdown
# IELTS Writing 批改报告
> 预估分，非官方成绩｜Task 2｜2025-01-01

## 一句话结论
（当前水平 + 最关键的 1 个瓶颈 + 提分最快的一步）

## 分数卡
| 项目 | 预估分 | 一句话依据 |
|---|---|---|
| Task Response | 6.0 | 立场清楚，但两个主体段都停在断言，无例证 |
| Coherence & Cohesion | 6.5 | 分段合理，连接词偏机械（Moreover 出现 5 次） |
| Lexical Resource | 6.0 | 搭配错误 4 处（make a progress…） |
| Grammatical Range & Accuracy | 5.5 | 复杂句 7 处出错，主谓一致 3 处 |
| **总分** | **6.0** | 四项均值 6.0 |

## 逐项诊断
### Task Response — 6.0（门槛 / 证据 / 差什么）
...
## 错误清单
| # | 位置 | 原文 | 代码 | 修改 | 原因 |
## 错误模式小结
## 句子升级（before → after）
## 段落结构图
## 词汇升级表（本文用词 → 目标分用词）
## 下一步 3 个动作（今天/本周可做）
## 附：目标分段示范
```

## 3. 参考资源

按需加载，不要一次性全读进上下文：

| 文件 | 何时加载 |
|---|---|
| `references/scoring-protocol.md` | 打分前——防虚高校准与判定流程 |
| `references/failure-modes.md` | 定位"这篇真正的问题是什么"、排定下一步动作优先级、做跨档算术（**建议每次批改都加载**） |
| `references/task1-guide.md` | **Task 1 必读**——overview 写法、数据取舍、GT 书信规则（第 7 节的 Task 1 检查配合此文件使用） |
| `references/band-descriptors.md` | 打分时——四项标准 Band 5–9 门槛（原创改写摘要） |
| `references/task2-guide.md` | Task 2——题型识别、立场、论证深度、跑题判定 |
| `references/error-taxonomy.md` | 建错误清单时——代码全表 + 中国考生高频错误 |
| `references/language-bank.md` | 改写与词汇升级时——学术词块与替换表 |
| `templates/report-template.md` | 生成报告时 |
| `templates/calibration-log.md` | Step 7 校准记录（用户想量「这个工具对我准不准」时） |
| `scripts/analyze_essay.py` | Step 1 客观预分析 |
| `scripts/track_progress.py` | Step 6 跨篇追踪（报告目录已有历史记录时） |
| `scripts/calibrate.py` | Step 7 汇总校准记录 |
| `scripts/report_to_docx.py` | 用户要带 Word 批注的 `.docx` 时——从已有报告生成，不重新批改 |
| `scripts/audit_report.py` | **交付报告前自查**——检查是否有同一处缺陷被多个评分项重复扣分 |

所有相对路径都相对本 skill 的 base directory 解析。

## 4. 常见失败模式（自查）

- ❌ 只给分数和泛泛建议，不引用原文 → 用户无法复核，也无法执行
- ❌ 把考生的中式表达"顺手改对"却不指出这是中式英语 → 错误模式被隐藏
- ❌ 四项分数都打 6.5（偷懒的平均分） → 四项必须独立判定，允许差异 ≥1.5
- ❌ 用 Task 2 的"论证充分性"去评判 Task 1 → Task 1 看概述与数据选取
- ❌ 报告只存在于对话里，没落成文件 → 无法分享、无法和下次对比
- ❌ 字数不足却照常打 6.5 → 字数不足是 Task Achievement/Response 的硬扣分
- ❌ **只查语言，漏掉相关轴与支撑轴** → 零语法错误的作文完全可能 TR 5.0（跑题）；三轴都要读，取低者
- ❌ **只评语言就低估 TR，或看到"内容好"就抬高 GRA** → 三轴独立，不许互相补偿
- ❌ **"下一步动作"四项平均用力** → 应聚焦单一瓶颈，并按公式算出跨档增量来说明为什么
- ❌ **把跨档增量当成固定的 +1.5** → 它是 0.5/1.0/1.5/2.0 之一，必须按公式算
- ❌ **不传题干就评 TR** → 偏题无法从作文本身看出来，此情形必须标注 TR/TA 未评
- ❌ **为了凑批注把定位失败的批注挂到别的句子** → 必须列为「未锚定」，错位的批注会让学生改错地方
- ❌ **重新批改一遍来生成 docx** → docx 必须从已有报告生成，两次批改会得出两套不一致的分数

