Open Knowledge Formatสร้าง knowledge base ที่ AI ช่วยดูแล — ตั้งแต่เริ่มต้นจนถึงระดับองค์กร
ฐานความรู้ที่เก็บเป็นไฟล์ Markdown ธรรมดา ที่ทั้งคนและ AI agent อ่าน เขียน และใช้งานร่วมกันได้
คำนำ
ยินดีต้อนรับสู่ คู่มือ 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 — แนวคิดหลัก
- Bundle, Concept และ Concept ID25
- Frontmatter (เมทาดาทา)27
- การลิงก์เป็น knowledge graph30
- ไฟล์สงวน: index.md และ log.md32
ภาคที่ 4 — การใช้งานประจำวัน
- Ingest: เก็บความรู้เข้า wiki35
- Query และ Search37
- เพิ่มและแก้ไข concept39
- Validate และ Visualize42
- ตัวอย่างใช้งานจริง: KB ร้านหนังสือ45
ภาคที่ 5 — เขียนให้ดี
ภาคที่ 6 — ระดับองค์กร (Enterprise)
- ภาพรวมสถาปัตยกรรม51
- ติดตั้งแบบ self-host54
- โมเดลการเขียน: PR-gated และ Lease57
- Search ระดับ scale และ semantic60
- ความปลอดภัยและ governance62
ภาคผนวก
OKF คืออะไร
Open Knowledge Format (OKF) คือสเปกแบบเปิดสำหรับเก็บ "ความรู้" ขององค์กรในรูปของ ไดเรกทอรีของไฟล์ Markdown ที่มี YAML frontmatter เพื่อให้ทั้งคนและ AI agent เขียน อ่าน แลกเปลี่ยน และใช้งานได้ — โดยไม่ต้องมี SDK, ฐานข้อมูล, หรือเครื่องมือเฉพาะทาง
ถ้าคุณ
catไฟล์ได้ คุณก็อ่าน OKF ได้ · ถ้าคุณgit clonerepo ได้ คุณก็ส่งต่อ 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 ID | path ของไฟล์ใน bundle ตัด .md ออก เช่น tables/orders.md → tables/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 ข้อ
- บังคับน้อยที่สุด (minimally opinionated) — frontmatter บังคับแค่ฟิลด์
typeเดียว ที่เหลือผู้ผลิตกำหนดเอง - ผู้ผลิตกับผู้บริโภคแยกอิสระ — bundle ที่คนเขียนด้วยมือ, agent สร้าง, หรือ pipeline export มา ล้วนถูกอ่านได้ด้วยเครื่องมือใดก็ได้
- เป็นกราฟ ไม่ใช่แค่ต้นไม้ — 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" ที่อยู่เอกสารเดียวกลับโดดเด่น:
| คำ | เอกสาร | ค่าความเด่น |
|---|---|---|
| the | D1, D2, D3 | 0 (ไร้ค่า) |
| dog | D3 | สูง |
เมื่อ 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
ตัวอย่าง:
| คำ | เอกสาร |
|---|---|
| cat | D1, D2 |
| dog | D3 |
ค้น "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
6. Vector / 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 |
| RAG | ground คำตอบ LLM | wiki (L1) + RAG (L2) |
| Hybrid / RRF | รวมหลายสัญญาณ | okf-search.py |
| Knowledge graph | entity + ความสัมพันธ์ | 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 — เริ่มเก็บความรู้
- วางไฟล์ต้นทาง (PDF, โน้ต, export) ลงในโฟลเดอร์
raw/ - บอก 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> |
| ตรวจ conformance | okf-validate.py ./wiki |
| ดู graph | okf-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. wiki | wiki/ | agent | ความรู้ที่สังเคราะห์แล้ว (OKF bundle) |
| 3. schema | AGENTS.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.md | tables/orders |
references/metrics/wau.md | references/metrics/wau |
playbooks/incident.md | playbooks/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 อ่านเพื่อตัดสินใจว่าจะโหลดไฟล์นี้ไหม เขียนให้คม |
resource | URI ของของจริงที่ concept อธิบาย (ละได้ถ้าเป็นแนวคิดนามธรรม) |
tags | YAML 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 จะมองทุกลิงก์เป็น "เส้นเชื่อมมีทิศทาง" แบบไม่ระบุชนิด
ลิงก์เสียได้ (broken links อนุญาต)
ลิงก์ที่ชี้ไปยัง 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 เข้า contextlog.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 (แบบมีคนกำกับ)
- อ่านแหล่ง ใน
raw/ - อ่าน
wiki/index.mdเพื่อรู้ว่ามี concept อะไรอยู่แล้ว - ดึง 5–15 ประเด็น (claim/decision/insight) ที่ควรเก็บ
- แสดงประเด็นที่ดึงมา + การ map ไปยัง concept ให้คุณอนุมัติ — แล้วรอ ก่อนเขียนอะไร
- ปรับข้อขัดแย้ง (reconcile) — ถ้าข้อมูลใหม่ขัดกับ concept เดิม ให้เติมธงในไฟล์เก่า:
> **CONTRADICTION FLAG**: ผลใหม่แทนที่ค่านี้ ดู references/metrics/new-wau.md - เขียน/อัปเดต concept (เริ่มจาก template) อัปเดต
tags+timestamp - อัปเดต
index.mdที่เกี่ยวข้อง - เพิ่มรายการลง
log.mdใต้วันที่วันนี้ - รัน 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 ก็เพียงพอ:
- อ่าน
wiki/index.mdก่อน เพื่อหา concept ที่เกี่ยว - เจาะเข้าไฟล์ concept นั้น ๆ
- ตอบ จากเฉพาะ concept ที่โหลดมา และ อ้าง Concept ID เสมอ
- ถ้าไม่มีข้อมูลครอบคลุม ให้บอกตรง ๆ และเสนอให้ 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
- คัดลอก template → ตั้งชื่อไฟล์ (kebab-case, นิ่ง)
- ตั้ง
typeให้ถูก (จาก controlled vocabulary) - เขียน body ใช้โครงสร้าง + ลิงก์ relative
- อัปเดต
tags+timestamp - อัปเดต
index.mdของไดเรกทอรีนั้น - เพิ่มรายการลง
wiki/log.md - รัน
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 ผ่านเมื่อ:
- ทุกไฟล์
.mdที่ไม่ใช่ไฟล์สงวน มี YAML frontmatter ที่ parse ได้ - ทุก frontmatter มีฟิลด์
typeที่ไม่ว่าง - ไฟล์สงวน (
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 ได้):
ทำให้เป็นนิสัย
รวมสองคำสั่งนี้หลังการแก้ทุกครั้ง:
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 ได้อย่างเชื่อถือได้
กฎทอง
- หนึ่ง concept ต่อไฟล์ — อย่ายัด 3 เรื่องลงไฟล์เดียว
- เขียน
descriptionเพื่อ agent — เป็นบรรทัดเดียวที่ agent อ่านเพื่อตัดสินใจโหลดไฟล์ เขียนให้เจาะจง - โครงสร้างชนะย่อหน้า — heading, bullet (
**key** — value), ตาราง โมเดลดึงข้อมูลจาก Markdown ที่มีโครงสร้างได้แม่นกว่า - identity = path — ตั้งชื่อไฟล์นิ่ง ๆ kebab-case การเปลี่ยนชื่อทำลายลิงก์ที่ชี้เข้ามา
typeสม่ำเสมอ — ใช้ controlled vocabulary- อ้างอิงแหล่งเสมอ — ทุก 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 | บทบาท |
|---|---|---|---|
| 1 | Git server | Gitea / GitLab CE | ต้นทางความจริง versioned (repo ต่อทีม หรือ monorepo + CODEOWNERS) |
| 2 | OKF MCP server | server/okf_mcp_server.py | access layer ที่ทุก agent ต่อ — read/search/propose; stdio + HTTP/SSE |
| 3 | Search index | tools/okf-index.py (+ embed) | ค้นเร็วเมื่อ wiki โตเกิน ~150 หน้า |
| 4 | CI gate | Gitea Actions / GitLab CI | บล็อก merge ที่ไม่ conformant + regen viz |
| 5 | Reverse proxy | Caddy / Traefik / nginx | TLS + auth (token / OIDC / mTLS) หน้า MCP |
Read path (กรณีปกติ — เร็ว ไม่มี lock)
- agent เรียก
okf_search("WAU นิยามยังไง")→ ได้ Concept ID จัดอันดับ okf_get_concept("metrics/weekly-active-users")→ frontmatter + body โหลดเข้า contextokf_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 แต่:
- สร้าง branch
okf/<concept>-<id>จากmain - เขียนไฟล์ commit push ขึ้น git server ภายใน
- เปิด PR/MR ผ่าน API ของ git server แล้วคืน URL
- 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)
เปรียบเทียบ
| โมเดล | ความเร็ว | review | conflict | เหมาะกับ |
|---|---|---|---|---|
| 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 concept | index.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 | ทำได้ |
|---|---|
reader | search / get / list เท่านั้น |
proposer | + okf_propose_change (branch/PR เท่านั้น ไม่แตะ main) |
curator | merge ได้ (ผ่าน 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
broken link ผิดไหม?
ไม่ผิด — แทน "ความรู้ที่ยังไม่ได้เขียน" okf-validate.py รายงานเป็น info ไม่ใช่ error
ทำ ingest อัตโนมัติเลยได้ไหม?
ไม่แนะนำอย่างยิ่ง — daemon เบื้องหลังจะสะสม noise จน wiki เน่า ให้ ingest เป็นคำสั่งที่คนสั่ง + รีวิว
wiki ใหญ่แค่ไหนถึงต้องใช้ search?
ประมาณ ~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 ID | path ของไฟล์ใน bundle ตัด .md ออก เช่น tables/orders.md → tables/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 |
| Reference | type ที่ใช้กับความรู้สังเคราะห์ (join, นิยาม metric) มักอยู่ใต้ references/ |
| RAG | Retrieval-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 server | service ที่เปิด 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 CE | git server ที่ self-host ได้ ใช้เป็นต้นทางความจริง |
| AGENTS.md | ไฟล์ schema ที่บอก agent ถึงโครงสร้าง/กฎ/workflow (อาจชื่อ CLAUDE.md/GEMINI.md) |
แหล่งข้อมูลอ้างอิง
รวมแหล่งอ้างอิงสำหรับบทประวัติศาสตร์ และแนวคิดพื้นฐาน
หมายเลข [1]–[6] ตรงกับยุคในบทประวัติศาสตร์ รวบรวมจากการทำ deep research (มิ.ย. 2026) อ้างอิงแหล่งปฐมภูมิเป็นหลัก
[1] ยุค Expert systems & knowledge representation
- Shortliffe, E. H. (1976). Computer-Based Medical Consultations: MYCIN. Elsevier/North-Holland.
- Buchanan, B. G., & Shortliffe, E. H. (Eds.) (1984). Rule-Based Expert Systems: The MYCIN Experiments of the Stanford Heuristic Programming Project. Addison-Wesley.
- Minsky, M. (1974). A Framework for Representing Knowledge. MIT AI Lab Memo 306.
- Feigenbaum, E. A., Buchanan, B. G., & Lederberg, J. (1971). On Generality and Problem Solving: A Case Study Using the DENDRAL Program. Machine Intelligence, 6.
- 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
- 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
- Gruber, T. (1993). A Translation Approach to Portable Ontology Specifications. Knowledge Acquisition, 5(2).
- W3C (1999, rev. 2004, 2014). Resource Description Framework (RDF). https://www.w3.org/RDF/
- W3C (2004, rev. 2009). OWL Web Ontology Language Overview. https://www.w3.org/OWL/
- schema.org (2011). schema.org — shared structured-data vocabulary (Google, Bing, Yahoo). https://schema.org/
[3] ยุค Databases & Information Retrieval
- 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
- Spärck Jones, K. (1972). A Statistical Interpretation of Term Specificity and Its Application in Retrieval. Journal of Documentation, 28(1), 11–21.
- Robertson, S. E., Walker, S., Jones, S., Hancock-Beaulieu, M., & Gatford, M. (1994). Okapi at TREC-3. Proceedings of TREC-3.
- Apache Software Foundation. Apache Lucene (Doug Cutting, 1999). https://lucene.apache.org/
- Elastic (2010). Elasticsearch (Shay Banon). https://www.elastic.co/
[4] ยุค Wiki & Personal Knowledge Management
- Cunningham, W. (1995). WikiWikiWeb — Portland Pattern Repository. https://en.wikipedia.org/wiki/WikiWikiWeb
- Wales, J., & Sanger, L. (2001). Wikipedia. Wikimedia Foundation. https://en.wikipedia.org/wiki/Wikipedia
- Luhmann, N. (1981). Kommunikation mit Zettelkästen. In Öffentliche Meinung und sozialer Wandel. https://zettelkasten.de/introduction/
- Obsidian.md (2020). About Obsidian. https://obsidian.md/about
[5] ยุค AI: embeddings, vector search, RAG
- 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
- Singhal, A. (2012). Introducing the Knowledge Graph: things, not strings. Google Blog. https://blog.google/products/search/introducing-knowledge-graph-things-not/
- Johnson, J., Douze, M., & Jégou, H. (2017). Billion-scale Similarity Search with GPUs (FAISS). arXiv:1702.08734. https://arxiv.org/abs/1702.08734
- 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
- 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
- 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
- Karpathy, A. (2026). LLM Wiki [GitHub Gist]. https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f
- 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
- GoogleCloudPlatform (2026). Open Knowledge Format — Specification & Reference Implementations [GitHub]. https://github.com/GoogleCloudPlatform/knowledge-catalog/tree/main/okf
- 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)
- เนื้อหาประวัติศาสตร์สังเคราะห์จากแหล่งปฐมภูมิ + สารานุกรม/เอกสารมาตรฐานเป็นบริบท ผู้อ่านควรตรวจสอบกับต้นฉบับเมื่อต้องการความแม่นยำสูง