☰
文档校审工具AiCheck:规则优先、模型辅助的工程复盘与停更思考
2026/10/18 17:46:25 网站建设 项目流程

看到这个标题的时候,很多人第一反应可能是:又一个项目挂了。其实恰恰相反,一个大项目不会因为"工作太忙"就挂掉,能让你主动按下暂停键的,往往是它已经活得太久、管得太累。AiCheck是一款文档校审工具,从最初的内部脚本到可以给编辑、运营、法务、内容团队随手用的独立校验服务,我前后折腾了好几年。今天想把它完整的来龙去脉写下来,包括它解决了什么问题、是怎么设计的、为什么最后选择"暂不更新",以及停更前我做了哪些收尾。如果你是文档密集型岗位的从业者,或者也在独立维护一个小工具,这篇应该能给你一点可复用的思路。

先简单交代背景:AiCheck做的是文档的"第二遍校对"。它不是帮你写文档,而是在你写完、发布或提交之前,把错别字、标点问题、体例不统一、数字单位混乱、术语前后不一致、风险表述等一眼能看出来的硬伤先扫一遍。做得最好的时候,覆盖了公司内外好几十个团队,每天处理上千篇文档。但它不是从第一天就是这个样子的,甚至一开始根本叫这个名字。

1. 从一个凌晨的发布事故说起:文档校审是怎么被逼出来的

1.1 凌晨两点,文档里那个错误的参数

做这个项目的起因特别朴素。有次公司准备一个对外发布的重要版本,前后准备了半个多月,版本说明、操作手册、FAQ都写好了。发布当晚,产品、开发、运营、公关全在线上盯场。结果第二天早上用户反馈炸了:文档里一个关键参数写错了,直接照做会出问题。更要命的是,同样的操作,另一份配套文档里用的是完全不同的格式和单位,两篇文档相互矛盾。

事后复盘,问题不在"没人检查",而在"人已经检查了三遍但都是同一双眼睛"。写文档的人自己检查,最大的盲区就是默认自己写的是对的;别的人来检查,又很难有耐心逐字逐句翻完几十页。我们当时就意识到:能做成规则的事情,应该交给规则去查,机器不该在这种低级错误上输给人。

那周我就写了一个命令行脚本,起名的时候偷懒叫"second eye"。功能很简单:跑一遍文档,把疑似错别字、重复标点、中英文混排问题、数字单位不统一的地方全部列出来,带行号。第一次跑完我们自己的说明文档,查出四十多处问题,其中七成是真的要改的。从那一刻起,这个"第二双眼"就从"玩票脚本"变成了"正式项目",也就是后来的AiCheck文档校审。

1.2 校审不是查错字:整理出的真实痛点清单

真正开始做之后才发现,文档校审远远不是"查错别字"四个字能概括的。我大概花了两个星期,把各团队经常反馈的文档问题整理了一遍,做了分类:

问题类型典型表现自动化难度AiCheck的处理方式
错别字与拼音输入残留"的/地/得"混用、"在/再"不分、拼音没删干净低通用词表+用户自定义词典
标点与排版半角括号混用、中文句号打成英文句点、多余空格低规则引擎直接命中
数字与单位"10000"写成"10000"后缺千分位、单位km/km/h混用中正则+格式化检测
术语一致性同一篇文档里"用户ID"/"用户编号"/"UserId"并存中高术语抽取+词频一致性
体例一致性标题层级跳级、编号格式不统一、日期格式混用中高状态机跟踪标题上下文
风险相关表述对外数据没有标注来源、承诺性表述缺少免责说明高语义模型候选+规则确认
逻辑连贯与语气前后指代不明、转折突兀、语气与受众不匹配很高只能给提示,不替代人

这个表基本决定了后面所有功能的设计方向。前四类属于"机器能做且该做"的,最后两类机器只能打辅助,绝对不能替人拍板。很多人觉得文档校审是个小众需求,但只要你接触过成体系的对外文档、操作手册、合规文件就会发现,这其实是一个巨大且长期被低估的痛点:写文档的人被细节压垮,审文档的人被重复劳动耗死,最后大家都疲惫,错误还是漏出去了。

2. AiCheck的核心架构:规则层、统计层、模型层怎么分工

2.1 我为什么不信任"一个模型解决所有问题"

市面上并不缺大而全的文档处理工具,很多号称"AI智能审校"。但我的判断是,把整篇文档直接扔给一个通用模型,让它"看着办",是做校审工具最容易踩的坑。

原因有三个。第一,模型输出不稳定,同样的句子今天报、明天不报,用户没法建立信任;第二,模型很难给出稳定的行号和修改依据,用户点开一条修改建议,不知道为什么要改,自然不会采纳;第三,模型对专有名词和领域术语不敏感,医学文档里的专业词、合同里的定义条款,模型经常当成错别字。

所以AiCheck从来不是一个"大模型包装壳",而是一个三层分工的管线:

  1. 规则层:负责高确定性检查。错别字、标点、格式、编号、单位、术语一致性,全部走规则和词典。
  2. 统计层:负责模糊信号的初筛。比如某个词在全文中的出现频率、相邻词搭配异常、ngram打分异常,先捞出来。
  3. 模型层:负责语义级判断。只在统计层和规则层都觉得"有点怪"但拿不准的时候,才把片段发给通用语言模型做候选判断。

设计原则很简单:能用规则解决的,绝不用模型;用规则的目的是为了"可解释",模型的目的是为了"扩展边界"。

2.2 一条文本在校审流程里走几趟

如果打开AiCheck的日志,看一条典型文本的流转过程,大概是这样的:

  1. 归一化处理。统一转成UTF-8编码,去掉BOM头,识别并标记出代码块、表格区域和URL,这些区域先单独摘出来。
  2. 规则层扫描。按照错别字词表、标点规则、数字格式规则、术语规则逐条跑。这一步一般能命中60%左右的问题,全部带行号和规则编号。
  3. 统计层分析。基于全文字符串做词频统计和ngram打分,找出"全文只出现一次的新写法""上下文搭配不寻常的词组"等候选。
  4. 模型层候选判断。把统计层捞出来的可疑片段,加上前后各若干字的上下文,发给语言模型,得到一个"是否异常"的置信度打分。
  5. 结果聚合与去重。三条检查流的输出合并,按照规则编号、位置、置信度排序,重复项去掉,同类问题聚合。
  6. 分组输出。最终报告分为"必改级""建议级""提示级"三档,方便用户按严重程度处理。

这个流程看起来繁琐,但对不同场景的适应能力非常强。比如"必改级"意味着规则层直接命中,几乎没有争议;"建议级"是统计层+模型层共同认为可疑,需要人工扫一眼;"提示级"则更多是风格提示,比如"这句话有歧义,建议换个说法"。三档设计让工具像一个有分寸的同事,而不是一个絮絮叨叨的老师。

2.3 为什么最终"决定权"必须回到规则层

你可能想问:模型层既然能判断置信度,为什么不直接让它输出"对/错"?

因为模型最擅长的是生成候选,而不是做审核。我做过很多次对比测试,通用模型直接给结论的模式,误报率高得惊人。它会把"我们已经部署了新的系统"里的"部署"当成疑似错别字,因为它觉得"部署"和"部暑"字形接近;它还会把"企业微信"这种专有名词当成"疑似漏字",非常令人头疼。

所以AiCheck的做法是:模型给出的永远只是候选信号,最后是否上报、以什么级别上报,由规则层决定。规则层维护着一张"判定表",里面写了每个检查项的阈值、优先级、自定义例外。比如用户在产品里添加"企业微信"到用户词典,那么所有分词、错别字、ngram检查都会跳过这个词。这个设计从一开始就定死了:凡是用户明确声称"这是对的",机器必须学会闭嘴。

这个"规则兜底、模型辅助"的思路,是我认为AiCheck区别于很多同类工具最核心的一点。它决定了这个工具能不能在真实的、存在大量行业黑话和专有名词的文档场景里活下来。

3. 真正能省时间的四种校审能力:从功能到用户体验

3.1 错别字与术语一致性:自定义词典优先级最高

错别字检查是最容易做也最容易挨骂的功能。如果按通用词表硬查,医疗文档里的"阿司匹林"、法律合同里的"甲方"、技术文档里的"后端"会被各种误判。所以我给AiCheck设计了用户词典机制:每个接入团队都可以上传自己的术语表,术语表里的词在整个校审管线里拥有最高优先级。

实际使用中最惊艳的效果不是查错字,而是术语一致性。有一家做硬件文档的团队,文档里一会儿写"固件升级",一会儿写"Firmware Update",一会儿又写"固件更新",多次出现同一对象的不同叫法。AiCheck通过统计层捞出了这些高频等价词,生成一份"疑似术语混用"清单,他们自己看的时候都愣了,因为所有人都没注意到这个细节。术语一致性检查不需要模型,原理就是:提取全文中的候选术语,统计每一种写法的出现次数,对同一语义聚类的写法给出一致性评分。这个功能后来成了很多法务和合规团队的刚需。

3.2 表格、代码块和URL:格式感知的文本清理

早期版本有一个很傻的问题:整份Markdown文档直接当纯文本跑,结果表格里的数据、代码片段里的英文变量、URL里的参数全被当成错别字报出来。用户打开报告,一半都是噪音。

后来做了一次重构,加了"格式感知"模块。文档进来先做结构分析,把Markdown/Word文档分割成普通段落、代码块、表格、链接引用四个区域。代码块直接跳过,只做最基础的拼写检查;表格做结构化提取,对列头、单元格分别处理;URL只检查链接格式是否符合预期、锚文本是否与目标页面主题相关。这次重构之后,误报率肉眼可见地降了一大截,用户反馈从"报告太吵"变成了"报告能看了"。

这件事给我的经验是:文档校审工具的第一功课,不是"更聪明",而是"知道哪些内容根本不用管"。很多团队研发这个过程时会沉迷于扩大检查项,但真正决定产品口碑的,往往是做减法、减少噪音。

3.3 体例一致性:需要一点状态机思维

体例检查比想象的复杂。比如"标题层级不能从二级直接跳到四级",这种检查就需要知道当前文档的上下文状态。单纯的正则表达式做不到,因为必须记住前面出现了哪些级别的标题。

AiCheck在这里引入了一个轻量级的标题状态机。每次遇到标题标记(Markdown的#、Word里的大纲级别),就更新当前层级栈;如果出现层级跳变,就记录一条"建议级"问题。标点符号检查则更简单,维护一张"中英文标点对照表",发现左侧中文全角的场景里出现半角标点就直接记录,因为绝大多数情况下那都是误输入。

日期格式统一也归在这一类。同一篇文档里"2024年1月1日""2024-01-01""01/01/2024"并存,规则层会按首次出现的格式作为基准,后续不一致的写入报告。这个功能特别适合跨国团队,不同地区的书写习惯差异,经常在一份文档里打架。

3.4 风险表述提醒与修订留痕,安全感和信任感从哪来

风险相关的检查是AiCheck里最谨慎的部分。不能做"判定",只能做"提醒"。比如一篇数据类文章引用了外部统计结果,却没有标注数据来源,AiCheck会提示"该数据建议补充来源说明";比如出现"保证""绝对"等绝对化表述,AiCheck会提示"该表述可能在特定场景下引发误解,建议补充说明或验证"。

设计这类功能的思路是:模型只负责把包含高不确定性的表述摘出来,规则层再判断是否值得报告,最终的"改不改"完全交给人来定。工具永远不下结论"你有风险",只说"这里可能存在需要你注意的地方"。

修订留痕是后来应几个客户需求加的功能。它的价值在于版本对比:当用户上传新版文档时,AiCheck自动对比历史版本,只检查发生变化的段落,并且生成一份"变更点清单"。这样既省时间,也避免了一个常见悲剧——改了一处、漏了另一处,旧版本的问题原封不动带到了新版本里。最终报告可以导出为Word批注格式,用户可以直接在原文上看到哪些地方被建议修改,然后在自己的写作流程里决定是否采纳。这比一个"自动把文档改好"的黑盒,要可信得多。

4. 误报治理:文档校审的死生之地

4.1 "宁可错杀"在文档校审里完全走不通

如果你做过机器学习类的项目,可能习惯了"宁可误报不能漏报"的评价标准。但在文档校审里,这个逻辑会杀死产品。因为用户对工具的信心建立在一件非常敏感的事情上:每一条报告,他都要点开看一遍。

初期我们犯过这个错。为了追求"查得多",开放了大量低置信度检查项,结果上线第二个月就收到大量反馈:"报告太长了,我根本懒得看。""你们报了十条,我核对完发现六条不用改,后来就不再看了。"这几乎是给工具判了死刑。

后来我们花了整整一个季度做误报治理,把重点从"查得多"转向"查得准"。每一次规则更新,都要过一遍积累的现实反馈样本,凡是误报率超过一定阈值的规则,要么删掉,要么调到更严格的置信度档。最后线上保留的检查项,全部是经过真实样本验证的。

4.2 三个最常见的误报来源,以及怎么治

根据线上反馈统计,误报主要来自三方面:

误报来源具体表现有效缓解手段
通用词表覆盖了专有名词把"红斑狼疮"当成拆错的词、"C++"当成疑似乱码用户自定义词典+专用领域词表分级
文本噪声混入代码块、URL、base64字符串被当成错别字格式感知模块先摘除噪声区域
上下文导致的多义词"杜鹃"既可能是鸟也可能是花,报成"疑似用词不当"拉长上下文窗口,交给模型消歧后再决定

第一类靠词典分层解决;第二类靠结构分析解决;第三类最麻烦,需要上下文。一开始我们只取前后各五六个字当上下文,效果很差,后来改成把整个段落文本完整传给模型,让模型判断"当前语境下这个词是否异常"。成本高了一点,但准确率提升非常明显。

4.3 "忽略"按钮,其实是整个产品里最宝贵的埋点

这是我想专门说的一点。AiCheck所有报告项旁边都有一个"忽略"按钮,用户点击忽略后,这条规则在这次报告里就不再展示,同时系统会记录一条匿名反馈。刚开始大家都觉得这就是一个常规的交互,直到后来我们分析数据时发现,忽略率是最有价值的训练信号。

比如有一条规则"疑似使用绝对化表述",上线第一周被忽略了40次,占比远超其他规则。我们点进去看才发现,很多合同模板里"唯一""仅"这类词的语境本来就是合理的,不应该一刀切报。于是我们把这条规则的置信度阈值从0.5提到了0.8,并增加了"结合上下文判断是否存在排他性承诺"的前置检查。调整之后,忽略率降到了5%以下。

很多文档校审工具都在谈算法多么先进,但真正让算法的边界变得可信的,恰恰是用户用"忽略"投票的结果。停更之前,我最舍不得的就是这份积累了上千条用户反馈的忽略清单,它是项目里最值钱的东西,比代码值钱得多。

5. 为什么最终选择"暂不更新":停更前我做的收尾工作

5.1 算一笔维护账:时间、费用和心力

很多人觉得"不更新"是因为项目不赚钱。真实情况是,AiCheck从一开始就没打算商业化,它一直是一个由维护者自掏腰包的内部开源式项目,但它带来的时间成本是真实且逐步膨胀的。

我粗算过一笔账:每周处理用户问题约3小时,更新词表和规则约2小时,跑回归测试占2小时,部署和监控占2小时,写版本更新说明和个人维护日志约3小时,合计每周12小时。加上每次模型API调用的费用、夜间批处理任务的云服务器费用,一个月大概要额外支出不少钱。这笔钱和时间,在项目早期是可以接受的,因为每修复一个问题都能获得正反馈;但当我本职工作开始明显变忙,这12小时从"充电"变成了"还债"。

有一阵子我一度连续几周没有打开后台,等再登录的时候看到了五百多条待处理消息。那一刻我突然意识到,如果我不能给用户一个体面的回应,那这个项目无论曾经多好,对用户来说都变成了一个"没人管的东西"。

5.2 选择"暂不更新"而不是"不再更新",是一种负责任的措辞

我考虑过直接下架,也考虑过彻底宣告终止。但最后标题里写的是"暂不更新",这个措辞是经过仔细权衡的。

"暂不更新"意味着项目对于现有用户仍然可用:已经部署的版本继续能跑,已有规则继续生效,用户词典导出、报告导出这些核心功能不关闭。我不承诺具体的新功能时间表,也不会假装还有人在全职维护。同时,我把主页和仓库里的说明改成一个清晰的"维护状态公告",写清楚哪部分可以继续使用、哪部分已经冻结、出现哪些问题建议用户做替代方案。这条路实际上保留了项目未来被重新激活的可能性,也给用户留了一条体面的退路——比直接消失要负责任得多。

5.3 停更前我列了一张收尾清单,逐项落实

停更不是删库跑路。我在最后两周做了这些事,也建议每一位计划停更的独立维护者参考:

  1. 发布最终稳定版,冻结当前规则库,确保所有历史功能在可见的未来内可正常工作。
  2. 整理完整的架构说明文档、部署指南和用户手册,统一归档到静态页面,保证资料永久可访问。
  3. 开放用户数据的导出接口,包括团队词典、自定义忽略规则、历史报告,防止用户被锁在系统里。
  4. 降低后台批处理任务频率,把原先生效的实时扫描改为一周一次,既减少费用也降低故障概率。
  5. 在文档首页写上"此项目目前处于低维护状态",并附上推荐的替代工具的说明,让新用户能自行决策。

很多人会觉得最后一条很傻,主动把用户往竞品推。但我的想法很简单:文档校审工具的核心是信任。如果我不能继续为用户负责,那至少应该告诉他一条明确的路,而不是让他对着一个不更新的工具空等。

5.4 承认做减法不是失败,是优先级管理

停更决定做了之后,我经历了大概一个月的内疚期。因为后台仍然有团队在持续提交文档扫描,每天还有新用户注册,每次看到那些使用数据,我都会怀疑自己是不是辜负了他们。

但后来我想明白一件事:一个维护者能给予用户的最有价值的承诺,不是"我会永远更新",而是"我会在你需要的时候告诉你真实状态"。把话说清楚、把收尾做干净,这个项目就没有死,它只是进入了一个更安静的生命周期。对维护者本人来说,也不再被一个永远滚动的需求列表绑架。那是我做这个项目以来,第一次觉得心里踏实。

6. 复盘:如果重来一次,我会保留的四个习惯

6.1 先做规则,再做模型,永远保持可解释

回到最初,如果让我重新设计一遍AiCheck,我依然会坚持"规则优先、模型辅助"。规则系统的好处不只是准确率高,更在于每一条规则都可以追溯到一段清晰的逻辑,用户问"为什么报这个",你能给出明确的答案。模型适合用来探索未知问题,但它不应该成为答案的终点。

反过来说,每一次引入一个新的模型能力,我都会要求自己同时准备一套对应的"失败用例集"。这个用例集里的每一个样本,都来自真实用户的反馈,或者从误报记录里挑出来的典型案例。新增规则之前,先跑一遍失败用例,保证不会把以前修好的问题又弄坏。

6.2 所有检查项都要能一句话说清理由

AiCheck的每条报告都要求带一个"依据说明",例如"检测到全角百分号,建议改为半角""该术语与第4段出现的'用户ID'不一致,建议统一"。这个要求一开始只是为了用户体验,后来发现它其实变成了一个检验标准:如果连我们自己的维护者都说不清一个检查项为什么要存在,那么用户更不可能理解,这就说明这条检查项大概率不应该存在。

这个习惯对任何文档工具、任何面向用户的自动化系统都适用。机器不能只说"我觉得这里有问题",它得说清楚依据,用户才会认真对待提示。

6.3 跟真实用户"坐在一起"看报告,比看后台数据有用一百倍

做这个项目的过程中,我养成的一个习惯是:每隔一段时间,就去找一个真实用户,不是看后台数据报表,而是打开一份真实的文档,跑一遍校审,然后跟用户坐在一起逐条看报告。

这个场景下会暴露出很多冷冰冰的数据完全发现不了的问题。比如有用户说"这个建议我根本不会看,因为我们团队的风格要求就是这种格式",比如有用户说"功能很好,但你们下发的报告里行号对不上原文,我没法定位"。这些反馈没有一个会出现在后台统计面板上,但每一个都直接影响产品好不好用。

6.4 从第一天起就预设退出机制,反而让项目活得更久

最后一条看似反直觉,但很重要:我在项目早期就设想过"如果某一天我不维护了会怎样",并且把这个场景对应的处理路径做了基本铺垫。正是因为有了这个心理建设和基础预案,多年后真正需要停更的时候,我没有慌乱,也没有拖延太久。

凡是准备长期维护项目的人,其实都应该在脑子里留一个"退出预案":用户数据怎么导出、文档怎么归档、对外状态怎么公告。提前想清楚这些,不是不吉利,而是让维护者有底气继续往前走。当你不再害怕停更,反而更能享受开发和维护的每一天。

如果你正在做一个类似的小工具,我的建议是:不要试图满足所有人,先把你自己和你的同行最痛的那几个问题解决透;工具永远不要替代人的判断,而是帮人把琐碎检查先扛起来。AiCheck停更了,但"机器应当替人类承担重复校对"这个思路还会继续以其他方式活着。做工具和养植物有些像——重要的不是永远枝繁叶茂,而是在合适的季节知道什么时候该修剪、什么时候该让位。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询