02 · 知识验证 · 落地方案
02 · 知识验证 · 落地方案
对应蓝图 §3。本文解决:知识条目在提交后、人工审核前,经过哪些自动化质量门控?
状态:草案(V1.3 / V2.4 / V2.5 / V2.6 待确认,见 §9)
前置依赖:01-知识生成(知识条目已产出草稿)
关联文档:01-知识生成(草稿产出)· 03-知识审核(人工审核)· 08-约束执行(CI 门禁)
1. 定位与边界
验证分为两道门:本地 pre-commit 快速校验(开发者提交前)和 CI Pipeline 完整校验(MR 触发)。两道门共同确保进入审核环节的知识草稿至少满足格式合规、源文件存在、符号可解析三项硬门禁。
2. 验证架构
3. 本地验证(pre-commit hook)
3.1 检测范围
本地 hook 只执行快速、无网络依赖的检查项,确保开发者在提交前即可发现基础错误:
| 检查项 | 阻断级别 | 实现方式 | 说明 |
|---|---|---|---|
| 格式合规 | Error | knowledge-lint.py --check-required-fields | frontmatter 7 个必填字段不为空,枚举值合法 |
| 源文件存在 | Error | knowledge-lint.py --check-source-exists | source_uri 指向的文件在当前仓库中存在 |
3.2 与权威源变更 hook 的关系
01-知识生成 中已定义了一个 pre-commit hook 用于检测权威源变更。本 hook 作为同一 hook 脚本的附加检查,合并执行:
# .git/hooks/pre-commit 统一入口
def main():
# 检查 1:权威源变更提醒(01-知识生成 §5.4)
rc = 0
# 检查 1:权威源变更提醒(01-知识生成 §5.4)
changed = check_authoritative_changes()
if changed and not has_knowledge_update():
print_authoritative_warning(changed)
# 不在这里 return:否则检查 2 永不执行——
# 知识 MR 若同时改了 application.yml,格式错误会整体漏检
# 检查 2:知识条目格式校验(本节)
knowledge_files = get_staged_knowledge_files()
if knowledge_files:
errors = run_local_lint(knowledge_files)
if errors:
print_lint_errors(errors)
return 1 # 阻断,格式错误必须修复
return 0 # 通过3.3 关键决策点
| # | 决策 | 已确认 | 说明 |
|---|---|---|---|
| V1.1 | 本地 hook 检查范围 | ✅ 仅格式合规 + 源文件存在 | 符号可解析依赖 tree-sitter/LSP 工具链,且 source_uri 可能跨仓(本地 clone 不含目标项目);本地 git 历史本身是完整的,不是障碍 |
| V1.2 | 与权威源 hook 合并 | ✅ 同一脚本 | 减少 hook 数量,降低维护成本 |
| V1.3 | 本地检查失败行为 | 待确认 | 选项:A) 阻断提交;B) 仅警告,允许 --no-verify |
4. CI Pipeline 验证
4.1 完整检查项
| 检查项 | 规则 | 阻断级别 | 实施方式 |
|---|---|---|---|
| 格式合规 | frontmatter 7 个必填字段不为空,枚举值合法 | Error | knowledge-lint.py --check-required-fields |
| 源文件存在 | source_uri 指向的文件在 source_revision commit 中存在 | Error | CI 脚本解析 gitlab:// URI 并检查文件 |
| 符号可解析 | 符号级引用(Class#method)在 source_revision 中确实存在 | Error | 静态分析(tree-sitter / LSP)解析符号表 |
| 内容完整性 | 正文包含「背景」「方案」「正反例」三个 H2 章节 | Warning | 正则匹配 markdown 结构 |
| 重复检测 | 与已有知识条目的标题/源文件/内容 hash 比对 | Warning | 确定性比对 + 向量相似度 |
| 冲突检测 | 同一业务主键是否存在矛盾陈述 | Warning | 结构化主张抽取后比较 |
| 可操作性检查 | 是否引用了具体代码路径、符号或文件位置 | Warning | 正则匹配 src/、gitlab://、Class#method |
| 状态门禁 | 被标记 conflicted / duplicate_candidate 的条目不得声明 status: active | Error | knowledge-lint.py --check-status-gate(重新计算冲突,不读 flags,见蓝图 §3.3) |
符号可解析检查的级别随实现方式变化:V2.4 选 C(正则)期间降为 Warning,或仅对 tree-sitter 已支持的语言(如 Java)生效为 Error。把一个精度未实测的正则检查挂在 Error 硬门禁上,与本文 §4.3 对冲突检测的处置理由(「抽取器准确率未经实测,硬门禁会误伤」)自相矛盾——同一文档不能对两类未实测检查采取双重标准。
4.2 Error 与 Warning 的执行差异
关键约束:Error 和 Warning 必须落到不同的退出码,否则 Warning 会事实上变成 Error(CI 红即不可合并),§4.3 的分级处置随之失效(对应蓝图 §3.2.1)。
# .gitlab-ci.yml
knowledge-validate:
stage: validate
script:
# Warning 类必须先跑:退出码 0,结果落盘,供 MR 评论回写
- python3 scripts/knowledge-lint.py --check-structure --report-only
- python3 scripts/knowledge-lint.py --check-duplicates --report-only
- python3 scripts/knowledge-lint.py --check-conflicts --report-only
- python3 scripts/knowledge-lint.py --check-actionability --report-only
# 回写 MR 评论需要 Project Access Token(api scope),CI_JOB_TOKEN 无此权限
- python3 scripts/knowledge-lint.py --post-mr-note
# Error 类放最后:串行 script 中任一失败即中止 Job,
# 若 Error 在前,后面的 Warning 结果永远不会产出
- python3 scripts/knowledge-lint.py --check-required-fields --strict
- python3 scripts/knowledge-lint.py --check-source-exists --strict
- python3 scripts/knowledge-lint.py --check-symbol-resolvable --strict
# 状态门禁:被标记 conflicted / duplicate_candidate 的条目不得声明 status: active
- python3 scripts/knowledge-lint.py --check-status-gate --strict
rules:
- changes:
- "docs/knowledge/**/*.md"
- "_drafts/**/*.md"4.3 冲突检测分级处置
冲突检测是自动化难度最高的检查项。P0/P1 阶段一律作为 Warning 处理,不阻断 MR 合并:
| 阶段 | 冲突检测角色 | 理由 |
|---|---|---|
| P0 / P1 | Warning:标记 flags: [conflicted],阻断该条目转 active,但不阻断 MR 合并 | 抽取器准确率未经实测,硬门禁会误伤 |
| P2 起(准确率达标后) | 对确定性冲突升级为 Error | 见下文「确定性冲突」定义 |
确定性冲突(可安全设为 Error):
- 同一
source_uri+ 同一符号,两条active知识给出互斥状态(一条deprecated、一条未标记) - 同一业务主键(同一错误码、同一表名)出现两个不同的权威定义,且都声明 T1 级来源
supersedes关系成环
语义冲突(需理解句意才能判定的矛盾)一律保持 Warning,进入人工裁决流程。
4.4 主张抽取的最小可行 Schema
不追求通用 NLP 抽取,只对结构化程度高的知识类型做抽取:
claim:
subject: "refund/v1" # 业务主键,须命中受控术语表
predicate: "lifecycle_status" # 受控谓词枚举
object: "deprecated" # 谓词对应的受控取值域
scope: # 缺失 scope 的主张不参与冲突判定
env: [production]
version: "v1"
evidence_ref: "KB-PAYMENT-REFUND-LIFECYCLE#方案"
extracted_by: "rule" # rule | llm,llm 抽取的一律降级为 Warning受控谓词枚举(初始集合):
| 谓词 | 取值域 | 冲突判定 |
|---|---|---|
lifecycle_status | active / deprecated / revoked | 同 subject + 同 scope 取值不同即冲突 |
idempotency_key | 字段组合表达式 | 同 subject 表达式不等价即冲突 |
default_value | 字面量 | 同 subject + 同 scope 字面量不同即冲突 |
owner | 团队标识 | 同 subject 取值不同即冲突 |
constraint | 自由文本 | 不做自动判定,仅列出候选供人工比对 |
4.5 关键决策点
| # | 决策 | 已确认 | 说明 |
|---|---|---|---|
| V2.1 | CI 检查项与阻断级别 | ✅ 蓝图 §3.2 的 8 项检查 | Error 4 项(含状态门禁)+ Warning 4 项 |
| V2.2 | Error/Warning 退出码分离 | ✅ 必须分离 | 否则 Warning 事实上变成 Error |
| V2.3 | 冲突检测 P0 级别 | ✅ Warning | 准确率未实测前不做硬门禁 |
| V2.4 | 符号可解析的实现方式 | 待确认 | 选项:A) tree-sitter 解析 Java;B) LSP 远程调用;C) 正则匹配(精度低但零依赖)。选 C 期间该检查必须降为 Warning(见 §4.1 注),否则与 §4.3 的处置原则冲突 |
| V2.5 | 重复检测的向量相似度阈值 | 待确认 | 必须使用企业语料校准,不能预设通用值 |
| V2.6 | --check-conflicts 命中时的额外动作 | 待确认 | 选项:A) 写入 flags: [conflicted] + 阻断转 active;B) 仅标记 MR 评论 |
5. 重复治理
5.1 重复识别层级
| 层级 | 识别方式 | 处置 |
|---|---|---|
| 确定性重复 | 相同业务主键、规范化 URI、源 ID 或内容 Hash | 自动标记,Owner 审核时处理 |
| 结构重复 | 相同接口、表、错误码或规则编号 | 自动标记疑似,Owner 确认 |
| 语义重复 | 向量相似度超阈值 | 仅生成疑似候选,不自动标记 |
5.2 重复处置原则
- AI 不得自动删除、覆盖或合并正式知识
- 清理动作必须经过 Owner 审核
- 重复条目的
flags字段标记duplicate_candidate
5.3 关键决策点
| # | 决策 | 已确认 | 说明 |
|---|---|---|---|
| V3.1 | 确定性重复自动标记 | ✅ | 误报率极低 |
| V3.2 | 语义重复仅生成候选 | ✅ | 相似度阈值未校准前不做自动标记 |
| V3.3 | 重复处置权限 | ✅ Owner 审核 | AI 不自动删除/合并 |
6. 实施步骤
| 步骤 | 内容 | 产出物 | 前置条件 |
|---|---|---|---|
| S1 | 实现 knowledge-lint.py 脚本 | Python 脚本,支持 8 个 --check-* 子命令 | 知识条目模板与元数据 Schema 已定义(蓝图 §5.5.1 + §5.2;01-知识生成 §6.1 只列要素要求,不含可校验的字段清单) |
| S2 | 集成到本地 pre-commit hook | 更新 hook 脚本 | S1 完成 |
| S3 | 配置 GitLab CI Pipeline | .gitlab-ci.yml 新增 knowledge-validate job | S1 完成 |
| S3.1 | 配置 MR 评论回写凭据 | Project Access Token(api scope),存入 CI/CD Variables(masked + protected) | S3 完成。CI_JOB_TOKEN 只能读取 MR,无权创建 note,缺此步则全部 Warning 结果无处输出 |
| S4 | 实现符号可解析检查 | tree-sitter / LSP 集成 | S1 完成,V2.4 决策已确认 |
| S5 | 实现冲突检测(主张抽取) | 受控谓词抽取器 | S1 完成,V2.6 决策已确认(V2.4 是符号解析的实现方式,为 S4 前置,与本步无关) |
| S6 | 端到端验证 | Error/Warning 退出码分别测试 | S1-S5 完成 |
7. 度量
| 指标 | 计算方式 | 目标 | 性质 |
|---|---|---|---|
| 符号可解析率 | 符号级引用(Class#method)能在 source_revision 中解析的比例 | 100% | P0 为阈值待实测,P1 起为机制保证。P0 采用 V2.4 推荐的正则降级方案(本文 §8 自认「精度低」),既保证不了 100% 也不构成机制;引入 tree-sitter/LSP 后静态分析才可判定。配套约束见 §4.1 注 |
| AI 审核通过率 | 首次提交即通过全部 Error 检查的 MR 比例 | ≥ 85% | 阈值待实测 |
| 自动拦截问题数 | 每个 MR 平均拦截的 Error 数 | 趋势下降 | 趋势指标 |
| 误报率 | 标记为重复/冲突但实际不重复的比例 | ≤ 10% | 阈值待实测 |
| CI 校验延迟 | 从 MR 提交到校验完成的时间 | ≤ 2 分钟 | 阈值待实测 |
8. 风险与依赖
| 风险 | 影响 | 缓解措施 |
|---|---|---|
| 符号可解析检查依赖 tree-sitter/LSP | 引入额外工具链复杂度 | P0 先用正则匹配降级,P1 再引入 tree-sitter |
| 冲突检测假阳性过高 | Owner 审核负担重 | P0/P1 一律 Warning,不阻断合并 |
| CI 校验延迟过长 | 开发者等待成本高 | 本地 hook 先拦截基础错误,CI 只做完整检查 |
| 向量相似度阈值未校准 | 重复检测效果不可控 | P0 只用确定性比对,向量相似度 P2 再引入 |
9. 待确认决策汇总
| 编号 | 决策 | 选项 | 推荐 |
|---|---|---|---|
| V1.3 | 本地检查失败行为 | A) 阻断提交;B) 仅警告 | A(格式错误应在本地发现) |
| V2.4 | 符号可解析实现方式 | A) tree-sitter;B) LSP;C) 正则 | C(P0 降级)→ A(P1) |
| V2.5 | 重复检测向量阈值 | 具体数值待实测 | — |
| V2.6 | 冲突检测命中时动作 | A) flags + 阻断转 active;B) 仅 MR 评论 | A |