跳到主要内容

内容审计手册 ​

治理元数据 | Owner:知识库管理员 | 最后评审:2026-10-28 | 下次复核:2027-01-31

这份手册解决一个问题:知识库最容易烂在「结构正常但内容不对」——链接通、构建过、页面在,但某一节讲的是别的意思,或某个数字与源头对不上。自动检查看不出这类问题,人眼逐篇读又不现实。

下面把审计拆成四层,每层给出「机器能做什么 / 人必须做什么」,并配可复跑的命令。


一、先看五道闸门在管什么 ​

pnpm run check 串了五个脚本,覆盖「结构、文本、口径、算术、组件」五个维度。

闸门脚本抓什么抓不到什么
文本卫生check-text-hygiene.mjsH1 里的 ~/_ 分隔符、代码块多余转义、纯文本引用、标题 emoji内容是否正确
一致性check-consistency.mjs死链、锚点、表格列数、表格被引用块截断、自指链接、正文指纹重复、Checklist 标题复读、中英结构差异表述是否准确
指标权威check-metrics.mjs同一指标在非权威篇重述阈值阈值本身是否合理
数字复算check-numbers.mjs公式与结论不自洽(105 条断言)参数取值是否现实
组件默认值check-component-defaults.mjs工具组件默认值与正文基准不一致工具逻辑是否正确

关键认知:这五道闸门只能保证「不自相矛盾」,不能保证「说得对」。后者必须人读。


二、四层审计方法与复跑命令 ​

第 1 层:标题 ↔ 正文 ​

要查什么:标题声称的内容(几个、什么事)在正文里是否落实。

机器能做的:数结构。标题说「六大杠杆」,就数这一节有几个 H3 / 加粗列表项 / 表格数据行。

bash
# 数量承诺抽查(129 处标题含「N 大/项/步/层」)
python3 - <<'PY'
import pathlib,re
CN={'一':1,'二':2,'三':3,'四':4,'五':5,'六':6,'七':7,'八':8,'九':9,'十':10}
QTY=r'([一二三四五六七八九十]|\d+)\s*(大|项|步|阶|层|类|种|档|级|条)'
for p in pathlib.Path('docs').rglob('*.md'):
    s=str(p)
    if '/en/' in s or '/public/' in s or '.vitepress' in s: continue
    inf=False
    for l in p.read_text(encoding='utf-8').split('\n'):
        if l.strip().startswith('```'): inf=not inf; continue
        if inf: continue
        if not l.startswith('## '): continue
        q=re.search(QTY,l)
        if q: print(f"{s[5:-3]}  {l[3:][:50]}  → {q.group(1)}{q.group(2)}")
PY

人必须做的:读每一节的「标题 + 首句 + 骨架」,判断是否跑题。

教训:试过三种统计法全部失效——

方法结果为什么不能用
中文 bigram 余弦相似度中位数 0.04标题短正文长,字面重合天然极低
标题概念在正文的命中率595 节里 481 节「命中率 0」分词切出「全球销售模块子文」这类半截词
小节用词归属模块208 节「不像本模块」01 总控、02 产品本就跨职能

跑题是语义问题,字面统计测不出来。 这一层只能人读,机器只做辅助筛选。

第 2 层:表格 ↔ 结论 ​

要查什么:表格算出的数是否支撑正文紧接着下的定性判断。

机器能做的:定位「表格 + 带数字的结论句」配对。

bash
# 找「表格后紧跟带数字结论」的 44 处
python3 - <<'PY'
import pathlib,re
pat=re.compile(r'(✅|❌|达标|通过|未达标|仍高|仍低|高于|低于|结论|因此)')
for p in pathlib.Path('docs').rglob('*.md'):
    s=str(p)
    if '/en/' in s or '/public/' in s or '.vitepress' in s: continue
    lines=p.read_text(encoding='utf-8').split('\n')
    inf=False; i=0
    while i<len(lines):
        l=lines[i]
        if l.strip().startswith('```'): inf=not inf; i+=1; continue
        if inf: i+=1; continue
        if l.strip().startswith('|') and i+1<len(lines) and re.match(r'^\s*\|[\s:|-]+\|\s*$',lines[i+1]):
            j=i+2
            while j<len(lines) and lines[j].strip().startswith('|'): j+=1
            for k in range(j, min(j+7,len(lines))):
                t=lines[k].strip()
                if t and pat.search(t) and re.search(r'\d', t):
                    print(f"{s[5:-3]}:{k+1}  {t[:100]}")
                    break
            i=j; continue
        i+=1
PY

人必须做的:判断结论与表格是否同一基准。

典型陷阱(本库真实案例):

现象真相
LTV:CAC 1.45 判「⚠️ 踩线」相对放行线 1.2 是刚过,相对稳态线 3.0 是远不达标——两个基准混着说
赠品上限「不超过 MAP 限价 5%」+ 举例 19.95按 MAP 是 16.96,按 MSRP 才是 19.95,同一赠品包两种口径结论相反
利润率 18.5%EBIT 按净营收 367.08 算,但百分比除以 MSRP 399;按净营收除是 20.1%

第 3 层:跨篇数字引用 ​

要查什么:引用他篇的数值时,数值对不对、口径带没带上。

机器能做的:锁定核心数字 → 找出所有引用点。

bash
# 锁定 11 个核心数字,列出它们在哪些篇出现
python3 - <<'PY'
import pathlib,re
CORE={'73.69':'07-finance/07-06-pl-model','88.69':'07-finance/07-06-pl-model',
      '789':'07-finance/07-06-pl-model','367.08':'07-finance/07-06-pl-model',
      '156.52':'07-finance/07-06-pl-model','108.34':'06-service/06-04-retention',
      '34.65':'06-service/06-04-retention','1,908':'03-supply/03-04-order-calculator',
      '1,057.8':'03-supply/03-04-order-calculator','2,860':'05-sales/05-02-01-kickstarter-deposit',
      '71,500':'05-sales/05-02-01-kickstarter-deposit'}
docs={}
for p in pathlib.Path('docs').rglob('*.md'):
    s=str(p)
    if '/en/' in s or '/public/' in s or '.vitepress' in s: continue
    docs[s[5:-3]]=p.read_text(encoding='utf-8')
for val,src in CORE.items():
    hits=[r for r,t in docs.items() if val in t and r!=src]
    print(f'{val:9} 权威={src.split("/")[-1]:34} 其他篇 {len(hits)}: {hits[:4]}')
PY

人必须做的:逐条核语义(不只是数字相同,还要口径一致)。

为什么不能全自动:试过三种方案都失败——

  1. 「引用他篇 + 上下文有数字」→ 1002 条,噪声 90%
  2. 「引用 + 关系词 + 数字」→ 97 条,混大量索引表
  3. 「引用 + 该句数值 + 他篇比对」→ 163 条,同句常引多篇,归属不清

最后靠「锁定核心数 → 找引用点 → 人工核口径」收敛到 34 处。

第 4 层:表格纵向自洽 ​

要查什么:同一张表里,逐行加减是否等于结算行。

机器能做的:全部(只要有明确公式关系),已写成 105 条断言。

bash
node scripts/check-numbers.mjs      # 105 条,覆盖 5 张关键表

已覆盖的表:

表验证内容
07.06 P&L 主表5 条链路 × 3 情景 = 15 项
03.05 PSI 折损链1,060 → 1,007 → 1,002 → 1,000
03.04 首批资金占用三项加总 + NRE,含上下限
06.03 RMA 五科目占比/MSRP%/金额三个合计 + 五项单项
05.02.01 众筹漏斗4 波次 → 买家/金额/加权 ASP

教训:验结算表必须逐行验。曾只验 EBIT 一行,而毛利行有两处错误(公式关系搞错 + 负号当正号)恰好互相抵消,最后一行「看起来对」,导致误判整表正确。


三、五道闸门的失败处置 ​

报错常见原因处置
H1 含 ~ / _ 分隔符从飞书导出时转义未还原改本地 H1,再 push 飞书同步节点标题
表格分隔行列数不一致手写表格漏一列补齐分隔行,列数必须等于表头
表格被引用块截断在表格中间插了 > 说明把说明移到表格之后
Checklist 条目是标题复读自动生成器产物改写成可执行动作
中英结构不一致只改了一边补另一边,或确认是否故意不同
指标阈值越权重述非权威篇写了数值+比较符改为「见 00.02 §五」,或登记进 EXEMPT_LINES
关键数字复算未通过参数变了但结论没跟同步改结论;若参数本身错,改参数
正文完全相同批量脚本写错文件从 git 历史恢复,见下

三个已踩过的坑 ​

坑 1:HTML 注释会被飞书抹掉

不要用 <!-- metric:exempt --> 做行内豁免。飞书 markdown 导入会丢弃 HTML 注释,一次 sync 后标记就没了,CI 会突然失败。豁免登记在脚本的 EXEMPT_LINES 里(版本可控)。

坑 2:批量脚本写成「跑完了」不等于「写对了」

去 emoji 脚本曾把 03.01 的正文整篇写成 01.07 的内容。页面还在、链接不断、构建通过,但内容已经没了。现在有「正文指纹重复」闸门兜底。

批量脚本必须按「文件 → 期望内容」逐条验证。

坑 3:先推飞书,再跑 sync

顺序反了,飞书旧版会覆盖本地改动。

bash
# 正确顺序
python3 /tmp/push_doc.py docs/<篇>.md <obj_token>   # 1. 推飞书
node scripts/sync-feishu.mjs                        # 2. 回拉校验
git add -A && git commit && git push                # 3. 提交部署

四、什么时候该停下来 ​

四层都跑完之后,剩下的只有两类问题,都不在审计范围内:

类型例子为什么机器做不了
业务判断毛利率红线定 35% 还是 50%、NPS 健康线 50 是否合理没有对错,只有取舍
外部数据真伪印尼 VAT 实际税率、各国平台费率需要当地网络与官方渠道

判断标准:如果一个问题可以问「这个数是从哪来的」,那它属于外部数据;如果必须问「这个数定多少合适」,那它属于业务判断。两者都不该指望自动检查。


五、审计记录 ​

历次审计的详细发现与修复,见 AUDIT-CHANGELOG(仓库根目录)。按轮次编号 3.1 ~ 3.31,每轮记录「发现了什么、怎么修的、加了什么闸门」。

huajun.wang 智能硬件 GTM 知识体系 · 方法论