LangGraph and LangChain tools, retriever, and navigator for OKF (Open Knowledge Format) Markdown bundles
Project description
okf-agents
LangGraph and LangChain tools, retriever, and navigator for OKF knowledge bundles.
Installation • Quick Start • Examples • Docs • Contributing
Have a directory of Markdown files with YAML frontmatter that link to
each other — a wiki, a knowledge base, internal docs, runbooks? okf-agents
parses the whole directory, builds the link graph, and gives you typed
LangGraph and LangChain building blocks: agent tools, a keyword retriever,
a graph-aware semantic retriever, a query router, and a bounded navigator
subgraph. Everything is composable, and everything except the navigator
works offline with no model.
The Markdown files follow the Open Knowledge Format (OKF)
convention — any .md file with a type field in its YAML frontmatter
qualifies.
Why graph-aware retrieval?
Most RAG pipelines chunk documents into a vector store and throw away
the link structure. okf-agents keeps the link graph as a first-class
citizen:
| Traditional RAG | okf-agents | |
|---|---|---|
| Input | Flat document chunks | Linked Markdown files with metadata |
| Retrieval | Vector similarity only | Vector search + link-graph expansion |
| Structure | Lost after chunking | Preserved — titles, tags, types, links |
| Multi-hop | Requires multiple retrievals + prompt engineering | Built-in navigator walks links within hard budgets |
| Determinism | Depends on embeddings | Search, traversal, and routing are fully deterministic |
| Dependencies | Embedding model required | No model required for tools, search, or routing |
Installation
pip install okf-agents
Only langgraph, langchain-core, pydantic, and pyyaml are
required. Provider SDKs and vector-store packages are never hard
dependencies — bring the ones you need.
Quick Start
import tempfile
from pathlib import Path
from okf_agents import OKFBundle
tmp = Path(tempfile.mkdtemp()) / "concepts"
tmp.mkdir()
(tmp / "orders.md").write_text(
"---\ntype: table\ntitle: Orders\ntags: [sales]\n---\n"
"# Orders\n\nEach order belongs to a [customer](customers.md).\n"
)
(tmp / "customers.md").write_text(
"---\ntype: table\ntitle: Customers\ntags: [crm]\n---\n"
"# Customers\n\nCustomer accounts and contact details.\n"
)
bundle = OKFBundle.load(tmp.parent)
print(bundle.concept_count, "concepts loaded")
for concept in bundle.search("customer", top_k=3):
print(concept.id, concept.frontmatter.title)
Point OKFBundle.load() at any directory of Markdown files with type
frontmatter. No index file is required — see
docs/concepts.md.
What your Markdown files look like
Any .md file with a type field in YAML frontmatter works:
---
type: runbook
title: Deploying to Production
tags: [devops, deploy]
---
# Deploying to Production
Before deploying, verify the [staging checklist](staging-checklist.md)
and confirm [monitoring](../monitoring/alerts.md) is green.
Links between files ([text](relative-path.md)) become edges in the
graph. okf-agents resolves them automatically and exposes them
through the tools, retriever, and navigator.
Examples
LangGraph agent with knowledge base tools
from okf_agents import create_okf_tools
tools = create_okf_tools(bundle) # read_concept, search_concepts, list_links, read_index
Drop these into any tool-calling agent. All four are deterministic and require no model.
Keyword retriever (no vector store)
from okf_agents import OKFRetriever
retriever = OKFRetriever(bundle=bundle, top_k=3)
docs = retriever.invoke("orders")
Returns LangChain Document objects ranked by title > tags >
description > body.
Query router
from okf_agents import create_okf_router
router = create_okf_router(bundle)
router({"query": "Orders"}) # exact title match → "bundle"
router({"query": "how do refunds work?"}) # vague, no vector store → "bundle"
Pass vector_store= to route vague queries to "vector", or
classifier= to let a model choose.
Navigator subgraph (autonomous multi-hop traversal)
import json
from langchain_core.language_models.fake_chat_models import FakeListChatModel
from okf_agents import create_okf_navigator
model = FakeListChatModel(
responses=[
json.dumps({"concept_ids": ["concepts/orders"]}),
json.dumps({"sufficient": True}),
json.dumps({
"answer": "Orders belong to customers.",
"citations": ["concepts/orders"],
}),
]
)
navigator = create_okf_navigator(bundle, model, max_hops=2)
result = navigator.invoke({"question": "How do orders relate to customers?"})
print(result["answer"], result["citations"])
The navigator reads concepts, follows links breadth-first, and produces
a cited answer — all within hard token/hop/concept budgets. Swap
FakeListChatModel for ChatAnthropic, ChatOpenAI, or any
BaseChatModel in production. See
docs/navigator-and-budgets.md.
Graph-aware semantic retrieval
sync_bundle_to_vector_store + OKFGraphRetriever work with any
LangChain VectorStore that supports ID-based lookup:
sync_bundle_to_vector_store(bundle, vector_store) # idempotent upsert
retriever = OKFGraphRetriever(bundle=bundle, vector_store=vector_store, top_k=3, expand_hops=1)
docs = retriever.invoke("order belongs")
# → concepts/orders + concepts/customers (reached via the link graph)
See docs/vector-stores.md for a full working example and the store-capability contract.
Architecture
Markdown directory (your wiki / knowledge base / docs)
│
▼
OKFBundle.load() deterministic parse + link graph + lexical search
│
├── create_okf_tools() four LangChain tools (no model required)
├── OKFRetriever keyword BaseRetriever
├── sync_bundle_to_vector_store + OKFGraphRetriever
│ idempotent sync + graph-aware semantic retrieval
├── create_okf_router() bundle / vector / both classification node
└── create_okf_navigator() bounded read → expand → cite subgraph
Every piece is independently usable. Use just the bundle loader, just the tools, or just the retriever — nothing forces you to wire the whole stack.
Use cases
- Internal wikis — point at a Confluence export or a docs directory and get an instant Q&A agent
- Runbooks and SOPs — navigable, citable answers grounded in your actual procedures
- Product knowledge bases — support agents that follow links between related articles instead of returning isolated chunks
- Research notes — Obsidian-style vaults with linked concepts get graph-aware retrieval out of the box
- API/SDK documentation — linked reference docs become searchable, traversable agent tools
Compatibility
- Python 3.11, 3.12, 3.13
langgraph>= 0.2,langchain-core>= 0.3,pydantic>= 2.0
Full API reference: docs/api-reference.md | Optional extras and dev setup: docs/testing.md
Contributing
Contributions welcome — see CONTRIBUTING.md.
License
MIT © Ronald Li
If this project saved you time, a ⭐ helps others find it.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file okf_agents-0.2.0.tar.gz.
File metadata
- Download URL: okf_agents-0.2.0.tar.gz
- Upload date:
- Size: 80.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4959275905d9e3b1393ef6cec5a33c8b2c24ad554907086f80f237c26ec897bf
|
|
| MD5 |
aad4d1b764a05e0ff1c1e1a279a043e7
|
|
| BLAKE2b-256 |
e7b5b13cdb87cffb52109154ac5de050d030ec6da335beb2b0f5cee32ce2d30a
|
Provenance
The following attestation bundles were made for okf_agents-0.2.0.tar.gz:
Publisher:
release.yml on RonCodes88/okf-agents
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
okf_agents-0.2.0.tar.gz -
Subject digest:
4959275905d9e3b1393ef6cec5a33c8b2c24ad554907086f80f237c26ec897bf - Sigstore transparency entry: 2180239921
- Sigstore integration time:
-
Permalink:
RonCodes88/okf-agents@12aa7d071079fcd6c98d2decabe6aaa09cae3bf8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/RonCodes88
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@12aa7d071079fcd6c98d2decabe6aaa09cae3bf8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file okf_agents-0.2.0-py3-none-any.whl.
File metadata
- Download URL: okf_agents-0.2.0-py3-none-any.whl
- Upload date:
- Size: 37.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc42e74c0934f03a25e98e15ad49a02aa6b730b01df636f07ae9b3eb899eead7
|
|
| MD5 |
a5705c6a3eb2b9b11262303f867702ff
|
|
| BLAKE2b-256 |
98076c200fb415b642bcd11ad12e66adcfae21abbf4c18440e803e7f0f1cc138
|
Provenance
The following attestation bundles were made for okf_agents-0.2.0-py3-none-any.whl:
Publisher:
release.yml on RonCodes88/okf-agents
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
okf_agents-0.2.0-py3-none-any.whl -
Subject digest:
dc42e74c0934f03a25e98e15ad49a02aa6b730b01df636f07ae9b3eb899eead7 - Sigstore transparency entry: 2180240011
- Sigstore integration time:
-
Permalink:
RonCodes88/okf-agents@12aa7d071079fcd6c98d2decabe6aaa09cae3bf8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/RonCodes88
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@12aa7d071079fcd6c98d2decabe6aaa09cae3bf8 -
Trigger Event:
push
-
Statement type: