OKF is markdown plus YAML frontmatter under an Apache-2.0 spec, so a bundle you author here is portable to any other OKF tool. ForceAI adds the catalog, the governed store, and the injection hook that makes an agent actually use it
How it fits together
Import and grounding run on two planes. The catalog API runs on the control plane, the grounding hook runs on the data plane, and both read and write one shared context store. That is why a bundle you import through the dashboard is available to every model call the gateway servesThe real-time flow
This is what happens on every grounded request, in the few milliseconds before the provider is called1
The caller opts in
The request carries
metadata.forceai_okf. Without it the hook returns immediately and the call is untouched2
The hook loads the bundle
It reads the named bundle, and a pinned version if you gave one, from the shared context store
3
Access groups are applied
A concept whose frontmatter lists
access_groups is dropped unless the caller’s access groups intersect it, so a caller is only grounded on knowledge it is entitled to4
The best concepts are selected
Every remaining concept is scored against the user’s last message, tags counting double and prose once. The top three are kept;
index.md and log.md are never injected5
Knowledge is injected and audited
The selected concepts are prepended as one system message and a summary is written to
spend_logs_metadata.forceai_okf, then the provider call proceeds with the knowledge in contextAuthor a bundle
A bundle is a directory of.md files, one concept per file. A type in the frontmatter is required; everything else is optional but improves how well a concept is retrieved and governed. Relative markdown links between files become edges in the concept graph
tags is the strongest lever on retrieval because it is weighted twice as heavily as prose, so tag a concept with the words a user would actually say. access_groups gates who can be grounded on the concept. index.md and log.md are reserved names and are never injected into a prompt
Import a bundle
Open the dashboard Knowledge Catalog page (admin only), give the bundle an id, add your.md files, and click Import. Valid files become concepts; invalid files are reported, not silently dropped. Select the bundle to browse its concepts and the concept graph. The same thing over the API:
Content-Type: application/gzip, which is exactly what GET /forceai/okf/bundles/{id}/export returns, so bundles round-trip cleanly. Each import is a new version, so a re-import never overwrites the old one
Ground a request in real time
This is the part an agent or app does on every turn. Addmetadata.forceai_okf to the chat completion and the gateway does the rest. The value is a bundle id, or an object that pins a version:
"stream": true needs no extra handling. Without forceai_okf in the request the model runs ungrounded, which is the point: you decide per call
How an agent uses it
Grounding keys off the request body, so whatever builds the model call sets the metadata. For a direct API or SDK client, setmetadata.forceai_okf as above; this is the supported path today for any OpenAI-compatible caller. Agent, A2A, and orchestrator turns all pass through the gateway, so grounding fires as soon as the metadata is present on the turn
Attaching a bundle to an agent so its runtime stamps
forceai_okf on every turn automatically, with no caller involvement, is a planned per-agent setting rather than a current option. Until then, ground an agent by setting the metadata wherever its turns originateTune what gets selected
Selection is lexical and deterministic, so you shape it by shaping the concepts. If the right concept is not being pulled in, add the user’s vocabulary to that concept’stags, since tags outweigh prose. At most three concepts are injected per turn, which keeps the added tokens small and predictable. Split a sprawling document into several focused concepts rather than one large file, so the matcher can pick the relevant piece
See what a request used
Open the request in Logs and expand it to see which concepts were injected, or read it back from the spend log. The summary is stamped intospend_logs_metadata.forceai_okf:
available is how many concepts the caller was allowed to see, loaded is how many were injected, and loaded_paths names them exactly
Scope and safety
A caller is only ever grounded on concepts it could see, sinceaccess_groups filtering runs before selection. The hook fails open, so a store hiccup leaves the request untouched rather than blocking it. Injected knowledge is system context the model reads, so treat a bundle as content any grounded caller may see and keep secrets out of it
API reference
Catalog routes are admin-gated and served on the control plane; chat completions are served on the data plane. Behind the dashboard both are the same origin, proxied by nginx, which is why the examples above usehttp://localhost:3000 for catalog calls and http://localhost:4000 for chat