OKF v0.1 · คู่มือฉบับภาษาไทย

Open Knowledge Formatสร้าง knowledge base ที่ AI ช่วยดูแล — ตั้งแต่เริ่มต้นจนถึงระดับองค์กร

ฐานความรู้ที่เก็บเป็นไฟล์ Markdown ธรรมดา ที่ทั้งคนและ AI agent อ่าน เขียน และใช้งานร่วมกันได้

เรียบเรียงโดย Supachai Jaturaprom [TumEz]
เขียนโดย Claude Code — Opus 4.8 (AI) · ปรับปรุง 2026-06-15 · OKF v0.1

คำนำ

ยินดีต้อนรับสู่ คู่มือ Open Knowledge Format (OKF) ฉบับภาษาไทย — หนังสือที่จะพาคุณสร้างและดูแล knowledge base ที่ AI ช่วยดูแล ด้วยรูปแบบ OKF: ฐานความรู้ที่เก็บเป็นไฟล์ Markdown กับ YAML frontmatter ที่ทั้งคนและ AI agent ใช้งานร่วมกันได้ โดยไม่ต้องพึ่ง SDK หรือฐานข้อมูลเฉพาะทาง

🌐 อ่านฉบับภาษาอังกฤษได้ที่ปุ่ม EN มุมขวาบน (English version available — click EN in the top bar)

สารบัญ

หนังสือเล่มนี้เหมาะกับใคร

  • ผู้เริ่มต้น ที่อยากมี knowledge base ส่วนตัว/ของทีม ที่ค้นได้และไม่ผูกกับ vendor
  • นักพัฒนา/ทีมข้อมูล ที่อยากให้ AI agent เข้าถึงความรู้ภายในองค์กรอย่างเป็นระบบ
  • สถาปนิกระบบ/ทีม platform ที่ต้องวางระบบใช้ร่วมกัน ข้าม session และข้ามทีม ระดับองค์กร (on-prem)

ไม่ต้องมีพื้นฐาน OKF มาก่อน ขอแค่พอใช้ command line และ Git ได้บ้าง

ข้อตกลงในหนังสือ

  • คำสั่งที่พิมพ์ใน terminal อยู่ในกล่องโค้ด · ศัพท์เทคนิค (concept, frontmatter, bundle, MCP) คงไว้เป็นภาษาอังกฤษเพื่อให้ตรงกับเอกสารต้นทางและโค้ด · กล่อง blockquote คือข้อควรระวัง/เคล็ดลับ

หมายเหตุเรื่องเวอร์ชัน: OKF เป็นสเปก v0.1 (เผยแพร่ 12 มิ.ย. 2026 โดย Google Cloud) สเปกหลักบังคับแค่ ฟิลด์ type — "แนวปฏิบัติที่ดี" อื่น ๆ ในเล่มนี้ส่วนใหญ่มาจากชุมชน LLM-wiki และ reference implementation ของ Google

โปรเจกต์ต้นทาง (โค้ด + เครื่องมือทั้งหมด): https://github.com/supachai-j/open-knowledge-format-starter

เริ่มกันเลยที่ OKF คืออะไร

สารบัญ

ภาคที่ 1 — รู้จัก OKF

ภาคที่ 2 — เริ่มต้นใช้งาน

ภาคที่ 3 — แนวคิดหลัก

ภาคที่ 4 — การใช้งานประจำวัน

ภาคที่ 5 — เขียนให้ดี

ภาคที่ 6 — ระดับองค์กร (Enterprise)

ภาคผนวก

OKF คืออะไร

Open Knowledge Format (OKF) คือสเปกแบบเปิดสำหรับเก็บ "ความรู้" ขององค์กรในรูปของ ไดเรกทอรีของไฟล์ Markdown ที่มี YAML frontmatter เพื่อให้ทั้งคนและ AI agent เขียน อ่าน แลกเปลี่ยน และใช้งานได้ — โดยไม่ต้องมี SDK, ฐานข้อมูล, หรือเครื่องมือเฉพาะทาง

ถ้าคุณ cat ไฟล์ได้ คุณก็อ่าน OKF ได้ · ถ้าคุณ git clone repo ได้ คุณก็ส่งต่อ OKF ได้

ที่มา

OKF v0.1 เผยแพร่เมื่อ 12 มิถุนายน 2026 โดยทีม Data Cloud ของ Google Cloud (Sam McVeety และ Amir Hormati) เป็นการทำให้ "LLM-wiki pattern" ที่ Andrej Karpathy เสนอไว้ กลายเป็นมาตรฐานที่พกพาได้และเป็นกลาง (vendor-neutral)

แนวคิด LLM-wiki คือ: แทนที่จะให้ LLM ไปค้นเอกสารดิบใหม่ทุกครั้งที่ถาม ให้ AI ค่อย ๆ สังเคราะห์ความรู้ลงเป็นหน้า Markdown ที่จัดระเบียบและเชื่อมโยงกันไว้ล่วงหน้า แล้วโหลด หน้าที่เกี่ยวข้องเข้า context ตรง ๆ

องค์ประกอบหลัก (ดูละเอียดในภาคที่ 3)

คำความหมายสั้น ๆ
Bundleไดเรกทอรีของไฟล์ความรู้ทั้งหมด — หน่วยที่ใช้แจกจ่าย
Conceptความรู้หนึ่งหน่วย = ไฟล์ .md หนึ่งไฟล์ (เช่น ตาราง, metric, playbook)
Concept IDpath ของไฟล์ใน bundle ตัด .md ออก เช่น tables/orders.mdtables/orders
Frontmatterบล็อก YAML บนหัวไฟล์ (เก็บ metadata เช่น type, title, tags)
Linkลิงก์ Markdown ระหว่าง concept = สร้างความสัมพันธ์เป็น graph

ตัวอย่าง concept หนึ่งไฟล์

ไฟล์ tables/orders.md:

---
type: BigQuery Table
title: Orders
description: หนึ่งแถวต่อหนึ่งคำสั่งซื้อของลูกค้า
tags: [sales, orders]
timestamp: 2026-06-15T00:00:00Z
---

# Schema
| Column | Type | Description |
| :--- | :--- | :--- |
| order_id | STRING | รหัสคำสั่งซื้อ (unique) |
| customer_id | STRING | FK ไปยัง [customers](customers.md) |

# Joins
เชื่อมกับ [customers](customers.md) ผ่าน `customer_id`

จะเห็นว่ามันคือ Markdown ธรรมดาที่อ่านออกได้ทันที — แค่มีหัว YAML เล็ก ๆ และมีลิงก์ไปยัง concept อื่น

หลักการออกแบบ 3 ข้อ

  1. บังคับน้อยที่สุด (minimally opinionated) — frontmatter บังคับแค่ฟิลด์ type เดียว ที่เหลือผู้ผลิตกำหนดเอง
  2. ผู้ผลิตกับผู้บริโภคแยกอิสระ — bundle ที่คนเขียนด้วยมือ, agent สร้าง, หรือ pipeline export มา ล้วนถูกอ่านได้ด้วยเครื่องมือใดก็ได้
  3. เป็นกราฟ ไม่ใช่แค่ต้นไม้ — concept เชื่อมกันด้วยลิงก์ Markdown เกิดเป็นความสัมพันธ์ที่รวยกว่าโครงสร้างโฟลเดอร์

OKF ไม่ใช่อะไร

  • ไม่ใช่ taxonomy ตายตัว — ไม่ได้กำหนดว่าต้องมี type อะไรบ้าง
  • ไม่ได้กำหนดว่าต้องเก็บ/เสิร์ฟ/ค้นด้วยโครงสร้างพื้นฐานแบบไหน
  • ไม่ได้มาแทน schema เฉพาะทาง (Avro, Protobuf, OpenAPI) — OKF อ้างอิง ถึงพวกนั้น ไม่ได้กลืนมันเข้าไป

ต่อไปเราจะดูว่า ทำไม ถึงเลือก OKF แทนการทำ RAG แบบเดิม → ทำไมต้อง OKF

ทำไมต้อง OKF (เทียบกับ RAG)

ถ้าคุณเคยทำระบบ AI ตอบคำถามจากเอกสารองค์กร คุณน่าจะเคยใช้ RAG (Retrieval-Augmented Generation) มาก่อน OKF ไม่ได้มาฆ่า RAG แต่มาแก้จุดอ่อนที่ RAG เจอบ่อยในงานจริง

RAG แบบเดิมทำงานยังไง

เอกสารดิบ → ตัดเป็น chunk → ทำ embedding → เก็บใน vector DB
                                                  ↓ (ตอนถาม)
                        ถาม → หา chunk ใกล้เคียง → ยัดเข้า context → ตอบ

LLM ค้นพบความรู้ใหม่จากศูนย์ทุกครั้งที่ถาม ไม่มีการสะสม ไม่มีการเข้าใจว่า chunk ไหน เกี่ยวกับอะไร ขัดกับอะไร หรือเก่าไปแล้ว

จุดอ่อนที่ RAG เจอบ่อย

ปัญหาเกิดอะไรขึ้น
Chunking artifactsตัดประโยคขาดกลาง เช่น "พนักงาน work from home ได้ ยกเว้น 90 วันแรก" อาจเหลือแค่ "พนักงาน work from home ได้" → ตอบผิดอย่างมั่นใจ
Knowledge decayเพิ่มเอกสารใหม่เรื่อย ๆ แต่ของเก่าที่ขัดกันยังอยู่ → ดึงของเก่ามาตอบ (เป็นสาเหตุความล้มเหลวของโปรเจกต์ RAG จำนวนมาก)
กล่องดำretrieval คืน chunk ที่ดูใกล้เคียงแต่ไม่ใช่คำตอบที่ดีที่สุด และไม่มีใครเห็น
ไม่สะสมคำถามที่ต้องสังเคราะห์ 5 เอกสาร ต้องประกอบใหม่ทุกครั้ง ไม่มีอะไรถูกสร้างขึ้นถาวร

OKF ต่างยังไง

OKF เปลี่ยนจาก "ดึง chunk ดิบตอนถาม" เป็น "wiki ที่ AI ดูแลและสังเคราะห์ไว้ล่วงหน้า":

  • เมื่อมีแหล่งใหม่เข้ามา AI อ่าน สรุป และผสานเข้า wiki ที่มีอยู่ — อัปเดตหน้า แก้ cross-reference และ ตั้งธงเมื่อข้อมูลใหม่ขัดกับของเก่า
  • ตอนถาม โหลดหน้า Markdown ที่ "ย่อยมาแล้ว" เข้า context ตรง ๆ — ไม่มี chunk, ไม่มี vector math
  • ความรู้กลายเป็น ของถาวรที่ทบต้น ทุกครั้งที่เพิ่มแหล่ง wiki ก็รวยขึ้น
มิติRAG (ดิบ)OKF (สังเคราะห์ไว้)
รูปแบบเก็บvector DB เฉพาะทางไฟล์ Markdown ธรรมดา + git
คนอ่านออกไหมไม่ (เป็น UI/ไบนารี)อ่านออกด้วย text editor
version controlยากได้ในตัว (git diff/PR/blame)
รู้ว่าขัดกัน/เก่าไหมไม่รู้ตั้งธงและ supersede ได้
ผูก vendorสูงไม่มี (เป็นไฟล์)

"RAG ตายแล้ว" จริงไหม?

ไม่ — วิศวกรส่วนใหญ่มองว่าเป็น คนละชั้น (layer) ไม่ใช่เลือกอย่างใดอย่างหนึ่ง:

  • Layer 1 — wiki (OKF): ความรู้แกนที่สังเคราะห์แล้ว ค้นเจอที่นี่ก็จบ (เร็วสุด สัญญาณดีสุด)
  • Layer 2 — เอกสารดิบ + vector search: ใช้เมื่อ wiki ยังไม่ครอบคลุม (fallback ลงไปขุดของดิบ)
  • Layer 3 — ความรู้ทั่วไปของ LLM: เติมช่องว่างที่ไม่มีทั้งใน wiki และเอกสารดิบ

OKF starter ในหนังสือเล่มนี้รองรับทั้งสองโลก: wiki เป็นหลัก และมี hybrid search (BM25 + semantic) ให้ต่อยอดเมื่อ wiki โตขึ้น (ดูภาคที่ 6)

เมื่อไรควร / ไม่ควรใช้ OKF

เหมาะ เมื่อ: ความรู้ต้องอยู่นาน, ใช้ซ้ำ, มีคนหลายคน/หลาย agent ใช้ร่วมกัน, ต้องตรวจสอบย้อนหลังได้, อยากเลี่ยง vendor lock-in

อาจไม่คุ้ม เมื่อ: เป็นเอกสารดิบจำนวนมหาศาลที่ไม่เคยสังเคราะห์ (ใช้ RAG ตรง ๆ คุ้มกว่า), หรือเป็นข้อมูลใช้ครั้งเดียวทิ้ง

พร้อมแล้วไปลงมือกัน → ติดตั้ง

ประวัติศาสตร์และวิวัฒนาการของ Knowledge Base

ว่าหกสิบปีที่มนุษย์ถามคำถามเดียวกันซ้ำ ๆ ว่า "เราจะทำให้เครื่องจักร จดจำ และ เข้าใจ สิ่งที่เรารู้ได้อย่างไร?" คำตอบเปลี่ยนไปทุกยุค — จากกฎที่เขียนด้วยมือ สู่กราฟความหมาย สู่ดัชนีคำ สู่โน้ตที่เชื่อมโยงกัน และล่าสุดคือ AI ที่สังเคราะห์ความรู้ให้เราเอง บทนี้คือเรื่องเล่าของการเดินทางนั้น และปลายทาง (ชั่วคราว) ที่ชื่อว่า OKF

หมายเลข [n] ชี้ไปยังแหล่งข้อมูลอ้างอิงท้ายเล่ม

flowchart LR
  E1["1960s–80s
Expert systems"] --> E2["1990s–2000s
Semantic Web"] --> E3["1970s–2010s
Databases & IR"] --> E4["1995–2020
Wiki & PKM"] --> E5["2012–2020s
AI / RAG"] --> E6["2026
LLM-wiki & OKF"]

องก์ที่ 1 — ยุคที่เราพยายาม"ป้อน"ความรู้ให้เครื่องด้วยมือ

ทศวรรษ 1960 ที่ Stanford นักวิทยาศาสตร์กลุ่มหนึ่งเชื่อว่าความฉลาดในเรื่องแคบ ๆ จับได้ด้วยการ เข้ารหัสความรู้ของผู้เชี่ยวชาญออกมาเป็นกฎ แล้วให้เครื่องให้เหตุผลบนนั้น พวกเขาสร้าง DENDRAL (1965) ที่วิเคราะห์โครงสร้างโมเลกุลจาก mass spectrometry ได้เทียบเท่านักเคมี [1] — เป็นครั้งแรกที่โลก เห็นว่า "ความรู้" ไม่ใช่ "การค้นหา" ต่างหากคือกุญแจของ AI

ไม่กี่ปีถัดมา MYCIN (ต้นยุค 1970, Edward Shortliffe) ใช้กฎ IF-THEN ราว 600 ข้อ วินิจฉัยการติดเชื้อ ในเลือดได้แม่นพอ ๆ กับแพทย์อาวุโส และยัง อธิบายเหตุผลของตัวเองได้ [1] หัวใจของมันคือสถาปัตยกรรมที่ ยังอยู่กับเราจนวันนี้ — แยก knowledge base (สิ่งที่รู้) ออกจาก inference engine (วิธีคิด):

IF   ชนิดการติดเชื้อ = primary-bacteremia
AND  ตำแหน่งเพาะเชื้อ = blood
AND  ช่องทางเข้า = gastrointestinal-tract
THEN มีหลักฐานพอควร (CF = 0.4) ว่าเชื้อคือ Bacteroides

แต่ความฝันมาเจอกำแพง ปี 1984 Douglas Lenat เริ่มโครงการ Cyc — ความพยายามป้อน "สามัญสำนึก" ของ มนุษย์ ทั้งหมด ด้วยมือ [1] หลายสิบปีและหลายสิบล้านดอลลาร์ผ่านไป โลกได้บทเรียนราคาแพงที่เรียกว่า "knowledge acquisition bottleneck": การป้อนความรู้ด้วยมือไม่มีวัน scale

🧬 DNA ที่ตกทอดสู่ OKF: การแยก "ความรู้ (ไฟล์)" ออกจาก "เครื่องที่ใช้ความรู้ (agent)" — โครงสร้าง producer/consumer ของ OKF คือลูกหลานโดยตรงของแนวคิดนี้

องก์ที่ 2 — ยุคที่เราพยายามให้ "ความหมาย" แก่เว็บ

ปี 2001 ผู้ให้กำเนิดเว็บอย่าง Tim Berners-Lee เขียนบทความใน Scientific American ฝันถึง Semantic Web [2] — เว็บที่ไม่ใช่แค่เอกสารให้คนอ่าน แต่เป็นข้อมูลที่ เครื่องเข้าใจความหมาย ได้ เขา เสนอให้เก็บความรู้เป็น triple สามส่วน (subject–predicate–object) ซึ่งก็คือ "เส้นเชื่อมในกราฟ" นั่นเอง:

@prefix ex: <http://example.org/> .
ex:TimBernersLee  ex:invented  ex:WorldWideWeb .

ด้วยภาษา RDF, OWL, SPARQL เครื่องจะอนุมานข้อเท็จจริงใหม่จากกราฟได้เอง [2] มันงดงามในทางทฤษฎี — แต่การเขียน ontology ให้ถูกต้องนั้นยากเกินกว่าคนทั่วไปจะทำไหว ปี 2013 มีเว็บใช้ markup เชิงความหมาย ไม่ถึง 2% สิ่งที่รอดและเฟื่องฟูแทนคือทายาทที่ "ใช้ง่ายกว่า" — linked data, schema.org (2011), และ knowledge graph [2]

🧬 DNA สู่ OKF: ความรู้ที่เชื่อมโยงเป็นกราฟมีค่ามหาศาล — แต่ OKF เลือก "ลิงก์ Markdown ธรรมดา" (untyped) แทน RDF/OWL ที่เข้มงวด เพื่อให้คนเขียนได้จริง

องก์ที่ 3 — ยุคที่เราเรียนรู้จะ "ค้น" อย่างชาญฉลาด

ระหว่างที่ AI ฝันใหญ่ อีกสายหนึ่งทำงานเงียบ ๆ แต่เปลี่ยนโลก ปี 1970 Edgar Codd แห่ง IBM เสนอ relational model ทำให้ข้อมูลเก็บเป็นตารางและ query ด้วย SQL ได้ [3] แต่มันจับคู่แบบตรงตัว ค้นข้อความ อิสระแล้วจัดอันดับความเกี่ยวข้องไม่ได้

คำตอบมาจาก Karen Spärck Jones (1972) ผู้เสนอ IDF — ความคิดเรียบง่ายแต่ลึกซึ้ง: คำที่พบในเอกสาร น้อยชิ้น คือสัญญาณที่ทรงพลังกว่าคำที่พบทุกที่ [3] รวมกับ term frequency กลายเป็น TF-IDF และต่อมา BM25 (~1994) ที่ยังเป็นมาตรฐาน lexical search ถึงวันนี้ ลองดูตัวอย่างจิ๋ว — คำว่า "the" อยู่ทุกเอกสาร จึงไร้ค่าในการแยกแยะ แต่คำว่า "dog" ที่อยู่เอกสารเดียวกลับโดดเด่น:

คำเอกสารค่าความเด่น
theD1, D2, D30 (ไร้ค่า)
dogD3สูง

เมื่อ Doug Cutting ปล่อย Lucene (1999) และต่อมา Elasticsearch (2010) full-text search ระดับอุตสาหกรรมก็อยู่ในมือทุกคน [3] ข้อจำกัดเดียวที่ยังค้างคา: มันเป็น lexical — ค้น "car" จะพลาด "automobile" เพราะไม่เข้าใจความหมาย

🧬 DNA สู่ OKF: BM25 ยังทรงพลังและเบามาก — tools/okf-index.py ใช้มันเป็น search หลัก

องก์ที่ 4 — ยุคที่ความรู้กลายเป็นของทุกคน

ปี 1995 Ward Cunningham สร้าง WikiWikiWeb เว็บแรกที่ใครก็แก้ได้ [4] หกปีถัดมา Wikipedia (2001) พิสูจน์ว่าความรู้ของมวลมนุษย์เติบโตได้ด้วยการเปิดให้ทุกคนร่วมเขียน [4]

แต่เรื่องที่น่าทึ่งที่สุดเกิดก่อนหน้านั้นบนโต๊ะของนักสังคมวิทยาชาวเยอรมัน Niklas Luhmann ผู้สะสมกล่อง บัตร Zettelkasten ราว 90,000 ใบ แต่ละใบเชื่อมโยงถึงกัน เขาผลิตหนังสือกว่า 50 เล่มจากมัน และทิ้ง หลักการอมตะไว้: "คุณค่าไม่ได้อยู่ที่ตัวโน้ต แต่อยู่ที่ลิงก์ระหว่างโน้ต" [4]

ยุคดิจิทัลค้นพบหลักการนี้ใหม่ราวปี 2016–2020 ผ่าน Notion, Roam, Obsidian — ทั้งหมดวางอยู่บน Markdown + [[wikilinks]] ที่ชนะสงครามฟอร์แมตเพราะเหตุผลทบกัน: คนอ่านออกโดยไม่ต้อง render และ เครื่องอ่านออกโดยไม่ต้อง parser พิเศษ [4]

---
title: "Zettelkasten Principle"
tags: [pkm]
---
คุณค่าของกล่องบัตรอยู่ที่ **ลิงก์ระหว่างโน้ต** — ดูเพิ่ม [[Obsidian]]

🧬 DNA สู่ OKF: นี่คือพันธุกรรมที่ตรงที่สุด — Markdown + YAML frontmatter + ลิงก์ระหว่าง concept คือหน้าตาของ OKF เป๊ะ ๆ

องก์ที่ 5 — ยุคที่ "ความหมาย" กลายเป็นเรขาคณิต

ปี 2013 ทีมของ Tomas Mikolov ที่ Google เปิดเผยสิ่งที่ดูเหมือนเวทมนตร์: word2vec แปลงคำเป็น เวกเตอร์ที่ "ความหมายใกล้ = ตำแหน่งใกล้" จนทำเลขคณิตของความหมายได้ [5]

flowchart LR
  K["king"] -- " − man + woman " --> Q["≈ queen"]

ปีต่อ ๆ มาเร่งเร้า: Google Knowledge Graph (2012, "things, not strings"), FAISS (2017) ค้น เวกเตอร์ระดับพันล้านตัว, BERT (2018) ที่ทำให้คำเดียวกันมีความหมายต่างกันตามบริบท [5] แล้วปี 2020 RAG (Lewis และคณะ) ก็มาแก้จุดอ่อนใหญ่ที่สุดของ LLM — การแต่งเรื่อง — ด้วยการดึงหลักฐานจริงมา ground คำตอบ [5]:

flowchart LR
  D["เอกสาร"] --> C["Chunk"] --> EM["Embed"] --> S["Vector store"]
  Q["คำถาม"] --> R["Retrieve top-k"]
  S --> R --> G["LLM generate
คำตอบที่อ้างอิงได้"]

และเพื่อรวมพลังของ "จับคำตรงตัว (BM25)" กับ "จับความหมาย (vector)" โลกก็หยิบ Reciprocal Rank Fusion (RRF, 2009) มาใช้ เกิดเป็น hybrid search ที่เป็นค่าเริ่มต้นของวันนี้ [5]

🧬 DNA สู่ OKF: wiki = Layer 1 (สังเคราะห์ไว้แล้ว), RAG/vector = Layer 2 (ขุดของดิบ); okf-search.py รวม BM25 + semantic ด้วย RRF พอดี

องก์ที่ 6 — ปัจจุบัน: เมื่อ AI ลงมือดูแลความรู้เอง

เมษายน 2026 Andrej Karpathy โพสต์แนวคิดสั้น ๆ ที่จุดประกายทั้งวงการ: "LLM wiki" [6] — แทนที่จะ ดึง chunk ดิบทุกครั้งที่ถาม (อย่าง RAG) ให้ agent คอมไพล์แหล่งดิบเป็น Markdown ที่จัดระเบียบ เชื่อมโยง และดูแลต่อเนื่อง สังเคราะห์ครั้งเดียวตอน ingest ความรู้จึง ทบต้น — ยิ่งใช้ยิ่งรวย ไม่ใช่เริ่มจากศูนย์ทุกครั้ง

สองเดือนถัดมา 12 มิถุนายน 2026 Google Cloud (Sam McVeety, Amir Hormati) ทำให้ pattern นี้เป็น มาตรฐานเปิดในชื่อ Open Knowledge Format (OKF) v0.1 [6] — ไดเรกทอรีของ Markdown + YAML frontmatter บังคับแค่ฟิลด์ type, แยก producer/consumer, พกพาข้ามคลาวด์และเฟรมเวิร์ก

ก่อนหน้านั้น MemGPT/Letta (2023) ได้แสดงให้เห็น "LLM as OS" — จัดการความจำแบบ tiered (in-context = RAM, external = disk) ปูทางให้ agent มีความจำถาวร [6]

บทส่งท้าย — และอนาคตที่กำลังมา

ทิศทางต่อไปคือ knowledge base ที่ดูแลตัวเอง: agent ไม่ใช่แค่ "ถาม" ความรู้ แต่คอย ดูแล — ตรวจว่า ข้อมูลเก่าไหม (ผ่าน timestamp/log.md), ปรับข้อขัดแย้งข้าม concept, และเสนออัปเดตให้คนอนุมัติก่อน commit [6] ชั้นถัดไปน่าจะเป็น hybrid wiki + RAG: wiki ที่สังเคราะห์ไว้เป็น index เร็ว ส่วน RAG เติม ช่องว่างของข้อมูลที่เปลี่ยนบ่อยเกินจะ precompile โดยมี agent memory เป็น runtime และ multi-agent ที่ แบ่งหน้าที่กันดูแล/บริโภคความรู้ — มุ่งสู่สิ่งที่เริ่มเรียกกันว่า "compiled-knowledge generation"

ทำไม OKF คือผลรวมของทั้งหกองก์

OKF ไม่ได้คิดใหม่หมด แต่ หลอมรวมชิ้นที่ดีที่สุดของทุกยุคเข้าด้วยกัน — หกสายธารไหลมาบรรจบเป็นหนึ่ง:

flowchart TD
  A["Expert systems
แยกความรู้ออกจากเครื่องคิด"] --> OKF B["Semantic Web
ความรู้เป็นกราฟเชื่อมโยง"] --> OKF C["IR / BM25
ค้นเร็วและเบา"] --> OKF D["Wiki / PKM
Markdown + links อ่านออก version ได้"] --> OKF E["AI / RAG
embeddings + AI สังเคราะห์"] --> OKF OKF["✦ Open Knowledge Format ✦"]

ต่อไปเจาะแนวคิดพื้นฐานที่ต้องรู้ (พร้อมตัวอย่าง) ที่กล่าวถึงในบทนี้

แนวคิดพื้นฐานที่ต้องรู้ (พร้อมตัวอย่าง)

บทนี้สรุปแนวคิดพื้นฐานของระบบ Knowledge Base ที่กล่าวถึงในบทประวัติศาสตร์ — แต่ละหัวข้อมี นิยามสั้น + ตัวอย่างรูปธรรม + เกี่ยวกับ OKF ยังไง เพื่อให้นำไปใช้ต่อได้ทันที

1. Knowledge representation (การแทนความรู้)

คือ วิธีเก็บ "สิ่งที่รู้" ให้เครื่องประมวลผลได้ รูปแบบคลาสสิก: production rule (IF-THEN), semantic network (กราฟแนวคิด), frame (slot-filler)

ตัวอย่าง (frame):

FRAME: Bacteroides
  IS-A: Anaerobic-Gram-Negative-Rod
  Gram-stain: negative (default)
  Treatment: [metronidazole, clindamycin]

ใน OKF: แต่ละ concept (ไฟล์ .md) คือหน่วยความรู้หนึ่งหน่วย — frontmatter เก็บ field ที่ query ได้, body เก็บรายละเอียด

2. Ontology (ออนโทโลยี)

คือ ข้อกำหนดความหมายของแนวคิด/ความสัมพันธ์ในโดเมน แบบเครื่องอ่านได้ (มากกว่า taxonomy — มี logic ให้อนุมานได้)

ตัวอย่าง (RDF triple): TimBernersLee — invented — WorldWideWeb (subject–predicate–object)

ใน OKF: ลิงก์ Markdown ระหว่าง concept ทำหน้าที่คล้าย triple แต่ untyped — ชนิดความสัมพันธ์อยู่ในเนื้อความ (เบากว่า OWL มาก)

3. Inverted index (ดัชนีกลับด้าน)

คือ โครงสร้างที่ map "คำ → รายการเอกสารที่มีคำนั้น" หัวใจของ full-text search

ตัวอย่าง:

คำเอกสาร
catD1, D2
dogD3

ค้น "dog" → ตอบ D3 ทันที โดยไม่ต้องสแกนทุกเอกสาร

ใน OKF: okf-index.py สร้าง inverted index ในหน่วยความจำเพื่อทำ BM25

4. TF-IDF & BM25 (การจัดอันดับความเกี่ยวข้อง)

คือ สูตรให้คะแนนว่าเอกสารตรงกับคำค้นแค่ไหน — TF (คำนี้ปรากฏบ่อยในเอกสาร) × IDF (คำนี้หายากทั้งคลัง = เด่น); BM25 ปรับปรุงด้วย length normalization + saturation

ตัวอย่าง: คำ "the" อยู่ทุกเอกสาร → IDF = log(3/3) = 0 → คะแนน 0 (ไม่ช่วยแยกแยะ); คำ "dog" อยู่เอกสารเดียว → IDF สูง → เด่น

ใน OKF: BM25 คือ search หลักของ okf-search.py (เบา ไม่ต้องมี dependency)

5. Embeddings (เวกเตอร์ความหมาย)

คือ การแปลงข้อความเป็นเวกเตอร์ตัวเลข ที่ "ความหมายใกล้ = เวกเตอร์ใกล้"

ตัวอย่าง (word2vec): king − man + woman ≈ queen — ความสัมพันธ์เชิงความหมายกลายเป็นเลขคณิตของเวกเตอร์

ใน OKF: okf-embed.py สร้าง embedding ของ concept ผ่านโมเดลในเครื่อง (Ollama) สำหรับ semantic search

คือ ค้นด้วยความใกล้เคียงของเวกเตอร์ (เช่น cosine similarity) → จับความหมาย/พ้องความที่ keyword พลาด

ตัวอย่าง: ค้น "รถ" แล้วเจอเอกสารที่เขียน "ยานยนต์/automobile" เพราะเวกเตอร์ใกล้กัน

ใน OKF: เป็นชั้นเสริม (opt-in) — ถ้าไม่มี embeddings/Ollama จะ fallback เป็น BM25 อัตโนมัติ

7. RAG (Retrieval-Augmented Generation)

คือ ดึงข้อมูลที่เกี่ยวมาใส่ context ของ LLM ตอนถาม เพื่อ ground คำตอบ (ลด hallucination, อ้างอิงได้)

ตัวอย่าง (5 ขั้น):

flowchart LR
  D["เอกสาร"] --> C["chunk"] --> E["embed"] --> S["vector store"]
  Q["คำถาม"] --> R["retrieve top-k"]
  S --> R --> G["LLM generate
คำตอบที่อ้างอิงได้"]

ใน OKF: wiki = Layer 1 (สังเคราะห์ไว้แล้ว ค้นเจอก็จบ); RAG = Layer 2 (ขุดเอกสารดิบเมื่อ wiki ยังไม่ครอบคลุม)

8. Hybrid search & RRF

คือ รวมผลค้นหลายแบบ (BM25 + semantic) ด้วย Reciprocal Rank Fusion: score(d) = Σ 1/(k + rank) (k=60)

ตัวอย่าง: เอกสารที่ติดอันดับดีทั้งใน BM25 และ semantic จะลอยขึ้นบนสุด โดยไม่มีสัญญาณใดครอบงำ

ใน OKF: okf-search.py ใช้ RRF รวม BM25 + semantic พอดี

9. Knowledge graph (กราฟความรู้)

คือ กราฟของ entity (จุด) + ความสัมพันธ์มีชนิด (เส้น) — "things, not strings" ให้ disambiguation และเหตุผลระดับ entity

ตัวอย่าง:

flowchart LR
  CU["ลูกค้า A"] -->|สั่ง| O["ออเดอร์ 123"]
  O -->|มีสินค้า| P["สินค้า X"]
  CU -->|อยู่กลุ่ม| SEG["ลูกค้าชั้นดี"]

ใน OKF: bundle ทั้งก้อนเป็น knowledge graph (concept = จุด, ลิงก์ = เส้น) — เปิดดูได้ด้วย okf-viz.py

ตารางสรุป

แนวคิดจับอะไรตัวอย่างใน OKF
Knowledge representationโครงสร้างความรู้concept + frontmatter
Ontologyความสัมพันธ์เชิงความหมายลิงก์ Markdown (untyped)
Inverted index / BM25จับคำตรงตัวokf-index.py
Embeddings / vector searchจับความหมายokf-embed.py
RAGground คำตอบ LLMwiki (L1) + RAG (L2)
Hybrid / RRFรวมหลายสัญญาณokf-search.py
Knowledge graphentity + ความสัมพันธ์bundle + okf-viz.py

ดูแหล่งข้อมูลอ้างอิงท้ายเล่ม สำหรับเปเปอร์/มาตรฐานต้นทางของแต่ละแนวคิด

ติดตั้ง

OKF starter เป็นเครื่องมือ Python ล้วน (ไม่มี dependency บังคับ) ใช้ได้แบบ offline/air-gap สิ่งที่ต้องมี:

  • Python 3.13+ (เครื่องมือทุกตัวเป็น stdlib ล้วน)
  • Git (สำหรับ version control ของ bundle)
  • (ไม่บังคับ) Ollama ถ้าจะใช้ semantic search ในเครื่อง
  • (ไม่บังคับ) Docker ถ้าจะ deploy แบบ self-host (ภาคที่ 6)

ทางเลือกที่ 1 — ติดตั้งเป็น Claude Code skill (แนะนำ)

วิธีนี้ทำให้ทุกโปรเจกต์/ทุก session สร้างและดูแล OKF bundle ได้ โดยไม่ต้องอยู่ใน repo ต้นทาง

git clone https://github.com/supachai-j/open-knowledge-format-starter.git
cd open-knowledge-format-starter

./install.sh                 # ติดตั้ง global → ~/.claude/skills/okf  (ทุกโปรเจกต์ใช้ได้)
./install.sh --project       # ติดตั้งเฉพาะโปรเจกต์ → ./.claude/skills/okf
./install.sh --dir <path>    # ติดตั้งที่อื่น
./install.sh --uninstall     # ถอนออก

install.sh จะประกอบ skill (ไฟล์ SKILL.md + เครื่องมือ Python ทั้งหมด + ไลบรารี viewer ที่ฝังในตัว) ไปไว้ในโฟลเดอร์ skill ที่ self-contained จากนั้นเปิด Claude Code แล้วพิมพ์ /okf หรือพูดว่า "init an OKF knowledge base here" ได้เลย

skill ทำงานยังไง: เมื่อเรียกใช้ Claude Code จะรู้ตำแหน่งของ skill และรันสคริปต์ใน scripts/ ของ skill นั้น — ไม่ว่าจะติดตั้ง global หรือ project ก็ทำงานได้

ทางเลือกที่ 2 — ใช้จาก repo ตรง ๆ

ถ้าอยากทำงานในตัว repo เอง (หรือยังไม่อยากติดตั้ง skill) เครื่องมือทั้งหมดอยู่ใน tools/:

git clone https://github.com/supachai-j/open-knowledge-format-starter.git
cd open-knowledge-format-starter
python3 tools/okf-validate.py ./wiki        # → ✓ CONFORMANT with OKF v0.1
python3 tools/okf-viz.py ./wiki             # → wiki/viz.html (เปิดในเบราว์เซอร์)

ทางเลือกที่ 3 — ใช้เป็น GitHub template

repo ต้นทางตั้งเป็น template repository — กดปุ่ม "Use this template" บน GitHub เพื่อสร้าง repo ใหม่ของคุณเองพร้อมโครงสร้างครบ

ตรวจว่าติดตั้งสำเร็จ

python3 --version                  # ควรเป็น 3.13 ขึ้นไป
python3 tools/okf-validate.py --help 2>/dev/null || python3 tools/okf-validate.py ./wiki

ถ้าเห็น ✓ CONFORMANT with OKF v0.1 แปลว่าพร้อมแล้ว ไปสร้าง knowledge base แรกกัน → สร้าง knowledge base แรก

สร้าง knowledge base แรก

มาสร้าง OKF bundle แรกกันภายในไม่กี่นาที

ขั้นที่ 1 — scaffold โครงสร้าง

ใช้ okf-init.py สร้างโครง bundle ใหม่ในโฟลเดอร์ปัจจุบัน (หรือโฟลเดอร์ที่ระบุ):

python3 tools/okf-init.py .            # สร้างในโฟลเดอร์ปัจจุบัน
# หรือถ้าติดตั้งเป็น skill:
python3 ~/.claude/skills/okf/scripts/okf-init.py ./my-kb

ผลลัพธ์:

Scaffolding OKF bundle in /path/to/project
  wrote: AGENTS.md
  wrote: raw/README.md
  wrote: wiki/index.md
  wrote: wiki/log.md
  wrote: wiki/getting-started.md
✓ done. Next: validate with okf-validate.py, then ingest sources from raw/.

ปลอดภัย: ถ้ามี wiki/ ที่ไม่ว่างอยู่แล้ว สคริปต์จะ ไม่เขียนทับ เว้นแต่ใส่ --force

ขั้นที่ 2 — ตรวจ conformance

python3 tools/okf-validate.py ./wiki
# → ✓ CONFORMANT with OKF v0.1  (0 warning(s), 0 info)

ขั้นที่ 3 — ดู graph

python3 tools/okf-viz.py ./wiki --name "My First KB"
# → wiki/viz.html  (ไฟล์เดียว เปิดในเบราว์เซอร์ได้ทันที ไม่ต้องต่อเน็ต)

เปิด wiki/viz.html จะเห็น concept เป็นจุด เชื่อมกันด้วยเส้น คลิกดูรายละเอียดได้

ขั้นที่ 4 — เริ่มเก็บความรู้

  1. วางไฟล์ต้นทาง (PDF, โน้ต, export) ลงในโฟลเดอร์ raw/
  2. บอก AI agent ว่า "ingest raw/<ไฟล์> เข้า wiki" — agent จะดึงประเด็นสำคัญมาให้คุณอนุมัติก่อนเขียน (รายละเอียดในบท Ingest)

เขียนเองด้วยมือก็ได้

OKF คือ Markdown ธรรมดา — สร้าง concept เองได้เลย เช่นไฟล์ wiki/glossary/wau.md:

---
type: Metric
title: Weekly Active Users (WAU)
description: จำนวนลูกค้าไม่ซ้ำที่มีคำสั่งซื้ออย่างน้อย 1 ครั้งในรอบ 7 วัน
tags: [growth, metric]
timestamp: 2026-06-15T00:00:00Z
---

# นิยาม
นับ `customer_id` ไม่ซ้ำ ที่มีออเดอร์อย่างน้อย 1 ครั้งในหน้าต่าง 7 วันล่าสุด

แล้วรัน okf-validate.py อีกครั้งเพื่อยืนยันว่ายัง conformant

สรุปคำสั่งที่ใช้บ่อย

ทำอะไรคำสั่ง
สร้าง bundle ใหม่okf-init.py <dir>
ตรวจ conformanceokf-validate.py ./wiki
ดู graphokf-viz.py ./wiki
สร้าง index ค้นหาokf-index.py build ./wiki
ค้นหาokf-search.py "คำถาม" --bundle ./wiki

ต่อไปทำความเข้าใจ โครงสร้างโปรเจกต์ ที่ scaffold ให้

โครงสร้างโปรเจกต์

OKF starter ใช้แนวคิด สถาปัตยกรรม 3 ชั้น ที่แยกหน้าที่ชัดเจน

my-kb/
├── AGENTS.md          ← ชั้นที่ 3: schema + กฎการทำงานของ agent (อ่านก่อน)
├── raw/               ← ชั้นที่ 1: แหล่งข้อมูลดิบ (อ่านอย่างเดียว)
│   └── README.md
├── wiki/              ← ชั้นที่ 2: OKF bundle (agent ดูแล)
│   ├── index.md       ← ไฟล์สงวน: สารบัญ (progressive disclosure)
│   ├── log.md         ← ไฟล์สงวน: บันทึกการเปลี่ยนแปลง
│   └── getting-started.md
└── tools/             ← เครื่องมือ (validate, viz, index, ...)

สามชั้นคืออะไร

ชั้นโฟลเดอร์ใครเขียนบทบาท
1. แหล่งดิบraw/คนต้นทางความจริง — อ่านอย่างเดียว agent ไม่แก้
2. wikiwiki/agentความรู้ที่สังเคราะห์แล้ว (OKF bundle)
3. schemaAGENTS.mdคน + agent ร่วมกันกฎ/ขนบ/workflow ที่กำกับ agent

แนวคิดสำคัญ: wiki/ คือ "bundle root" ดังนั้น Concept ID จะนับจาก wiki/ เช่น wiki/tables/orders.md มี Concept ID = tables/orders

AGENTS.md — ไฟล์ที่สำคัญที่สุด

นี่คือไฟล์แรกที่ agent อ่าน มันบอก agent ว่า:

  • โครงสร้าง bundle เป็นยังไง
  • กฎ frontmatter (ฟิลด์ไหนบังคับ/แนะนำ, controlled vocabulary ของ type)
  • กฎการลิงก์ (ใช้ relative, ห้ามขึ้นต้นด้วย /)
  • workflow ของ ingest / query / validate

ไฟล์นี้คือสิ่งที่ทำให้ AI เป็น "ผู้ดูแล wiki ที่มีวินัย" แทนที่จะเป็น chatbot ทั่วไป คุณกับ agent จะค่อย ๆ พัฒนาไฟล์นี้ร่วมกันตามโดเมนของคุณ

ถ้าคุณใช้ agent อื่น ชื่อไฟล์อาจเป็น CLAUDE.md (Claude Code) หรือ GEMINI.md ก็ได้ — เนื้อหาเหมือนกัน

raw/ — แหล่งข้อมูลดิบ

วางต้นฉบับไว้ที่นี่: PDF, โน้ตประชุม, export, dataset

  • เปลี่ยนแปลงไม่ได้ (immutable) — agent อ่านแต่ไม่แก้ นี่คือต้นทางความจริง
  • ไฟล์ใน raw/ ไม่ใช่ส่วนหนึ่งของ bundle (bundle คือ wiki/) แต่เป็น "input" ของการ ingest
  • ใน starter ตัวจริง .gitignore จะ ไม่ commit ไฟล์ใน raw/ เพื่อกันเผลอ push ข้อมูลส่วนตัว/ใหญ่ (เก็บแค่ raw/README.md) — ถ้าอยาก version คุม source จริง ให้คอมเมนต์บรรทัด raw/* ออก

wiki/ — OKF bundle

โฟลเดอร์นี้ agent เป็นเจ้าของ มันจะจัด concept เป็นหมวด เช่นในโครงเริ่มต้นจะมี:

wiki/
├── index.md              ← สารบัญ root (มี okf_version)
├── log.md                ← บันทึกการเปลี่ยนแปลง
├── getting-started.md    ← concept ตัวอย่าง
└── (ของคุณ) tables/  references/  playbooks/ ...

หมวดที่เจอบ่อย (ตาม reference implementation ของ Google):

  • tables/ — ตาราง (type: BigQuery Table)
  • datasets/ — ชุดข้อมูล (type: BigQuery Dataset)
  • references/ — ความรู้สังเคราะห์ เช่น references/metrics/, references/joins/ (type: Reference)

ต่อไปเจาะลึกแนวคิดหลัก เริ่มที่ Bundle, Concept และ Concept ID

Bundle, Concept และ Concept ID

สามคำนี้คือหัวใจของ OKF เข้าใจสามคำนี้ก็เข้าใจสเปกครึ่งหนึ่งแล้ว

Bundle (มัด/ชุดความรู้)

Bundle คือไดเรกทอรีของไฟล์ความรู้ทั้งหมด — เป็น หน่วยที่ใช้แจกจ่าย (unit of distribution) หนึ่ง bundle อาจส่งต่อได้หลายรูปแบบ:

  • เป็น git repository (แนะนำ — ได้ history, diff, review ฟรี)
  • เป็น tarball / zip
  • เป็นไดเรกทอรีย่อยใน repo ที่ใหญ่กว่า

ในโปรเจกต์นี้ bundle คือโฟลเดอร์ wiki/

Concept (หน่วยความรู้)

Concept คือความรู้หนึ่งหน่วย แทนด้วย ไฟล์ Markdown หนึ่งไฟล์ มันอาจอธิบาย:

  • ของที่จับต้องได้ — ตารางในฐานข้อมูล, API endpoint
  • ของที่เป็นนามธรรม — metric ทางธุรกิจ, playbook, กระบวนการ

กฎทอง: หนึ่งไฟล์ = หนึ่ง concept อย่ายัด 3 เรื่องลงไฟล์เดียว

concept มี 2 ส่วน:

---
type: Metric          ← (1) Frontmatter — บล็อก YAML
title: ...
---
                      ← (2) Body — Markdown อิสระ
# นิยาม
...

Concept ID (รหัสประจำ concept)

Concept ID = path ของไฟล์ใน bundle ตัด .md ออก

ไฟล์ (ใน wiki/)Concept ID
tables/orders.mdtables/orders
references/metrics/wau.mdreferences/metrics/wau
playbooks/incident.mdplaybooks/incident

จุดสำคัญ: identity ผูกกับ path ของไฟล์ ดังนั้น...

⚠️ การเปลี่ยนชื่อ/ย้ายไฟล์ = เปลี่ยน Concept ID = ลิงก์ที่ชี้เข้ามาพัง ตั้งชื่อไฟล์ให้นิ่งตั้งแต่แรก ใช้ตัวพิมพ์เล็ก-คั่นด้วยขีด (kebab-case) เช่น weekly-active-users.md

ข้อดีของการใช้ path เป็น identity: ได้ identity แบบ sovereign โดยไม่ต้องมี registry กลาง — แค่ดูที่อยู่ไฟล์ก็รู้ว่าเป็น concept อะไร

โครงสร้างเป็นต้นไม้ แต่ความสัมพันธ์เป็นกราฟ

โฟลเดอร์ให้โครงสร้างแบบต้นไม้ (พ่อ-ลูก) แต่ concept เชื่อมกันด้วย ลิงก์ Markdown ได้อิสระ เกิดเป็น กราฟ ที่รวยกว่าโครงสร้างโฟลเดอร์ (ดูบท การลิงก์)

wiki/
├── tables/orders.md ─────┐ (ลิงก์ "joins-with")
├── tables/customers.md ◄─┘
└── references/metrics/wau.md ──► tables/orders.md ("derived-from")

ต่อไปดูส่วนหัวของไฟล์ให้ละเอียด → Frontmatter

Frontmatter (เมทาดาทา)

Frontmatter คือบล็อก YAML บนหัวไฟล์ คั่นด้วย --- เก็บ metadata ที่ต้องการให้ค้น/กรอง/ทำดัชนีได้

---
type: BigQuery Table              # บังคับ
title: Orders                     # แนะนำ
description: หนึ่งแถวต่อหนึ่งคำสั่งซื้อ   # แนะนำ
resource: https://...             # แนะนำ (ถ้ามีของจริงให้ชี้)
tags: [sales, orders]             # แนะนำ
timestamp: 2026-06-15T00:00:00Z   # แนะนำ (ISO 8601)
---

ฟิลด์ที่บังคับ

ฟิลด์คำอธิบาย
typeชนิดของ concept — เป็น ฟิลด์เดียวที่บังคับ ใน v0.1 ผู้บริโภคใช้ค่านี้ในการ route/filter/แสดงผล

ฟิลด์ที่แนะนำ (เรียงตามความสำคัญ)

ฟิลด์คำอธิบาย
titleชื่อสำหรับมนุษย์อ่าน ถ้าไม่ใส่ ผู้บริโภคอาจเดาจากชื่อไฟล์
descriptionสรุปหนึ่งบรรทัด — นี่คือสิ่งที่ agent อ่านเพื่อตัดสินใจว่าจะโหลดไฟล์นี้ไหม เขียนให้คม
resourceURI ของของจริงที่ concept อธิบาย (ละได้ถ้าเป็นแนวคิดนามธรรม)
tagsYAML list สำหรับจัดหมวดข้ามสายงาน เช่น [sales, revenue]
timestampเวลาที่แก้ครั้งสำคัญล่าสุด (รูปแบบ ISO 8601)

💡 description สำคัญกว่าที่คิด — เขียนให้เจาะจง เช่น "จำนวนลูกค้าไม่ซ้ำที่มีออเดอร์ ≥1 ใน 7 วัน" ดีกว่า "เรื่อง WAU"

ฟิลด์เสริม (extension fields)

ผู้ผลิต เพิ่มฟิลด์อะไรก็ได้ และผู้บริโภค ต้องทนต่อ key ที่ไม่รู้จัก (ไม่ปฏิเสธไฟล์) เช่นเพิ่ม owner, sla, pii: true ตามโดเมนของคุณ

controlled vocabulary ของ type

แม้สเปกไม่บังคับ taxonomy แต่ ควรใช้ค่า type ให้สม่ำเสมอ (ไม่งั้นเครื่องรวมข้อมูลไม่ได้) ชุดที่ starter นี้ใช้:

BigQuery Table · BigQuery Dataset · Metric · Reference · Playbook · API Endpoint · Concept · Entity

ขนบจาก reference bundle ของ Google: ความรู้สังเคราะห์/อ้างอิง (join, นิยาม metric, glossary) มักจัดไว้ใต้ references/ และตั้ง type: Reference ส่วนของจับต้องได้อยู่ tables/ / datasets/

ข้อควรระวัง

  • อย่ายัด frontmatter เกินจำเป็น — เก็บให้เป็น semantic (entity, intent, นิยาม) อย่าทุ่ม keyword เพราะ noise ลดคุณภาพการค้น
  • ใช้ชื่อฟิลด์ให้สม่ำเสมอ — ไฟล์หนึ่งใช้ author_name อีกไฟล์ใช้ written_by เครื่องรวมข้อมูลไม่ได้

Body ใต้ frontmatter

ส่วนเนื้อหาเป็น Markdown อิสระ แต่ ควรใช้โครงสร้าง (heading, bullet, ตาราง) มากกว่าย่อหน้ายาว ๆ heading ที่เป็นขนบ (ใช้เมื่อเหมาะ เรียงตามนี้):

# Overview# Schema# Common query patterns (โค้ด sql) → # Joins# Examples# Citations

ต่อไปดูวิธีเชื่อม concept เข้าด้วยกัน → การลิงก์เป็น knowledge graph

การลิงก์เป็น knowledge graph

concept เชื่อมกันด้วย ลิงก์ Markdown มาตรฐาน ทำให้ไดเรกทอรีกลายเป็น กราฟของความสัมพันธ์ ที่รวยกว่าโครงสร้างพ่อ-ลูกของโฟลเดอร์

ใช้ลิงก์แบบ file-relative เท่านั้น

ดูตาราง [customers](../tables/customers.md) สำหรับ key ที่ใช้ join

⚠️ อย่าขึ้นต้นลิงก์ด้วย / — นี่คือกฎที่สำคัญและละเอียดอ่อน

สเปก OKF §5.1 แนะนำ ลิงก์แบบ absolute (/tables/customers.md) โดยอ้างว่าเสถียรเมื่อย้ายไฟล์ แต่ enrichment agent ตัวจริงของ Google สั่งห้าม เพราะลิงก์ / ทำให้ GitHub render พัง และ bundle จริงทุกตัวของ Google ก็ใช้ลิงก์ relative ทั้งหมด

เราทำตาม implementation จริง: ใช้ relative เท่านั้น (okf-validate.py จะเตือนถ้าเจอลิงก์ /)

ลิงก์เป็นแบบ "ไม่มีชนิด" (untyped)

ลิงก์จาก concept A → B แค่ "ยืนยันว่ามีความสัมพันธ์" แต่ ชนิดของความสัมพันธ์ (พ่อ-ลูก, อ้างอิง, joins-with, depends-on) อยู่ใน เนื้อความรอบ ๆ ไม่ใช่ตัวลิงก์

เชื่อมกับ [customers](../tables/customers.md) ผ่าน `customer_id` (หลายออเดอร์ → ลูกค้าหนึ่งคน)
        └─ ลิงก์ untyped         └─ ชนิดความสัมพันธ์อยู่ในประโยคนี้

ผู้บริโภคที่สร้าง graph view จะมองทุกลิงก์เป็น "เส้นเชื่อมมีทิศทาง" แบบไม่ระบุชนิด

ลิงก์ที่ชี้ไปยัง concept ที่ ยังไม่มี ไม่ถือว่าผิด — มันแทน "ความรู้ที่ยังไม่ได้เขียน" (เหมือน placeholder/ช่องว่างให้เติมทีหลัง) ผู้บริโภค ต้องทนต่อ broken link

กฎการลิงก์ที่ดี

  • ✅ ใช้ relative path เท่านั้น (../tables/orders.md, customers.md)
  • ✅ ลิงก์เฉพาะ concept ที่มีอยู่จริง (หรือจงใจทิ้ง placeholder)
  • ❌ อย่า over-link — ลิงก์ครั้งเดียวต่อการกล่าวถึงต่อ section ก็พอ
  • ❌ อย่าลิงก์จาก heading, ใน code block, หรือในรายการชื่อฟิลด์ schema
  • ❌ อย่าลิงก์ไฟล์หาตัวเอง

ตัวอย่าง: graph เล็ก ๆ

references/joins/orders__customers.md
   ├──► tables/orders.md
   └──► tables/customers.md

metrics/weekly-active-users.md ──► tables/orders.md
playbooks/incident-response.md ──► metrics/weekly-active-users.md

เมื่อเปิด viz.html คุณจะเห็นกราฟนี้แบบ interactive พร้อม "Cited by" (backlink — ใครลิงก์มาหา concept นี้บ้าง)

ต่อไปดูไฟล์พิเศษ 2 ตัวที่ช่วยนำทางกราฟ → ไฟล์สงวน: index.md และ log.md

ไฟล์สงวน: index.md และ log.md

OKF สงวนชื่อไฟล์ไว้ 2 ชื่อ ที่มีความหมายพิเศษในทุกระดับของไดเรกทอรี และ ห้ามใช้เป็นไฟล์ concept

ไฟล์หน้าที่
index.mdสารบัญของไดเรกทอรี (progressive disclosure)
log.mdบันทึกประวัติการเปลี่ยนแปลง

index.md — สารบัญเพื่อ progressive disclosure

ช่วยให้คน/agent เห็นว่ามีอะไรบ้างก่อนเปิดไฟล์จริง — สำคัญมากเพราะช่วยไม่ให้ context window ล้นตอนสำรวจ agent อ่าน index.md ก่อนเพื่อหา concept ที่เกี่ยว แล้วค่อยเจาะเข้าไฟล์

รูปแบบ: ไม่มี frontmatter (ยกเว้น root index — ดูด้านล่าง) เนื้อหาเป็นหัวข้อ + รายการ * [ชื่อ](ลิงก์) - คำอธิบายสั้น

# Subdirectories

* [tables](tables/index.md) - BigQuery tables และ schema/join
* [references](references/index.md) - ความรู้สังเคราะห์ (join, นิยาม metric)

# Concepts

* [tables/orders](tables/orders.md) - หนึ่งแถวต่อหนึ่งคำสั่งซื้อ

ผู้ผลิตจะ gen index.md อัตโนมัติ ก็ได้ ผู้บริโภคจะ สร้างเองตอนอ่าน ก็ได้ ถ้าไม่มี

okf_version ที่ root index

ที่ root ของ bundle เท่านั้น index.md สามารถมี frontmatter ได้ — และมีได้แค่ฟิลด์เดียวคือ okf_version เพื่อประกาศเวอร์ชันสเปกที่ bundle นี้ยึด:

---
okf_version: "0.1"
---
# Concepts
...

log.md — บันทึกประวัติ

บันทึกการเปลี่ยนแปลงของขอบเขตนั้น เป็นรายการ เรียงใหม่สุดขึ้นก่อน จัดกลุ่มด้วยหัววันที่ ISO

# Directory Update Log

## 2026-06-15
* **Update**: เพิ่มตาราง [Customer Metrics](references/metrics/cm.md)
* **Creation**: สร้าง [Dataplex Playbook](playbooks/dataplex.md)

## 2026-06-12
* **Initialization**: สร้างโครงสร้างไดเรกทอรีพื้นฐาน

กฎ:

  • หัววันที่ ต้อง เป็นรูปแบบ ISO YYYY-MM-DD (ไม่มีวงเล็บ)
  • คำขึ้นต้นตัวหนา (**Update**, **Creation**, **Deprecation**) เป็น ขนบ ไม่ใช่ข้อบังคับ

💡 ถ้าใช้ prefix สม่ำเสมอ จะ grep ได้ง่าย เช่น grep '^- ' log.md ดูรายการล่าสุด

ทำไมไฟล์สองตัวนี้สำคัญ

  • index.md = ตัวนำทาง ให้ agent ไม่ต้องโหลดทั้ง bundle เข้า context
  • log.md = audit trail ที่อ่านง่าย ช่วยให้รู้ว่า wiki วิวัฒน์มายังไง และช่วย agent เข้าใจว่าเพิ่งทำอะไรไป

okf-validate.py จะตรวจว่า index.md ไม่มี frontmatter (ยกเว้น root ที่มีได้แค่ okf_version) และเตือนถ้าหัววันที่ใน log.md ไม่ใช่รูปแบบ ISO

จบภาคแนวคิดหลักแล้ว ต่อไปลงมือใช้งานจริง → Ingest: เก็บความรู้เข้า wiki

Ingest: เก็บความรู้เข้า wiki

Ingest คือการนำแหล่งข้อมูลดิบมาสังเคราะห์เป็น concept ใน wiki นี่คือหัวใจของการทำให้ wiki "รวยขึ้น"

หลักการสำคัญที่สุด: ingest ต้องมีคนกำกับ

🚫 อย่าทำ ingest อัตโนมัติเบื้องหลัง (background daemon)

นี่คือ anti-pattern ที่สำคัญที่สุด — daemon ที่กลืนทุกอย่างที่เห็นจะ สะสม noise เร็วเท่ากับสะสมสัญญาณ แล้ว wiki จะ เน่าอย่างเงียบ ๆ จนเชื่อถืออะไรไม่ได้

ให้ ingest เป็น คำสั่งที่คนตั้งใจสั่ง — การตัดสินใจของมนุษย์ว่า "แหล่งนี้คุ้มที่จะสังเคราะห์ไหม" คือ ประตูคุณภาพ (quality gate) ที่ตัดความล้มเหลวทั้งกองทิ้งไปได้

ขั้นตอน ingest (แบบมีคนกำกับ)

  1. อ่านแหล่ง ใน raw/
  2. อ่าน wiki/index.md เพื่อรู้ว่ามี concept อะไรอยู่แล้ว
  3. ดึง 5–15 ประเด็น (claim/decision/insight) ที่ควรเก็บ
  4. แสดงประเด็นที่ดึงมา + การ map ไปยัง concept ให้คุณอนุมัติ — แล้วรอ ก่อนเขียนอะไร
  5. ปรับข้อขัดแย้ง (reconcile) — ถ้าข้อมูลใหม่ขัดกับ concept เดิม ให้เติมธงในไฟล์เก่า:
    > **CONTRADICTION FLAG**: ผลใหม่แทนที่ค่านี้ ดู references/metrics/new-wau.md
    
  6. เขียน/อัปเดต concept (เริ่มจาก template) อัปเดต tags + timestamp
  7. อัปเดต index.md ที่เกี่ยวข้อง
  8. เพิ่มรายการลง log.md ใต้วันที่วันนี้
  9. รัน validate ก่อนถือว่าเสร็จ

ใช้ผ่าน AI agent

ถ้าติดตั้ง skill แล้ว แค่บอก:

ingest raw/q3-strategy.pdf เข้า wiki

agent จะทำตามขั้นตอนข้างบน — ดึงประเด็น แสดงให้คุณอนุมัติก่อน แล้วค่อยเขียน concept, อัปเดต index.md และ log.md ให้

ทำไมต้องปรับข้อขัดแย้งทุกครั้ง

สมมติมี paper บอกว่า "Model Z เก่งสุด" แต่ใน wiki มีหน้าเขียนว่า "Model X เก่งสุด"

  • RAG แบบเดิม: สองหน้าอยู่ด้วยกัน agent อาจดึงหน้าเก่ามาตอบผิดอย่างมั่นใจ
  • OKF (ingest แบบ agentic): ทุกครั้งที่เพิ่มความรู้ จะ ตรวจรอบ ๆ ว่าขัด/แทนที่/ยืนยันอะไร แล้วเขียนความสัมพันธ์นั้นลงไปชัด ๆ — หน้าเก่าได้ธาย "ถูกแทนที่แล้ว ดู B" หน้าใหม่ได้บริบท "ปรับปรุงจาก A" ทั้งสองหน้าถูกต้องพร้อมกัน wiki มี "ปัจจุบันกาล" ที่สอดคล้อง

เคล็ดลับ

  • ingest ทีละแหล่ง แล้วอยู่ร่วมตรวจ — อ่านสรุป เช็กการอัปเดต ชี้แนะว่าให้เน้นอะไร
  • แหล่งหนึ่งอาจแตะ 10–15 หน้าใน wiki (concept + entity + index + log)
  • เริ่ม ingest แบบ เลือกสรร ไม่ต้องเทเข้าทั้งหมดทีเดียว — ปัญหา cold-start เล็กกว่าที่คิด เพราะหัวข้อที่คุณสนใจที่สุดมักถูกครอบคลุมก่อน

ต่อไป: เมื่อมีความรู้แล้ว จะถามและค้นยังไง → Query และ Search

Query และ Search

มีสองวิธีในการดึงความรู้ออกมาใช้ ขึ้นกับขนาดของ wiki

วิธีที่ 1 — Query ผ่าน index (wiki เล็ก)

สำหรับ wiki ขนาดเล็ก (ไม่เกิน ~150 หน้า) การอ่าน index.md ก็เพียงพอ:

  1. อ่าน wiki/index.md ก่อน เพื่อหา concept ที่เกี่ยว
  2. เจาะเข้าไฟล์ concept นั้น ๆ
  3. ตอบ จากเฉพาะ concept ที่โหลดมา และ อ้าง Concept ID เสมอ
  4. ถ้าไม่มีข้อมูลครอบคลุม ให้บอกตรง ๆ และเสนอให้ ingest แหล่งเพิ่ม

ผ่าน agent: "wiki ว่ายังไงเรื่อง WAU" → agent อ่าน index → เปิด concept → ตอบพร้อมอ้างอิง

วิธีที่ 2 — Search ด้วย index (wiki ใหญ่)

เมื่อเกิน ~150 หน้า การสแกน index จะช้า ให้สร้างดัชนีค้นหา:

# สร้าง BM25 index (ทำครั้งเดียว / รันใหม่เมื่อเนื้อหาเปลี่ยน)
python3 tools/okf-index.py build ./wiki

# ค้นหา
python3 tools/okf-search.py "how is WAU defined" --bundle ./wiki -k 8

ผลลัพธ์ (จัดอันดับด้วย BM25):

mode: bm25-only (no embeddings — run okf-embed.py build)
   2.675  metrics/weekly-active-users   [Metric]  จำนวนลูกค้าไม่ซ้ำที่มีออเดอร์...
   2.463  tables/customers              [BigQuery Table]  ...

BM25 คืออะไร: อัลกอริทึมค้นแบบ keyword ที่ให้คะแนนความเกี่ยวข้อง ดีมากสำหรับการจับคำ/รหัสตรงตัว (เช่น รหัส policy, ชื่อคอลัมน์) เครื่องมือนี้เป็น Python ล้วน ไม่ต้องลง dependency

Hybrid search (BM25 + semantic)

ถ้า keyword อย่างเดียวยังจับความหมายไม่พอ เพิ่มชั้น semantic ด้วยโมเดล embedding ในเครื่อง (Ollama):

ollama pull nomic-embed-text          # ครั้งเดียว (on-prem)
python3 tools/okf-embed.py build ./wiki   # สร้าง embeddings → wiki/.okf-embed.json
python3 tools/okf-search.py "ลูกค้าที่ active" --bundle ./wiki
# → mode: hybrid (bm25+semantic, RRF)

okf-search.py จะ ฟิวชันผลของ BM25 + semantic ด้วย Reciprocal Rank Fusion (RRF) เอง

ปลอดภัยเสมอ: ถ้ายังไม่ได้สร้าง embeddings หรือ Ollama ไม่ทำงาน search จะ fallback เป็น BM25 อัตโนมัติ และบอก mode ให้รู้ — semantic เป็น upgrade ล้วน ๆ ไม่ใช่ dependency บังคับ

(รายละเอียดสถาปัตยกรรม hybrid อยู่ในบท Search ระดับ scale และ semantic)

เปรียบเทียบ

สถานการณ์ใช้อะไร
wiki เล็ก (< ~150 หน้า)อ่าน index.md ตรง ๆ
wiki ใหญ่ จับ keyword/รหัสokf-search.py (BM25)
ต้องจับความหมาย/พ้องความhybrid (BM25 + semantic)

ต่อไป: วิธีเพิ่มและแก้ไข concept → เพิ่มและแก้ไข concept

เพิ่มและแก้ไข concept

เริ่มจาก template

ใช้ tools/concept-template.md เป็นจุดเริ่ม:

---
type: Concept            # บังคับ — เลือกจาก controlled vocabulary ใน AGENTS.md
title: <ชื่อสำหรับมนุษย์>
description: <สรุปหนึ่งบรรทัด — ใช้ตัดสินใจว่า agent จะโหลดไฟล์นี้ไหม>
resource: <URI ของของจริง หรือลบบรรทัดนี้ถ้าเป็นนามธรรม>
tags: [<tag1>, <tag2>]
timestamp: 2026-06-15T00:00:00Z   # ISO 8601 UTC
---

# <หัวข้อ>
ใช้โครงสร้าง: heading, bullet สั้น ๆ, ตาราง มากกว่าย่อหน้ายาว

# Related
ลิงก์ concept อื่นด้วย relative path เช่น [orders](../tables/orders.md)
ชนิดความสัมพันธ์อยู่ในประโยคนี้ ไม่ใช่ที่ตัวลิงก์

# Citations
อ้างอิงแหล่งใน raw/ ที่ใช้สังเคราะห์ concept นี้

ขั้นตอนเพิ่ม/แก้ concept

  1. คัดลอก template → ตั้งชื่อไฟล์ (kebab-case, นิ่ง)
  2. ตั้ง type ให้ถูก (จาก controlled vocabulary)
  3. เขียน body ใช้โครงสร้าง + ลิงก์ relative
  4. อัปเดต tags + timestamp
  5. อัปเดต index.md ของไดเรกทอรีนั้น
  6. เพิ่มรายการลง wiki/log.md
  7. รัน okf-validate.py

ลำดับ section ที่เป็นขนบ

ใช้เมื่อเหมาะ เรียงตามนี้ (มาจาก enrichment prompt ของ Google):

# Overview                  ← เกริ่น 1–3 ย่อหน้า: คืออะไร ใช้ยังไง
# Schema                    ← สรุปคอลัมน์/ฟิลด์ (RECORD ซ้อนให้ย่อหน้า/ตาราง)
# Common query patterns     ← 1–3 SQL snippet (โค้ด sql)
# Joins                     ← เชื่อมกับ concept ไหน ผ่าน key อะไร
# Citations                 ← แหล่งอ้างอิง (รูปแบบ [1] [Title](url))

ตัวอย่าง concept แบบ Reference (join)

ไฟล์ wiki/references/joins/orders__customers.md:

---
type: Reference
title: Orders → Customers join
description: วิธี join ตาราง orders กับ customers ผ่าน customer_id
tags: [join, sales]
timestamp: 2026-06-15T00:00:00Z
---

Join [orders](../../tables/orders.md) กับ [customers](../../tables/customers.md)
ผ่าน `customer_id` (หลายออเดอร์ → ลูกค้าหนึ่งคน)

# Common query patterns
```sql
SELECT c.email, COUNT(*) AS orders, SUM(o.total) AS ltv
FROM orders o JOIN customers c USING (customer_id)
GROUP BY c.email;
```

หลังแก้เสร็จ — Definition of Done

  • concept มี type ไม่ว่าง และ description ที่คม
  • อัปเดต timestamp เป็นปัจจุบัน
  • อัปเดต index.md ที่เกี่ยวข้อง
  • เพิ่มรายการใน log.md ใต้วันที่วันนี้
  • python3 tools/okf-validate.py ./wiki ผ่าน

ต่อไป: ตรวจสอบและมองเห็น wiki → Validate และ Visualize

Validate และ Visualize

Validate — ตรวจ conformance

รันหลังแก้ทุกครั้ง:

python3 tools/okf-validate.py ./wiki
# → ✓ CONFORMANT with OKF v0.1  (0 warning(s), 0 info)

เกณฑ์ conformance (OKF v0.1)

bundle ผ่านเมื่อ:

  1. ทุกไฟล์ .md ที่ไม่ใช่ไฟล์สงวน มี YAML frontmatter ที่ parse ได้
  2. ทุก frontmatter มีฟิลด์ type ที่ไม่ว่าง
  3. ไฟล์สงวน (index.md, log.md) ที่มีอยู่ ทำตามโครงสร้างที่กำหนด

ระดับของผลตรวจ

ระดับความหมายตัวอย่าง
errorไม่ conformant (ต้องแก้)ไม่มี frontmatter / ไม่มี type / index.md มี frontmatter ผิดกฎ
! warnผ่าน แต่ควรแก้ลิงก์ขึ้นต้นด้วย / (พัง GitHub) / หัว log ไม่ใช่ ISO
· infoไม่ใช่ปัญหาbroken link (สเปก §5.3 อนุญาต)

ผู้บริโภค ต้องไม่ปฏิเสธ bundle เพราะ: ฟิลด์ optional หาย, type แปลก, key เกิน, ลิงก์เสีย, หรือไม่มี index.md — นี่คือ "permissive consumption" ที่ทำให้ OKF ยังใช้ได้แม้ bundle โต/ถูก refactor

Visualize — ดู knowledge graph

python3 tools/okf-viz.py ./wiki --name "My Wiki"
# → wiki/viz.html  (ไฟล์เดียว เปิดในเบราว์เซอร์)

viz.html เป็น ไฟล์ HTML เดียวที่ self-contained — ฝังไลบรารี (Cytoscape + marked) และข้อมูล bundle ไว้ในตัว ไม่ดึงอะไรจากเน็ตตอนเปิด เหมาะกับ air-gap แชร์เป็นไฟล์ หรือ commit ไว้ข้าง bundle

สิ่งที่ viewer แสดง

  • กราฟ force-directed ของทุก concept ระบายสีตาม type เส้นเชื่อมตามลิงก์ในเนื้อหา
  • แผงรายละเอียด ของ concept ที่เลือก: frontmatter + body ที่ render แล้ว
  • "Cited by" — backlink (ใครลิงก์มาหา concept นี้บ้าง)
  • ช่องค้นหา (จับ title/id/tags), ตัวกรองตาม type, สลับ layout ได้

ค่าเริ่มต้นจะ ฝังไลบรารีจาก tools/vendor/ ทำให้ air-gap ได้จริง ถ้าต้องการใช้ CDN ใส่ --cdn

ลองเล่นของจริง

ด้านล่างคือ viz.html ของ wiki ตัวอย่างในโปรเจกต์นี้ (คลิกที่ node เพื่อดูรายละเอียด ลองค้นหา/กรองตาม type ได้):

🕸 กราฟ interactive — แสดงเฉพาะบนหน้าเว็บ (iframe ไม่แสดงในไฟล์ PDF)
เปิดดูออนไลน์ได้ที่: https://supachai-j.github.io/open-knowledge-format-starter/viz-example.html

เปิดแบบเต็มจอ →

ทำให้เป็นนิสัย

รวมสองคำสั่งนี้หลังการแก้ทุกครั้ง:

python3 tools/okf-validate.py ./wiki && python3 tools/okf-viz.py ./wiki

ในระดับองค์กร CI จะรัน validate ทุก PR และ regenerate viz อัตโนมัติ (ดูภาคที่ 6)

จบภาคการใช้งานประจำวัน ต่อไปดูแนวทางเขียนให้ดี → แนวทางการเขียนและ anti-patterns

ตัวอย่างใช้งานจริง: KB ร้านหนังสือ

บทนี้เดินครบทุกขั้นตั้งแต่ศูนย์จนค้นได้ — สร้าง knowledge base เล็ก ๆ ของร้านหนังสือออนไลน์ ด้วยคำสั่งจริง ใช้เป็นแม่แบบกับโดเมนของคุณได้เลย

1. สร้างโครง (init)

python3 tools/okf-init.py ./bookstore-kb
cd bookstore-kb

ได้ AGENTS.md + wiki/{index.md, log.md, getting-started.md} + raw/

2. ใส่ความรู้ (จำลอง ingest)

สร้าง concept ตามโครงสร้าง canonical — ตาราง 2 ตัว, metric, join, playbook ตัวอย่าง wiki/tables/books.md:

---
type: BigQuery Table
title: Books
description: หนึ่งแถวต่อหนังสือหนึ่งเล่มในแคตตาล็อก
tags: [catalog, books]
timestamp: 2026-06-16T00:00:00Z
---

# Schema
| Column | Type | Description |
| :--- | :--- | :--- |
| book_id | STRING | รหัสหนังสือ (PK) |
| author_id | STRING | FK ไปยัง [authors](authors.md) |
| price | NUMERIC | ราคา (USD) |
| stock | INT64 | จำนวนคงคลัง |

# Joins
เชื่อม [authors](authors.md) ผ่าน `author_id` — ดู [Books → Authors](../references/joins/books__authors.md)
stock ต่ำ → [restock runbook](../playbooks/low-stock-runbook.md)

ทำแบบเดียวกันกับ authors, references/metrics/monthly-revenue, references/joins/books__authors, playbooks/low-stock-runbook แล้วอัปเดต wiki/index.md + wiki/log.md

ในงานจริง: วาง source ลง raw/ แล้วให้ agent ทำ INGEST แบบมีคนกำกับ (บท Ingest) — agent จะดึงประเด็น แสดงให้อนุมัติ แล้วเขียน concept + อัปเดต index/log ให้

KB ที่ได้เป็นกราฟแบบนี้:

flowchart LR
  D["datasets/bookstore"] --> B["tables/books"]
  D --> A["tables/authors"]
  B -->|author_id| A
  J["references/joins/books__authors"] --> B
  J --> A
  M["references/metrics/monthly-revenue"] --> D
  P["playbooks/low-stock-runbook"] --> B

3. ตรวจ conformance

python3 tools/okf-validate.py ./wiki
# → ✓ CONFORMANT with OKF v0.1  (0 warning(s), 0 info)

4. ค้นหา

python3 tools/okf-index.py build ./wiki                       # สร้าง BM25 index
python3 tools/okf-search.py "how to join books to authors" --bundle ./wiki
# → references/joins/books__authors  [Reference]   อันดับ 1

เพิ่ม semantic (ไม่บังคับ, on-prem):

ollama pull nomic-embed-text
python3 tools/okf-embed.py build ./wiki
python3 tools/okf-search.py "who wrote the novels" --bundle ./wiki
# → mode: hybrid (bm25+semantic, RRF) — จับ authors ได้แม้ไม่มีคำตรงกัน

5. ดูกราฟ

python3 tools/okf-viz.py ./wiki --name "Bookstore KB"
open wiki/viz.html        # ไฟล์เดียว เปิด offline ได้

6. (ทีม) แชร์ผ่าน MCP

ทำให้ทั้งทีม/agent ใช้ร่วมกัน: commit wiki/ ขึ้น git ภายใน แล้วยก MCP server ชี้มาที่ bundle นี้ — agent จะ okf_search แบบ hybrid และเสนอแก้ผ่าน PR/lease ได้

สรุปลำดับ

okf-init → (ingest concepts) → okf-validate → okf-index/okf-search → okf-viz → [MCP share]

ครบลูปแล้ว! ต่อไปดูแนวทางการเขียนที่ดี เพื่อให้ KB โตอย่างมีคุณภาพ

แนวทางการเขียนและ anti-patterns

แนวทางเหล่านี้ซ้อนอยู่บนสเปก (ที่บังคับแค่ type) เพื่อให้ทั้งคนและ agent ใช้ wiki ได้อย่างเชื่อถือได้

กฎทอง

  1. หนึ่ง concept ต่อไฟล์ — อย่ายัด 3 เรื่องลงไฟล์เดียว
  2. เขียน description เพื่อ agent — เป็นบรรทัดเดียวที่ agent อ่านเพื่อตัดสินใจโหลดไฟล์ เขียนให้เจาะจง
  3. โครงสร้างชนะย่อหน้า — heading, bullet (**key** — value), ตาราง โมเดลดึงข้อมูลจาก Markdown ที่มีโครงสร้างได้แม่นกว่า
  4. identity = path — ตั้งชื่อไฟล์นิ่ง ๆ kebab-case การเปลี่ยนชื่อทำลายลิงก์ที่ชี้เข้ามา
  5. type สม่ำเสมอ — ใช้ controlled vocabulary
  6. อ้างอิงแหล่งเสมอ — ทุก claim ที่สังเคราะห์ควรสืบกลับไปไฟล์ใน raw/ ได้ ใส่ใต้ # Citations

ตาราง anti-patterns

Anti-patternทำไมแย่ทำแทน
ingest อัตโนมัติเบื้องหลังสะสม noise เร็วเท่าสัญญาณ wiki เน่าเงียบ ๆทำให้ ingest เป็นคำสั่งที่คนสั่ง + รีวิว
เท PDF ดิบลง wiki/retrieval ไม่น่าเชื่อถือ ทำลายการสังเคราะห์สังเคราะห์เป็น concept Markdown เก็บดิบไว้ raw/
frontmatter ยัดเกินnoise ลดความแม่นการค้นเก็บ tags ให้เป็น semantic และน้อย
ข้ามระดับ heading (H1→H3)ทำลายโครงเอกสารสำหรับโมเดลรักษาลำดับ H1→H2→H3
ย่อหน้าแทรกกลางรายการรายการแตกเป็นชิ้นในสายตา parserใช้ย่อหน้าซ้อน หรือจบรายการก่อน
ชื่อ type/ฟิลด์ไม่สม่ำเสมอเครื่องรวมข้อมูลไม่ได้ใช้ controlled vocabulary
anchor text กำกวม ("คลิกที่นี่")ไม่มีสัญญาณหัวข้อให้ LLMใช้ข้อความลิงก์ที่บรรยาย
ขึ้นต้นลิงก์ด้วย /พัง GitHub renderingใช้ relative path
ลดความอ่านง่ายเพื่อเครื่องwiki ต้องรับใช้คนด้วยโครงสร้างเพื่อเครื่อง ความชัดเจนเพื่อคน

สเปกหลัก vs แนวปฏิบัติของชุมชน

แยกให้ออก:

  • สเปก OKF v0.1 (เล็กมาก): บังคับแค่ type + กฎ index/log + กฎ conformance
  • แนวปฏิบัติที่ดี (ในเล่มนี้): ส่วนใหญ่มาจากชุมชน LLM-wiki และ reference implementation ของ Google เช่น confidence decay, hybrid search, การจัดกลุ่ม references/ — ถือเป็น pattern เสริม ไม่ใช่ข้อบังคับ

ประเด็นที่แหล่งข้อมูลเห็นไม่ตรงกัน

  • "RAG ตายแล้ว" — วิศวกรส่วนใหญ่บอกว่า wiki = Layer 1, RAG = Layer 2 fallback ไม่ใช่เลือกอย่างใดอย่างหนึ่ง
  • ลิงก์ absolute vs relative — สเปกแนะนำ absolute แต่ implementation ใช้ relative (เราตาม implementation)
  • freshness scoring 4 มิติ — เป็นแนวทางที่ vendor (Atlan) โปรโมต ไม่ใช่ส่วนของสเปก

ต่อไปเข้าสู่ระดับองค์กร → ภาพรวมสถาปัตยกรรม

ภาพรวมสถาปัตยกรรม (Enterprise)

เมื่อต้องใช้ knowledge base ร่วมกัน ข้าม session และข้ามทีม ระดับองค์กร บน on-prem (เชื่อมต่อภายใน ใช้ได้แม้ air-gap) แนวคิดหลักมีประโยคเดียว:

Git คือต้นทางความจริง · MCP server ภายในคือ access layer กลาง

ทุก session และทุก agent — ไม่ว่า framework หรือ model ไหน — ต่อ MCP endpoint ภายในตัวเดียวกัน ประวัติ git คือ "ความจำข้าม session" โดยธรรมชาติ · อ่านเร็วทันที · เขียนผ่าน gate (PR หรือ lease)

แผนภาพ

flowchart TB
  subgraph net["เครือข่ายภายใน (on-prem / air-gap)"]
    MCP["OKF MCP server
search · get · propose / commit"] GIT["Git server (Gitea/GitLab)
= OKF repo · ต้นทางความจริง"] IDX["Search index
BM25 (+ semantic)"] CI["CI runner
okf-validate + viz"] MCP -->|"pull / webhook"| GIT MCP --> IDX GIT -->|"PR/MR triggers"| CI end A1["Agent team A"] -->|"MCP: HTTP/SSE + token/mTLS"| MCP A2["Agent team B"] --> MCP CR["CI / cron"] --> MCP

องค์ประกอบ

#ส่วนตัวเลือก self-hostบทบาท
1Git serverGitea / GitLab CEต้นทางความจริง versioned (repo ต่อทีม หรือ monorepo + CODEOWNERS)
2OKF MCP serverserver/okf_mcp_server.pyaccess layer ที่ทุก agent ต่อ — read/search/propose; stdio + HTTP/SSE
3Search indextools/okf-index.py (+ embed)ค้นเร็วเมื่อ wiki โตเกิน ~150 หน้า
4CI gateGitea Actions / GitLab CIบล็อก merge ที่ไม่ conformant + regen viz
5Reverse proxyCaddy / Traefik / nginxTLS + auth (token / OIDC / mTLS) หน้า MCP

Read path (กรณีปกติ — เร็ว ไม่มี lock)

  1. agent เรียก okf_search("WAU นิยามยังไง") → ได้ Concept ID จัดอันดับ
  2. okf_get_concept("metrics/weekly-active-users") → frontmatter + body โหลดเข้า context
  3. okf_read_index() เมื่อต้องการสำรวจแบบ progressive disclosure

อ่านพร้อมกันได้ไม่จำกัด ไม่มี contention

Write path

มี 2 โมเดลให้เลือก (บทถัดไป):

  • PR-gated (ค่าเริ่มต้น): เขียนผ่าน branch + PR → CI ตรวจ → คน/curator merge — ปลอดภัย มี audit/review
  • Lease/lock: สำหรับทีมที่เขียนหนัก — lease ต่อ concept กันชนกัน เขียนตรงเข้า shared branch

ความหมายของ "ข้าม session / ข้ามทีม"

  • ข้าม session: ไม่มี state ต่อ session — session ใหม่ git pull ได้ทุกอย่างที่ session ก่อนเขียน wiki ทบต้น
  • ข้ามทีม: monorepo + CODEOWNERS ต่อ subtree หรือ federated bundles (repo ต่อโดเมน, MCP server mount หลาย bundle และ namespace ด้วยชื่อ bundle เช่น sales:tables/orders)

ต่อไป: ลงมือ deploy → ติดตั้งแบบ self-host

ติดตั้งแบบ self-host

deploy/docker-compose.yml ยกสแต็กภายในขึ้นมาทั้งชุดบน VM เดียว — ไม่เปิดสู่ภายนอก ใช้ได้แม้ air-gap

สแต็กที่ได้

gitea   →  ต้นทางความจริง (git server)
okf-mcp →  access layer ที่ agent ต่อ (build จาก deploy/Dockerfile)
proxy   →  Caddy: TLS + auth (token/OIDC/mTLS) หน้า MCP

ขั้นตอน

cd deploy
cp .env.example .env        # ตั้งค่า OKF_GIT_REMOTE, token, ฯลฯ
docker compose up -d

ค่าใน .env ที่ต้องตั้ง:

OKF_GIT_REMOTE=http://gitea:3000/okf/knowledge.git   # repo ที่ MCP จะ clone/pull
OKF_GITEA_API=http://gitea:3000/api/v1               # เปิด PR อัตโนมัติจาก propose_change
OKF_GITEA_TOKEN=<token>
OKF_GITEA_OWNER=okf
OKF_GITEA_REPO=knowledge
OKF_TOKEN=<long-random>                              # token ที่ agent ต้องส่งให้ proxy
OKF_READONLY=0                                       # 1 = replica อ่านอย่างเดียว

ต่อ agent เข้า MCP endpoint

ใน Claude Code (หรือ MCP client ใด ๆ) ชี้ไป URL ภายใน:

{ "mcpServers": { "okf": {
    "transport": "http",
    "url": "https://okf.internal.example/mcp",
    "headers": { "Authorization": "Bearer ${OKF_TOKEN}" }
} } }

โหมด local / dev (ไม่ต้องมีเน็ต)

ทดสอบ server โดยไม่ต้องยกทั้งสแต็ก:

python3 server/okf_mcp_server.py                       # stdio transport
# หรือ HTTP:
OKF_MCP_TRANSPORT=streamable-http OKF_MCP_PORT=8765 \
  python3 server/okf_mcp_server.py

เครื่องมือ (tools) ที่ server เปิดให้ agent

Toolทำอะไร
okf_search(query, k, type)ค้นแบบ hybrid (BM25 + semantic ถ้ามี)
okf_get_concept(id)คืน frontmatter + body ของ concept
okf_list_concepts(prefix)ลิสต์ id/type/description
okf_read_index(path)อ่าน index.md (progressive disclosure)
okf_propose_change(...)เขียนผ่าน branch + PR (โหมด PR)
okf_acquire_lease / renew / release / list_leasesจองสิทธิ์เขียน (โหมด lease)
okf_commit_concept(..., token)เขียนตรงโดยถือ lease (โหมด lease เท่านั้น)

CI conformance gate

ตั้ง branch protection บน main ให้ต้องผ่าน check นี้ — bundle ที่ไม่ conformant จะ merge ไม่ได้

  • Gitea Actions: .gitea/workflows/conformance.yml
  • GitLab CI: ci/.gitlab-ci.yml

ทั้งคู่รัน okf-validate.py (บล็อกถ้าไม่ผ่าน) + rebuild index + regenerate viz.html

ความปลอดภัยเบื้องต้น

  • หน้า MCP มี reverse proxy ทำ TLS + auth (รายละเอียดในบท ความปลอดภัยและ governance)
  • raw/ ไม่อยู่ใน bundle (มี .gitignore กันเผลอ commit ข้อมูลส่วนตัว)
  • air-gap: viz.html ฝังไลบรารีในตัว, semantic ใช้ Ollama ในองค์กร — ไม่มีอะไรออกนอกเครือข่าย

ต่อไป: เลือกโมเดลการเขียน → โมเดลการเขียน: PR-gated และ Lease

โมเดลการเขียน: PR-gated และ Lease

เมื่อหลาย agent เขียนความรู้ร่วมกัน ต้องเลือกว่าจะคุม concurrency ยังไง starter รองรับ 2 โมเดล (และมีโมเดลที่ 3 เป็นแนวคิด) เลือกด้วย env OKF_WRITE_MODE

โมเดล 1 — PR-gated (ค่าเริ่มต้น)

okf_propose_change(...) ไม่เขียน main แต่:

  1. สร้าง branch okf/<concept>-<id> จาก main
  2. เขียนไฟล์ commit push ขึ้น git server ภายใน
  3. เปิด PR/MR ผ่าน API ของ git server แล้วคืน URL
  4. CI รัน okf-validate.py (+ regen viz) → คน/curator รีวิวและ merge
flowchart LR
  AG["Agent"] -->|propose_change| BR["branch + commit"]
  BR --> PR["Pull Request"]
  PR --> CIv["CI: okf-validate"]
  CIv --> RV["review (คน/curator)"]
  RV -->|merge| MAIN["main"]
  MAIN -->|webhook| RE["MCP pull + reindex"]

ได้คุณสมบัติ enterprise ครบ: audit trail (git log), review/diff, rollback (git revert), ไม่มี write conflict (merge ทีละครั้งตามลำดับ), quality gate (CI + review)

เมื่อ merge เข้า main → webhook → MCP server pull → reindex → ทุก session เห็น

เหมาะเมื่อ review ทุกการเปลี่ยนแปลงสำคัญกว่าความเร็ว

โมเดล 2 — Lease/lock (เขียนตรง)

เปิดด้วย OKF_WRITE_MODE=lease สำหรับทีมที่เขียนหนัก ใช้ lease (สิทธิ์จองแบบมี TTL) กันสอง agent แก้ concept เดียวกันพร้อมกัน

# flow ต่อ agent:
okf_acquire_lease("tables/orders", ttl_seconds=300)   # → {token, expires_at}
# ... แก้ ...
okf_commit_concept("tables/orders", frontmatter, body, token=...)   # server ตรวจ lease แล้ว write+commit+push
okf_release_lease("tables/orders", token=...)         # คืนเมื่อเสร็จ
flowchart LR
  ACQ["acquire_lease
(TTL)"] --> ED["edit concept"] ED --> CM["commit_concept
(verify token)"] CM --> PUSH["pull --rebase + push"] PUSH --> REL["release_lease"] OT["agent อื่น ขอ concept เดียวกัน"] -.->|locked| ACQ

agent อื่นที่ขอ concept เดียวกันจะได้ {error:"locked", held_by} → ไปทำตัวอื่น ความปลอดภัยจาก concurrency: lease กัน concept ซ้ำ + git pull --rebase ก่อน push จัดการ commit คนละไฟล์ (auto-merge)

คุณสมบัติของ lease:

  • advisory + TTL หมดอายุเอง — agent crash ไม่ทำให้ concept ค้าง (lease ที่หมดอายุถูก "ขโมย" ได้)
  • token-verified — เฉพาะผู้ถือ lease commit/renew/release ได้
  • single-authority — MCP server ตัวเดียวแจก lease ด้วยไฟล์ atomic (O_CREAT|O_EXCL); git ถูก serialize ด้วย lock

CLI สำหรับ ops: python3 tools/okf-lease.py list · ... break <concept> (admin บังคับปลด)

เหมาะเมื่อ throughput การเขียนสำคัญกว่าการรีวิวทุกครั้ง

โมเดล 3 — Append-only proposals + curator (แนวคิด)

agent หย่อน proposal ลง inbox/; มี curator agent ตัวเดียว รวบ, ปรับข้อขัดแย้ง, แล้ว merge เข้า wiki — quality gate สูงสุด ตรงกับปรัชญา supervised ingest (ยังไม่ implement ใน starter)

เปรียบเทียบ

โมเดลความเร็วreviewconflictเหมาะกับ
PR-gatedปานกลางทุกครั้งไม่มี (merge ตามลำดับ)governance, ทีมทั่วไป
Lease/lockเร็วอ่อนกันด้วย leaseทีมเขียนหนัก
Curatorช้าสูงสุดcurator จัดการคุณภาพสำคัญสุด

💡 รันได้ทั้งสองโหมดบน repo เดียว — ทีมเขียนหนักใช้ server โหมด lease, ที่เหลือ PR-gated ชี้ git ตัวเดียวกัน

ต่อไป: ค้นหาเมื่อ wiki โตใหญ่ → Search ระดับ scale และ semantic

Search ระดับ scale และ semantic

เมื่อ wiki โตขึ้น การสแกน index.md แบน ๆ จะช้า บทนี้ว่าด้วยการค้นที่ scale ได้ บน on-prem ล้วน

ตามขนาด wiki

ขนาดใช้อะไร
< ~150 conceptindex.md progressive disclosure ก็พอ
> ~150สร้าง BM25 index (okf-index.py build) — okf_search ใช้อัตโนมัติ
recall ไม่พอเพิ่มชั้น semantic + RRF (ด้านล่าง)
ใหญ่มาก/หลายทีมfederate bundles, MCP ต่อโดเมน, cache index ใน memory rebuild ตาม webhook

ชั้น semantic (on-prem)

ฝัง concept ด้วยโมเดล embedding ที่ self-host (ผ่าน Ollama) — ไม่มีอะไรออกนอกเครือข่าย:

ollama pull nomic-embed-text          # ครั้งเดียว
python3 tools/okf-embed.py build ./wiki   # → wiki/.okf-embed.json
python3 tools/okf-search.py "ลูกค้าที่ active" --bundle ./wiki
# → mode: hybrid (bm25+semantic, RRF)

Reciprocal Rank Fusion (RRF)

okf-search.py รวมผล BM25 (lexical) กับ semantic (vector) ด้วย RRF:

fused(doc) = Σ_signals  1 / (RRF_K + rank)      (RRF_K = 60)

แต่ละสัญญาณจัดอันดับ doc ของตัวเอง แล้วเอาคะแนนผกผันของอันดับมาบวกกัน — doc ที่ติดอันดับดี ในหลายสัญญาณจะลอยขึ้นบน โดยไม่มีสัญญาณใดครอบงำ

ทำไมต้องสองสัญญาณ:

  • BM25 เก่งเรื่องจับคำ/รหัสตรงตัว (policy code, ชื่อคอลัมน์)
  • semantic เก่งเรื่องจับความหมาย/พ้องความ ("ลูกค้าที่ active" ↔ "weekly active users")

fallback อัตโนมัติ (สำคัญ)

ถ้ายังไม่ได้สร้าง embeddings หรือ Ollama ไม่ทำงาน → search fallback เป็น BM25 อัตโนมัติ และรายงาน mode ให้รู้ semantic จึงเป็น upgrade แบบ opt-in ล้วน ๆ ไม่มี hard dependency

ทำให้ระบบทนทาน: เครื่องไหนไม่มี Ollama ก็ยังค้นได้ด้วย BM25

ทำให้ scale ขึ้นอีก

  • federate bundles — แยก repo ต่อโดเมน/ทีม
  • MCP server ต่อโดเมน หลังหนึ่ง gateway
  • cache index ใน memory และ rebuild แบบ incremental เมื่อ webhook แจ้งว่ามีการ merge
  • index/embeddings เป็น artifact ที่ gen ได้ (CI / MCP server สร้างเมื่อต้องการ) — ไม่ต้อง commit (.okf-index.json, .okf-embed.json อยู่ใน .gitignore)

ต่อไป: ความปลอดภัยและการกำกับดูแล → ความปลอดภัยและ governance

ความปลอดภัยและ governance

ระบบ self-host ภายในต้องคุมว่าใครอ่าน/เขียนอะไรได้ และตรวจสอบย้อนหลังได้ OKF ได้ governance หลายอย่างมาฟรีจาก git อยู่แล้ว

คุมการเข้าถึง 2 ชั้น

ชั้น git

  • สมาชิก org/team บน Gitea/GitLab
  • branch protection บน main — บังคับให้ผ่าน CI + review ก่อน merge

ชั้น MCP

วาง HTTP transport ไว้หลัง reverse proxy พร้อม:

  • mTLS (service-to-service) หรือ OIDC/SSO (สำหรับคน) + bearer token ต่อ agent identity
  • map identity → role:
roleทำได้
readersearch / get / list เท่านั้น
proposer+ okf_propose_change (branch/PR เท่านั้น ไม่แตะ main)
curatormerge ได้ (ผ่าน git server ไม่ใช่ผ่าน MCP)

ตั้ง OKF_READONLY=1 เพื่อรัน MCP replica แบบอ่านอย่างเดียว

ตัวอย่าง Caddy (proxy) — bearer token

okf.internal.example {
    # internal CA / self-signed สำหรับ air-gap:
    #   tls /etc/caddy/okf.crt /etc/caddy/okf.key
    # หรือ mTLS:
    #   tls { client_auth { mode require_and_verify trusted_ca_cert_file /etc/caddy/internal-ca.crt } }

    @noauth not header Authorization "Bearer {$OKF_TOKEN}"
    respond @noauth "Unauthorized" 401
    reverse_proxy okf-mcp:8765
}

สำหรับ SSO ให้แทน bearer ด้วย forward_auth ไปยัง OIDC proxy (เช่น oauth2-proxy) แล้ว map identity → role

ความลับและ PII

  • raw/ ไม่อยู่ใน bundle และอยู่ใน .gitignore แล้ว — กันเผลอ push ข้อมูลส่วนตัว/ใหญ่
  • อย่าใส่ credential ใน concept — concept คือความรู้ ไม่ใช่ที่เก็บความลับ
  • รีวิว PR ช่วยจับข้อมูลอ่อนไหวก่อนเข้า main (อีกเหตุผลที่ PR-gated ดีในองค์กร)

air-gap (เครือข่ายปิด)

  • viz.html ฝังไลบรารี (Cytoscape + marked) ในตัว — ไม่ดึง CDN ตอนเปิด
  • semantic search ใช้โมเดล embedding ที่ self-host (Ollama) — ไม่มีอะไรออกนอกเครือข่าย
  • เครื่องมือทั้งหมดเป็น Python stdlib (ยกเว้น MCP server ที่ใช้แพ็กเกจ mcp — ติดตั้งจาก mirror ภายในได้)

audit & rollback (มาจาก git)

งานคำสั่ง
ใครแก้ WAU บ้างgit log --follow wiki/metrics/weekly-active-users.md
ย้อนความรู้ที่ผิดgit revert <sha> → PR → merge
ไทม์ไลน์การเปลี่ยนแปลงอ่าน wiki/log.md หรือ git log

governance ที่ได้มาฟรี

เพราะ wiki เป็นไฟล์ใน git ทุกการเปลี่ยนแปลงจึงมี diff, blame, review, history, rollback เหมือนการพัฒนาซอฟต์แวร์ปกติ — การดูแลความรู้กลายเป็น workflow วิศวกรรมที่ทีมคุ้นเคยอยู่แล้ว

จบภาคองค์กร ดูภาคผนวกสำหรับอ้างอิง → อ้างอิงเครื่องมือ (CLI)

อ้างอิงเครื่องมือ (CLI)

เครื่องมือทั้งหมดเป็น Python stdlib ล้วน อยู่ใน tools/ (หรือ scripts/ ถ้าติดตั้งเป็น skill)

okf-init.py — สร้าง bundle ใหม่

python3 tools/okf-init.py [target_dir] [--force] [--date YYYY-MM-DD]

สร้าง AGENTS.md + wiki/{index.md, log.md, getting-started.md} + raw/ · ไม่เขียนทับ wiki/ ที่ไม่ว่าง เว้นแต่ --force

okf-validate.py — ตรวจ conformance

python3 tools/okf-validate.py [wiki_dir]

ออก 0 ถ้า conformant, 1 ถ้าไม่ · error = ไม่มี frontmatter/type, index.md ผิดกฎ · warn = ลิงก์ /, log ไม่ใช่ ISO · info = broken link

okf-viz.py — สร้าง graph viewer

python3 tools/okf-viz.py [bundle] [-o out.html] [--name "ชื่อ"] [--cdn]

สร้าง viz.html ไฟล์เดียว self-contained (ฝัง Cytoscape + marked) · --cdn = โหลดไลบรารีจาก CDN แทนการฝัง

okf-index.py — BM25 search index

python3 tools/okf-index.py build [bundle] [-o index.json]
python3 tools/okf-index.py query "คำถาม" [-k 8] [--type Metric]

okf-embed.py — embeddings (Ollama)

python3 tools/okf-embed.py build [bundle]
python3 tools/okf-embed.py query "คำถาม" [-k 8]

env: OKF_OLLAMA_URL (default http://localhost:11434), OKF_EMBED_MODEL (default nomic-embed-text)

okf-search.py — hybrid search (BM25 + semantic, RRF)

python3 tools/okf-search.py "คำถาม" [--bundle ./wiki] [-k 8] [--type ...] [--bm25-only]

fallback เป็น BM25 อัตโนมัติถ้าไม่มี embeddings / Ollama ไม่ทำงาน

okf-lease.py — lease/lock concurrency

python3 tools/okf-lease.py acquire <concept> --owner <id> [--ttl 300]
python3 tools/okf-lease.py renew   <concept> --owner <id> --token <tok> [--ttl 300]
python3 tools/okf-lease.py release <concept> --owner <id> --token <tok>
python3 tools/okf-lease.py list
python3 tools/okf-lease.py break   <concept>      # admin บังคับปลด

env: OKF_LEASE_DIR (ที่เก็บ lease), OKF_LEASE_TTL (default 300)

okf-selftest.sh — ทดสอบ toolchain ทั้งชุด

bash tools/okf-selftest.sh

รัน 10 ข้อ end-to-end (init → validate ทั้ง clean และจับ bundle เสีย → index → search → viz air-gap → lease → embed/hybrid ถ้ามี Ollama) · exit ≠ 0 ถ้ามีข้อพลาด · เหมาะใช้ใน CI

install.sh — ติดตั้ง skill

./install.sh                 # global  → ~/.claude/skills/okf
./install.sh --project       # project → ./.claude/skills/okf
./install.sh --dir <path>    # custom
./install.sh --uninstall

server/okf_mcp_server.py — MCP access layer

python3 server/okf_mcp_server.py            # stdio
OKF_MCP_TRANSPORT=streamable-http OKF_MCP_PORT=8765 python3 server/okf_mcp_server.py

env หลัก: OKF_REPO_DIR, OKF_BUNDLE, OKF_BASE_BRANCH, OKF_WRITE_MODE (pr|lease), OKF_READONLY, OKF_GITEA_API/TOKEN/OWNER/REPO, OKF_AGENT_ID

คำถามที่พบบ่อย (FAQ)

OKF ต่างจาก Obsidian / Notion ยังไง?

ใกล้เคียงกันมาก (Markdown + frontmatter + ลิงก์) แต่ OKF ถูก specify — กำหนดกฎเล็ก ๆ ที่จำเป็น ต่อการ interoperate (เช่น type บังคับ, ไฟล์สงวน, กฎ conformance) โดยไม่บังคับเครื่องมือ คุณเปิด OKF bundle ใน Obsidian/MkDocs/Hugo ได้เลยเพราะมันคือ Markdown

ต้องใช้ Google Cloud / BigQuery ไหม?

ไม่ OKF เป็น vendor-neutral ตัวอย่างใน reference ของ Google ใช้ BigQuery แต่ type เป็นอะไรก็ได้ starter นี้ไม่ผูกกับ cloud ใด

จำเป็นต้องมี AI agent ไหม?

ไม่จำเป็น เขียน concept เองด้วยมือได้ (มันคือ Markdown) AI agent แค่ช่วยงานหนัก — สรุป, cross-reference, filing, bookkeeping

ลิงก์ควรเป็น relative หรือ absolute?

relative เท่านั้น อย่าขึ้นต้นด้วย / เพราะพัง GitHub rendering (ดู การลิงก์) แม้สเปกจะแนะนำ absolute แต่ implementation จริงของ Google ใช้ relative

ไม่ผิด — แทน "ความรู้ที่ยังไม่ได้เขียน" okf-validate.py รายงานเป็น info ไม่ใช่ error

ทำ ingest อัตโนมัติเลยได้ไหม?

ไม่แนะนำอย่างยิ่ง — daemon เบื้องหลังจะสะสม noise จน wiki เน่า ให้ ingest เป็นคำสั่งที่คนสั่ง + รีวิว

ประมาณ ~150 หน้า ก่อนหน้านั้น index.md ก็พอ เกินกว่านั้นใช้ okf-search.py (BM25) และเพิ่ม semantic เมื่อ recall ไม่พอ

ต้องมี Ollama ไหมถึงจะค้นได้?

ไม่ BM25 ทำงานโดยไม่ต้องมี Ollama · semantic เป็น upgrade เสริม ถ้า Ollama ไม่ทำงาน search จะ fallback เป็น BM25 เอง

หลาย agent เขียนชนกันทำยังไง?

เลือกโมเดลการเขียน: PR-gated (ปลอดภัย มี review) หรือ lease/lock (เร็ว สำหรับทีมเขียนหนัก) ดู โมเดลการเขียน

air-gap (เครือข่ายปิด) ใช้ได้ไหม?

ได้ — viz.html ฝังไลบรารีในตัว, เครื่องมือเป็น stdlib, semantic ใช้ Ollama ในองค์กร, git/MCP อยู่ภายใน

.okf-index.json / .okf-embed.json ต้อง commit ไหม?

ไม่ — เป็น artifact ที่ gen ได้ อยู่ใน .gitignore แล้ว CI/MCP server สร้างใหม่เมื่อต้องการ

validate ขึ้น error "missing type" แก้ยังไง?

ทุก concept ต้องมี type ที่ไม่ว่างใน frontmatter เพิ่ม type: ... (เลือกจาก controlled vocabulary)

จะ migrate wiki เดิม (Obsidian ฯลฯ) เข้า OKF ยังไง?

ส่วนใหญ่แค่เพิ่มฟิลด์ type ใน frontmatter + เพิ่ม index.md/log.md + ปรับลิงก์ให้ relative แล้วรัน validate

จะตรวจว่า toolchain ใช้ได้จริงทั้งชุดยังไง?

รัน bash tools/okf-selftest.sh — เทสต์ end-to-end 10 ข้อ (init/validate/index/search/viz/lease + embed/hybrid ถ้ามี Ollama) exit ≠ 0 ถ้ามีข้อพลาด · ดูตัวอย่างใช้งานจริง สำหรับการเดินครบลูปด้วยมือ

อภิธานศัพท์

คำความหมาย
OKF (Open Knowledge Format)สเปกเปิดสำหรับเก็บความรู้เป็นไดเรกทอรีของ Markdown + YAML frontmatter (v0.1, Google Cloud, 2026)
Bundleไดเรกทอรีของไฟล์ความรู้ทั้งหมด — หน่วยที่ใช้แจกจ่าย (ในโปรเจกต์นี้คือ wiki/)
Conceptความรู้หนึ่งหน่วย = ไฟล์ .md หนึ่งไฟล์
Concept IDpath ของไฟล์ใน bundle ตัด .md ออก เช่น tables/orders.mdtables/orders
Frontmatterบล็อก YAML บนหัวไฟล์ คั่นด้วย --- เก็บ metadata
Bodyเนื้อหา Markdown ใต้ frontmatter
Linkลิงก์ Markdown ระหว่าง concept = ความสัมพันธ์ (untyped)
Citationลิงก์จาก concept ไปแหล่งภายนอกที่สนับสนุน claim ในเนื้อหา
Reserved fileไฟล์สงวน: index.md (สารบัญ), log.md (บันทึกการเปลี่ยนแปลง)
Progressive disclosureการให้เห็นสารบัญก่อนเปิดไฟล์จริง — ลดการล้น context window
Conformanceการที่ bundle ทำตามกฎ v0.1 (frontmatter parse ได้ + มี type + ไฟล์สงวนถูกโครงสร้าง)
typeฟิลด์ frontmatter เดียวที่บังคับ — ระบุชนิดของ concept
Referencetype ที่ใช้กับความรู้สังเคราะห์ (join, นิยาม metric) มักอยู่ใต้ references/
RAGRetrieval-Augmented Generation — ดึง chunk เอกสารดิบตอนถามมายัด context
LLM-wiki patternแนวคิด (Karpathy) ที่ให้ AI สังเคราะห์ความรู้ลง Markdown wiki ที่ดูแลต่อเนื่อง แทนการดึงดิบทุกครั้ง
Ingestการนำแหล่งดิบมาสังเคราะห์เป็น concept ใน wiki (ควรมีคนกำกับ)
Contradiction flagธง > **CONTRADICTION FLAG**: ... ที่เติมเมื่อข้อมูลใหม่ขัดของเก่า
BM25อัลกอริทึมค้นแบบ keyword ให้คะแนนความเกี่ยวข้อง
Embeddingเวกเตอร์แทนความหมายของข้อความ (สร้างด้วยโมเดล เช่นผ่าน Ollama)
Semantic searchค้นด้วยความใกล้เคียงเชิงความหมาย (cosine ของ embedding)
Hybrid searchรวม BM25 + semantic
RRF (Reciprocal Rank Fusion)วิธีรวมผลจัดอันดับหลายสัญญาณ: Σ 1/(k + rank)
MCP (Model Context Protocol)มาตรฐานเปิดให้ AI agent ต่อกับเครื่องมือ/ข้อมูลภายนอก
MCP serverservice ที่เปิด tool (search/get/propose) ครอบ bundle ให้ agent ต่อ
PR-gatedโมเดลเขียนผ่าน branch + Pull Request + CI + review
Lease/lockโมเดลเขียนที่จองสิทธิ์ต่อ concept แบบมี TTL กันเขียนชนกัน
Leaseสิทธิ์จองแบบมี TTL หมดอายุเอง ตรวจด้วย token
Curator(โมเดลที่ 3) agent ตัวเดียวที่รวบ proposal แล้ว merge เข้า wiki
CODEOWNERSไฟล์กำหนดเจ้าของต่อ subtree (ใช้แบ่งความรับผิดชอบข้ามทีมใน monorepo)
Federated bundlesหลาย repo/bundle ต่อโดเมน MCP server mount หลายตัว namespace ด้วยชื่อ bundle
air-gapสภาพแวดล้อมที่ไม่ต่ออินเทอร์เน็ต (เครือข่ายปิด)
Gitea / GitLab CEgit server ที่ self-host ได้ ใช้เป็นต้นทางความจริง
AGENTS.mdไฟล์ schema ที่บอก agent ถึงโครงสร้าง/กฎ/workflow (อาจชื่อ CLAUDE.md/GEMINI.md)

แหล่งข้อมูลอ้างอิง

รวมแหล่งอ้างอิงสำหรับบทประวัติศาสตร์ และแนวคิดพื้นฐาน หมายเลข [1][6] ตรงกับยุคในบทประวัติศาสตร์ รวบรวมจากการทำ deep research (มิ.ย. 2026) อ้างอิงแหล่งปฐมภูมิเป็นหลัก

[1] ยุค Expert systems & knowledge representation

  1. Shortliffe, E. H. (1976). Computer-Based Medical Consultations: MYCIN. Elsevier/North-Holland.
  2. Buchanan, B. G., & Shortliffe, E. H. (Eds.) (1984). Rule-Based Expert Systems: The MYCIN Experiments of the Stanford Heuristic Programming Project. Addison-Wesley.
  3. Minsky, M. (1974). A Framework for Representing Knowledge. MIT AI Lab Memo 306.
  4. Feigenbaum, E. A., Buchanan, B. G., & Lederberg, J. (1971). On Generality and Problem Solving: A Case Study Using the DENDRAL Program. Machine Intelligence, 6.
  5. Lenat, D. B., & Guha, R. V. (1990). Building Large Knowledge-Based Systems: Representation and Inference in the Cyc Project. Addison-Wesley.

[2] ยุค Ontologies & the Semantic Web

  1. Berners-Lee, T., Hendler, J., & Lassila, O. (2001). The Semantic Web. Scientific American, 284(5), 34–43. https://www.lassila.org/publications/2001/SciAm.html
  2. Gruber, T. (1993). A Translation Approach to Portable Ontology Specifications. Knowledge Acquisition, 5(2).
  3. W3C (1999, rev. 2004, 2014). Resource Description Framework (RDF). https://www.w3.org/RDF/
  4. W3C (2004, rev. 2009). OWL Web Ontology Language Overview. https://www.w3.org/OWL/
  5. schema.org (2011). schema.org — shared structured-data vocabulary (Google, Bing, Yahoo). https://schema.org/

[3] ยุค Databases & Information Retrieval

  1. Codd, E. F. (1970). A Relational Model of Data for Large Shared Data Banks. Communications of the ACM, 13(6), 377–387. https://dl.acm.org/doi/10.1145/362384.362685
  2. Spärck Jones, K. (1972). A Statistical Interpretation of Term Specificity and Its Application in Retrieval. Journal of Documentation, 28(1), 11–21.
  3. Robertson, S. E., Walker, S., Jones, S., Hancock-Beaulieu, M., & Gatford, M. (1994). Okapi at TREC-3. Proceedings of TREC-3.
  4. Apache Software Foundation. Apache Lucene (Doug Cutting, 1999). https://lucene.apache.org/
  5. Elastic (2010). Elasticsearch (Shay Banon). https://www.elastic.co/

[4] ยุค Wiki & Personal Knowledge Management

  1. Cunningham, W. (1995). WikiWikiWeb — Portland Pattern Repository. https://en.wikipedia.org/wiki/WikiWikiWeb
  2. Wales, J., & Sanger, L. (2001). Wikipedia. Wikimedia Foundation. https://en.wikipedia.org/wiki/Wikipedia
  3. Luhmann, N. (1981). Kommunikation mit Zettelkästen. In Öffentliche Meinung und sozialer Wandel. https://zettelkasten.de/introduction/
  4. Obsidian.md (2020). About Obsidian. https://obsidian.md/about

[5] ยุค AI: embeddings, vector search, RAG

  1. Mikolov, T., Chen, K., Corrado, G., & Dean, J. (2013). Efficient Estimation of Word Representations in Vector Space. arXiv:1301.3781. https://arxiv.org/abs/1301.3781
  2. Singhal, A. (2012). Introducing the Knowledge Graph: things, not strings. Google Blog. https://blog.google/products/search/introducing-knowledge-graph-things-not/
  3. Johnson, J., Douze, M., & Jégou, H. (2017). Billion-scale Similarity Search with GPUs (FAISS). arXiv:1702.08734. https://arxiv.org/abs/1702.08734
  4. Devlin, J., Chang, M.-W., Lee, K., & Toutanova, K. (2018). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. arXiv:1810.04805 (NAACL-HLT 2019). https://arxiv.org/abs/1810.04805
  5. Lewis, P., Perez, E., Piktus, A., et al. (2020). Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks. arXiv:2005.11401 (NeurIPS 2020). https://arxiv.org/abs/2005.11401
  6. Cormack, G. V., Clarke, C. L. A., & Buettcher, S. (2009). Reciprocal Rank Fusion Outperforms Condorcet and Individual Rank Learning Methods. SIGIR 2009.

[6] ปัจจุบัน & อนาคต: LLM-wiki, OKF, agent memory

  1. Karpathy, A. (2026). LLM Wiki [GitHub Gist]. https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f
  2. McVeety, S., & Hormati, A. (2026, June 12). How the Open Knowledge Format Can Improve Data Sharing. Google Cloud Blog. https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing
  3. GoogleCloudPlatform (2026). Open Knowledge Format — Specification & Reference Implementations [GitHub]. https://github.com/GoogleCloudPlatform/knowledge-catalog/tree/main/okf
  4. Packer, C., Wooders, S., Lin, K., et al. (2023). MemGPT: Towards LLMs as Operating Systems. arXiv:2310.08560. https://arxiv.org/abs/2310.08560

หมายเหตุความน่าเชื่อถือ

  • ปี BM25 — เปเปอร์ Okapi at TREC-3 (1994) เป็นการอ้างอิงหลัก แต่สูตรพัฒนามาตั้งแต่ปลายยุค 1980; "~1994" หมายถึงสิ่งพิมพ์สำคัญ ไม่ใช่การปรากฏครั้งแรก
  • วันที่ OKF — แหล่งทุติยภูมิส่วนใหญ่ระบุ 12 มิ.ย. 2026 ขณะที่หน้าบล็อก Google Cloud แสดง 13 มิ.ย. (น่าจะเป็นเรื่อง timezone) — ใช้ 12 มิ.ย. เป็นวันเผยแพร่หลัก
  • gist ของ Karpathy — แหล่งระบุระหว่าง 3–4 เม.ย. 2026 (โพสต์ X วันที่ 3, gist ตามมาวันที่ 4)
  • เนื้อหาประวัติศาสตร์สังเคราะห์จากแหล่งปฐมภูมิ + สารานุกรม/เอกสารมาตรฐานเป็นบริบท ผู้อ่านควรตรวจสอบกับต้นฉบับเมื่อต้องการความแม่นยำสูง