Command Palette

Search for a command to run...

0

给 Agent 知识库换个标准格式:OKF 转换实战

Google 刚发了 Open Knowledge Format (OKF) v0.1。我用了两天,把自己 270 份知识文档全部转了过去。这篇文章是转换过程中的真实体验——踩了什么坑,哪些是白送的,以及我为什么觉得这个格式值得一试。

一次真实的 Agent 知识 OKF 化记录:199 个概念文档,5 个 bundle,100% 合规。


一切从一个念头开始

事情是这样的。

六月中旬,Google Cloud 发了 OKF v0.1(Open Knowledge Format)。当时扫了一眼,心想:又一个大厂标准?没太当回事。

但隔了几天刷到社区讨论时,我越看越觉得眼熟。

OKF 的核心描述是:一个目录的 Markdown 文件,每份文件带 YAML frontmatter,用 type 字段标记概念类型

这不就是我那个 compound-system 知识库在用的格式吗?

我的 solutions/ 目录下,bug 记录、知识条目、模式提取——全是 Markdown + YAML frontmatter,只是 type 字段叫的是 problem_type

这种巧合让人手痒。

加上我之前一直有个困扰——compound-system 跑了一年,攒了快 170 份文件,但除了我没人能摸清里面有什么。没有目录索引,没有统一元数据,想让另一个 agent 读一读都不知道从哪下手。

OKF 说它解决的就是这个问题:让 agent 能遍历你的知识库,而不是在文件名列表里瞎猜。

那行,试试吧。

OKF 到底是什么

先简单交代一下格式,如果你已经看过 SPEC,这段可以跳过去。

OKF 定义了一种叫 Knowledge Bundle 的东西:一个目录树,里面全是 .md 文件。

每个 .md 文件代表一个 概念(Concept),由两部分组成:

---
type: Bug
title: 修复了一个 compression 导致的 session 分裂
tags: [hermes-agent, compression]
timestamp: 2026-06-21T00:00:00Z
---
这里是概念的正文,标准的 Markdown。

唯一必须有的字段就是 type。其他都是推荐——titledescriptiontagstimestampresource

整个格式的约束少得可怜:

  • 每个概念的 type 不能为空
  • 不能把概念叫 index.mdlog.md(这是保留文件名,用于目录索引和变更日志)
  • 其他任何额外字段都可以保留,消费者不能拒收

加上一个 optional 的 index.md 作目录索引,然后就没有了。

没有 schema registry,没有 SDK,没有 schema 注册中心。

bundle/
├── index.md          ← okf_version: 0.1
├── bugs/
│   ├── index.md      ← 目录索引
│   ├── fix.md        ← type: Bug
│   └── crash.md      ← type: Bug
└── patterns/
    ├── index.md
    └── tdd-workflow.md

要是这个格式看着像 Obsidian vault 或者任何一个 LLM wiki 仓库,那是因为它本来就是从这些模式里萃取出来的。

Google 团队做的事情不是发明新格式,而是把已经存在的模式明确写成了规范

说实话,这个思路本身也是一种 OKF 式的实践——把隐式知识显式化。

我的文档长什么样

动手之前,我先做了个全量盘点。作为一个长期跑 compound-system 的人,我的知识文档散落在这些地方:

来源文件数已有 frontmatter主要问题
compound-system 知识库~170✅ 全有,但 type 字段错位problem_type 代替 type
Hermes skills (SKILL.md)~42✅ 全有,type 缺失type 字段的只有 PM skill
dual-form 自动挖掘~46✅ 全有缺标准元数据
~/docs/ 文档目录~20❌ 一个都没有纯 Markdown
各项目 AGENTS/HANDOVER~55❌ 一个都没有纯 Markdown

总计:大约 270 份可转换的知识文件。

其中约有 55 份是已经很接近 OKF 的——有 frontmatter、有关键元数据、有 Markdown 正文,只是差一个 type 字段。

另外大约 215 份是纯 Markdown 文档,什么都没有。

还有一个特殊群体:compound-system 里 auto-mined 的 70 多条机器记录。它们的前置元数据是用 JSON dump 直接写的,YAML 解析器看了直接报错。

这种我才不转。

转换过程:几个值得说的点

1. type 字段是最后的那层纸

compound-system 的 frontmatter 长这样:

---
title: "CodexPlusPlus #1303 UA cache fix"
module: hermes-agent
tags: [task, auto-reflection]
problem_type: knowledge
severity: low
created: 2026-07-02
---

转成 OKF 只需要做一件事:加一个 type: SessionKnowledge,把 problem_type 原样保留(OKF 允许扩展字段),把 created 标准化为 timestamp

整个转换最重的逻辑就是这个。剩下的都是体力活。

2. 半成品知识不值得归档

compound-system 里有一批 auto-mined 条目,是 pipeline 自动扫描 session 后生成的 bug 记录。它们的 title 字段直接塞了 JSON 片段:

title: '{"content": "1|[package]\n2|name = "codex-plus-core"\n3|version.workspace = tr'

这不是 YAML 格式的问题,这是内容本身就坏了——标题里塞了 raw 日志输出,引号没转义,换行符没处理。

开始我试图让转换器处理这些边缘情况——写自定义 YAML representer、手动构造安全输出、加 fallback 编码函数。搞了两轮后我意识到:不值得。

这些不是知识文档,是管线中间产物。它们有文件名、有记录、但没有人会主动翻阅。OKF 的设计哲学里有一条很重要的假设:知识是被策划的(curated),不是被倾倒的。

所以我加了过滤:源文件 YAML 解析失败的自动跳过。73 条记录,全部跳过,一条不亏。

3. 纯 Markdown 文档反而最简单

那些没有 frontmatter 的文档——AGENTS.md、HANDOVER.md、~/docs/reports/ 下的报告——处理方式反而纯粹:从第一个 # 标题 提取 title,根据文件名推断 type,自动生成 frontmatter。

---
type: AgentInstruction
title: Agent Workspace — lennney
timestamp: 2026-07-05T16:23:18+00:00
---

这种推断不是完美的。比如 ~/AGENTS.md 的 description 是我截取的第一段有意义文字——"项目地图"的表格开头。它不够优雅,但足够让 agent 在浏览目录索引时知道自己找到了什么。

OKF 的渐进式暴露机制(progressive disclosure)解决的就是这个问题:不要试图一次给全部信息,先给一个摘要,用户/agent 感兴趣再点进去。

最终结果

处理完 270 份源文件后,产出是 5 个 bundle:

Bundle概念文件目录索引类型分布
compound-system717Bug(8) + Knowledge(40) + Pattern(6) + SessionKnowledge(4) + PiInsight(1) + Archive(12)
skills8254HermesSkill(16) + Reference(39) + 已有 type(27)
dual-form4626SourcePattern(23) + HermesSkill(19) + SubAgentConfig(4)
docs205Report(6) + Plan(5) + Doc(6) + Requirement(2) + MemoryReport(1)
projects518AgentInstruction(15) + HandoverDoc(8) + Readme(8) + 其他(20)
合计270100✅ 100% OKF v0.1 合规

这 100 个 index.md 是我最在意的产出。每个目录一个索引文件,agent 可以从 bundle root 开始,逐层展开,找到它需要的知识。

以前的方式是:agent 拿到一个 "BUGS-2026-07-05-foobar.md" 文件名,猜内容。现在的方式是:agent 读到 bugs/index.md,看到每条记录的 title 和 description,再做决定。

区别就像从文件名猜书的内容,变成了翻目录。

几个意料之外的事

写转换器的时间少于写格式适配的时间

整个 okf-convert.py 大约 650 行。写第一版大概花了四十分钟。剩下的时间全花在:

  • 处理坏掉的 YAML frontmatter
  • 调整 index.md 的排版
  • 修复 bundle root 元数据被覆盖的问题
  • 验证 270 个文件都能被 YAML 解析器读回去

格式转换从来不是技术问题,是数据质量问题。

中间产物最难处理

这一点前面说过了,但值得再提一下。我没想到 compound-system 里 auto-mined 记录的比例这么高——170 条里有 73 条。这意味着 pipeline 自动产出的东西,真正有价值的不到 60%。

但这个比例本身就很有意思——如果知识管线产出的东西大部分是垃圾,问题可能不在 OKF 转换,而在管线本身。

index.md 的生成比想象中有用

开始我把 index.md 当作一个"顺便做了"的 feature。实际生成后,我第一次用 cat bugs/index.md 看了一眼——发现几条记录的 title 显示为 Untitled——因为源文件根本没有标题。

这些小问题以前淹没在文件列表里,index.md 把它暴露了出来。

现在能用 OKF 做什么

OKF 的生态还在早期,目前能做的是这些:

  1. Git clone 就是知识转移 —— bundle 是一个目录,你可以 git push、打 tar 包、或者直接 rsync。不需要任何服务端,不需要数据库
  2. Agent 可以遍历 —— 从 index.md 开始,逐层深入到具体概念。Google 的 reference agent 演示了这种模式
  3. 可视化 —— Google 给了 viz.html 生成器,一个 HTML 文件就能把 bundle 渲染成交互图
  4. 任意框架消费 —— OKF 不绑定 agent 框架。Google ADK、LangChain、甚至 Hermes 的 skill 系统都能读

但对我的实际场景来说,最有价值的是第三条——viz.html。一图胜千言,对非技术队友尤其如此。

下一步

OKF 还只是一个 v0.1 草案,很多问题还没答案:

  • Bundle 大了之后怎么办?200 个文件以上的搜索和检索,不能全靠遍历 index.md
  • 多 bundle 之间怎么交叉引用?目前只能在一个 bundle 内链接
  • 如何保证知识不过期?OKF 有 timestamp 字段但没有过期策略

这些问题不是格式能解决的,需要上层工具。

不过从另一个角度看:一份格式在 v0.1 阶段就能把 270 份文档干净利落地组织起来,已经相当了不起了。

代码见 GitHub: okf-convert.py

以上,既然看到这里了,如果觉得不错,随手点个赞、在看、转发三连吧~
谢谢你看我的文章,我们,下次再见。

/ 作者:Lennney