用 Knowledge Catalog 跨组织扩展 OKF Bundle 治理与共享
DataHot 速览
Google Cloud 介绍如何通过 Knowledge Catalog 将 OKF bundle 扩展为组织级可治理的 Agent 上下文。OKF v0.1 定义基于 Markdown 与 YAML frontmatter 的便携格式,v0.2 加入 provenance、verification、freshness、attestation 等信任信号;但跨团队共享仍面临可搜索性、安全合规和元数据孤岛问题。将 bundle 映射到 Knowledge Catalog 的现有类型后,任何查询该目录的 Agent 都能发现、访问这些上下文,并通过 IAM 控制权限。发布只需一次性设置和一次推送,官方提供 OKF 示例代码。
为什么值得关注:数据从业者需要管理 Agent 的上下文与治理边界;本文给出用数据目录统一 OKF bundle 的可行路径,避免知识分散在 Git 仓库。
译文
AI 逐段翻译我们继续迭代开放知识格式 (OKF),这是一个开放规范,将LLM-wiki模式形式化为可移植、可互操作的格式。但一个大问题依然存在:如何在整个组织内共享并治理对OKF包的访问?
OKF v0.1建立了一种可移植格式,用于代理所需的上下文:带有YAML前置元数据的Markdown文件,一个必填字段和五个约定。然后,OKF v0.2添加了信任信号(来源、验证、新鲜度、证明),这是机器编写的包被依赖所需的,使团队能够为自己的代理发布可信包。
然而,OKF没有回答的是团队如何在组织内共享包。每个包一个Git仓库是可移植的,但它无法与其描述的数据一起被搜索,无法使用相同的组织身份和合规策略进行安全和治理,也不与数据团队已经使用的技术元数据(模式、血缘、所有权)并存。每个下游代理必须知道每个包的位置,这在小数量包之外无法扩展。
要在整个组织内扩展OKF包,您可以使用知识目录,即Google Cloud的代理上下文引擎。通过将包映射到知识目录的现有类型,每个概念都变得可发现、可治理,并且任何已从目录读取的代理都能访问。
知识目录是代理的上下文引擎
每个查询知识目录的代理都从一个受治理的索引中读取,该索引涵盖组织在BigQuery、Cloud Storage、操作数据库和应用程序中已有的内容。每个条目携带模式、血缘、所有权和标签,并可通过添加领域特定字段的类型化方面进行扩展。同一目录提供搜索和跨项目查找,以检索针对每个代理查询优化的上下文。上下文检索是安全的,由IAM控制治理,因此代理只能看到基于IAM身份他们有权限访问的条目。
将OKF包发布到知识目录需要一次性设置和一次推送。两者都使用知识目录仓库中的OKF示例代码,其包装器调用gcloud dataplex进行设置,并将推送委托给kcmd(同一仓库中的Metadata-as-Code CLI)。
设置注册三个知识目录资源:一个EntryGroup用于保存包,一个名为okf-bundle的EntryType用于其概念,以及一个名为okf的AspectType,它携带OKF信号字段(来自okf-aspect.json中的示例代码模式)。然后推送为每个概念创建一个okf-bundle条目,每个条目有两个方面:一个overview方面用于Markdown正文,一个okf方面用于结构化信号。显示名称、描述和标签位于条目本身。包的index.md导航文件和根log.md也作为条目发布:索引文件只携带overview方面(无OKF前置元数据),log.md携带两个方面,okf_type: Log。
知识目录已经为技术元数据所做的所有事情(搜索、IAM、血缘、跨项目发现)同样适用于OKF包,与其描述的数据并存。
okf方面类型
示例代码中的okf-aspect.json模式定义了AspectType。它携带13个字段,涵盖完整的OKF v0.2规范:
| # | 字段 | 类型 | 用途 |
|---|---|---|---|
| 1 | okf_type | 字符串 | OKF文档类型(自由格式,例如BigQuery表、指标、已证明计算)。 |
| 2 | generated | 记录{by, at} | 最后有意义更改的行为者和时间戳。 |
| 3 | sources | 数组{id, resource, title, author, usage_count, last_modified} | 概念所依据的材料,带有可信度信号。 |
| 4 | verified | 数组{by, at} | 验证事件。一个human:行为者标记最高信任级别。 |
| 5 | status | 字符串 | 生命周期状态:draft、stable或deprecated。 |
| 6 | stale_after | 日期时间 | 内容过时或之后的时间点(带有显式偏移的RFC3339)。 |
| 7 | usage_window | 记录{from, to} | 来源使用计数测量期间。 |
| 8 | runtime | 字符串 | 已证明计算的运行方式(例如,bigquery)。 |
| 9 | parameters | 数组{name, type, required} | 调用方可以填写的类型化命名孔。调用方唯一可以变化的表面。 |
| 10 | computation | 字符串 | 保存计算正文的文件的路径。 |
| 11 | executor | 记录{resource, receipt[]} | 计算如何运行以及必须返回什么证据。 |
| 12 | attester | 记录{resource} | 确定性代码,接收收据并返回裁决。 |
| 13 | extra | 字符串 | 模板未建模的生产者定义的前置元数据,作为JSON[path, value]对。保持往返无损耗。 |
每个字段都带有显示名称、描述和必填索引。okf方面的任何顶级标量字段(okf_type、status、stale_after、runtime、computation、extra)可以直接驱动知识目录搜索谓词,因此aspect:acme-analytics.us-central1.okf.okf_type=Metric返回作用域内的每个OKF指标。记录字段的标量子字段(generated.by、usage_window.from、executor.resource、attester.resource)也驱动谓词。数组字段(sources、verified、parameters)在服务器端不可在其子字段上搜索;代理在entries.get后使用view=ALL在客户端进行缩小范围。对datetime类型字段的搜索谓词有一个注意事项(stale_after、generated.at、usage_window.from/.to),使用裸日期(stale_after=2026-12-31)或范围比较(stale_after>2026-01-01),而不是完整的RFC3339时间戳。
推送包
kcmd push从git读取OKF包,并将每个概念作为条目写入目标知识目录EntryGroup。index.md文件也成为条目,每个概念都父级到其上面的索引,因此包的目录结构作为可浏览的层级保留。
kcmd期望包采用文档布局:markdown文件位于catalog/子目录下,以及包根目录的catalog.yaml,列出快照的条目和方面类型。示例代码的示例代码的setup.ts生成catalog.yaml 从其 --entry-group 标志(默认 okf_demo)中获取,因此将示例接入新包的读者传递该标志,而不必手动编辑 catalog.yaml。
以下是我们在 Acme Retail 包 中介绍的端到端工作流,OKF v0.2 博客:
加载中...
要选择不同的 EntryGroup 名称或推送不同的包,传递 --entry-group your-name 给 setup.ts 和 --bundle path/to/your/bundle 给 push.ts。例如:bun run setup.ts --entry-group acme-bundle 后跟 bun run push.ts。这会重新生成清单,因此后续 push、pull 和 cleanup 都针对新的 EG;使用 gcloud dataplex entry-groups delete <name> --project <your-project> --location <your-location> 手动删除早期的 EG。
The Acme Retail 包 是面向美国零售商 BigQuery 资产组合的合成 OKF 包。它包含六个目录(attesters、tables、metrics、computations、policies、skills)下的九个叶子概念,每个目录有自己的 index.md,加上包根目录,有自己的 index.md 和 log.md。总共推送了 17 个 Entry;Dataplex 自动创建了一个 <eg>_entry 在旁边,所以 gcloud dataplex entries list 返回 18 行。
推送完成后:
- 每个概念 markdown 文件是一个 Knowledge Catalog Entry,可通过搜索在整个项目或组织中发现,具体取决于 IAM 配置。
-
revenue-ytdAttested Computation 在控制台中显示,包含其认可的 SQL、执行器、认证者、验证历史以及完整概念正文。 - 在 Knowledge Catalog 中搜索 “revenue” 的分析师会找到 Acme Retail 的业务定义以及它计算的 BigQuery 表,两者都在一个权限模型下。
- 已经为 BigQuery 表 Entry 调用 LookupContext 的下游代理,通过将 OKF 条目名称添加到其
resources列表中来检索包的上下文。
此外,metrics/revenue.md 成为一个具有两个 Aspect 的 Entry。完整的 entries.get 响应(使用 view=ALL)如下:
加载中...
The overview Aspect 包含 revenue.md 的完整正文。okf Aspect 携带结构化信号字段,因此代理可以直接获取来源、出处和 OKF 类型,而无需解析 markdown。服务端 searchEntries 过滤顶级标量字段和记录字段的标量子字段;代理在客户端 entries.get 后进一步缩小数组元素子字段。(在实际 API 响应和搜索谓词中,Aspect 和 EntryType 按项目编号键控;为了可读性,全文显示 acme-analytics 项目 ID。)
将 OKF 推送到 Knowledge Catalog 的功能
一旦包在 Knowledge Catalog 中,它为任何从目录读取的代理提供两个功能:
- 跨组织可发现性。 代理通过他们已有的 searchEntries 和 LookupContext API 发现包概念,因此 OKF 包在其匹配的每个查询中与 BigQuery 表和其他资源并列出现。
- 治理。 Bundle Entry 继承 EntryGroup 的 IAM,因此单次代理调用返回调用者被允许读取的内容,无需维护并行权限模型。
跨组织可发现性 OKF 包 Entry 出现在 searchEntries 结果中,与 BigQuery 表和其他已编目资源并列,因此已经查询目录的代理会自动获取新包。要从匹配项中检索概念正文、信任信号或链接概念,代理转向 LookupContext 和 entries.get。
一个 LookupContext 调用如下:
加载中...
响应是单个 context 字段,包含预格式化的 YAML 块。该块携带条目的 catalogEntry、其类型、描述、标签作为标签,以及其 overview:概念的完整 markdown 正文,包括信任和新鲜度部分。LookupContext 不渲染自定义 Aspect,因此需要结构化 OKF 信号字段的代理(okf_type、generated、sources 以及其他十个)通过 entries.get 和 view=ALL 以及 LookupContext 调用读取。
没有仓库克隆、手动 Aspect 合并或重新解析 frontmatter。代理使用任何 Knowledge Catalog 客户端已经进行的相同 API 调用。
遍历 OKF 包的代理通常遵循三步流程。已经知道所需 Entry 名称的代理跳过步骤 1。已经知道目标 EntryGroup 并想详尽枚举包的代理用 entryGroups.entries.list 代替步骤 1。
- searchEntries 返回候选 Entry 名称和描述。其
scope接受项目或组织;在该范围内通过查询词缩小范围,包括诸如aspect:acme-analytics.us-central1.okf.okf_type=Metric的 Aspect 谓词。 - 对顶部几个 Entry 名称(每次调用最多十个)的 LookupContext 返回完整概念正文作为预格式化 YAML;
context_budget限制响应大小。 -
entries.get使用view=ALL在任何 Entry 上返回其结构化 OKF 信号(okf_type、generated、sources以及其他十个),代理可以直接过滤或认证。
当概念的 sources[] 通过路径引用另一个概念时,代理调用该 Entry 名称上的 LookupContext 来遍历引用。
Revenue Entry 的完整响应:
加载中...
治理 EntryGroup 上的权限使用标准 Knowledge Catalog IAM。在单次调用中同时命名包概念及其依据的 BigQuery 表的代理会同时收到两者,每个都受其现有访问控制列表(ACL)约束,因此响应只包含调用者已被允许读取的内容。无需维护并行权限模型。
读取代理使用 roles/dataplex.catalogViewer,它授予读取路径:entries.get、LookupContext 和 searchEntries。运行 kcmd push 的身份使用 roles/dataplex.catalogEditor,它授予写入路径:entries.create 和 entries.patch.每个拥有捆绑包的团队一个EntryGroup是多团队模式,EntryGroup上的IAM会级联到其Entries。
LookupContext在单个location中解析给定的条目名称,每次调用最多十个。它不会跟随概念正文中的链接,因此想要引用概念的代理必须明确命名它。将捆绑包的EntryGroup与它描述的数据放在同一个location中,以便在一次调用中获取两者。
生命周期
kcmd push 是幂等的upsert。重新运行是安全的(没有重复,没有错误),但每次推送都会写入每个Entry。概念删除需要对Entry执行显式的 kcmd delete,或使用 cleanup.ts 一次性移除整个EntryGroup;cleanup.ts 只删除EntryGroup及其Entries,因此共享的 okf AspectType和 okf-bundle EntryType会保留在原地,供其他引用它们的捆绑包使用。对于生产中的持续摄取,将CI作业连接到 kcmd push,在每次提交到捆绑包仓库时运行,使用具有 roles/dataplex.catalogEditor 权限的服务账户凭证,作用于目标EntryGroup。
入门指南
OKF定义了一个值得信赖的捆绑包应该是什么样。Knowledge Catalog使其在整个组织中可访问。要开始使用,请查看以下资源:
- 阅读 OKF v0.2规范 并浏览 Acme Retail捆绑包。
- 为你团队拥有的一个领域编写一个小型捆绑包。
- 使用 示例代码 中的
setup.ts(用于注册资源)和push.ts(委托给kcmd)将其同步到你的Knowledge Catalog项目。 - 将你现有的代理指向Knowledge Catalog。新的上下文通过它们已经使用的相同LookupContext和searchEntries调用变得可访问。
发布于
这篇内容对你有用吗?
反馈只用于改善内容筛选,不等同于收藏