在 AI 生成内容越来越多的今天,技术文章里最常见的问题不是错误,而是 slop:信息密度低、套话多、步骤模糊、看起来专业却无法复现。我一度以为自己的 anti-slop skill 是缺一套写作模板,直到我从一本 1986 年的飞机手册里得到真正的答案。那本手册没有一句吸引眼球的话,没有铺垫,没有总结,但它能让维护者照着完成检查、排故和维修,并且在每个关键点上都写了“合格标准”和“不符合标准怎么办”。技术文档要做的并不是让读者觉得读懂了,而是让读者在真实环境里按步骤做完,并且拿到一致的结果。这篇文章就用那本手册带来的启发,讲一套适合技术博客和技术文档的反废话写作方法,包括检查单结构、故障树、极限值表、发布前自审清单。
这篇文章适合正在写技术博客、接口文档、内部 Wiki、排错手册,或者用 AI 辅助写作但总感觉内容“空”的开发者。读完你会得到一套可以直接套用的段落检查单和文章审查方法。
1. 为什么一本 1986 年的飞机手册能治好技术写作的“slop”
1.1 手册的第一课:文档是为了让操作者做对,不是为了让作者看起来专业
飞机手册里的指令,写法和我们平时看到的很多技术教程完全不同。以常见飞机维护手册里的“检查前起落架减震支柱”为例,它不会写“请确保起落架状态良好,如有异常及时处理”,而是会写成类似这样的结构:
- 操作对象:前起落架减震支柱。
- 操作动作:目视检查支柱外筒是否有油液痕迹,测量支柱伸出长度。
- 合格标准:伸出长度在 X 到 Y mm 范围,外筒无连续油迹。
- 不符合标准:停飞,按手册任务编号进入更换流程。
- 完成后动作:在维护记录上填写检查结果。
换成技术文档的语境,这段话的等价写法是:
- 操作对象:Redis 服务。
- 操作动作:执行
redis-cli ping。 - 合格标准:返回
PONG。 - 不符合标准:检查进程、端口、日志,并给出对应修复命令。
- 完成后动作:在文档记录中填写验证结果。
很多技术文章之所以“软”,不是因为没有干货,而是把干货包装成了“请确保”“建议合理配置”“注意检查”这类安全套话。读者看完后知道应该做某件事,却不知道做到什么程度算成功,失败了应该从哪里查起。
注意:技术文档最重要的不是读完感觉懂了,而是照着做能得到一致结果。这个标准可以用来区分“教程”和“读后感”。
1.2 现代技术文章里的 slop 到底是什么
slop 在英文技术社区里指低信息密度、高套路感的内容。它不是完全错误,而是“正确的废话”。技术文章里的 slop 有很多固定长相,比如:
- 空泛开头:“随着业务的不断发展,系统面临越来越多的挑战。”
- 过渡废话:“既然我们已经了解了基本概念,下面进入实际操作。”
- 无参数建议:“超时时间要根据实际情况合理设置,避免过长或过短。”
- 无判定标准:“配置完后请检查服务是否正常运行。”
- 无失败分支:“如果出现问题,请检查日志。”
- 模块化总结:“总之,通过上述步骤,我们可以提升系统的稳定性和可靠性。”
这些句子单独看都没问题,合在一起却组成了一篇无法执行的文章。问题在于,它们没有回答读者在真实环境里最关心的四个问题:做什么、做到什么标准、失败怎么看、修好后怎么验证。
1.3 为什么飞机手册天然反 slop
飞机手册之所以几乎不存在这类废话,是因为它的读者要在高风险环境里执行操作。手册里的歧义可能被直接转化成错误操作,错误操作又可能带来严重后果。因此,手册作者必须默认读者没有上下文,必须把每个步骤写到“不依赖作者在场也能完成”的程度。
技术文档的处境越来越接近这一点。读者部署一套系统时,文档作者并不会在旁边解释。服务宕机时,排障文档要能帮值班人员快速定位问题。生产环境的一次误操作,后果未必比一次飞行检查错误轻松多少。所以技术文档应该继承飞机手册的写作纪律:每一句话要么支撑一次操作,要么支撑一个决策,否则删除。
当我把这个标准带回自己的文章里,原来很多段落都经不住审问。比如“建议开启持久化以保证数据安全”这句话,读者无法判断开启哪种持久化、RDB 和 AOF 怎么选、开启后对性能有多大影响。它看起来正确,却不能让读者完成任何操作,这就是典型的 slop。
2. 飞机手册的核心结构,正是技术文章缺失的骨架
2.1 检查单结构:动作、标准、预期结果
飞机手册里大量内容以检查单形式出现,尤其是飞行前检查。检查单不是简单的待办列表,而是每个项目都带操作动作和合格标准。把这种结构迁移到技术文章里,一个操作步骤就不再是“安装 Redis”,而是“在 Ubuntu 22.04 上安装 Redis 7.0,执行redis-server --version后能看到 7.0 以上版本号”。
一个合格的技术检查单条目通常包含五部分:
| 组成部分 | 要回答的问题 | 反面写法 |
|---|---|---|
| 操作对象 | 对什么进行操作 | 修改配置 |
| 操作动作 | 具体执行什么命令或写什么代码 | 正确配置服务 |
| 合格标准 | 什么输出或现象算成功 | 运行正常 |
| 失败分支 | 不合格时怎么办 | 检查配置 |
| 完成确认 | 如何留下可追溯结果 | 记录成功 |
没有这五部分,步骤就只是愿望清单。
2.2 故障排除结构:现象、可能原因、隔离步骤
飞机故障排除手册通常不会直接从结论开始,而是先写清楚“故障现象”和“出现条件”,再按优先级列出可能原因。原因不能并列堆在一起,要按可能性或成本排序,并给出隔离手段。例如:
- 现象:发动机启动后滑油压力低。
- 出现条件:冷启动后 2 分钟内,环境温度 -10℃。
- 可能原因 1:滑油量不足。
- 隔离步骤:检查滑油尺油位。
- 可能原因 2:滑油压力传感器故障。
- 隔离步骤:用机械压力表对比实测值。
- 可能原因 3:滑油泵磨损。
- 隔离步骤:完成前两项隔离后,进入分解检查流程。
技术排错文章如果跳过“现象”和“出现条件”,直接写解决方案,读者很容易把错误方案套到自己的场景里。更常见的问题是,文章只列原因,不教读者如何区分这些原因。正确的做法是把“判断依据”写进每一步里。
2.3 极限值表:参数必须带单位、边界和条件
飞机手册里大量使用表格来消除歧义。以滑油系统参数为例,一页典型的极限值表会包含最低值、正常范围、最高值以及测量条件。这样维护者不会把“正常值”误当作所有条件下都成立的值。
技术文档里的参数也应该这样写。拿 Nginx 的超时参数举例,如果只写“timeout 设置为 60”,读者既不知道单位是秒还是毫秒,也不知道适用对象是proxy_read_timeout还是keepalive_timeout,更不知道设置过短或过长会出现什么现象。极限值表的思路要求我们补齐这些信息。
2.4 飞机手册结构映射到技术博客章节
飞机手册的章节安排和技术文章没有一一对应关系,但存在很强的映射。把这种映射关系摆在面前,写文章时就有了一条骨架:
| 飞机手册模块 | 对应技术文章模块 | 解决的问题 |
|---|---|---|
| 飞行前检查单 | 环境准备与依赖安装 | 让读者确认前置条件就绪 |
| 正常操作程序 | 核心配置和代码实现 | 让读者按步骤完成主流程 |
| 故障排除树 | 常见问题与排查路径 | 让读者在异常时找到定位方向 |
| 极限值表 | 参数说明和配置速查 | 让读者知道边界条件和推荐范围 |
| 维修记录 | 变更记录、踩坑记录、版本升级记录 | 让读者理解过去发生过什么 |
| 适航指令和服务通告 | 安全公告、紧急修复说明 | 让读者知道哪些问题必须优先处理 |
这张表可以直接用来规划一篇技术博客的章节。先想清楚有没有“检查单”,有没有“排错树”,有没有“极限值表”,再开始动笔。
3. 从“我说清楚了”到“读者能复现”:用检查单式写作重写一段技术内容
3.1 一段典型的 slop 写法
假设要写一篇 Spring Boot 使用 Redis 做缓存的技术文章,很多初稿会这样写:
请先确保 Redis 已经部署并正确运行。如果连接失败,请检查网络和配置。设置缓存过期时间时,要根据业务需求合理设置,避免缓存雪崩。建议开启持久化以保证数据安全。
这段话的问题非常明显:
- “确保 Redis 已经部署并正确运行”没有给出验证命令。
- “检查网络和配置”没有指出检查哪些配置、看到什么结果才算正常。
- “合理设置”没有给出建议范围和判断逻辑。
- “开启持久化以保证数据安全”没有说明开启哪种持久化,也没有说可能带来什么代价。
读者读完这段话,既不能确认自己的环境是否正常,也不能做出参数决策。
3.2 检查单式重写版
下面是按照飞机手册检查单思路重写的版本:
操作前先确认 Redis 可用。执行
redis-cli -h 127.0.0.1 -p 6379 ping,返回PONG表示连接正常。如果返回Could not connect to Redis,先执行ps -ef | grep redis-server确认进程存在,再执行ss -lntp | grep 6379确认端口监听;进程不存在则按启动脚本拉起服务,端口未监听则检查redis.conf中bind和port配置。缓存过期时间按业务可接受的延迟选择。读多写少且能容忍最多 5 分钟旧数据的场景,可先设置 300 秒;需要分钟级一致性的场景,设置 60 秒。不要对同一业务域的所有键设置相同过期时间,建议在 60 到 300 秒之间加随机偏移,避免大量键在同一时间过期。
生产环境建议开启 AOF 持久化,配置项为
appendonly yes。开启后写入性能会有一定下降,需要同时监控redis-cli info persistence中的aof_last_write_status;该值为ok表示 AOF 写入正常,出现错误时需要检查磁盘空间和dir目录权限。
这段重写后的文字比原版长,但每一句都有明确用途。第一段是操作和验证,第二段是参数决策,第三段是生产环境注意事项。它不是“更加详细”,而是把原来模糊的指令替换成了可执行的指令。
3.3 拆解重写后为什么更好
把重写后的段落与飞机检查单结构对照,可以看得很清楚:
| 原版问题 | 重写后的对应写法 | 对应飞机手册动作 |
|---|---|---|
| 没有验证命令 | 给出ping命令和预期输出PONG | 检查液压油位并确认达到刻度线 |
| 没有失败分支 | 给出连接失败后的进程和端口检查命令 | 油位低于标准时补充液压油并再次检测 |
| 参数没有范围 | 给出 60 秒和 300 秒两个参考值 | 标出正常压力范围:55 到 65 psi |
| 没有说明边界加入随机偏移避免同时过期 | 对应手册中的“在限定范围内调整” | 不同工况下采用不同调校值 |
| 生产建议不完整 | 说明 AOF 开启后的代价和监控指标 | 维修后必须执行地面功能测试 |
关键在于,每一句话都能回答一个“读者会在执行时遇到的问题”。如果一句话不能回答任何执行问题,它大概率就是废话。
3.4 可复用的“技术段落检查单”模板
写任何技术段落前,可以用下面这套清单自检。它也可以直接作为文章草稿的批注标准:
- [ ] 这一段读者要完成什么具体任务?
- [ ] 是否给出了可执行的命令、代码或配置片段?
- [ ] 是否写明了成功时的预期输出?
- [ ] 是否写明了失败时的典型报错和检查顺序?
- [ ] 参数是否包含单位、参考范围、边界条件和调整后果?
- [ ] 是否标注了学习环境与生产环境的区别?
- [ ] 删掉这一段后,读者是否仍然无法完成操作?
- [ ] 是否出现了类似“合理”、“正确”、“确保”但没解释的词?
这套清单每篇都值得过一遍。它很像飞行前的 cockpit check,过程重复,但能拦住大量低级问题。
4. 用飞机故障树设计排错章节,让读者不再“到处翻日志”
4.1 飞机故障树怎么组织
飞机故障排除树的结构是稳定的:先写现象,再写出现条件,再按优先级列可能原因,每个原因都配有隔离验证方法,最后才是修复动作和验证标准。它很少直接写“可能是 X 导致的”,因为那会让维护者盲目更换部件。
一台发动机出现滑油压力低,手册不会只告诉你“检查滑油泵”。它会要求你先确认油量、再确认传感器读数、再检查油路,最后才拆泵。这样做的目的是用最少的成本和风险定位问题,避免把好部件换下来,也避免新手直接进入高风险维修动作。
技术排错文章同样应该遵守这个顺序。最常见的技术排错低效做法,是把可能原因按罗列方式写出来,没有告诉读者如何区分它们。读者只能逐个试,运气好一次成功,运气不好把配置改乱了。
4.2 技术排错章节的标准顺序
技术排错章节建议按这个顺序组织:
- 写清楚现象:用户在哪个页面、哪个接口、哪个命令上看到了什么。
- 写清楚环境:操作系统、版本、部署方式、关键配置。
- 写出现场证据:日志关键字、错误码、CPU/内存/网络指标。
- 列可能原因,但每个原因必须带“如何判断是这个原因”。
- 给出修复动作,并说明修好后怎么验证。
- 最后写预防措施,避免同一类问题再次出现。
这里的难点不是写原因,而是写“如何判断是这个原因”。只列原因而不给判断方法的排错文章,等于只给零件清单不给拆装顺序。
4.3 例:Nginx 502 排错章节的表格化写法
以最常见的 Nginx 502 Bad Gateway 为例,用表格呈现排错树:
| 现象 | 可能原因 | 检查命令 | 判断标准 | 处理方式 |
|---|---|---|---|---|
| 所有请求稳定返回 502 | 后端服务未启动 | systemctl status backend或ps -ef | grep backend | 进程状态为 active/running 为正常 | 启动服务,确认开机自启 |
| 502 间歇性出现,后端偶有请求 | 后端处理超时 | 查看 Nginx error.log,搜索upstream timed out | 日志中出现超时记录 | 调大proxy_read_timeout,或优化后端接口耗时 |
| 502 稳定出现,后端日志没有对应请求 | upstream 地址配置错误 | nginx -T | grep proxy_pass | 与后端实际监听地址和端口一致 | 修改配置后执行nginx -t并 reload |
| 后端进程正常但连接数过高 | 连接池或最大连接数不足 | ss -s或后端连接数监控 | 连接数达到配置上限 | 调大后端最大连接数,或引入连接池 |
| 后端返回异常但 Nginx 记 502 | 接口抛未捕获异常 | 查看后端应用日志,搜索最近异常栈 | 存在 NPE、DB 连接失败等异常 | 修复代码或数据库连接配置 |
这张表的作用不是让读者直接跳到最后一行,而是按现象找到自己的分支,再逐步排除。每一行里都有“判断标准”,这样读者不会把配置错误导致的问题,错误地压到后端接口优化上。
注意:排错文章最忌只给原因不给验证方法。每个解决方案都要回答“怎么知道修好了”。表格里加一列“检查命令”和“判断标准”,就是强制回答这个问题。
4.4 如何采集故障证据,避免无效排查
飞机维修记录里,故障描述通常包含机号、日期、故障现象、处置动作、结果和签署人。技术排错也一样,如果文档读者来提问时能按统一结构提供信息,排查效率会高很多。
技术博客和内部文档应该直接给出一个“排错记录四要素”模板,让读者在提问或排查前先填完:
环境:操作系统版本 / 应用版本 / 部署方式 / 关键配置项 现象:用户看到什么、哪个接口、哪个页面、错误信息原文 复现:按什么顺序操作可以稳定触发 日志:关键日志片段,含时间戳和异常堆栈 期望:正常情况下应该得到什么结果这份模板看起来简单,但能大幅减少“我这边报错了,帮我看看”这样的无效沟通。它和飞机手册要求维修者记录故障条件一样,是为了把“偶然现象”变成“可复现问题”。
5. 反 slop 的技术写作纪律:单位、范围、条件、例外
5.1 参数不写单位等于没有参数
飞机手册里的扭矩数据一定带单位,比如“105 至 115 磅·英寸”,并且会注明是否适用于干螺纹或润滑螺纹。技术文章里不写单位的参数,会让读者在完全不同的指标下做出错误决策。
| 写法 | 问题 | 改进 |
|---|---|---|
| 设置连接超时为 5 | 5 是秒还是毫秒?哪个连接? | 设置 HTTP 客户端 connectTimeout 为 5000 ms |
| 将线程池核心线程数设为 10 | 10 是根据什么估算的? | 先按 CPU 核数的 2 倍设为初始值,再根据压测结果调整 |
| 队列容量建议为 1000 | 队列满了怎么办?拒绝策略是什么? | 队列容量 1000,拒绝策略 CallerRunsPolicy,线程耗尽时由调用线程执行任务 |
| 将日志级别设为 INFO | 磁盘占用和日志量可能怎样变化? | 在测试环境确认单小时日志量,再决定是否使用 INFO |
参数不完整不是“少写一句话”,而是会让读者直接跳到错误操作。飞机手册里的每个参数都带条件,条件决定参数适用范围。
5.2 范围声明:明确适用版本、环境和数据量级
技术文档经常因为“版本没写清楚”变成误导。一份 Nginx 配置在 Nginx 1.18 上生效,不代表在 1.25 上行为完全相同。飞机手册会在每一章开头写明适用机型、发动机型号和改型状态,技术文章也应该在开头写明适用范围。
推荐在文章开头加一段范围声明:
适用于: - Spring Boot 2.7.x - Redis 6.2 及以上 - Linux 环境,bash shell 不适用: - Spring Boot 1.x 自动配置差异 - Redis Cluster 模式下的键过期广播行为(需单独说明)范围声明不只是免责,它能帮读者快速判断这篇文章是否适合自己,也能提醒作者不要写出跨越所有版本的确定结论。
5.3 不要写“绝对解决”,要写“在条件下成立”
飞机手册很少写“更换这个部件后故障一定消失”,而是写“如果故障原因是燃油泵磨损,更换燃油泵后,执行慢车测试和最大功率测试,确认滑油压力和燃油流量在规定范围内”。这是更严谨的表达方式:结论绑定到原因和验证条件。
技术文档可以这样写:
- 错误写法:调大
proxy_read_timeout后 502 问题就解决了。 - 正确写法:如果 502 的原因是后端响应超过
proxy_read_timeout当前值,将超时时间调到 60 秒后,用连续 1000 次请求验证,502 数量应降为 0。
这样写的好处是,读者不会把“某种条件下的修复”当成“所有场景的万能药”。当问题没有解决时,也能根据条件倒推出需要检查的方向。
5.4 区分学习环境与生产环境,避免读者误操作
很多技术文章只写“怎么启动”,不写“生产环境还要做什么”,导致读者直接把学习配置搬到生产环境。飞机手册会把“地面测试”和“飞行前检查”分开,因为场景不同,风险不同。
技术文档也建议用一张表明确区分:
| 操作 | 学习环境 | 生产环境 |
|---|---|---|
| Redis 持久化 | 可关闭持久化,加快验证 | 开启 AOF,配置appendonly yes,监控aof_last_write_status |
| Nginx 配置热加载 | 直接nginx -s reload | 先nginx -t,观察error.log,保留上一版配置回滚 |
| 数据库变更 | 可清库重建 | 通过备份、双写、灰度发布逐步执行 |
| 日志级别 | DEBUG 便于观察 | 用 INFO/ERROR,并配置日志轮转 |
| 账号权限 | 统一 root/管理员 | 最小权限,独立账号,操作留痕 |
清楚了环境边界,读者才不会把教程里的临时命令用在生产服务器上。
6. 发布前用“手册审查法”过滤废话
6.1 逐段审查流程:这条信息能支撑一次操作吗
写完初稿后,不要直接发布。把自己当成一个第一次接触该系统的读者,逐段问三个问题:
- 这段文字能不能让读者执行一个具体操作?
- 读者完成操作后,能不能知道自己做对了没有?
- 如果读者做错了,文章有没有给出检查方向?
三段都回答“不能”的内容,无论读起来多通顺,都建议重写或删除。这个流程和飞机放行前的检查类似:不追求发现所有错误,但必须避免带着明显问题出去。
实际操作时,可以把文章打印出来或放在另一个阅读窗口里,每读一段就在旁边标记:
- 可执行标记:这一段有命令、有代码、有配置,读者能动手。
- 可验证标记:这一段有预期输出、日志、测试结果。
- 可失败标记:这一段有异常提示和排查方式。
- 无效标记:这一段只是泛泛而谈,没有以上三种信息。
一篇文章如果无效标记太多,说明它更接近“概念说明”,而不是“技术教程”。
6.2 反 slop 审查清单(Markdown 可直接复制)
下面这份清单可以直接放进文章草稿或写作任务里。每一条都对应一种常见的废话类型:
- [ ] 开头前 200 字是否直接出现核心关键词和读者受益点? - [ ] 是否在开头写明了文章适用范围和版本前提? - [ ] 每个步骤是否包含:操作命令/配置代码、预期成功输出、失败处理? - [ ] 每个参数是否包含:含义、单位、默认值、推荐场景、边界影响? - [ ] 是否区分了学习环境和生产环境? - [ ] 排错部分是否按“现象 -> 条件 -> 原因 -> 检查 -> 修复 -> 验证”组织? - [ ] 是否给出了至少一个判断“确实修好了”的方法? - [ ] 是否存在“确保”“合理”“注意”“正确”但未解释具体标准的句子? - [ ] 是否使用了表格来整理对比项和参数速查? - [ ] 是否设置了至少 3 个常见坑,并且每个坑都给出了解决方案? - [ ] 删除任意一段后,读者是否仍能完整复现? - [ ] 是否避免了“绝对有效”“一定解决”这类无条件的结论?这份清单可以作为文章发布前的最后一道检查。它不能保证内容正确,但能筛掉一大半“看起来专业、读起来没用”的内容。
6.3 改写示例对比:同一段文字的三轮迭代
把同样的知识点放在三个版本里,能直观看出 slop 被逐步清除的过程。
第一版:
线程池大小要合理配置,建议根据业务设置,避免过大或过小。
第二版:
线程池核心线程数初始值可以设为 CPU 核数的 2 倍,队列容量 1000,拒绝策略使用 CallerRunsPolicy。生产环境需要结合 QPS、接口耗时和依赖服务的资源情况调整。
第三版:
先用
ThreadPoolExecutor默认参数运行压测。观察 10 分钟内队列积压、任务拒绝数和 CPU 使用率。如果队列积压持续增长,说明核心线程数或队列容量不足;如果 CPU 使用率长期超过 80% 且队列长期为空,说明核心线程数偏高。调整后重新压测,并记录调整前后 QPS、P99 耗时和拒绝次数。
第三版给出了执行动作、观察指标、判断标准、调整逻辑和验证方法。它不再需要读者猜测“合理”是什么意思,因为所有判断标准都摆在了台面上。
6.4 把飞机手册当作长期训练样本
反 slop 不是一次改稿就能练成的技能,更像是对“文档用途”的持续敏感度训练。可以定期找一份高质量的专业手册,不管是飞机维护手册、铁路设备手册还是大型软件操作手册,抽几页分析它的句式,看它是如何写检查项、如何写警告、如何写极限值的。
更好的训练方式是回改旧文章。把半年或一年前写的技术博客拿出来,用本文的检查单重新审一遍。那些“请合理配置”“注意查看日志”“结合业务情况调整”的句子,大部分都能被改写成带命令、带参数、带验证条件的具体操作。
真正让 1986 年那本飞机手册变得有价值的,不是纸张发黄,而是它在每一页都坚持了同一条原则:文档必须经得起执行。这个原则放在今天的技术写作里,就是最好的 anti-slop skill。