สร้าง AI Agent ตรวจสุขภาพคลังความรู้ส่วนบุคคล: ค้นหาโน้ตรกร้าง เติม Metadata และจัดหมวดหมู่อัตโนมัติใน Obsidian ด้วย Python + Ollama

เมื่อ Second Brain ขยายตัวจนเกิดโน้ตรกร้างและ Metadata ไม่ครบ มาสร้าง AI Agent ส่วนตัวรันแบบ Local 100% เพื่อสแกน ตรวจสุขภาพ และจัดทำรายงานคลังความรู้ Obsidian Vault พร้อมคำแนะนำการปรับปรุงอย่างอัตโนมัติ

Share
สร้าง AI Agent ตรวจสุขภาพคลังความรู้ส่วนบุคคล: ค้นหาโน้ตรกร้าง เติม Metadata และจัดหมวดหมู่อัตโนมัติใน Obsidian ด้วย Python +

เมื่อระบบ Second Brain หรือคลังความรู้ส่วนตัวในแอปพลิเคชันอย่าง Obsidian ของเราเติบโตขึ้นจากหลักสิบเป็นหลักร้อยหรือหลักพันโน้ต สิ่งที่มักจะเกิดขึ้นตามมาโดยไม่รู้ตัวคือ "ขยะทางปัญญา (Digital Clutter)"

ปัญหาที่พบบ่อยได้แก่: * Orphan Notes (โน้ตรกร้าง): โน้ตที่ไม่มีการสร้างลิงก์เชื่อมโยงเข้า ([[...]]) หรือออกไปหาโน้ตอื่นเลย ทำให้หลุดออกจากเครือข่ายความรู้ * Missing Metadata: โน้ตที่ขาดข้อมูลส่วนหัว (YAML Frontmatter) เช่น วันที่สร้าง, สถานะ (Status), หรือหมวดหมู่ * Untagged Notes: โน้ตที่ไม่ติด แท็ก (Tag) ทำให้ค้นหาและกรองข้อมูลยากในอนาคต

การต้องมานั่งสแกนดูโน้ตทีละไฟล์เพื่อทำความสะอาด vault เป็นงานที่ใช้พลังสมองและเวลาอย่างมหาศาล ในบทความนี้ เราจะมาสร้างระบบ Cognitive Automation ด้วยภาษา Python ร่วมกับ Ollama เพื่อสร้าง Vault Health Check Agent ทำหน้าที่ตรวจสุขภาพคลังความรู้ สกัดข้อบกพร่อง และใช้ Local AI ช่วยวิเคราะห์พร้อมแนะนำการปรับปรุงให้อัตโนมัติแบบ Local 100% ปลอดภัย ไร้กังวลเรื่องข้อมูลส่วนตัวรั่วไหล


ทำไมต้องตรวจสุขภาพ Obsidian Vault แบบ Local 100%?

คลังความรู้ส่วนตัวคือ "สมองส่วนที่สอง" ที่บันทึกทั้งไอเดียธุรกิจ บันทึกส่วนตัว งานวิจัย และแผนการดำเนินชีวิต การวิเคราะห์เนื้อหาใน vault เพื่อจัดหมวดหมู่หรือแนะนำแท็ก จำเป็นต้องให้ AI อ่านเนื้อหาภายในโน้ตเหล่านั้น

หากเราใช้บริการ Cloud AI ทั่วไป ข้อมูลความคิดทั้งหมดจะถูกส่งออกนอกเครื่อง เสี่ยงต่อการนำไปใช้ฝึกโมเดลภายนอก การใช้ Local LLM ผ่าน Ollama ช่วยให้กระบวนการทั้งหมดเกิดขึ้นภายในเครื่องคอมพิวเตอร์ของคุณ 100% ประมวลผลได้เร็ว ไม่เสียค่าบริการรายเดือน และทำงานได้แม้ไม่มีอินเทอร์เน็ต


โครงสร้างการทำงานของ Vault Health Check Agent

สคริปต์ Python ที่เรากำลังจะสร้าง จะทำงาน 4 ขั้นตอนหลัก:

  1. สแกนไฟล์ (Vault Scanning): อ่านไฟล์ .md ทั้งหมดใน Obsidian Vault เพื่อดึงข้อมูล YAML Frontmatter, แท็ก #tag, และลิงก์ภายใน [[Link]]
  2. วิเคราะห์ความผิดปกติ (Health Audit): ค้นหา Orphan Notes, ไฟล์ที่ไม่มี Metadata, และโน้ตที่สั้นเกินไป
  3. สังเคราะห์คำแนะนำด้วย Local AI (AI Recommendation): ส่งเนื้อหาของโน้ตที่มีปัญหาให้ Ollama เพื่อช่วยคิด Tag, Category, และแนะนำโน้ตที่ควรลิงก์ถึงกัน
  4. ออกรายงานสุขภาพ (Health Report Generation): บันทึกรายงานสรุปเป็นไฟล์ Markdown เข้าไปใน Obsidian Vault โดยตรง

สิ่งที่ต้องจัดเตรียมก่อนเริ่มต้น

  1. Python 3.8+ ติดตั้งในเครื่องเรียบร้อย
  2. Ollama ติดตั้งและรัน Service เรียบร้อย (ดาวน์โหลดจาก ollama.com)
  3. ดาวน์โหลดโมเดลภาษาที่เหมาะกับภาษาไทย เช่น gemma2 หรือ llama3.2:
ollama pull gemma2

โค้ด Python: สร้าง Vault Health Check Agent

สร้างไฟล์ vault_health_agent.py แล้ววางโค้ดสคริปต์ที่ออกแบบมาให้อ่านง่าย และใช้ไลบรารีมาตรฐานของ Python โดยไม่ต้องติดตั้งแพ็กเกจเสริม (Zero-dependency):

import os
import re
import json
import urllib.request
from pathlib import Path

# ================= ตั้งค่าระบบ (Configuration) =================
OBSIDIAN_VAULT_PATH = "/home/linn/notes"  # ปรับเป็น Path ของ Obsidian Vault ของคุณ
REPORT_OUTPUT_DIR = os.path.join(OBSIDIAN_VAULT_PATH, "Reports")
LLM_MODEL = "gemma2"                       # โมเดลใน Ollama ที่ต้องการใช้
MAX_NOTES_TO_AI_ANALYZE = 5                 # จำกัดจำนวนโน้ตที่มีปัญหาเพื่อส่งให้ AI ช่วยวิเคราะห์ต่อรอบ
# =============================================================

def parse_md_file(file_path):
    """อ่านและสกัดโครงสร้างของไฟล์ Markdown"""
    with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
        content = f.read()

    # สกัด YAML Frontmatter
    has_frontmatter = bool(re.match(r'^---\s*\n.*?\n---\s*\n', content, re.DOTALL))

    # สกัด WikiLinks [[...]]
    links = set(re.findall(r'\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]', content))

    # สกัด Tags #tag
    tags = set(re.findall(r'(?<!\w)#([a-zA-Z0-9_\-ก-๙]+)', content))

    # คำนวณความยาวเนื้อหาแบบหยาบ
    clean_text = re.sub(r'^---\s*\n.*?\n---\s*\n', '', content, flags=re.DOTALL).strip()
    word_count = len(clean_text.split())

    return {
        "path": file_path,
        "name": Path(file_path).stem,
        "has_frontmatter": has_frontmatter,
        "links": links,
        "tags": tags,
        "word_count": word_count,
        "content_snippet": clean_text[:400] # สแนปชอตสั้นๆ สำหรับ AI
    }

def scan_vault(vault_path):
    """สแกนโน้ตทั้งหมดใน Vault เพื่อหาจุดที่ต้องปรับปรุง"""
    all_notes = {}
    inbound_links = {}

    # เดินสแกนทุกไฟล์ .md
    for root, _, files in os.walk(vault_path):
        for file in files:
            if file.endswith(".md") and not file.startswith("."):
                full_path = os.path.join(root, file)
                parsed = parse_md_file(full_path)
                note_name = parsed["name"]
                all_notes[note_name] = parsed
                inbound_links.setdefault(note_name, 0)

    # นับการลิงก์ข้ามโน้ต (Inbound count)
    for note_name, data in all_notes.items():
        for target in data["links"]:
            clean_target = Path(target).stem
            if clean_target in inbound_links:
                inbound_links[clean_target] += 1
            else:
                inbound_links[clean_target] = 1

    # แยกประเภทปัญหา
    orphans = []
    missing_metadata = []
    untagged = []

    for note_name, data in all_notes.items():
        # เป็น Orphan ถ้าไม่มีลิงก์ออก และไม่มีใครลิงก์เข้ามาหา
        if len(data["links"]) == 0 and inbound_links.get(note_name, 0) == 0:
            orphans.append(data)

        if not data["has_frontmatter"]:
            missing_metadata.append(data)

        if len(data["tags"]) == 0:
            untagged.append(data)

    return all_notes, orphans, missing_metadata, untagged

def ask_ollama_for_suggestions(note_data):
    """ส่งเนื้อหาโน้ตที่มีปัญหาให้ Ollama ช่วยคิด Tag และ Category"""
    prompt = f"""คุณคือผู้เชี่ยวชาญด้านระบบ Second Brain และ PKM (Personal Knowledge Management)
โปรดวิเคราะห์โน้ตด้านล่างนี้ แล้วแนะนำ:
1. หมวดหมู่หลัก (Category) 1 หมวด
2. แท็กที่เหมาะสม 3-5 แท็ก (รูปแบบ #tag)
3. สรุปแนวคิดหลัก 1 ประโยค

ชื่อโน้ต: {note_data['name']}
เนื้อหาบางส่วน:
{note_data['content_snippet']}

ตอบสั้นๆ ชัดเจน ภาษาไทย:"""

    payload = {
        "model": LLM_MODEL,
        "prompt": prompt,
        "stream": False
    }

    try:
        req = urllib.request.Request(
            "http://localhost:11434/api/generate",
            data=json.dumps(payload).encode("utf-8"),
            headers={"Content-Type": "application/json"}
        )
        with urllib.request.urlopen(req, timeout=30) as resp:
            res = json.loads(resp.read().decode("utf-8"))
            return res.get("response", "").strip()
    except Exception as e:
        return f"ไม่สามารถเรียก AI ได้: {str(e)}"

def generate_health_report(all_notes, orphans, missing_meta, untagged):
    """สร้างรายงานผลสรุปเป็นไฟล์ Markdown เข้า Obsidian"""
    os.makedirs(REPORT_OUTPUT_DIR, exist_ok=True)
    report_file = os.path.join(REPORT_OUTPUT_DIR, "Vault-Health-Report.md")

    total_count = len(all_notes)
    orphan_count = len(orphans)
    meta_count = len(missing_meta)
    untagged_count = len(untagged)

    # คำนวณคะแนนสุขภาพ Vault (คะแนนเต็ม 100)
    health_score = max(0, 100 - int((orphan_count * 3 + meta_count * 2 + untagged_count * 1) / (total_count or 1) * 20))

    lines = []
    lines.append("---")
    lines.append("title: 'Vault Health Check Report'")
    lines.append("type: 'report'")
    lines.append("tags: ['pkm', 'vault-health', 'automation']")
    lines.append("---\n")
    lines.append("# 🏥 รายงานตรวจสุขภาพคลังความรู้ (Vault Health Report)")
    lines.append(f"\n* **จำนวนโน้ตทั้งหมด:** {total_count} ไฟล์")
    lines.append(f"* **คะแนนสุขภาพ Vault:** `{health_score}/100`")
    lines.append("\n---")
    lines.append("### 📊 ภาพรวมข้อบกพร่องที่พบ")
    lines.append(f"* 🔗 **Orphan Notes (โน้ตรกร้าง ไร้การเชื่อมโยง):** {orphan_count} ไฟล์")
    lines.append(f"* 📋 **Missing Metadata (ขาด Frontmatter):** {meta_count} ไฟล์")
    lines.append(f"* 🏷️ **Untagged Notes (ไม่มีแท็ก):** {untagged_count} ไฟล์")

    lines.append("\n---\n### 💡 คำแนะนำจาก AI สำหรับโน้ตที่ควรปรับปรุง\n")

    # สุ่ม/ดึงโน้ตที่มีปัญหามาให้ AI ช่วยแนะนำ
    problematic_notes = (orphans + untagged)[:MAX_NOTES_TO_AI_ANALYZE]
    for idx, note in enumerate(problematic_notes, 1):
        print(f"กำลังวิเคราะห์ข้อเสนอแนะสำหรับ: {note['name']}...")
        ai_suggestion = ask_ollama_for_suggestions(note)
        lines.append(f"#### {idx}. [[{note['name']}]]")
        lines.append(f"**ปัญหาที่พบ:** {'ไร้ลิงก์เชื่อมโยง ' if note in orphans else ''}{'ไม่มีแท็ก' if note in untagged else ''}")
        lines.append(f"**คำแนะนำจาก AI:**\n{ai_suggestion}\n")

    lines.append("---\n### 🛠️ Action Items ที่แนะนำให้ทำ")
    lines.append("1. เปิดโน้ตในกลุ่ม **Orphan Notes** แล้วเพิ่ม `[[...]]` เชื่อมไปยังโน้ตที่เกี่ยวข้องหรือ MOC")
    lines.append("2. เติม YAML Frontmatter ให้กับโน้ตที่ขาดข้อมูลพื้นฐาน")
    lines.append("3. ติดแท็กหมวดหมู่หลักเพื่อเพิ่มความสะดวกในการค้นหาผ่าน Dataview")

    with open(report_file, "w", encoding="utf-8") as f:
        f.write("\n".join(lines))

    print(f"\n✅ สร้างรายงานสุขภาพสำเร็จแล้วที่: {report_file}")

if __name__ == "__main__":
    print("🔍 กำลังเริ่มสแกน Obsidian Vault...")
    all_notes, orphans, missing_meta, untagged = scan_vault(OBSIDIAN_VAULT_PATH)
    generate_health_report(all_notes, orphans, missing_meta, untagged)

วิธีการนำไปใช้งาน

  1. เปิด Terminal แล้วเปลี่ยน Path ในตัวแปร OBSIDIAN_VAULT_PATH ในสคริปต์ให้ตรงกับโฟลเดอร์ Obsidian จริงของคุณ
  2. รันสคริปต์ผ่าน Terminal:
python3 vault_health_agent.py
  1. เมื่อสคริปต์ทำงานเสร็จ ให้เปิดแอป Obsidian แล้วเข้าไปดูที่โฟลเดอร์ Reports/Vault-Health-Report.md คุณจะพบกับรายงานสุขภาพที่คำนวณคะแนนและมีคำแนะนำจัดแท็กแบบอัตโนมัติจาก Local AI

ต่องานแบบอัตโนมัติด้วย Cron หรือ Task Scheduler

เพื่อให้คลังความรู้ของคุณได้รับการดูแลอย่างสม่ำเสมอ คุณสามารถตั้งให้สคริปต์นี้ทำงานทุกคืนวันอาทิตย์ผ่าน Cron Job บน Linux/macOS ได้ง่ายๆ:

# เปิดแก้ไข cron
crontab -e

# เพิ่มบรรทัดนี้เพื่อรันทุกวันอาทิตย์ เวลา 22:00 น.
0 22 * * 0 /usr/bin/python3 /path/to/vault_health_agent.py

บทสรุป

การสร้าง Second Brain ไม่ใช่เรื่องของการสะสมปริมาณโน้ตให้ได้มากที่สุด แต่เป็นเรื่องของการรักษาคุณภาพและความเชื่อมโยงของระบบความรู้ การใช้ Cognitive Automation ผ่าน Python และ Ollama ช่วยเปลี่ยนงานดูแลระบบที่น่าเบื่อ ให้กลายเป็นระบบอัตโนมัติที่คอยดูแลสุขภาพสมองส่วนที่สองของคุณอยู่เสมอ โดยที่ข้อมูลความรู้ทั้งหมดยังคงเป็นของคุณ 100% บนเครื่องคอมพิวเตอร์ส่วนตัว

Read more

สร้าง AI Agent สำหรับการทำ Decision Log อัตโนมัติ: เปลี่ยนทุกการตัดสินใจสำคัญให้เป็นบทเรียนเพื่อการเติบโต

สร้าง AI Agent สำหรับการทำ Decision Log อัตโนมัติ: เปลี่ยนทุกการตัดสินใจสำคัญให้เป็นบทเรียนเพื่อการเติบโต

เรียนรู้วิธีใช้ AI Agent ช่วยบันทึกและวิเคราะห์การตัดสินใจสำคัญในชีวิตประจำวัน เพื่อเปลี่ยนทุกทางเลือกให้กลายเป็นฐานข้อมูลบทเรียนที่มีค่าสำหรับอนาคต

By Linn
คู่มือใช้งาน Obsidian Graph View: เปลี่ยนใยแมงมุมความรู้ให้เป็นเครื่องมือนำทางความคิดใน Second Brain

คู่มือใช้งาน Obsidian Graph View: เปลี่ยนใยแมงมุมความรู้ให้เป็นเครื่องมือนำทางความคิดใน Second Brain

Graph View ใน Obsidian ไม่ใช่แค่ภาพกราฟสวยๆ ไว้ดูเล่น มาเรียนรู้วิธีปรับแต่ง Local Graph, Color Groups และฟิลเตอร์ เพื่อเปลี่ยนเครือข่ายความรู้ให้กลายเป็นเครื่องมือนำทางความคิดจริง

By Linn
สร้าง Smart Clipboard Agent: ดักจับและคัดแยกข้อความที่คัดลอกระหว่างวัน บันทึกเข้า Obsidian อัตโนมัติด้วย Python + Ollama

สร้าง Smart Clipboard Agent: ดักจับและคัดแยกข้อความที่คัดลอกระหว่างวัน บันทึกเข้า Obsidian อัตโนมัติด้วย Python + Ollama

เปลี่ยนข้อความ โค้ด ลิงก์ และไอเดียที่คุณคัดลอกระหว่างวันให้กลายเป็นบันทึกความรู้ที่มีบริบทใน Second Brain โดยอัตโนมัติ ด้วยสคริปต์ Python คอยมอนิเตอร์คลิปบอร์ดคู่กับ Local LLM บน Ollama แบบออฟไลน์ 100%

By Linn
บอกลาคำสั่ง Docker CLI ที่ซับซ้อน: คู่มือติดตั้ง Dockge จัดการ Docker Compose บน Home Server อย่างมือโปร

บอกลาคำสั่ง Docker CLI ที่ซับซ้อน: คู่มือติดตั้ง Dockge จัดการ Docker Compose บน Home Server อย่างมือโปร

ยกระดับการจัดการคอนเทนเนอร์บน Home Server ให้ง่ายและเป็นระเบียบ ด้วย Dockge ตัวจัดการ Docker Compose สไตล์มินิมอลที่เน้นความโปร่งใส ควบคุมไฟล์ .yml ได้โดยตรง 100%

By Linn