By the end of this lab you will have built a small Open Knowledge Format (OKF) bundle — knowledge as plain markdown files — and then embedded it, so an AI can find the right file by meaning and answer grounded in its exact contents. That combination — vectors to find, the folder to ground — is the architecture the Folders vs Vectors course builds toward. Here you build it.
Before you start
Python 3.10+, an Anthropic API key (export ANTHROPIC_API_KEY=...), about 45 minutes.
uv init okf-lab && cd okf-lab
uv add anthropic sentence-transformers numpy pyyaml
# or: pip install anthropic sentence-transformers numpy pyyaml
Build the OKF bundle
An OKF bundle is just a folder of markdown files, each with a little YAML frontmatter (the only required field is type). This script writes a tiny one. Create and run build_bundle.py:
import os
FILES = {
"knowledge/tables/orders.md": """---
type: BigQuery Table
title: Orders
description: One row per completed customer order.
tags: [sales, revenue]
---
# Schema
- order_id (STRING): globally unique order id
- customer_id (STRING): foreign key to [customers](customers.md)
- amount_eur (FLOAT): order total, in euros
# Joins
Joined with [customers](customers.md) on customer_id.
""",
"knowledge/tables/customers.md": """---
type: BigQuery Table
title: Customers
description: One row per customer.
tags: [sales]
---
# Schema
- customer_id (STRING): globally unique id
- country (STRING): ISO country code
- created_at (DATE): sign-up date
""",
"knowledge/metrics/weekly_active_users.md": """---
type: Metric
title: Weekly Active Users
description: Distinct customers with an order in the last 7 days.
tags: [metric, engagement]
---
# Definition
COUNT(DISTINCT customer_id) from orders where the order date is
within the last 7 days. This is order-based activity, not app opens.
""",
}
for path, content in FILES.items():
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, "w") as f:
f.write(content)
print("Wrote", len(FILES), "files into knowledge/")
uv run build_bundle.py
That folder is your knowledge base — human-readable, git-versionable, no database required.
Load and parse the bundle
Reading an OKF bundle is just walking the folder and splitting each file into its frontmatter (structured fields) and its body (the markdown). Create ask.py:
import glob
import yaml
def load_bundle(root: str = "knowledge") -> list[dict]:
docs = []
for path in sorted(glob.glob(f"{root}/**/*.md", recursive=True)):
raw = open(path).read()
meta, body = {}, raw
if raw.startswith("---"):
_, front, body = raw.split("---", 2) # frontmatter, then the body
meta = yaml.safe_load(front) or {}
docs.append({"path": path, "meta": meta, "body": body.strip()})
return docs
docs = load_bundle()
print("Loaded:", [d["path"] for d in docs])
Embed the files — the vector half
Now turn each file into a vector so we can find it by meaning. We embed the title, description, and body together.
import numpy as np
from sentence_transformers import SentenceTransformer
embedder = SentenceTransformer("all-MiniLM-L6-v2")
texts = [
f"{d['meta'].get('title', '')} — {d['meta'].get('description', '')}\n{d['body']}"
for d in docs
]
vectors = embedder.encode(texts, normalize_embeddings=True)
Find with vectors, ground in the folder
This is the whole architecture in one function: embed the question, find the nearest file (vector find), then hand the model that file's exact contents and make it answer only from there, citing the path (folder ground).
from anthropic import Anthropic
client = Anthropic()
def ask(question: str) -> None:
q = embedder.encode([question], normalize_embeddings=True)[0]
i = int(np.argmax(vectors @ q)) # VECTOR: nearest file by meaning
doc = docs[i] # FOLDER: open that exact file
system = (
"Answer using ONLY the knowledge file below, and cite it by its path. "
"If the file does not contain the answer, say you don't know.\n\n"
f"File: {doc['path']}\n"
f"Type: {doc['meta'].get('type', '')}\n\n"
f"{doc['body']}"
)
resp = client.messages.create(
model="claude-opus-4-8",
max_tokens=512,
system=system,
messages=[{"role": "user", "content": question}],
)
print(f"\nQ: {question}")
print(f"[vector matched → {doc['path']}]")
print(resp.content[0].text)
ask("How is weekly active users calculated?")
ask("What does an order row contain, and how does it link to customers?")
Run it
uv run ask.py
The first question never says "metric" or the file name — yet the vector index finds weekly_active_users.md by meaning, and the answer is grounded in that file's exact definition, with a citation. The second lands on orders.md and answers from its real schema and join. Vectors found the door; the folder gave the exact contents behind it.
Where to go next
- Follow the links — after matching a file, parse its markdown links and pull in the neighbours it references (e.g. orders → customers) before answering.
- Let an agent navigate — give the folder to a ReAct agent as tools (search, open file, follow link) and let it explore.
- Go deeper — Folders vs Vectors covers the whole picture; RAG in Production covers scaling the vector half.