cannbot-knowledge 治理体系深度剖析:Schema、Profile、Registry 与 Contract 的 5 层分工
【免费下载链接】cannbot-knowledgecannbot算子开发知识库插件依赖的知识库本体仓,给cannbot提供统一的知识底座。项目地址: https://gitcode.com/cann/cannbot-knowledge
cannbot-knowledge 是 CANN 算子开发知识库的治理底座仓,它为 cannbot 提供统一的知识底座。本文将带新手快速看懂它的 5 层治理分工:Schema(字段形状)、Profile(字段组合)、Registry(受控词表)、Contract(跨文件检查)以及Checks + Indexes(分类执行与索引生成),帮你彻底搞懂这张知识卡片背后的"质量防线"是怎么搭起来的 🧱。
为什么知识库需要一套"治理体系"?
想象一下:几千张 Markdown 知识卡片(概念、API、算子、Runbook)散落仓库,如果没人管——
- 字段名五花八门,搜索召回直接失效;
- 平台、标签随手乱写,过滤结果不可信;
- 目录索引过期,链接断掉,读者迷失在知识迷宫里;
- 草稿和废弃结论混在一起,下游工具拿到错误答案。
cannbot-knowledge 的解法是:把"规则"写成机器可执行的声明,把"检查"收敛到唯一的 Contract 入口。核心原则只有一句:
同一规则只能有一个机器事实源——字段形状归 JSON Schema,字段组合归 Profile,受控值归 Registry,跨字段/跨文件关系归 Contract。
完整语义解释见 governance/specs/schemas.md。
5 层治理架构一图总览
| 层 | 文件 | 负责什么 | 不负责什么 |
|---|---|---|---|
| ① Schema | frontmatter.schema.json | Frontmatter 字段白名单、数据类型、数组形状、基础枚举 | 不按路径选择字段,不保存平台/标签词表 |
| ② Profile | profiles.yaml | 8 个公共必选字段、Profile→OKFtype映射、字段组合 | 不定义字段类型,不判断路径合法性 |
| ③ Registry | registries.yaml | domain、route、platform、标签等受控词表 | 不保存知识正文或变更历史 |
| ④ Contract | knowledge.py | 加载声明,为 Ingest/Query/Lint 提供统一入口 | 不重复实现各检查类别 |
| ⑤ Checks+Indexes | contracts/checks/、indexes.py | 按路径、来源、导航等类别做确定性检查;生成索引 | 不保存平行枚举,不决定 CI 展示 |
第 1 层:Schema——Frontmatter 的"字段形状"
每张知识卡片头部都有 YAML Frontmatter,frontmatter.schema.json 基于 JSON Schema(draft 2020-12)定义了它的形状:
- 白名单制:
additionalProperties: false,未登记的字段直接拒绝; - 类型与形状:
tags必须是 2–6 个不重复字符串,status只能是draft/stable/deprecated; - 嵌套对象约束:
sources[].resource必选,verified的by/at必选。
⚠️ 注意:Schema 只认"形状",不认"语义"。比如title为空字符串,Schema 管不了,那要交给下一层的 Profile 检查。执行器是自研的 SchemaValidator,采用失败即关闭(fail-closed)策略:连 Schema 文件本身用了不支持的关键字都会被拒。
第 2 层:Profile——由"路径"决定字段组合
Profile 的核心逻辑是:你放在哪个目录,就必须写哪些字段、声明什么类型。profiles.yaml 中:
common_required声明 8 个公共必选字段:type、title、description、tags、status、sources、created_at、updated_at;- 每个 Profile(
concepts、apis、runbooks、operators等)再追加自己的必选字段,并映射到唯一的 OKFtype。
举个例子 📌:
# 放在 apis/ 目录的卡片 → Profile 决定它 type: API # 必须是 API,不能自由改成别的 platforms: [a3] # Profile 强制要求| 路径 Profile | OKFtype | 额外必选字段 |
|---|---|---|
concepts | Concept | platforms |
apis | API | platforms |
runbooks | Runbook | platforms |
interoperability | Interoperability | platforms+ 源/目标技术 |
glossaries | Glossary | 无 |
这套"路径即类型"的设计来自 OKF Bundle 规范,详解见 governance/specs/okf.md 和 governance/specs/frontmatter.md。
第 3 层:Registry——受控词表,拒绝"自由发挥"
registries.yaml 是多个工具共享的小型"字典",主要分区:
- domains:
ops(算子)、model(模型)、common、graph、runtime五大知识域; - technologies:
ascendc、triton、tilelang、pypto等技术栈路由; - scopes:
shared、platforms、inference、training等非技术维度; - platforms:
a2、a3、950、310p、agnostic等平台 ID; - tags:
task.*(任务)、topic.*(主题)、paradigm.*(范式)三维标签体系; - local_sources:登记固定到具体 commit 的本地源码来源(如
cann-ops-raw/ascendc/ops-nn),保证证据可回溯。
"已注册"≠"必须建目录",注册只是让工具认识它。Registry 加载时的自检非常严格:technology 与 scope 的 ID 不允许重叠、每个 route 必须声明所属 domain、标签前缀必须与维度一致,详见 knowledge.py 中的注册表契约校验逻辑。
第 4 层:Contract——跨字段、跨文件的"关系裁判"
JSON Schema 只能看单个对象的形状,但很多规则是"关系型"的,必须由 Contract 统一裁定:
- 从路径推导出 domain、technology/scope、Profile 和 Concept ID;
- 校验卡片
type必须等于 Profile 声明的okf_type; - 判断 route 与 domain 的组合是否被允许;
- 要求
tags同时覆盖task.*和topic.*; - 限制
agnostic平台不能与具体平台混用; - 比较
created_at与updated_at的时间先后; - 校验
verified事件、replaced_by指针和跨技术端点。
Contract 还内置了防坑细节:YAML 解析使用 UniqueKeySafeLoader,拒绝重复 key,避免解析时静默覆盖规则。它只保留一个门面,把 Ingest(写前拒绝)、Query(加载失败关闭)、Lint(只读报告)三个消费者统一接到同一套规则上,杜绝"各写一套例外"。
第 5 层:Checks 与 Indexes——分类执行 + 索引生成
最底层是"干活的手":
- contracts/checks/把检查拆成职责单一的模块:
path.py(路径合法性)、profile.py(Profile 字段)、tags.py(标签覆盖)、links.py(链接可达)、lifecycle.py(时间线)、trust.py(verified 信任层级)、images.py(图片合规)等,并按 P0–P2 等级注册; - indexes.py负责生成并比较"直接子项索引":每个目录的
index.md必须准确列出直接子卡片及摘要,Ingest 与 Lint 共用同一份生成逻辑,不写文件、不重复实现。
这条分工链与 governance/specs/paths.md 中的路径规范互为表里:Spec 解释语义和贡献边界,机器文件才是事实源。
5 层如何协作:一次完整的校验之旅
知识路径 + Frontmatter │ ├─ Schema:字段形状对不对? ├─ Profile:这个目录该写哪些字段? ├─ Registry:平台/标签/路由注册过吗? ├─ Contract:跨字段、跨文件关系成立吗? └─ Checks + Indexes:分类检查 + 索引同步 │ ┌─────┴─────┬──────────┐ ▼ ▼ ▼ Ingest Query Lint 写前拒绝 加载失败关闭 只读报告日常维护时不需要逐个理解每个检查器,直接运行仓库的统一质量入口 check.sh:它依次执行知识 Lint、索引同步检查、检索索引构建与验证、检索回归和单元测试,一次跑完所有治理层。
新手贡献知识卡片的 3 条实用建议
- 先选路径,再写字段:想好卡片属于
concepts还是apis,Profile 会自动决定你的type和必选字段,别试图自己发明映射; - 只用注册过的值:平台、标签去 registries.yaml 里查,找不到就提变更而不是随手造词;
- 贡献前读规范:字段与证据的完整规则在 governance/specs/frontmatter.md,贡献流程见 recipes/contribute_knowledge.md。
总结
cannbot-knowledge 的治理体系可以浓缩为一张图:Schema 管形状,Profile 管组合,Registry 管取值,Contract 管关系,Checks 管执行。五层各司其职、单一事实源,使得几千张知识卡片的结构一致、取值受控、引用可达——这正是它能作为 cannbot 可靠知识底座的原因。理解这 5 层分工后,你再看任何一张卡片的 Frontmatter,都会知道每个字段是被哪一层规则守护着的 ✅。
【免费下载链接】cannbot-knowledgecannbot算子开发知识库插件依赖的知识库本体仓,给cannbot提供统一的知识底座。项目地址: https://gitcode.com/cann/cannbot-knowledge
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考