换气检查
贴进一篇草稿,得到两个数字:每个非段落元素的词数,以及每 100 词的加粗处数。它也能处理中文——中文得先定一个明说的计数约定,才谈得上任何评分:表意文字按字计数,再用一个明说、且任意选定的除数换算。在页面内运行,无需注册。
本页如何生产
由 AI agent 起草。 由与生产方不同模型族的模型逐条对照来源与原始数据做了对抗式审查,无未决 P0。尚未经人工通读。 证据最近核验于 2026-09-09。
一篇长文需要有地方让人歇脚。小标题、列表、表格、引文块——凡是「不是又一段正文」的 东西。没有它们,扫读的读者找不到落脚点,就走了。
这个工具量为这件事服务的两个代理指标,而且它老实承认:我们自己大多数长页面也没过线。
这两个数字
| 检查项 | 阈值 | 它在问什么 |
|---|---|---|
| 每个非段落元素的词数 | ≤ 150 | 往下滚多远,才会有个东西打断这片灰? |
| 每 100 词的加粗处数 | ≥ 1 | 扫读的眼睛有没有东西可抓? |
| 长文门槛 | > 800 词 | 低于它,两条都不适用 |
低于门槛时,工具报的是未判定——不是 0,也不是不达标。「没有依据可评」和「评过 了,很糟」是两件不同的事实;一个对两者输出同样文字的工具,必然在其中一个上撒了谎。
单纯数词数做不到的那部分:中文
可读性工具数词。中文没有以空格分界的词边界,所以「有多少个词」在有人选定一个答案之 前根本不成立。靠数词建立起来的评分,在定下约定之前对中文无话可说;而定下约定却不告 诉你定了哪一条的,报的是偏好,不是测量。
这里的约定写死,并且明说:
词数 = 拉丁词 + (表意文字字符数 ÷ 1.7)
1.7 是任意的。 选它,是因为没有数字就建不成一道门,不是因为它对。只要写死一个常 数,换成别的也行。正因如此,工具在每份结果里都打印这个切分——「拉丁 1607 + 表意文字 0 ÷ 1.7」——而不是递给你一个看着权威的合计数。
「表意文字」指的是 CJK Unified Ideographs 基本区,U+4E00–U+9FFF,取自 Unicode
字符数据库。这是一个刻意收窄的读法:数据库用这个名义列了十一个区(基本区加扩展
A–J),把整族都算进去才是更宽松的选择。我们只算基本区,因为我们自己仓库里执行这条
规则的构建门只算基本区——同一条规则出现两个互相打架的实现,比任何一种读法都糟。代
价是:罕见的扩展区表意文字不计入词数。假名、谚文、全角形式和 CJK 标点也在范围之外:
。,、「」 都不是词。
拿译文跟原文对比之前,有一件事值得知道。截至提交 a746249,本站用两种语言发布过的
文章有七篇;这七篇里,每个中文版都带着与英文原文相同的小标题和列表——元素数逐对
完全一致。词数则不然:从比英文低 8% 到比英文高 9% 都有,七篇里四篇中文更长、
三篇更短。
所以这条共用阈值并不是一律对中文更苛刻。译文写得长的页面,它咬得更狠;写得短的,它 更宽松。某一对往哪边走,是那篇译文的事实,不是语言的事实。下面表里的三对中,有两对 走的是另一边:中文更短,比值也更好看。别推断方向,去量你眼前这一对。
什么算一个元素
- 每个列表项算一个元素——一个圆点就是它自己的落脚点。
- 一张表格算一个元素,不是每行一个。引用块同理。
##与###小标题计入;#标题不计,因为一篇文章只有一个,它不是用来换气的。- 一个围栏代码块算一个元素——它像表格一样打断灰墙——但里面的代码不是正文, 所以它的词一个都不计。围栏里的列表记号也不算列表项。
- h4 到 h6 与
##、###合并计入。R4.2 只点了后两者;把更深的子标题也算作换气, 才是诚实的读法。 - 独占一行的图片算一个元素。
- 出现在行首的组件或块级标签算一个元素——本页下方那个
<BreathingCheck />、 一个<figure>、一个<table>。那里明明坐着一个一看就不是正文的东西,所以它算一 处落脚点。
我们自己就没过这道检查——而第一次量它的方法也是错的
在提交 a746249 这个时点、任何整改之前,拿本站已发布的六篇长文跑一遍:
| 页面 | 词数 | 每元素词数 | 每 100 词加粗 |
|---|---|---|---|
| 从研究到高管报告(en) | 1342 | 53.7 | 0.67 |
| 从研究到高管报告(zh) | 1459 | 58.4 | 0.62 |
| 锁定,是有文件格式的(en) | 1524 | 138.5 | 0.52 |
| 锁定,是有文件格式的(zh) | 1458 | 132.5 | 1.10 |
| 导出,才是产品(en) | 1607 | 160.7 | 0.44 |
| 导出,才是产品(zh) | 1475 | 147.5 | 0.88 |
六篇里有五篇没过加粗阈值,还有一篇连元素阈值也没过。写这个工具的时候,这些页面 正在线上。
有意思的是那个不在表里的数字。这套测量的第一版报的是六篇全挂。它错了,而且错得值 得给你看——因为写这类工具的人都会踩到这个 bug:
加粗计数器用的正则禁止加粗区间里出现换行。本仓库的源文件硬换行在 80 列左右, 于是每一个恰好跨两行的加粗短语对它都不可见。《锁定,是有文件格式的》中文版其实有 16 处加粗,不是 11 处——它一直是过关的。
它后面还藏着第二个更隐蔽的 bug:计数前先删掉行内代码,会把空白推到收尾的 ** 前
面,CommonMark 于是不认它是强调。修法是遮蔽代码段、保持长度不变,而不是删掉。
两个都是拿真正的 MDX 解析器重新计数、再做对比找出来的。你接下来要用的这个计数器, 现在与我们自己仓库里执行这条规则的构建门给出完全相同的数字——这个一致由单元测试断 言,不靠指望。
这个教训不限于这一个工具: 对一个已有真正解析器的格式做近似,得到的数字看着合 理,偏差却是系统性的。我们白纸黑字写下了关于自家存档的错误数字,直到对着解析器重新 量才发现。你没有试着弄坏过的指标,它的误差范围你也不知道。
一个实例
下面是这群里最糟那篇的工具原始输出——我们的文章《导出,才是产品》英文版,a746249
时的样子。下面这段是把工具逻辑跑在那一份文件上生成的,不是手写的:
长文且换气不足——R4.2 判定见下。
词数:1607(拉丁 1607 + 表意文字 0 ÷ 1.7)
每个非段落元素几词:160.7(10 个元素,阈值 ≤ 150)——不达标
每 100 词加粗数:0.44(7 处加粗,阈值 ≥ 1)——不达标
由 AtomStorm 换气检查生成(atomstorm.ai/zh/tools/breathing-check/)。靠撒 ** 凑够加粗数并不会带来换气——该做的是把长段拆开。
贴进一篇草稿
Markdown 或 MDX。不会上传——统计在本页内完成。frontmatter 与代码块在测量前已排除。
第二个数字里的陷阱
加粗密度是一个代理指标。往一堵文字墙里撒 **,九十秒就能达标,而页面事后照样一
个字都读不进去——只是分数更好看。
诚实的做法,是那些顺手把数字抬上去的改动:
- 把一段长的拆成两段,各给一个小标题。
- 把一个三小句的长句变成三个列表项。
- 把你用文字描述的那组对照放进一张表。
- 把那条保留意见拎出来做成引用块。
如果数字上去了、页面却没有更好扫读,那这次修改就是错的。这一页之所以给你看一张我们 自己不及格的表、而不只给一个阈值,理由全在这里。
我们核验了什么,没核验什么
- 已核验。 对仓库里每一份内容文件,这个计数器给出的词数、元素数和加粗处数,都与
scripts/readability-verify.mjs——我们自己仓库里执行这条规则的构建门——相同。一个 单元测试会跑那道门、逐文件对比两边,所以两者不会无声地漂开。那道门的加粗计数器本 身也对着真正的 MDX 编译器交叉核验过。比值用的是未取整的词数做除数;先取整会让最 后一位变样。上面那个例子,是从它点名的那个冻结提交重新生成的。 - 未核验。 两条阈值中任何一条能否预测真实的阅读行为。它们编码的是一种编辑偏好, 测试过的语料只有我们自己的存档,没有别人的。我们没做过读者研究。计数卡给这两个数字的是同一种身份:本站自己守的阈值。
来源
Unicode Consortium
Unicode Character Database — Blocks.txt (the CJK Unified Ideographs block ranges)unicode.org · 核查于 2026-09-09
Unicode Consortium
UAX #29: Unicode Text Segmentation — why word boundaries are not a whitespace problemunicode.org · 核查于 2026-09-09