สร้าง AI Agent สกัดข้อมูลและสรุปเปเปอร์วิจัย: เปลี่ยน PDF ขนาดยาวเป็น Literature Review อัจฉริยะด้วย Python + Ollama
เปลี่ยนการอ่านเปเปอร์วิจัยที่แสนน่าเบื่อและใช้เวลานาน ให้เป็นระบบอัตโนมัติด้วย AI Agent ที่ช่วยอ่านไฟล์ PDF สกัดหัวข้อ วิธีการวิจัย ผลลัพธ์ และข้อจำกัด ออกมาเป็น Literature Review พร้อมลิงก์เข้า Obsidian Vault แบบออฟไลน์ 100%
สำหรับนักวิจัย นักศึกษา หรือใครก็ตามที่ต้องทำงานกับข้อมูลวิชาการ การติดตามงานวิจัยใหม่ๆ เป็นเรื่องที่เหนื่อยล้าทางความคิดมาก ในแต่ละวันเรามักต้องเจอกับไฟล์ PDF วรรณกรรมยาวเหยียดหลายสิบหน้า การอ่านและสรุปใจความสำคัญของเปเปอร์เหล่านี้จึงสร้าง Cognitive Load หรือภาระทางสมองอย่างมหาศาล
หากเราหันไปพึ่งพาบริการ Cloud AI อย่าง ChatGPT หรือ Claude ในการอัปโหลดไฟล์เพื่อสรุปข้อมูล นอกจากจะมีข้อจำกัดเรื่องขนาดไฟล์และค่าใช้จ่ายรายเดือนแล้ว สิ่งสำคัญที่สุดที่ต้องแลกไปคือ ความเป็นส่วนตัวของข้อมูล (Data Privacy) โดยเฉพาะอย่างยิ่งหากงานวิจัยที่คุณกำลังอ่านอยู่นั้นเป็นงานดราฟต์ที่ยังไม่ได้ตีพิมพ์ หรือเอกสารลับทางธุรกิจขององค์กร
ในบทความนี้ เราจะมาสร้าง AI Agent ส่วนตัว บนเครื่องคอมพิวเตอร์ของคุณเอง 100% โดยใช้ภาษา Python และ Ollama เพื่อทำหน้าที่คอยตรวจสอบโฟลเดอร์เปเปอร์ ดึงเนื้อหาจาก PDF ออกมาสกัดใจความสำคัญอย่างหัวข้อ วัตถุประสงค์ วิธีการวิจัย ผลลัพธ์ และข้อจำกัด แล้วจัดทำเป็นโน้ตสรุปวรรณกรรม (Literature Review) ส่งตรงเข้าสู่สมองส่วนที่สองอย่าง Obsidian โดยอัตโนมัติ
โครงสร้างการทำงานของ Research Assistant Agent
ระบบอัตโนมัตินี้มีกระบวนการไหลของข้อมูลที่เรียบง่ายแต่ทรงพลัง ดังนี้:
- Monitor & Scan: Agent ทำการตรวจสอบโฟลเดอร์เก็บไฟล์ PDF ในเครื่อง เพื่อค้นหาไฟล์เปเปอร์ใหม่ที่ยังไม่เคยผ่านการประมวลผล
- Smart Extraction: ดึงข้อความจากหน้าแรกๆ (Abstract/Intro) และหน้าท้ายๆ (Conclusion) ของ PDF เพื่อประหยัด Token และไม่ให้เกิน Context Window ของ Local LLM
- LLM Synthesis: ส่งข้อมูลให้ Ollama ประมวลผลโดยใช้โมเดลภาษาขนาดใหญ่ที่รันในเครื่อง (เช่น
gemma2หรือllama3) เพื่อสกัดประเด็นและสรุปตามหัวข้อที่กำหนด - Obsidian Integration: เซฟผลลัพธ์เป็นไฟล์ Markdown (.md) ลงใน Obsidian Vault โดยตรง พร้อมแท็กหัวข้อและแนบลิงก์เชื่อมโยงกลับไปยัง PDF ต้นฉบับเพื่อความสะดวกในการย้อนอ่าน
สิ่งที่ต้องเตรียมก่อนเริ่มสร้าง
โปรดตรวจสอบให้แน่ใจว่าเครื่องคอมพิวเตอร์ของคุณได้รับการติดตั้งสิ่งเหล่านี้เรียบร้อยแล้ว:
- Python 3: สำหรับรันสคริปต์และควบคุมขั้นตอนทั้งหมด
- Ollama: ตัวรัน LLM ออฟไลน์ภายในเครื่อง (ดาวน์โหลดได้จาก ollama.com)
- Obsidian: แอปพลิเคชันจดโน้ตแนว Second Brain สำหรับจัดเก็บผลสรุป
สำหรับงานสรุปเปเปอร์วิชาการซึ่งมักมีคำศัพท์เทคนิคและภาษาอังกฤษปนอยู่มาก เราแนะนำให้ดาวน์โหลดโมเดลที่มีความสามารถในการเข้าใจภาษาผสมผสานได้เป็นอย่างดี เช่น gemma2 หรือ llama3 โดยรันคำสั่งใน Terminal:
ollama pull gemma2
ถัดมา ให้ติดตั้งแพ็กเกจสำหรับอ่านและดึงข้อความจากไฟล์ PDF ใน Python:
pip install pypdf
เขียนสคริปต์ Python ควบคุม AI Agent
ให้สร้างไฟล์สคริปต์ Python ชื่อ research_agent.py ขึ้นมา แล้วใส่โค้ดด้านล่างนี้ลงไป โดยอย่าลืมแก้ไข Path ของโฟลเดอร์ PDF และตำแหน่ง Obsidian Vault ให้ตรงกับเครื่องของคุณ:
import os
import json
import urllib.request
from pypdf import PdfReader
# ================= ตั้งค่าระบบ (Configuration) =================
PDF_FOLDER = "/home/linn/research/pdfs" # โฟลเดอร์ที่เก็บไฟล์ PDF วิจัย
OBSIDIAN_VAULT_PATH = "/home/linn/notes/Research" # Path สำหรับเก็บโน้ตสรุปใน Obsidian
LLM_MODEL = "gemma2" # โมเดล Ollama ที่ต้องการใช้
# =============================================================
def extract_pdf_context(pdf_path):
try:
reader = PdfReader(pdf_path)
num_pages = len(reader.pages)
pages_to_read = []
if num_pages <= 5:
pages_to_read = list(range(num_pages))
else:
# ดึงเฉพาะ 3 หน้าแรก (Abstract/Intro) และ 2 หน้าสุดท้าย (Conclusion/Discussion)
pages_to_read = [0, 1, 2] + [num_pages - 2, num_pages - 1]
text_content = []
for page_num in pages_to_read:
if page_num < num_pages:
page = reader.pages[page_num]
text = page.extract_text()
if text:
text_content.append(text)
return "\n--- PAGE BREAK ---\n".join(text_content)
except Exception as e:
print(f"เกิดข้อผิดพลาดในการอ่านไฟล์ PDF: {e}")
return ""
def process_paper_with_ollama(text, pdf_filename):
prompt = f"""
คุณคือ AI Research Assistant ผู้เชี่ยวชาญด้านการวิเคราะห์และสรุปวรรณกรรมทางวิชาการ (Literature Review)
จงวิเคราะห์ข้อความจากเปเปอร์วิจัยต่อไปนี้ และสรุปข้อมูลออกมาเป็นภาษาไทยตามโครงสร้างที่กำหนดอย่างเคร่งครัด:
[เป้าหมายการสรุป]
1. ดึงข้อมูล Metadata ที่สำคัญ (ชื่อเรื่อง, ผู้แต่ง, ปีที่พิมพ์)
2. สรุปวัตถุประสงค์หลักของการวิจัย (Research Objective)
3. อธิบายระเบียบวิธีวิจัย (Methodology) อย่างกระชับ
4. สรุปผลลัพธ์สำคัญ (Key Findings) เป็นข้อๆ
5. อธิบายข้อจำกัดของงานวิจัยหรือแนวทางในอนาคต (Limitations & Future Work)
6. กำหนดคำสำคัญ (Keywords) 3-5 คำเพื่อสร้างเป็น tag
[ข้อความจากเปเปอร์]
{text[:12000]}
[รูปแบบรายงาน (Markdown Output Format)]
---
title: "[ชื่อเปเปอร์ภาษาอังกฤษ/ไทย]"
authors: "[ชื่อผู้แต่งทุกคน]"
year: "[ปีที่พิมพ์ ค.ศ.]"
tags: ["Research", "[keyword1]", "[keyword2]"]
---
# Literature Review: [ชื่อเปเปอร์]
### 📌 ข้อมูลสังเขป
- **ผู้แต่ง:** [ชื่อผู้แต่ง]
- **ปีที่เผยแพร่:** [ปี]
- **ลิงก์อ้างอิงไฟล์:** [[{pdf_filename}]]
### 🎯 วัตถุประสงค์การวิจัย (Research Objective)
[เขียนอธิบายสั้นๆ เกี่ยวกับเป้าหมายหลักและปัญหาที่งานวิจัยต้องการแก้ไข]
### 🛠️ ระเบียบวิธีวิจัย (Methodology)
[ขั้นตอนหรือกระบวนการวิจัย เช่น วิธีการเก็บข้อมูล, เครื่องมือ, การวิเคราะห์ข้อมูล]
### 📊 ผลลัพธ์และข้อค้นพบสำคัญ (Key Findings)
- [ผลลัพธ์ข้อที่ 1]
- [ผลลัพธ์ข้อที่ 2]
- [ผลลัพธ์ข้อที่ 3]
### ⚠️ ข้อจำกัดและงานในอนาคต (Limitations & Future Work)
- [ข้อจำกัดหรือสิ่งที่ยังขาดอยู่]
- [แนวทางการพัฒนาต่อยอด]
"""
url = "http://localhost:11434/api/generate"
data = {
"model": LLM_MODEL,
"prompt": prompt,
"stream": False,
"options": {
"num_ctx": 16384 # กำหนดขนาด Context ให้กว้างขึ้นเพื่อรองรับบทความยาว
}
}
req = urllib.request.Request(
url,
data=json.dumps(data).encode('utf-8'),
headers={'Content-Type': 'application/json'}
)
try:
with urllib.request.urlopen(req) as response:
result = json.loads(response.read().decode('utf-8'))
return result.get('response', '')
except Exception as e:
print(f"เกิดข้อผิดพลาดในการเชื่อมต่อกับ Ollama: {e}")
return ""
def main():
if not os.path.exists(PDF_FOLDER):
os.makedirs(PDF_FOLDER)
print(f"สร้างโฟลเดอร์สำหรับใส่ PDF แล้วที่: {PDF_FOLDER} กรุณานำไฟล์ PDF มาใส่")
return
if not os.path.exists(OBSIDIAN_VAULT_PATH):
os.makedirs(OBSIDIAN_VAULT_PATH)
pdf_files = [f for f in os.listdir(PDF_FOLDER) if f.lower().endswith('.pdf')]
if not pdf_files:
print("ไม่พบไฟล์ PDF ในโฟลเดอร์สำหรับประมวลผล")
return
for pdf_file in pdf_files:
pdf_path = os.path.join(PDF_FOLDER, pdf_file)
# ตั้งชื่อโน้ตสรุปตามชื่อไฟล์เดิมและเปลี่ยนนามสกุลเป็น .md
note_name = os.path.splitext(pdf_file)[0] + " - Summary.md"
note_path = os.path.join(OBSIDIAN_VAULT_PATH, note_name)
# ปฏิบัติตามหลักการ Idempotence ป้องกันการประมวลผลซ้ำ
if os.path.exists(note_path):
print(f"ข้ามไฟล์ {pdf_file} (ตรวจพบไฟล์สรุปแล้ว)")
continue
print(f"\nกำลังจัดการไฟล์: {pdf_file}")
# 1. ดึงข้อความจาก PDF
pdf_text = extract_pdf_context(pdf_path)
if not pdf_text:
print(f"ไม่สามารถอ่านข้อความจาก {pdf_file} ได้")
continue
# 2. ส่งให้ Ollama สรุป
print("กำลังส่งประมวลผลผ่าน Ollama...")
summary = process_paper_with_ollama(pdf_text, pdf_file)
if summary:
# 3. บันทึกลง Obsidian Vault
with open(note_path, 'w', encoding='utf-8') as f:
f.write(summary)
print(f"สร้างโน้ตสรุปเรียบร้อยแล้ว: {note_name}")
else:
print(f"การสรุปข้อมูลล้มเหลวสำหรับ: {pdf_file}")
if __name__ == "__main__":
main()
เทคนิคการสกัดข้อมูลอัจฉริยะ (Smart Context Extraction)
หนึ่งในอุปสรรคสำคัญของการรันโมเดลภาษาขนาดใหญ่ (LLM) ในเครื่องตัวเอง คือข้อจำกัดเรื่องหน่วยความจำและ Context Window Limit ไฟล์ PDF วิจัยโดยทั่วไปมักมีความยาว 10-30 หน้า ซึ่งหากเราส่งเนื้อหาทั้งหมดเข้าไปพร้อมกัน อาจทำให้เครื่องคอมพิวเตอร์ค้าง ประมวลผลช้ามาก หรือชนขีดจำกัดจำนวนคำจนข้อมูลปลายทางสูญหาย
ความเจ๋งของ Agent ตัวนี้อยู่ที่ฟังก์ชัน extract_pdf_context() ซึ่งจะใช้วิธี สุ่มเลือกหน้าสำคัญแบบจำเพาะเจาะจง โดยจะอ่านเฉพาะ 3 หน้าแรก และ 2 หน้าสุดท้ายของเอกสาร ซึ่งเป็นตำแหน่งที่บรรจุ Abstract (บทคัดย่อ), Introduction (บทนำ), Conclusion (บทสรุป) และ Discussion (บทอภิปรายผล) เอาไว้เกือบทั้งหมด วิธีการนี้ช่วยลดจำนวนข้อความที่จะส่งให้ LLM ได้ถึง 70-80% ทำให้การประมวลผลผ่านโมเดล Local รวดเร็วและแม่นยำขึ้นอย่างมหาศาล
[!TIP] สำหรับเครื่องที่มีการ์ดจอแยกที่มี VRAM สูง (เช่น 8GB ขึ้นไป) คุณสามารถเพิ่มขีดจำกัดnum_ctxในการตั้งค่า Ollama ได้ถึง16384หรือ32768เพื่อให้อ่านหน้าเนื้อหากลางเรื่องได้ละเอียดยิ่งขึ้น
การออกแบบ Prompt สำหรับสร้างวรรณกรรมปริทัศน์ (Literature Review)
เพื่อให้โน้ตที่ได้จาก AI Agent สอดคล้องและเป็นระเบียบเหมาะสมกับการจัดเก็บในคลังความรู้ เราจึงบังคับโครงสร้าง (Format Enforcement) ใน Prompt อย่างชัดเจน
ผลลัพธ์ที่ AI ส่งกลับมาจะมีรูปแบบ Markdown Frontmatter ประกอบไปด้วย Title, Authors, Year และ Tags เสมอ ซึ่งสิ่งนี้จะเอื้อต่อการค้นหาและรวบรวมข้อมูลในระบบ Second Brain ของคุณได้เป็นอย่างดี นอกจากนี้ ในหัวข้อข้อมูลสังเขป ระบบยังสร้างลิงก์เชื่อมโยงไปยังไฟล์ PDF ต้นฉบับในรูปแบบ [[ชื่อไฟล์.pdf]] ให้อัตโนมัติอีกด้วย
เชื่อมโยงเข้าสู่ระบบ Second Brain
เมื่อ AI Agent บันทึกสรุปเป็นไฟล์ .md ลงในโฟลเดอร์ Obsidian Vault ของคุณแล้ว คุณจะสามารถปลดล็อกพลังของ Obsidian ในการจัดการและเชื่อมโยงความรู้ต่อได้อย่างง่ายดาย:
- การสร้างความเชื่อมโยง (Bidirectional Links): หากคุณเก็บไฟล์ PDF ต้นฉบับไว้ในโฟลเดอร์เดียวกับคลังโน้ต Obsidian ลิงก์
[[ชื่อไฟล์.pdf]]ที่ AI สร้างให้จะกลายเป็นลิงก์ที่สามารถคลิกเพื่อเปิดไฟล์ PDF ขึ้นมาอ่านคู่กับโน้ตสรุปได้ทันที - การกรองข้อมูลด้วย Dataview: คุณสามารถสร้างแดชบอร์ดรวมงานวิจัยโดยใช้ปลั๊กอิน Dataview เพื่อดึงโน้ตสรุปทั้งหมดมาแสดงผล แยกตามปีที่ตีพิมพ์หรือหัวข้อแท็ก เช่น:
markdowndataview TABLE authors as Author, year as Year, tags as Keywords FROM #Research SORT year DESC - การสร้าง Map of Content (MOC): เชื่อมโยงโน้ตสรุปวรรณกรรมนี้เข้ากับโน้ตหลักของแต่ละโปรเจกต์งานวิจัย เพื่อวางโครงสร้างไอเดียเป็นเครือข่ายความรู้ที่จับต้องได้จริง
ด้วยแนวคิด Cognitive Automation แบบ Local-first นี้ นอกจากจะช่วยให้คุณประหยัดเวลาในการอ่านคัดกรองเปเปอร์วิจัยลงไปได้มหาศาลแล้ว ข้อมูลงานวิจัย แผนงาน และประเด็นการคิดวิเคราะห์ทั้งหมดของคุณจะยังถูกเก็บรักษาไว้ภายในฮาร์ดแวร์ของคุณเองอย่างปลอดภัย ไร้ความกังวลเรื่องการรั่วไหลของทรัพย์สินทางปัญญาอย่างสมบูรณ์แบบ