สร้าง AI Agent แนะนำลิงก์เชื่อมโยงโน้ตใน Obsidian: เชื่อมโยงไอเดียอัตโนมัติแบบ Local 100% ด้วย Python + Ollama
เบื่อไหมกับการมานั่งนึกว่าโน้ตตัวนี้จะเชื่อมกับโน้ตไหนดี? มาสร้าง AI Agent ค้นหาความสัมพันธ์ระหว่างไอเดีย และช่วยแนะนำลิงก์เชื่อมโยง (Semantic Linking) ใน Obsidian แบบอัตโนมัติและปลอดภัย 100%
ในระบบการจัดการความรู้ส่วนบุคคล (PKM) หรือ Second Brain สิ่งที่มีพลังที่สุดไม่ใช่จำนวนโน้ตที่เราจด แต่คือ \"การเชื่อมโยงความรู้\" (Bi-directional Linking) เพื่อสร้างเครือข่ายของไอเดียที่สามารถต่อยอดกันได้ตามแนวคิด Zettelkasten หรือ Map of Content (MOC)
อย่างไรก็ตาม เมื่อคลังโน้ตใน Obsidian ของเราเติบโตจนมีขนาดใหญ่ขึ้นเรื่อยๆ มีโน้ตสะสมหลักร้อยหรือหลักพัน การที่เราจะจดจำได้ทั้งหมดว่าเคยเขียนเรื่องอะไรไปแล้วบ้าง และควรสร้างลิงก์เชื่อมโยงไปยังโน้ตเล่มเก่าตัวไหน เป็นเรื่องที่ใช้พลังงานสมองเป็นอย่างมาก (Decision Fatigue) หลายครั้งเราจึงทำได้เพียงจดโน้ตใหม่ทิ้งไว้เฉยๆ กลายเป็นโน้ตที่ถูกทอดทิ้งและสูญเสียความเชื่อมโยงไปอย่างน่าเสียดาย
นี่คือหน้าที่สำคัญของ Cognitive Automation หรือการทำให้กระบวนการคิดวิเคราะห์ทำงานได้โดยอัตโนมัติ ในบทความนี้ เราจะมาสร้าง AI Agent แนะนำลิงก์เชื่อมโยงโน้ต (Semantic Linker) ที่ประมวลผลภายในเครื่องแบบ Local 100% ด้วยภาษา Python และ Ollama เพื่อทำหน้าที่สแกนเนื้อหาในโน้ตล่าสุดของคุณ เปรียบเทียบกับรายการโน้ตทั้งหมดที่มี และแนะนำโน้ตที่น่าจะมีความเกี่ยวข้องกันเพื่อให้คุณกดสร้างลิงก์เชื่อมโยงได้ทันที
ทำไมต้องจัดการความสัมพันธ์ของโน้ตแบบ Local AI?
การใช้ปัญญาประดิษฐ์มาช่วยวิเคราะห์และแนะนำลิงก์ในคลังโน้ตส่วนตัว มีข้อคำนึงที่ต่างจากการใช้งานทั่วไปอย่างสิ้นเชิง:
- ความเป็นส่วนตัวและความมั่นคงของข้อมูล (Data Privacy): โน้ตใน Second Brain มักเป็นบันทึกส่วนตัว ไอเดียธุรกิจ รายงานการประชุม หรือแม้แต่ไดอารี่ประจำวัน การส่งข้อมูลเหล่านี้ไปประมวลผลบน Cloud ถือเป็นความเสี่ยงอย่างยิ่ง การใช้ Ollama ประมวลผลแบบออฟไลน์ในเครื่องจึงเป็นทางเลือกที่ดีที่สุด
- ไม่ทำลายระบบนิเวศการจดโน้ตแบบ Local-first: Obsidian ถูกออกแบบมาให้รันแบบออฟไลน์และเก็บข้อมูลเป็นไฟล์ธรรมดา (.md) การมีสคริปต์ Python ที่รันในเครื่องเดียวกันช่วยรักษาแนวคิดการเป็นเจ้าของข้อมูล (Data Sovereignty) ไว้อย่างสมบูรณ์
- ปรับแต่งคำสั่งแนะนำ (Prompting) ได้ตามใจชอบ: คุณสามารถสั่งให้ AI ค้นหาเฉพาะกลุ่มโน้ตที่ต้องการ หรือจำกัดประเภทความสัมพันธ์ตามวิถีการเขียนของคุณได้อิสระ
โครงสร้างการทำงานของ AI Semantic Linker
กระบวนการเชื่อมโยงความรู้อัตโนมัติจะแบ่งออกเป็น 4 ขั้นตอนสั้นๆ: 1. สแกนระบบไฟล์ (Scan Files): ค้นหารายชื่อโน้ตทั้งหมดใน Obsidian Vault 2. ค้นหาโน้ตล่าสุด (Target Note): ค้นหาไฟล์ที่เพิ่งผ่านการแก้ไขล่าสุดเพื่อนำมาเป็นโจทย์หลัก 3. ส่งให้ LLM วิเคราะห์ (LLM Reasoning): ส่งเนื้อหาโน้ตหลักพร้อมรายชื่อหัวข้อโน้ตอื่นๆ ไปให้ Ollama ประมวลผลผ่านโมเดลที่ต้องการ 4. บันทึกผลลัพธ์ (Write-back): นำคำแนะนำที่ได้ไปเขียนบันทึกต่อท้ายไฟล์เดิมโดยอัตโนมัติ
สิ่งที่ต้องเตรียมก่อนเริ่มต้นใช้งาน
โปรดแน่ใจว่าเครื่องคอมพิวเตอร์ของคุณมีโปรแกรมเหล่านี้พร้อมทำงาน: * Python 3: สำหรับเรียกใช้สคริปต์จัดการไฟล์และเครือข่าย * Ollama: ตัวรันแบบจำลองภาษาขนาดใหญ่ในเครื่อง (ดาวน์โหลดจาก ollama.com) * Obsidian: ตัวแสดงผลและจัดการโน้ตที่ใช้อยู่เป็นประจำ
ถัดไป ให้เปิด Terminal และดึงแบบจำลองภาษาที่เราจะนำมาประมวลผล ในตัวอย่างนี้เราจะใช้ gemma2 (ขนาด 9B) ซึ่งโดดเด่นมากในเรื่องการเข้าใจความหมายของบริบท:
ollama pull gemma2
สร้างสคริปต์ Python สำหรับรันระบบวิเคราะห์
ให้สร้างไฟล์ชื่อ obsidian_semantic_linker.py และคัดลอกโค้ดด้านล่างนี้ไปบันทึกไว้ โดยโค้ดชุดนี้จะเรียกใช้งานโมดูลมาตรฐานของ Python เท่านั้น ทำให้ไม่ต้องติดตั้งไลบรารีภายนอกเพิ่ม:
import urllib.request
import json
import os
import glob
# กำหนดโฟลเดอร์คลังโน้ต Obsidian ของคุณ (กรุณาแก้ไขให้ตรงกับเครื่องของคุณ)
OBSIDIAN_VAULT_PATH = "/home/linn/notes"
LLM_MODEL = "gemma2" # สามารถสลับเป็น llama3 หรือรุ่นอื่นๆ ได้ตามความต้องการ
def get_all_notes(vault_path):
"""ค้นหารายชื่อโน้ต Markdown ทั้งหมดในคลัง"""
search_pattern = os.path.join(vault_path, "**", "*.md")
all_files = glob.glob(search_pattern, recursive=True)
notes = {}
for filepath in all_files:
filename = os.path.basename(filepath)
title = os.path.splitext(filename)[0]
# คัดกรองไม่เอาไฟล์ระบบหรือไฟล์ชั่วคราว
if not title.startswith("."):
notes[title] = filepath
return notes
def get_latest_modified_note(notes):
"""ค้นหาไฟล์โน้ตล่าสุดที่มีการเขียนหรือแก้ไข"""
if not notes:
return None
latest_file = max(notes.values(), key=os.path.getmtime)
for title, filepath in notes.items():
if filepath == latest_file:
return title, filepath
return None
def read_note_content(filepath):
with open(filepath, "r", encoding="utf-8") as f:
return f.read()
def ask_ollama_for_links(note_title, note_content, all_titles, model=LLM_MODEL):
"""ส่งข้อมูลให้ Ollama ประมวลผลและเสนอแนะลิงก์"""
# ปรับปรุงลิสต์รายชื่อโน้ตตัวเลือกเพื่อป้องกันปัญหาระบบวนลูป
titles_list_str = "\n".join([f"- {t}" for t in all_titles if t != note_title])
prompt = f"""
คุณคือ AI Agent ผู้เชี่ยวชาญการจัดการความรู้ส่วนบุคคล (PKM) และระบบ Second Brain
หน้าที่ของคุณคือการวิเคราะห์หาความสัมพันธ์เชิงความหมาย (Semantic Relations) ระหว่างโน้ตปัจจุบัน กับโน้ตอื่นๆ ในคลังสมอง (Vault)
โน้ตปัจจุบันที่เพิ่งบันทึก:
หัวข้อ: {note_title}
เนื้อหา:
{note_content}
---
รายชื่อหัวข้อโน้ตอื่นๆ ทั้งหมดใน Vault:
{titles_list_str}
---
คำสั่ง:
1. จงเลือกโน้ตจากรายชื่อด้านบนที่มีความเกี่ยวข้องกับเนื้อหาของโน้ตปัจจุบันมากที่สุดมา 3-5 โน้ต
2. อธิบายเหตุผลสั้นๆ (1 ประโยค) ว่าทำไมโน้ตนั้นจึงเกี่ยวข้องกัน และควรเชื่อมโยงกันอย่างไร
3. จัดรูปแบบผลลัพธ์ในรูปแบบ Markdown เป็นรายการ (List) โดยทำลิงก์คู่ (Bi-directional Link) ในแบบของ Obsidian เช่น `[[ชื่อโน้ต]] - อธิบายเหตุผล`
4. ตอบกลับเป็นภาษาไทยที่กระชับ ตรงประเด็น และไม่ต้องเขียนเกริ่นนำใดๆ ทั้งสิ้น
"""
url = "http://localhost:11434/api/generate"
payload = {
"model": model,
"prompt": prompt,
"stream": False
}
req = urllib.request.Request(
url,
data=json.dumps(payload).encode("utf-8"),
headers={"Content-Type": "application/json"}
)
try:
with urllib.request.urlopen(req) as response:
res_data = json.loads(response.read().decode("utf-8"))
return res_data.get("response", "").strip()
except Exception as e:
return f"เกิดข้อผิดพลาดในการเชื่อมต่อ Ollama: {str(e)}"
def append_suggestions(filepath, suggestions):
"""บันทึกข้อเสนอแนะลิงก์ต่อท้ายไฟล์โน้ตเดิม"""
if not suggestions or "เกิดข้อผิดพลาด" in suggestions:
return
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()
# ป้องกันไม่ให้รันซ้ำซ้อนในโน้ตใบเดิม
if "## 🔗 Related Notes (AI Suggested)" in content:
print("โน้ตนี้ได้รับการแนะนำลิงก์ไปก่อนหน้านี้แล้ว")
return
with open(filepath, "a", encoding="utf-8") as f:
f.write("\n\n---\n## 🔗 Related Notes (AI Suggested)\n")
f.write(f"{suggestions}\n")
f.write("\n*แนะนำลิงก์อัตโนมัติด้วย Local AI Agent*")
print(f"บันทึกข้อเสนอแนะนำลิงก์ลงท้ายโน้ต '{os.path.basename(filepath)}' เรียบร้อย!")
def main():
if not os.path.exists(OBSIDIAN_VAULT_PATH):
print(f"ไม่พบโฟลเดอร์ตามเส้นทางที่ระบุ: {OBSIDIAN_VAULT_PATH}")
return
print("กำลังสแกนหาไฟล์โน้ตทั้งหมด...")
notes = get_all_notes(OBSIDIAN_VAULT_PATH)
if not notes:
print("ไม่พบไฟล์โน้ตสกุล .md เลย")
return
latest = get_latest_modified_note(notes)
if not latest:
return
note_title, filepath = latest
print(f"พบไฟล์แก้ไขล่าสุด: {note_title}")
content = read_note_content(filepath)
all_titles = list(notes.keys())
print("กำลังวิเคราะห์ความเกี่ยวข้องกันด้วย Ollama...")
suggestions = ask_ollama_for_links(note_title, content, all_titles)
print("\nข้อเสนอแนะลิงก์เชื่อมโยง:")
print(suggestions)
print("\nกำลังอัปเดตไฟล์โน้ต...")
append_suggestions(filepath, suggestions)
if __name__ == "__main__":
main()
ยกระดับด้วยการติดตั้งปลั๊กอินใน Obsidian
เพื่อเสริมความเป็นระบบอัตโนมัติ (Automation) ให้กลมกลืนที่สุด โดยไม่จำเป็นต้องรันสคริปต์จากภายนอกคีย์บอร์ด คุณสามารถผสานสคริปต์นี้โดยตรงผ่านตัวช่วยใน Obsidian:
- ติดตั้งปลั๊กอินชุมชนชื่อ \"Shell Commands\" ในระบบ Obsidian
- สร้างชุดคำสั่งใหม่ให้รันโปรแกรมภาษา Python:
bash python /path/to/obsidian_semantic_linker.py - กำหนดเงื่อนไขการทำงาน (Event Triggers) ให้โปรแกรมตรวจพบเมื่อคุณปิดโน้ต หรือจะตั้งค่า Hotkey (คีย์ลัด) พิเศษขึ้นมาปุ่มเดียวเพื่อคลิกรันคำแนะนำความสัมพันธ์ได้ทันใจ
บทสรุป
การสร้าง AI Agent มาคอยเสนอแนะทิศทางความเชื่อมโยงของไอเดีย จะเปลี่ยนประสบการณ์การสร้าง Second Brain จากกระบวนการแยกส่วน (Isolated Notes) ให้กลายมาเป็นสิ่งมีชีวิตที่มีความผูกพันเชื่อมโยงกันอย่างต่อเนื่อง ยิ่งคลังโน้ตเติบโตขึ้น ปัญญาประดิษฐ์ก็จะยิ่งมองเห็นมุมมองที่เราอาจหลงลืมไปได้ดียิ่งขึ้น
การเลือกใช้สถาปัตยกรรมแบบ Local-first ไม่เพียงแต่เป็นการปกป้องสิ่งที่เราคิดไว้เป็นความลับ แต่ยังเป็นรากฐานที่ดีของการเป็นเจ้านายผู้มีอำนาจสั่งการความมั่นคงของข้อมูลตนเอง 100% ลองดาวน์โหลดสคริปต์นี้ไปประยุกต์ปรับใช้กับคลังโน้ตของคุณกันครับ!