AIOKFAgentsKnowledge ManagementTutorial

How to write an OKF bundle: one directory, three rules, one minimal example

···7 min read

The first time I read the OKF spec, I was surprised how small it is. It is not a database, an SDK, or a query language — it is a directory of markdown files plus a few conventions. This piece walks you straight through writing a minimal, runnable bundle.

Not sure what OKF is? Start here

Three rules: the conformance conditions in section 11

Section 11 of the spec lists three conformance conditions. This piece calls them the three rules. First, every non-reserved .md file has parseable YAML frontmatter. The reserved files are index.md and log.md. Second, every frontmatter block has a non-empty type. Third, index.md and log.md, when present, follow the structure in sections 8 and 9. A bundle that meets all three conforms.

The spec also says there is no schema registry, no central authority, and no required tooling. Because the files are plain text, you can diff, review, and roll back like code. That is a benefit of the format, not a rule in the spec.

The smallest bundle looks like this

text
my-knowledge-bundle/
├── index.md            # directory listing: files at this level
├── weekly-active-users.md
└── user-events.md

index.md: the entry point for the whole bundle

index.md is what the spec calls a "Directory listing." It has no frontmatter. Its body has one or more "# Group heading" sections. Each entry is written as "* [Title](relative/path) - one-line description." The description should come from the concept file’s frontmatter description. One exception applies: the bundle-root index.md may carry one frontmatter key, okf_version, such as okf_version: "0.2". The example below omits it. An agent enters here and reads further once it sees the concept it needs.

markdown
# Metrics

* [Weekly Active Users](weekly-active-users.md) - Unique users who open the product at least once a week

# Tables

* [User events table](user-events.md) - Raw records of every valid event

Each concept file: declare a type, write links

Every non-reserved markdown file needs parseable frontmatter and a non-empty type. The type can be concept, howto, reference, decision, metric, and so on. Fields such as title and description are recommendations, not requirements. Concepts connect through ordinary markdown links — those links are the knowledge graph.

markdown
---
type: metric
title: Weekly Active Users
description: Unique users who open the product at least once a week
---

# Definition

Unique users who produced at least one valid event in the last seven days.

# Related

- [User events table](user-events.md)

How an agent uses it

The key is type and links. An agent enters through index.md, uses type to tell whether a file is a concept, a how-to, or a decision — no keyword guessing — and traverses markdown links to related nodes when it needs more context. The whole thing is traversal, not search, which is the biggest difference from vector retrieval.

A real example: checking this site’s /knowledge against the three rules

The example above is a sketch. The one below is real: the knowledge directory in this site’s repo. I counted it on November 4, 2026. It has 25 .md files. index.md lists the other 24 nodes. There is no log.md. The spec says a log.md MAY appear; it is not required.

text
knowledge/
├── index.md                          # root listing; frontmatter has only okf_version
├── how-agents-use-this.md            # type: howto
├── architecture-i18n-routing.md      # type: reference
├── architecture-ssr-prerender.md     # type: concept
├── gotcha-hydration-mismatch-418.md  # type: decision
└── ...20 more nodes

Here is the full text of a short node. A short node shows most clearly what a conforming node needs. architecture-i18n-routing.md has 27 lines. It records how Chinese and English URLs differ and which component to use for internal links. The node is written in Chinese and is shown as is.

markdown
---
type: reference
title: i18n 與路由
description: "中英文網址前綴與語系切換規則。"
---

# i18n 與路由

## 語言
- 繁中(`zh`)為預設,在根路徑 `/`;英文(`en`)在 `/en` 前綴下。
- i18next 設定在 `src/i18n/index.ts`,語言依 pathname 判定(`/en` 開頭 → en,
  否則 zh)。翻譯字串在 `src/i18n/zh.json` / `en.json`。
- 路由樹 `src/App.tsx`:`localizedRoutes` 同時掛在 `/`(zh)與 `/en`(en)之下。

## 內部連結一律用 LocalizedLink
- `src/components/LocalizedLink.tsx` + `src/i18n/routing.ts` 的 `localizePath()`:
  在 en 語系自動加 `/en` 前綴。**寫連結用它,不要手拼 `/en/...`。**
- 爬蟲側對應的 helper 在 `scripts/lib/render-article-html.mjs` 的 `localizeHref()`
  (鏡像同一規則)。

## SEO
- 每頁有 canonical + hreflang(zh ↔ en ↔ x-default)。
- 靜態頁(v1~v4)自帶這些 meta;React 頁由
  `scripts/generate-localized-entrypoints.mjs` 注入。

## 相關
[SSR 雙渲染器](architecture-ssr-prerender.md) · [部署](infra-deploy.md)

This node covers three things. Chinese pages live at the root path, and English pages live under /en. Internal links always go through LocalizedLink; do not build URLs by hand. LocalizedLink is this site’s link component, and it adds /en on English pages. Every page has canonical and hreflang tags. canonical tells search engines which URL is the original. hreflang tells them where the other language versions of the page are. When an agent changes links or routes, it reads this one page to learn the rules.

The frontmatter of this node has only three keys: type, title, and description. The spec also recommends resource and tags. A resource is a URI for the underlying asset, such as a data table. This node describes rules and has no single matching asset, so it has no resource. The "related" line at the end is a set of ordinary markdown links to other nodes.

Diagram: the file tree of this site’s knowledge directory, the frontmatter of one node, and the result of each OKF v0.2 conformance rule
This site’s /knowledge checked against the three rules in OKF v0.2 section 11 (November 4, 2026). Diagram drawn by KeepOnFirst.

I wrote a small script that checks each file against the three rules. These are the results.

Rule 1: every non-reserved .md file has parseable frontmatter. The script parsed all 24 nodes with a YAML parser. All 24 parsed.

Rule 2: type is not empty. All 24 nodes have a type: 13 concept, 6 reference, 3 howto, and 2 decision. The spec says type values are not registered centrally. I chose these four values myself.

Rule 3: index.md follows section 8. The root index.md has one frontmatter key, okf_version: "0.2". All 24 entries use the form "* [Title](path) - description", and every linked file exists.

All three rules pass, with 0 violations. The script found one small difference. For the tools-page node, the description in index.md differs from the node’s own description. The spec uses SHOULD here, not MUST, so this is not a violation. But the same fact now lives in two places, and a later edit to one of them can miss the other.

To add a log.md, follow section 9 of the spec. Entries are grouped by date, newest first. Date headings must use the ISO 8601 form YYYY-MM-DD, for example "## 2026-11-04". Each entry is plain prose about what changed that day.

Another piece explains how this /knowledge divides the work with llms.txt and AGENTS.md:

llms.txt vs AGENTS.md vs OKF: three kinds of "markdown for AI"

A few trade-offs I hit myself

I built a real bundle for this site’s repo, in /knowledge. It now has 24 nodes that cover architecture, decisions, traps, and more. With it, Claude and Codex do not re-crawl the whole repo every time. A few trade-offs became clear while I was doing it.

Keep nodes small, ideally one concept per file. Rather than one big file, split the knowledge into small linked nodes so an agent reads only the relevant one.

Do not store trivial state that goes stale (a commit hash, a temporary TODO); that is what git is for. The bundle should hold the stabler stuff: architecture, decisions, conventions, and traps. Most important, a bundle alone does nothing. Put "read before you work, update after" into the entry files the agent loads, or the bundle will not stay alive.

Hands-on: a repo as an OKF bundle for agent memory (with A/B data)

You need no new database, query language, or SDK. One directory and three rules are enough for a knowledge base that a human can read, an agent can traverse, and Git can version.

Correction log

Corrected on 2026-10-17. The earlier version listed three rules: one index, one truth; typed frontmatter; and git-native. Those phrases came from okf.md, a community website, not from the specification Google published. I had treated the okf.md summary as the spec. The earlier index.md example also had title, version, and entries in its frontmatter. That breaks the spec: index.md has no frontmatter, and the spec defines no entries field. This revision follows sections 8 and 11 of the official v0.2 spec. It rewrites the three rules and the index.md example. It also replaces "manifest" with the spec term "directory listing."

Sources