# Blog Writing

> 写博客文章或改文章时的统一入口。覆盖选题自检、定类型、搭骨架、起标题、写正文、配图、收尾、润色、验证到 hugo build 的全流程。本 skill 是工作流骨架,详细的风格规范、分类型规范、结构工具、选题同理心、润色 SEO 在 references/ 下的 5 个文件,按步骤按需加载。每次写新文章或大改现有文章前调用。

- Skill: `xiaoshuai1024/blog-writing` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add xiaoshuai1024/blog-writing`
- Raw SKILL.md: https://api.skillmd.com/api/skills/xiaoshuai1024/blog-writing/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Marketing & Growth
- Author: xiaoshuai1024 (https://skillmd.com/u/xiaoshuai1024)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/xiaoshuai1024/blog-writing

---


# 博客写作全流程

## 何时用本 skill

**写新文章**或**大改现有文章**(扩写、去 AI 味、改标题)时,先调用本 skill。它把写文章从「凭感觉」变成「按流程」,避免漏掉选题、结构、篇幅、配图、去味、润色、验证这些环节。

## 渐进式披露:本 skill 的文件结构

本 skill 采用标准 skill 结构。**SKILL.md(本文件)是工作流骨架,不重复细节**。详细规范在 `references/` 下,按步骤按需加载:

| 文件 | 何时读 | 管什么 |
|------|--------|--------|
| `references/topic-and-empathy.md` | **第 0 步 选题** | 选题六来源 + 三标准 + 主题上升法 + 读者同理心 |
| `references/post-types-guide.md` | **第 1 步 定类型** | 六类文章结构 + 篇幅定法(内容决定) + 配图配额 + 掘金爆款化 + AI 辅助边界 |
| `references/structure-toolkit.md` | **第 3 步 搭骨架** | 金字塔原理 + MECE + 黄金圈 + 奥卡姆剃刀 |
| `references/style-guide.md` | **第 2/4/6 步 标题/正文/收尾** | 语气、排版、标题六模式、SEO 长尾、故事连贯 |
| `references/polishing-and-seo.md` | **第 7 步 润色** | 精简/准确/生动三目标 + SEO 落地 |
| `references/wechat-retention.md` | **同步公众号前** | 公众号留存层:标题/摘要变体、首屏、节奏、钩子兑现、转化合规 + 48h 回看 |

> 单一入口原则:写文章只调这一个 skill。它内部会指引你读哪个 reference,不用手动找。

## 核心工作流(从选题到发布,9 步)

### 第 0 步:选题自检(动笔前,决定成败的 60%)

写之前先过选题关。**读 `references/topic-and-empathy.md` 的「选题方法论」**,用三标准自检:

1. **分享欲**:不吐不快 vs 硬凑?(硬凑的放弃)
2. **稀缺性**:网上同类多吗?我的角度稀缺在哪?(新数据/新场景/新观点/更深一层)
3. **对他人价值**:读者读完带走什么,一句话说清?

**主题上升法**:具体项目经历 → 通用方法论(「我们项目的定时器」→「如何实现分布式定时器」),扩大读者面。上升要适度,别硬拔成空洞哲学。

选题通不过这三关,**换题或拆系列**,不要硬写。

### 第 1 步:定类型(决定结构和篇幅)

**读 `references/post-types-guide.md`**,先回答:**这篇属于哪一类?**(教程/深度/踩坑/最佳实践/观点/日常)。类型决定结构和配图策略;**篇幅由观点和内容决定,不按类型设字数**(2026-08-26 定规)。一篇文章只允许**一个主导类型**。

判不准时,问「读者读完带走什么」:怎么做→教程;为什么→深度;别踩坑→踩坑;该这么做→最佳实践;一个观点→观点;一点共鸣→日常。

### 第 2 步:起标题(写作第一步,不是最后一步)

标题定调性,先把标题想清楚再写正文。**必走 metadata-optimizer skill(2026-08-26 定规):出 fact card → 分档候选 5-7 个 → `score_title.py` 打分 → 人选定稿,不许自拍一条直接用**;候选注意结构红线词(凭什么/打赢/吊打等)与事实边界(素材里核过的数字才能进标题)。**同步公众号的文章,候选时一并出 `标题_公众号` 变体(≤25 字、钩子前 13 字,见 `references/wechat-retention.md` 打开层),写 front matter 可选字段 `wechat_title`,缺省回退主标题**。先读 `references/style-guide.md` 标题章节:

- **去掉方括号前缀**(【AI 研发实战】【SOP】)——降低点击欲
- **15-30 字,结构自由**:主副结构是可选不是默认,拒绝「XX:YY」模板化
- **抓眼球三动作**(去同质化核心,最重要):前 5-8 字埋冲突点、每篇只打一个冲突点、口语化 + 情绪词(翻车/白装/骨折/当场/甩开/别切)
- **情绪档位停在第 2 档**:打脸感可以,但禁止「震惊/吓尿」级标题党(档位 3)——触发限流、透支信任
- **套六种模式**:数字+痛点 / 揭秘 / 踩坑复盘 / 决策为什么 / 对比选型 / 成长路径
- **SEO 热词 + 长尾思维**:出候选前先列「核心概念词」——趋势热词(harness / Agent / AI 编程 / AI 工程化)+ 内容长尾词(命令体系 / 自治体系 / 夜间巡检),每个候选都要带上至少一个热词 + 一个长尾词,热词放前 8 字;隐喻词(裸 CPU 之类)不是搜索入口,不能只靠它撑标题
- 写完用**自检三问**验:3 秒能看懂吗 / 会想点吗 / 内容能兑现吗

### 第 3 步:搭骨架(动笔前,决定文章好不好读)

> **核心观点与表达流程先行(2026-09-05 用户定规,文章与视频一体适用,动笔硬前置)**:正文一个字不许先写——先把两件产物整理出来再开写:① **核心观点清单**:这篇要立住的观点逐条列出,每条挂证据(数据/源码/实测/案例)与「读者现状→读完改变什么」;观点立不住或证据挂空的,回第 0 步换角度,不许边写边找观点。② **表达流程**:观点的输出顺序与承接关系(先给哪个钩子、每个钩子在哪节回收、转场怎么接、备查卡/清单放哪),一段话+有序列表讲清。两件产物是工作底稿(落 `.tmp/<slug>-core-points.md` 或稿内注释),写正文全程对照;写完复验——正文漏掉清单上任何一条观点或回收点 = 返工。视频口播稿同规(video-generation skill 口播稿节已同步)。

**读 `references/structure-toolkit.md`**,用三步搭骨架法:

1. **定主张**(金字塔顶端):一句话写出这篇文章的核心判断/结论/目标。写不出 = 选题没想清,回第 0 步。
2. **MECE 拆分支**:支撑这个主张,分哪几个维度?用 MECE 五种分类法(二分/过程/要素/公式/矩阵)拆 3-5 个二级标题。
3. **奥卡姆剪枝**:层级 ≤3、同层 ≤7、奇数优先、能删则删。

**关系**:类型模板(`post-types-guide.md`)定文章有哪几段(容器),骨架工具定每段内部的逻辑。两者叠加,不是冲突。

### 第 4 步:写正文(边写边守三条硬约束)

**约束一:结构门禁 + 篇幅由内容定(2026-08-26)+ **`5000 字硬下限(2026-08-28 用户定规,再次固化,详见 post-types-guide 总则)`**。发布门禁是结构完整度(本类型必需块齐全)+ 内容讲透 + 正文中文字符 ≥5000——上限仍由内容定不凑字,下限不足就是单薄,必须多角度补素材(实操数据 / 事故复盘 / 对照表 / 反模式集 / 使用方式 / 边界反例)。定篇幅用**观点清点法**(详见 `references/post-types-guide.md` 总则):列观点清单 → 每个观点问「读者现状 / 给什么证据 / 讲到什么程度算懂」→ 展开量加总即篇幅。写完明显偏短 → 先对照结构清单查缺块(步骤没讲透 / 弯路没写全),查不出缺块也要多角度补素材到 5000 字,不许短稿交门禁。

**约束二:配图配额**(按成文实际字数,硬性,详见 `references/post-types-guide.md` 第八章):最低配图数 = **max(2, 正文字数 ÷ 1800 四舍五入)**,只能多不能少(第 8 步脚本自动算)。**开头前 800 字必有 1 张总览图,任何连续 1500 字纯文字都要补图**。

**约束三:去 AI 味**(本博客核心差异化,详见下文「去 AI 味实战手册」)。

**约束四:钩子兑现**。开头钩子(反直觉发现,2026-08-18 定规)作的承诺必须逐节兑现:写稿时列**钩子 → 回收清单**(哪个承诺、在哪节兑现),无回收点的钩子不许埋;章节转场用**陈述式预告**(「下一节会看到 X」)制造期待,禁自问自答设问(去 AI 味行为规范 #10)。清单是工作产物(稿内 HTML 注释或 .tmp),不进正文。

**约束五:扫读可用性**(2026-08-26 调研增补,源 NN/g 眼动研究)。读者只读约 20% 文本、按 F-pattern 扫「标题+段首+加粗」,所以:**段首承重**(每段第一句 = 该段结论,支撑句跟后)、**每段一个观点**(两个论点拆两段)、段落间过渡用**指向具体内容的短句**(「先看数据」「更麻烦的在后面」),不用「但是/然而」空垫词也不用设问。自检:**扫读测试**——只读小标题+段首句+加粗,文章逻辑仍成立才算过。

**正文写作风格**(语气、段落、代码、句式)见 `references/style-guide.md` 第二、三章。

**代码例子偏好**:优先用**后端**例子(Java/Maven/Spring Boot/**MySQL**),构建命令用 `mvn package`/`gradle build`,测试用 JUnit 语境;**数据库默认 MySQL**(用户常用,不要用 PostgreSQL);除非文章本身就是讲前端(用 Vue),否则不放 Vue 组件、webpack 配置、`npm run dev` 这类前端例子。

### 第 5 步:配图(用 drawio skill)

架构图/部署图/数据流/时序图 → 调用 `drawio` skill,用 mxGraph XML,**禁止 mermaid**。概念图/对比图 → Excalidraw 手绘风。

工作流:写 `.drawio` 源文件到 `static/diagrams-src/<slug>.drawio` → 用 drawio CLI 导出 SVG 到 `static/svg/<slug>.svg` → 文章里 `<img src="/svg/<slug>.svg" alt="描述性文字">`。

**公众号配图走 PNG**:公众号不支持 SVG,`<img>` 引用 SVG 显示不出来。现行通道 `make wechat-publish-mp`(wechat-publishing skill)的 `prepare.py` 自动把正文 SVG 转成 PNG(首图另按 9:5 裁 `cover.png`),不用手工转换——旧的 rsvg-convert 手工流程随 wechatsync 于 2026-08-30 退役。掘金/知乎是 Web 平台,SVG 正常显示,不用转(掘金已降级低优先渠道,用户点名才发)。

**同步公众号前过留存层**:读 `references/wechat-retention.md`(与掘金第十章同构的平台适配层)——标题/摘要变体(`wechat_title`/`wechat_digest`)、首屏 150 字、小标题间隔、钩子兑现、转化合规与 48h 数据回看,清单全过再走 wechat-publishing。

**去 AI 味配色硬规则**:白底为主、最多 1 个主色(`#2563eb` 蓝 或 `#0f766e` 青绿)+ 深灰文字 `#1e293b`、字号 14/12 两级、箭头统一 `edgeStyle=orthogonalEdgeStyle`、标签说人话不要对仗短语、坐标手画不要等距对齐。

**应用窗口截图(教程/踩坑型常用)**:教程型文章需要应用界面截图时,调用 **app-screenshot skill** **只截应用窗口、不截全屏**(跨平台:macOS Quartz / Windows 调 .ps1;按进程名+窗口标题模糊匹配窗口):

```bash
cd app-screenshot/scripts && python screenshot_app.py --process "ChatGPT" --title "ChatGPT" --output static/images/<slug>/01.png
```

- macOS 依赖 pyobjc(Vision/Quartz);Windows 自动调 `screenshot-app.ps1`(Win32 GetWindowRect)
- 产物存 `static/images/<slug>/`,正文用 `<img src="/images/<slug>/01.png">` 引用
- 截图后如无法目视验证(模型不支持看图),用 app-screenshot skill 的 **OCR 功能**(跨平台:macOS Vision / Windows WinRT)核对窗口文字
- **真实截图拿不到时的兜底 = Playwright 复刻**:调用 app-screenshot skill——从真实会话 rollout jsonl **逐字取内容**,采样真实截图配色,填 `templates/conv.html`,用 `shoot.py`(Playwright headless,不依赖屏幕会话)截图,再 OCR 核验完整性。复刻是**忠实渲染,不编造内容**;配图左侧私人信息(侧栏/项目名)一律不进图。

### 第 6 步:收尾(结论式,反 AI 味最关键的一环)

- **禁止用「检查清单/落地清单/Checklist」收尾**——最典型的 AI 味
- 收尾必须是**结论**:回到核心判断,1-3 段陈述句,讲清「我最终的观点/本质是什么/读者带走什么」
- **不要复述要点**(那是 PPT 的活)
- 全文**最后一段不能是列表**,必须是连贯文字
- 同理禁止:「以上就是…的全部内容」「希望对你有帮助」「你学会了吗」

### 第 7 步:润色(正向,让文章好读)

**读 `references/polishing-and-seo.md`**,过润色三目标:

- **精简**(Omit Needless Words):删冗余修饰、删口头禅、被动改主动、长句拆短句
- **准确**:术语精确到版本、数字具体(别用「很多/大幅」)、避免含糊
- **生动**:动词>名词、具体>抽象、场景>概念、类比(谨慎用)

润色是**正向**(把句子写好),去 AI 味是**负向**(删套话),两个都要。同时顺手过一遍 **SEO 清单**(标题含关键词、slug 用英文词、front matter 写 description、首段含关键词、图片有 alt、内链用锚文本)。

### 第 8 步:验证(发布前的门禁)

**先跑机检门禁（2026-08-31 openspec `article-quality-gate` 定规，第 8 步自动执行点）**:

```bash
make article-check slug=<slug>   # 九项 ERROR 阻断 + WARN 提示,❌ 必须处置后复跑
```

机检覆盖 relref 断链/段落超长(>4 行)/标题数字正文兑现/代码块超 15 行/清单式收尾/SVG 缺失/时间简写/重复句 + 配额破折号等 WARN。**机检全绿后,按 article-quality-check skill 的六大编辑终检组(A 润色复查/B AI 味复判/C 趣味密度(趣味向文章)/D 流畅性/E 合理性/F 技术深度)逐组过一遍**——重点盯修改轮引入的新问题与时效性技术断言(计费/版本/机制类);同批产出 ≥2 篇文章时加跑多篇隔离检查。问题清单修稿处置,复跑 `make article-check` 到无阻断。

配额与摘要的补充体检脚本(配额已并入 article-check,此脚本可作双保险):

```bash
PYTHONIOENCODING=utf-8 python -c "
import re, os, sys
slug = '$SLUG'  # 传入 slug
path = f'content/posts/{slug}.md'
t = open(path).read()
parts = t.split('+++\n',2)
body = parts[2] if len(parts)>2 else t
body = re.sub(r'\`\`\`.*?\`\`\`', '', body, flags=re.DOTALL)
body = re.sub(r'<img[^>]*>', '', body)
cn = len(re.findall(r'[\u4e00-\u9fff]', body))
imgs = len(re.findall(r'src=\"/svg/', t))
refs = re.findall(r'src=\"/svg/([^\"]+)\"', t)
missing = [r for r in refs if not os.path.exists(f'static/svg/{r}')]
# 硬门禁:配图配额 + SVG 完整性(结构/讲透是人工 checklist,不程序量化;字数仅体检信号)
quota = max(2, round(cn/1800))
ok = imgs>=quota and not missing
warn = ' ⚠️ 偏短体检信号:对照结构清单查缺块,查不出缺块即内容如此,不凑字' if cn<2000 else ''
print(f\"{'✅' if ok else '❌'} {slug}: {cn}字 / {imgs}图(需≥{quota})\" + warn + (f' 缺失SVG:{missing}' if missing else ''))
# 摘要/公众号变体提示(WARN 级,不阻断——详见 references/wechat-retention.md 打开层)
fm = parts[1] if len(parts)>1 else ''
m = re.search(r'^description\s*=\s*\"(.*?)\"', fm, re.M)
desc = m.group(1) if m else ''
if desc:
    h = desc[:40]
    hooky = any(c.isdigit() for c in h) or any(w in h for w in ['坑','别','为什么','问题','错','翻车','失败','白'])
    print('   摘要 %d字 | %s' % (len(desc), '前40字有钩子 ✅' if hooky else '⚠️ 前40字无痛点/数字,公众号推送转化弱'))
else:
    print('   ⚠️ 无 description:公众号 digest 会抓正文前54字')
print('   公众号变体: wechat_title %s' % ('有' if re.search(r'^wechat_title', fm, re.M) else '无(回退主标题,SEO长标题需出变体)'))
"
```

然后 `hugo --gc --minify --quiet` 确认构建无报错。

### 第 9 步:发布前完成检查清单(2026-08-26 重构为分组式,写完逐组过)

**A. 标题与描述**
- [ ] `title` 无方括号前缀;**已走 metadata-optimizer 候选→打分→人选定稿流程**(第 2 步),无结构红线词,前 5-8 字埋冲突点,情绪停第 2 档
- [ ] `description` 54-120 字三段式(痛点+给什么+数字背书),**前 40 字含痛点或硬数字**(公众号推送可见域,第 8 步脚本会提示)
- [ ] front matter 用 TOML `+++` 围栏;**`date` 取当前真实时间**(未来时间 Hugo 会静默跳过,见「踩过的坑」)

**B. 黄金开头与钩子(留存生死线)**
- [ ] **黄金开头**:反直觉发现/数据/痛点场景开场(2026-08-18 定规),无寒暄/背景铺垫/自我介绍;正文前 150 字可见「问题定义 + 钩子」+ **首屏内有一张图**(读者 5%-15% 位置跳出最多,第一屏是留存最高杠杆,见 `references/wechat-retention.md`)
- [ ] **钩子兑现**:开头承诺逐节回收,「钩子→回收清单」逐条核对过(第 4 步约束四),无只埋不收的钩子;转场无自问自答
- [ ] **结尾转化**:结论式散文收尾(最后一段连贯文字,禁 checklist 收尾);转化段只在公众号版补(draft-only 后台加,不进源稿)

**C. 正文与配图**
- [ ] **骨架合规**:有明确主张,段落 MECE,层级 ≤3、同层 ≤7(第 3 步)
- [ ] 结构门禁:本类型必需块齐全;篇幅与内容匹配——观点清单逐条讲透、无凑字块(明显偏短先查结构缺块,查不出缺块即内容如此)
- [ ] 密度:砍掉 20% 不损失信息?(砍得动 = 有水,先砍)
- [ ] 配图达标,SVG 文件存在,图片有描述性 alt;二级标题间隔 ≤1200 字(公众号节奏)
- [ ] **扫读测试**:只读「小标题+段首句+加粗」逻辑仍成立;每段一个观点,段首承重(第 4 步约束五)
- [ ] 代码例子走后端语境(Java/Spring Boot/MySQL),代码块 ≤15 行(手机体验)
- [ ] 时间用完整年月日时分秒(2026-08-14 定规);数字有出处,无编造事实
- [ ] **读者验证**:找无背景者读一遍,或自检模拟跳步/术语未解释(第 0 步同理心)

**D. 去 AI 味与润色**
- [ ] `make check-ai-smell` 跑过,L1 无未处理命中(命中需人工判,引用/反讽语境标注保留)
- [ ] de-ai-smell L1-L4 分层清单过:破折号 ≤2、无「不是A而是B」顿悟句、无翻译腔(的链/虚动词/预判冒号)、类比密度未超(一段≤1/一篇≤3)
- [ ] 润色三目标过一遍(精简/准确/生动)
- [ ] SEO:slug 英文词、首段含关键词、内链用锚文本

**E. 封面**
- [ ] **每篇文章必须有专用封面**(2026-08-28 定规,博客与公众号共用,缺封面=检查不过):用封面生成脚本出图,`python .agents/skills/blog-writing/scripts/make_cover.py --slug <slug> --line1 .. --line2 .. [--subtitle ..] [--tags a,b,c]`(1800×1000、**居中构图**文字全在 2.35:1+1:1 双安全区、大字双行**第二行黄底色块锚点**(默认 block)、≤3 标签 pill),产物 `static/images/<slug>/cover.png`
- [ ] **封面不进正文**(2026-09-05 用户定规:所有文章正文不展示封面,存量 31 篇已批量清理):`cover.png` 只落 `static/images/<slug>/`,公众号封面由 prepare.py 直取该文件裁 9:5(不再依赖正文首图);正文首图 = 第一张内容图(总览图);**禁视频封面直搬**(角标/贴纸/CTA 在公众号小卡片被裁且不可读)、**禁架构图/截图当封面兜底**(无钩子,转化趋近零)
- [ ] **专门封面走大字风格**(2026-08-26 定规,后续新文章逐步配):参考 `video-cover-standard`(scripts/video/cover.py + cover_template.html)——大字双行 96/72/56px 分级、关键词青色 #22d3ee 高亮、副标题 36px、≤3 个标签 pill、单一主强调色;文章封面横版按此风格出图,存 `static/images/<slug>/cover.png`

**F. 平台发布**
- [ ] 同步发掘金时,套 `post-types-guide.md` 第十章爆款化(标题钩子/开头改写/互动引导)
- [ ] 同步公众号:**先跑机检 `make article-check slug=<slug> wechat=1`**(转化泄漏/posts 死路径/wechat_title 折叠线/封面缺失为 ERROR,留存层 WARN 逐条判),后过 `references/wechat-retention.md` 留存清单(**长度决策**(≤2500 直发 / 2500-4000 压缩变体 / **>4000 默认压缩变体**——2026-08-29 自有数据收紧:首批 12 篇 11 篇 >4000 直发完读全 <30%,直发改为例外需记豁免理由;拆系列仅限多独立主题,不动日更节奏;只管公众号版,博客端不动)、`wechat_title`/`wechat_digest` 变体(标题含 1 个可搜关键词)、**封面独立定制**(make_cover.py,禁视频封面直搬/架构图兜底)、首屏、**90 秒规则**(前 600 字含核心判断)、节奏、扫读、钩子兑现、**收藏触发**(至少一处可收藏资产)、**文末往期关联 2-3 篇**、转化段不进源稿(**关注引导带持续价值理由**——下一篇预告/清单持续更新))
- [ ] 公众号**发布配置四查**(发布前逐项核对,见 wechat-publishing Step 1.5):①作者已录入(`WECHAT_AUTHOR` 非空,草稿作者栏不空)②合集挂对(`--album` 默认 AI,前端类传 前端技术,不挂传 none)③原创声明开(`copyright_type=1` 文字原创,转载/重编文除外)④广告开关与预期一致(群发前 mp 后台核对流量主文中/文末广告状态)
- [ ] 文章间用 `{{< relref "posts/xxx.md" >}}` 互链,融入成长线
- [ ] `hugo build` 成功;公众号发布 48h 回看已排期(跑 `make wechat-analytics` + `make wechat-analytics-report` 看诊断卡,**对照完读率 30/50/65 与打开率 1.9%/4% 基准线归档**,流失位置用留存曲线 5% 节点读,打开低修标题摘要、完读低修首屏节奏/长度档位,数据结论写 link-map.json 备注);**定时群发落 20:00-21:00 窗口**(晚间打开峰)

### 第 10 步:生成图文版(小红书/抖音) — 已退役

> ⚠️ **2026-08 归档、2026-08-30 退役**(openspec `xiaohongshu-image-notes-retirement`):图文发布管线(`scripts/xiaohongshu/`、`scripts/douyin/`、`image-text/`、旧第三方发布脚本 及对应 Makefile 目标)已删,`image-text-cards` skill 亦已整体删除——仓库不再生成/发布任何图文笔记,暂时目标全部是视频。历史内容与卡片设计规范见 git 历史。

---

## 去 AI 味实战手册(全站清理沉淀,最高价值)

这是全站清理 56 篇文章后沉淀的方法。**AI 味是本博客的头号敌人**,写作时和改稿时都要盯紧。

### 五类 AI 味(从最严重到最轻)

#### 1. 补丁式总结段(最严重,跨篇通用)

AI 最爱在文末贴一段「## 回到本质:...」重复前文。**特征**:章节标题含「回到本质」「本质是」「核心是」,内容是对正文的复述和升华。

**处理**:整段删除。有新信息的挑出来并入正文相应位置;没有就直接删。判不准时问「这段删了,读者会少知道什么吗」——答不上来就删。

#### 2. 「我的判断是」前缀(最高频)

句子去掉「我的判断是」照样成立,这是 AI 的口头禅。变体:「我的判断很直接」「先说我的判断」「关键判断是」。

**处理**:直接删前缀。

#### 3. 空洞强调词

「真正的」「恰恰」「正是」「本质上」「核心在于」「终极」「护城河」「分水岭」「定时炸弹」。删掉意思不变,但立刻不像 AI。

**处理**:「真正的X」→ 多数删「真正的」(保留「真正的需求/问题/瓶颈」);「恰恰相反」→ 删;「护城河/分水岭/定时炸弹」→ 换具体词(优势/标志/隐患);「终极」→ 删。

#### 4. 三连对仗(机械感最强)

「把 X 移到 Y,把 A 扩成 B,把 C 串成 D」——三连对仗太工整,像口号。还有「不仅...而且...」「无论是...都...」。

**处理**:拆短句或删减。三连改两连或直接陈述。

#### 5. 模板化开头

「在「前端 → 全栈 → AI 开发」这条线上,这篇落在...」——系列文章一字不差重复,是机械感来源。

**处理**:系列连接保留(融入成长线),但每篇句式要变化。

#### 6. 套话开场词(PPT 体标志,来自爆款改造 SOP)

这些词出现在开头/段首,基本就是「工作汇报体」:「综上所述」「值得注意的是」「值得一提的是」「不难发现」「毋庸置疑」「本质上,」(句中作过渡也算)「在...的今天」「随着...的发展」。

**处理**:整句删除或改写。这些词删掉,后面的内容直接接上,读起来更干净。

#### 7. PPT 名词滥用(大词堆砌,显虚)

这些是「PPT 高频词」,一出现文章质感就掉:「赋能」「闭环」「抓手」「落地」「链路」「体系化」「底层逻辑」「全生命周期」「降本增效」「技术底座」。

**处理**:
- 多数直接换具体词:「赋能业务」→「帮业务做成 X」;「降本增效」→「从 3 天降到半天」;「底层逻辑」→「原理」。
- **2026-08-26 用户定规:全部 L1 无例外**——「SaaS 商业闭环」这类业务术语、反讽用法都不再豁免,一律换写法(权威词表见 de-ai-smell skill)。

#### 8. 对仗句式(机械感,来自 SOP)

「不只是 X,更是 Y」「既...又...」「一方面...另一方面...」——单个对仗偶尔可用,但连用或凑成「三连」就显机械。

**处理**:单个对仗可留;连续出现就拆成短句。三连对仗(第 4 类)必删。

#### 9. 新晋 AI 网络词(2026-08-03 用户定规,技术语境无例外)

「兜底」「铁证」这类词,技术语境读着挺合理(「DB 唯一约束兜底」「SSR 兜底页」),但已成 AI 味重灾区。用户定规:**一律不出现**,技术语境也**无例外**(不是误报)。候选同批:拉满、主打一个、破防、解锁新姿势、YYDS。

**处理**:
- 「兜底」→ 按语境换具体词:「DB 约束兜底」→「DB 约束当最后防线」;「兜底页」→「降级页」(文章里本来就混用);「给 X 兜底」→「替 X 把关 / 把 X 的错误拦下来」;「sparse 兜底」→「sparse 接住漏网的」。
- 「铁证」→ 「实测 / 日志为证 / 数据摆在面前」。

### 心法:工作汇报体 → 真人分享体

上面九类 AI 味,本质都是「工作汇报体」。改稿的心法一句话:**把「工作汇报体」改成「真人分享体」**——改完读出来,要像一个真人在工位上跟你聊,而不是一份周报在念稿。

光删还不够,要**补进人味**(这和 `polishing-and-seo.md` 的正向润色一致):

- **第一人称 + 口语**:「我以为」「老实讲」「我之前也踩过」「这里绕了弯路」「说真的」。允许不完美和小情绪。
- **具体代抽象**:「提升效率」→「从 3 天降到半天」;「优化体验」→「首屏从 4 秒到 1 秒」。
- **长短句混用**:偶尔来个短句(「那只占一小块。」「根本扛不住。」),别每句都一样长。

### 去 AI 味扫描脚本(发布前/改稿后跑一遍)

词表与可运行脚本已收敛到 **de-ai-smell skill**(全站唯一权威,含 2026-08-03 定规的 兜底/铁证/说白了/先说/根子/扎眼 等)。直接跑:

```
make check-ai-smell                                  # 全站
make check-ai-smell path=content/posts/xxx.md        # 单篇
```

脚本只定位不自动改,命中必须人工判断(见下文「误报处理」);另附破折号/冒号密度风格提示。

### 误报处理(扫描结果必须人工判断,不能无脑全删)

扫描会命中两类误报,**不能删**:

1. **front matter 里的 tags/keywords**:如 `tags = ['业务赋能']`——这是标签不是正文,不动。
2. **L2 慎用词的合法用法**:如「问题的本质」「事件真相」——名词有实质语义,L2 提示人工判,真表实质就留。

> ⚠️ 2026-08-26 定规后,「反讽」「业务术语」**不再是 L1 无例外词的豁免理由**——兜底/铁证/PPT 名词(赋能/闭环/打通/沉淀…)/口头禅(一句话/一件事/踩坑)命中一律改,新稿连引用 skill 描述原文都改转述。存量文章的引用语境(讲禁词表的那篇)留待清理变更单独处理。

**判断口诀**:**这个词换掉,意思变吗?** 不变就删/换;变了(变成反讽失效/术语不准)就留。拿不准的,留着——为了去味破坏内容是红线。

**批量删「回到本质」段**(Python 正则,从后往前删避免偏移):
```python
seg_pattern = re.compile(r"(^## [^\n]*回到本质[^\n]*\n)(.*?)(?=^## |\Z)", re.M | re.DOTALL)
```

**批量删/换高频词**(`re.subn` 统计替换数):
```python
rules = [
    (r"我的判断是[,，:：]\s*", ""),
    (r"核心判断[:：]\s*", ""),
    (r"恰恰相反", ""),
    (r"真正的(?!需求|问题|瓶颈|价值)", "实际"),
]
```

**批量验证残留**(目标 0 处或仅剩合理用法):
```python
patterns = {"回到本质":r"回到本质","我的判断是":r"我的判断是","终极":r"终极(?!服)",
            "恰恰":r"恰恰","护城河":r"护城河","分水岭":r"分水岭"}
```

### 去 AI 味的红线(不能为了去味破坏内容)

- **扫描结果必须人工判断**:见上文「误报处理」(tags / L2 合法用法两类;L1 无例外词不豁免),不能无脑全删
- **保留有对比/实质语义的「真正」**:「真正的需求」「真正的瓶颈」「压测真正的难点不在跑工具」里「真正」有实质作用,别全删
- **保留合理术语**:「PRD 的核心判断」是产品术语,「SaaS 商业闭环」是业务术语,不是套话
- 删完**复验结构**——去 AI 味削掉的是套话,若误伤信息块(观点缺论据 / 步骤缺件套),补有信息量的内容,不是把套话塞回来

---

## 踩过的坑(实战经验)

### drawio CLI 导出偶发失败

**现象**:`drawio --export` 对某些 `.drawio` 文件报 `Export failed`,但 XML 合法、xmllint 通过。排查过文件名/目录/symlink/xattr/进程残留,均非根因,疑似 CLI 对特定 cell 组合 + 文件元数据的兼容 bug。

**可靠 workaround**:源文件 `cp` 到 `/tmp/` 短路径 → 从 `/tmp/` 导出 SVG 到 `/tmp/` → `cp` 回 `static/svg/`。仍失败就简化图(减 cell 或拆子图)。

### drawio 源文件的书写方式(2026-08-27 补)

`.drawio` XML 一律用 **Write 工具直接写文件**,禁止 bash heredoc 内嵌 Python 字符串生成——heredoc 遇中文/引号/转义会被吞(实测三连失败:`unterminated triple-quoted string`、属性笔误 `vertex="parent"1"` 混入)。XML 属性手写易错,写完先 `py_compile` 级别的自查(标签配对/属性引号),导出失败先查最近一次手改的属性。

### 字数统计的口径与用途

字数统计用 `[\u4e00-\u9fff]` 只数中文,英文术语和标点不计,别用「含英文」的宽松计数自欺欺人。2026-08-26 起字数**只作两个用途**:配图配额基数 + 偏短体检信号,不再是篇幅合格线。

### 去 AI 味会削内容,完成后要复验结构

删「回到本质」段平均削 300-400 字。**每次去 AI 味后都要对照观点清单和结构清单复验**:削掉的应是套话;若观点没了论据、步骤没了四件套,补有信息量的内容,不是补套话。

### 时间格式(2026-08-14 定规)

文章里所有时间用**完整年月日时分秒**(`2026-08-13 11:56:32`,UTC 带时区标注),禁止"8 月 13 日""13 号""昨天"等简写。规范正文在 `style-guide.md`「时间格式」节,改稿时全文扫一遍时间表述。

### front matter 的 date 不许写未来时间(2026-08-26 实战踩坑)

**现象**:文章写完 `hugo` 构建成功、`hugo list all` 也能看到,但 `public/posts/<slug>/` 页面不生成,用户本地预览/线上都看不到文章。

**根因**:Hugo 默认 `buildFuture=false`,front matter 的 `date` 晚于当前时刻的文章**静默跳过**(构建不报错、不警告)。手写 date 很容易拍个"今天晚上"的时间戳,结果当时还是上午——文章直接消失。

**定规**:新建文章时 `date` **必须取当前真实时间**(`date "+%Y-%m-%dT%H:%M:%S+08:00"` 拿到什么写什么),不要手拍整点/未来时刻。排查手法:文章"构建成功却不存在"时,第一时间查 `date` 是否在未来,改成当前时间后重建即可。

---

## 标题六种模式速查(详见 style-guide.md)

> ⚠️ 六种模式是**合格底线**,不是差异点——多篇套同一套模式会撞出同一张脸(AI 味)。真正的差距在「去同质化抓眼球」:前 5-8 字埋冲突、每篇只打一个冲突点、口语化情绪词。先写钩子再套模式。

| 模式 | 适用 | 例子 |
|------|------|------|
| 数字+痛点 | 教程/最佳实践 | `3 人两月交付 512 功能:30 条 AI 命令锁死测试纪律` |
| 揭秘 | 深度 | `低代码渲染引擎揭秘:schema 驱动到可编辑画布` |
| 踩坑复盘 | 踩坑 | `编译能过 ≠ 代码正确:一次 AI 静默删 270 行的事故复盘` |
| 决策为什么 | 最佳实践/观点 | `没用 K8s 也能自治:单机部署 + 夜间 AI Loop` |
| 对比选型 | 最佳实践 | `代开 vs 按租户打包:一份代码怎么变多租户小程序` |
| 成长路径 | 观点/日常 | `让研发长出产品脑:从需求到全自动开发` |

---

## 全站现状(写新文章前了解,避免重复造轮)

- 全站 56 篇,分 6 类,按「前端→全栈→AI 开发」成长线组织
- **篇幅规则以 `references/post-types-guide.md` 为准**:结构门禁 + 篇幅由观点和内容决定(2026-08-26 取消各类文章字数限制),不以固定字数为合格线
- 已覆盖主题见各文章 slug,新文章尽量用 `relref` 互链,补全成长线
- 标题前缀问题已全站清除,新文章不要再加【XX】前缀

