
1. 为什么“再检查一遍”总是失效impeccable 的诞生动机过去很长一段时间里我都有个特别典型的坏毛病交付前的最后一刻我会盯着屏幕告诉自己“再检查一遍就交”。但这遍检查通常只持续几分钟眼睛从开头滑到结尾看到几个格式问题顺手改掉然后觉得“应该没问题了”点击发送。结果呢对方隔天回邮件列出三处术语不一致、两处编号错位、一个过期数据。那一刻我意识到问题不是我不认真而是“再检查一遍”这个动作本身不可执行。“impeccable”这个词的意思是无可挑剔、毫无瑕疵。但我后来想明白一件事如果你只是把“无可挑剔”当成目标而不把它拆成具体规则那它就和“再检查一遍”一样是一句正确的废话。真正的无可挑剔不是感觉出来的是验证出来的。打个比方体检报告不会写“你身体看起来还行”它会写血压多少、血糖多少、某项指标是否超标。交付物也该这样——每个维度都得有明确数值和判定标准。所以我开始做一件事把“交付前自检”从一种行为习惯改造成一套规则引擎。它不是复杂的质量管理理论就是一个能跑在终端里的轻量工具名字就叫 impeccable。核心逻辑非常简单你把“什么算合格”写成清单它按清单逐项执行每项只输出 pass、fail、warn 三种结果并且附上证据。有了这套东西之后“再检查一遍”终于变成了一句可以执行、可以被追问的话。这套思路受代码 lint 工具的启发很深。我们写代码时绝不允许自己“感觉没什么问题就提交”一定会跑一遍 eslint、cppcheck 之类的静态检查。为什么代码需要规则而文档、方案、设计稿就不需要因为它们同样是交付物。我坚信任何交付物都可以被形式化地定义“合格标准”只是大多数人没花时间去写这份标准。impeccable 要解决的就是这个缺口。这篇文章适合的人很明确经常做项目交付、写技术方案、发文章、提 PR 的从业者。如果你也经历过“检查了半天还是漏了低级错误”那你应该会很需要这套思路。2. impeccable 的核心机制检查项、上下文与结果三件事2.1 三个抽象概念impeccable 不复杂核心只有三个概念Context上下文、Check检查项、Result结果。Context 描述的是“被你检查的交付物是什么”。它至少包含交付物路径、交付类型文档/代码/方案、面向对象以及一些可选的元信息比如版本号、日期、文件清单。为什么需要上下文因为同一个检查项在不同场景下判定规则不同。比如“标题存在性”对一篇博客是必需的但对一个代码 PR 就没有意义。框架只负责执行规则怎么生效由上下文决定。Check 是清单里的每一条规则。我给它设计了七个字段id唯一编号方便在结果里定位问题title一句话说明这条检查的目的category属于哪个维度完整性、一致性、可读性、合规性、可验证性typeauto 或 manual自动执行还是人工确认where针对哪些文件执行支持 glob 模式rule具体的判定条件severityblocker、normal、suggestion 三档Result 则是执行结果。每一条检查跑完都会输出状态和证据。pass 就是满足fail 就是不满足需要改warn 是存在风险但不一定致命。证据这一项我特别看重——fail 的时候必须指出是哪一行、哪个文件、哪个数据出了问题绝不允许只说“不通过”三个字就完事。2.2 为什么做成“自动 人工”混合模式早期我把所有检查都设计成自动执行结果发现团队用起来非常痛苦。原因是文档领域的很多规则没法写成纯代码判断比如“语气是否得体”“前后逻辑是否连贯”“这段描述读者能不能看懂”。它们高度依赖人的判断强行自动化只会写出大量脆弱正则误报率高到让人想删掉工具。反过来如果全部靠人工检查又回到原来的老路——注意力迟早会疲劳“确认”会变成“打卡”。所以我在设计上做了一个取舍能形式化判断的尽量自动必须靠经验的就转化成“人工确认问题”。人工确认项也有讲究。我不会问“你觉得内容精彩吗”这种开放问题没有判定基准。我会问成选择题“如果让一个从没看过本项目的同事读这段背景介绍他能说出项目解决什么问题吗——能/不能/不确定”。把抽象感受改成可回答的选项人工确认的质量会稳定很多。强调一下自动检查项和人工确认项的比例我实测下来 80% 自动、20% 人工是最舒服的区间。纯自动容易过拟合人工太多容易流于形式。2.3 证据比结论更重要impeccable 跑完一遍之后输出的不是一张只有 pass/fail 的统计表而是一份“证据链”。每条结果后面跟着检测到的实际内容比如匹配到的行号、扫描到的 TODO 清单、文件大小值、链接状态码。我会把这套结果当成交付物的一部分随邮件或 PR 一起发出。有人觉得这样很麻烦但我想说证据有两个无法替代的价值。第一它逼着框架诚实——软件不会因为“感觉良好”就放行每条结论都有事实支撑。第二它让接收方快速信任你的交付质量。当对方看到结果表里写着“链接检查45 个链接全部返回 200证据时间戳 12:30”他很难不放心。这种做法把个人能力转化成组织级信誉长期积累下来收益非常大。严格来说这套机制本身不复杂有价值的在于背后的思维转变从“我检查过了”变成“我按照这 47 条规则逐项验证过了结果如下”。3. 写配置就是写标准一套可直接改用的交付检查模板3.1 为什么选 YAML 写清单在配置格式上我最初犹豫过 JSON 还是 YAML最后选了 YAML。理由很朴素它支持注释。检查项是给人看的标准不是只给机器读的数据。每条规则背后都应该写一行注释说明“为什么会有这条”比如“链接有效期检查曾经因为运气不好刚好碰到某宣传页过期被投诉所以这个必须列为 blocker”。一年后再看自己的配置你会感谢当初写的这些注释。下面是我目前用于项目文档交付的完整配置模板。你可以直接存成 checklist.yaml 使用字段含义我会逐条解释。meta: name: 项目文档交付自检 version: 1.0 context: type: document path: ./docs audience: 外部客户 checks: - id: DOC-001 title: 必须有 README 文件且非空 category: 完整性 type: auto where: ./docs/README.md rule: 文件存在且大小 200 字节 severity: blocker - id: DOC-002 title: 标题层级不能跳级 category: 一致性 type: auto where: ./docs/**/*.md rule: 解析 Markdown 标题不存在 H2 后直接出现 H4 的情况 severity: normal - id: DOC-003 title: 禁止遗留 TODO/FIXME category: 可验证性 type: auto where: ./docs/**/*.md rule: 扫描出现次数为 0 severity: blocker - id: DOC-004 title: 核心术语在全文首次出现时必须有解释 category: 可读性 type: manual where: 所有文档 rule: 随机抽查三个术语上下文中有清晰定义即可通过 severity: normal - id: DOC-005 title: 所有外部链接返回 200 category: 合规性 type: auto where: ./docs/**/*.md rule: 提取 http/https 链接并发 HEAD 请求状态码为 200超时按 fail 处理 severity: blocker3.2 为什么每条规则都要求“可观察”判断一条检查项写得好不好我有一个简单测试你能不能说出“当它不满足时你会看到什么具体现象”。如果说不出来这条规则就先不要写。举几个反例。“内容要精彩”“逻辑要清晰”“格式要美观”这些全是不可观察的描述执行者看到这种规则时只能靠猜。正确的做法是把抽象形容词翻译成具体现象“逻辑要清晰” → “每个章节的目标读者是明确的章节第一段出现‘本节我们将’这类引导句”“格式要美观” → “表格列宽不溢出页面、代码块有语言标注、图片按顺序编号”我写规则时会做一个“失败样例先行”的动作先写出一个故意不合格的交付物看规则能不能抓住它。如果连明显的不合格都抓不住就说明规则写得太虚需要继续拆解。这方法听上去很笨但它保证了每条检查项在真实世界有区分度。3.3 人工确认项的正确写法人工项如果写不好是整个框架里最容易失效的部分。我最初写过一个很失败的例子“文档是否对读者友好”——团队成员全都选了“是”但在随后的评审中仍然被吐槽“看不懂”。后来我才意识到这是因为“友好”是感觉词没有触发人的分析脑。改成选择题后效果立刻不一样。比如这样写“请从文中找出并摘录一段本项目的两个核心指标如果 30 秒内找不到对应文字则本项 fail”。这种要求把模糊判断变成了具体的操作任务。人一旦需要去“找证据”就不得不真正阅读内容确认质量的行为才有意义。人工项最忌讳模棱两可的中立答案。我在设计里只给三个选项能、不能、不确定。选择“不确定”也要解释原因。这样即便这轮检查没过下一轮改进时也有了明确方向。4. 三个落地场景文章、代码、设计方案怎么接入 impeccable4.1 场景一技术文章发布前的自检我做知识分享内容时最怕的是文章里充斥一些空泛句式或者标题互相重复、结构松散。这些在“自我感觉良好”时发现不了于是我把一些规则写进 impeccable 配置里。重点看这段配置我觉得它特别能说明问题- id: POST-001 title: 前 100 字内出现核心主题词 category: 可读性 type: auto rule: 读取正文前 100 字匹配关键词列表中的至少一个词 severity: normal - id: POST-002 title: H2 标题不能与其他 H2 相同或高度相似 category: 一致性 type: auto rule: 计算 H2 之间的编辑距离相似度 0.8 视为重复 severity: blocker - id: POST-003 title: 禁止出现空话套话句式 category: 可读性 type: auto rule: 扫描‘随着技术的发展’‘综上所述’‘通过本文’等高频空话出现即 fail severity: normalPOST-003 这条很有意思。它本质上是字符串匹配技术上很幼稚但在实际工作中意外地有效。空话套话是有套路的套路就说明可以用规则框住。我甚至建议你维护一张“废话黑名单”持续往里加你在真实写作中发现的新套话。规则不是死的它是会成长的。执行的时候我会用一条命令impeccable check --config blog.yaml --context path.。跑完之后结果表里能清楚看到哪一篇没通过、哪一条证据挂在哪一行。发稿前我可以对着结果一条一条改而不是凭感觉“再润色一遍”。4.2 场景二代码 PR 提交前的自检代码场景大家其实已经很熟悉 CI 了但 CI 是“提交之后”的质量闸门而 impeccable 的价值在于“提交之前”的个人自检。区别在于CI 发现问题时你已经把脏数据推上去了必须再走一轮修改、提交、评审而在本地自检拦截下来整个过程只要几秒钟。我用的代码 PR 配置包含几个维度- id: PR-001 title: 新增文件必须有对应测试 category: 完整性 type: auto rule: 解析 git diff新增 .py 文件必须能找到同路径 test_*.py severity: blocker - id: PR-002 title: 禁止残留调试代码 category: 可验证性 type: auto rule: 扫描 diff 内容出现 print(、console.log、debugger 即 fail severity: blocker - id: PR-003 title: 变更涉及公共接口时必须更新文档 category: 一致性 type: manual rule: 请在 PR 描述中说明本次变更对外部使用者的影响 severity: blocker把它接进 pre-commit hook 只需几行脚本#!/bin/bash if ! impeccable check --config pr.yaml; then echo PR 自检未通过请先解决 fail 项 exit 1 fi注意不要把 pre-commit 变成可绕过的形式。我的经验是hook 一旦允许--no-verify跳过团队就一定会跳过。你要做的其实是在沟通层面立规矩跳过意味着对自己交付质量不负责。技术上强制文化上也要形成共识。4.3 场景三设计方案评审会前的自检写方案的人最怕什么评审会开了半小时大家还不知道这份方案要解决什么问题。为了杜绝这种情况我在方案交付前强制要求通过几个结构检查项。方案类检查项其实是对思考的约束“用三句话说明背景现状和要解决的核心问题”写不清楚就退回重写“成功指标必须可量化”比如“性能提升 30%”可以“体验变好”不可以“必须有失败场景分析”至少列出两个可能失败的环节和应对策略“明确本次不做的事项”防止范围悄悄蔓延这些规则我用 manual 类型配置但会要求提交者在评审前把回答写在文首的清单区块中。如果有一条没答上来评审会我会直接暂停讨论让对方先回去补充。听起来很严格但实践下来反而节省了所有人的时间因为大家的注意力能直接放在真正需要决策的地方而不是一直在补基础背景。我还会把跑完的结果发到群里作为会议附件。会议一开始每个人看到的就是同一张检查结果表讨论效率提升非常明显。5. 跑了大半年之后的反思检查项设计如何避坑5.1 坑一检查项无限膨胀最后变成“全过就行”我从最初 12 条规则一路加到 54 条然后开始出问题了。团队执行时只关心 blocker 项normal 和 suggestion 几乎不看因为数量太多根本翻不过来。更糟的是大家形成了“只要全 pass 就万事大吉”的心态把质量责任完全外包给工具。这个问题的解法是分级 配额。blocker 级别不超过整份清单的三分之一normal 项允许少量不通过但同一交付物累计超过三个 normal fail 就需要整体返工。关键是打破“数量假象”“我过了 54 项检查”听起来很厉害但如果最核心的 3 项没过整个交付仍然不合格。5.2 坑二自动规则写得太细误报比漏报更致命有一次我在文档配置里加了一条“禁止使用‘非常’这个副词”的规则结果所有含“非常好”“非常重要”的句子全部标红。问题在于这些词本身并不总是冗余的强行删除反而让文档变得僵硬。那次之后我给自己定了个规矩自动规则的误报率超过 5%就必须删除或者降级为 warn。怎么评估误报率我会拿最近三份真实且公认质量不错的交付物去跑新规则如果其中有一份明明合格却被判 fail这条规则就要重写。自动化要先进“低垂果实”先做存在性、数量、格式这类高确定性检查语义层面的判断等规则成熟了再加。5.3 坑三清单一旦固化就立刻失效质量标准的背后是活的经验经验会变化规则就必须跟着变。我现在把检查项的更新节奏定为每季度一次更新依据只有两个来源一个是外部反馈中别人替你发现的错误另一个是复盘时自己意识到的问题。每当有新的“失败模式”出现我就会把它变成一个正式的检查项确保同类问题不会第二次出现。这套框架运行大半年我给它的评价是它没有让我变成一个更好的人但确实让我成了一个更稳定的交付者。因为每次交付我都能拿出一张可以说“为什么我敢说它无可挑剔”的结果表。这种确定感很难得也很让人上瘾。如果你也想做一套自己的检查框架我最后的建议是不要从质量理论开始从你最近三次被批评的真实错误开始。把它们写成具体的规则就是你 impeccable 的第一版配置。后面的事情等你跑起来自然会知道怎么迭代。