Tech Blog

จำแนกบันทึกส่วนตัวออกเป็น 5 หมวดหมู่โดยอัตโนมัติด้วย LLM (Ollama) - การออกแบบไปป์ไลน์กลั่นและข้อผิดพลาด

Ollama LLM RAG ChromaDB Python 自動分類 AIアシスタント

🔗 สารบัญซีรีส์: บทความนี้เป็น ฉบับการใช้งาน (3) ของซีรีส์ บันทึกการปฏิบัติงานของผู้ช่วย AI - บันทึกการปฏิบัติสำหรับการเพิ่มรหัส Copilot / Claude ในฐานะคู่หูของคุณ

สิ่งที่คุณสามารถเรียนรู้ได้จากบทความนี้

  • เมื่อใช้งาน RAG ส่วนตัว “ฉันเขียนบันทึก แต่ฉันลืมเลื่อนระดับให้เป็นบทเรียนที่ได้รับ” โครงสร้างปัญหา
  • กลไกของ การจำแนกอัตโนมัติ 5 หมวดหมู่ ด้วย LLM (เฉพาะภาษาญี่ปุ่น Ollama / Llama 3)
  • หากดำเนินการอย่างไม่ระมัดระวัง อุบัติเหตุ เช่น “ฉันขอโทษ” จะถูกจัดว่าเป็นบทเรียน จะเกิดขึ้น และจะรับมืออย่างไร
  • วิธีใช้โหมด JSON และการออกแบบทางเลือกหากยังคงล้มเหลว
  • ป้องกันไฟล์สถานะการประมวลผลซ้ำ + การตรวจจับส่วนต่างใน mtime
  • ผลกระทบและข้อควรทราบหลังจากใช้งานครบ 1 เดือน

กลุ่มเป้าหมาย

  • ผู้ที่ใช้งาน RAG ส่วนบุคคลและกำลังประสบกับ “บันทึกที่ยังไม่เสร็จ” เพิ่มขึ้น
  • ผู้ที่ต้องการรวม LLM ท้องถิ่น (Ollama) เข้ากับ การประมวลผลเป็นชุดในทางปฏิบัติ
  • ผู้ที่ต้องการทราบความรู้วิธีการ ลดการจัดประเภทที่ไม่ถูกต้องโดยไม่คาดคิด ในงานการจัดประเภท LLM

สภาพแวดล้อมการทำงาน

รายการเวอร์ชั่น
หลาม3.13 (venv)
โอลามาเซิร์ฟเวอร์เริ่มต้นแล้ว (localhost:11434)
LLM สำหรับการจำแนกประเภทmicroai/suzume-llama3 (ลามะ 3 เฉพาะภาษาญี่ปุ่น)
การฝังnomic-embed-text (สำหรับอินพุต ChromaDB)
ChromaDBโหมดคงอยู่

1. บทนำ — ปัญหา “เขียนบันทึกต่อไป”

เมื่อใช้งาน RAG ส่วนบุคคล ขั้นตอนแรกคือการเพิ่มจำนวนอินพุต “วัสดุ” ลงใน ChromaDB ฉันใช้คำสั่ง rag note "..." เพื่อสร้างระบบที่ช่วยให้ฉันสามารถจดบันทึกสั้นๆ ได้ทันทีที่นึกถึงบางสิ่งบางอย่าง

หลังจากนั้นไม่กี่สัปดาห์ data/diary/ ก็สะสม บันทึกหลายร้อยรายการ

# 30-04-2026

## 04:09
บทเรียนที่ได้รับสำหรับ Qiita 429: ค่าของส่วนหัวการรีเซ็ตอัตราเป็นคำตอบที่ถูกต้องเท่านั้น
อย่าปฏิบัติตามสมมติฐานของ Gemini หรือ LLM (รอ 24 ชั่วโมง ฯลฯ)

## 12:30
30-04-2026 ใช้ฟังก์ชันการกลั่น my-rag-brain
ความเป็นมา: เดิมทีฉันเขียนบันทึกทั้งหมดของฉันไว้ในบันทึก (ไดอารี่/)
ปฏิบัติการด้วยตนเองเพื่อส่งเสริมเป็นบทเรียน/ความคิด/ความรู้/โปรไฟล์...## 15:51
มาตรการรับมือต่อการกลั่นกรองประเภทที่ไม่ถูกต้อง: ปัญหาจดหมายขอโทษของ AI และคู่มือการใช้งานที่ถูกจัดประเภทผิดเป็นบทเรียนจะได้รับการแก้ไขในสองขั้นตอน...

หากคุณดึง rag search "Qiita Rate-Reset" ในการค้นหาเวกเตอร์ คุณจะพบเนื้อหาของบันทึกย่อ แต่มีบางอย่างขาดหายไป.

สิ่งที่ขาดหายไปคือ การจัดหมวดหมู่ เช่น สิ่งนี้ควรถูกใช้เป็นบทเรียนเพื่อป้องกันการเกิดซ้ำ'' และ สิ่งนี้ควรบันทึกไว้เป็นแนวคิดสำหรับอนาคต” ในสถานะบันทึกย่อ ผลการค้นหาจะผสมกันเท่าๆ กัน ฉันต้องการแยกความแตกต่างระหว่าง “บทเรียนที่ฉันเขียนในขณะนั้น” และ “แนวคิดที่ฉันเขียนในขณะนั้น”

ตอนแรกฉันพยายามทำ การจัดหมวดหมู่แบบแมนนวล data/lessons/ data/ideas/ และอัปเกรดในขณะที่อ่านบันทึก

**ฉันยอมแพ้หลังจากผ่านไป 3 วัน ** อย่าลืมการทำงานแบบแมนนวลเสมอไป ฉันลืมแม้กระทั่งหลังจากที่ฉันเขียนมัน

นั่นคือสิ่งที่ฉันคิดว่า

**บางทีนี่ควรจัดเป็น LLM **

Ollama กำลังทำงานในพื้นที่ ซีรีส์ Llama 3 ดูเหมือนจะสามารถแยกแยะโน้ตภาษาญี่ปุ่นได้ อ่านบันทึกของเดือนหนึ่งพร้อมกันและจัดเรียงเป็น 5 หมวดหมู่โดยอัตโนมัติ ฉันตัดสินใจสร้างชุดงาน

บทความนี้เกี่ยวกับการนำไปใช้งานและ อุบัติเหตุที่เกิดขึ้นตามธรรมชาติเมื่อทำอย่างเลอะเทอะ


2. คำจำกัดความของ 5 หมวดหมู่

ขั้นแรก ตัดสินใจว่าคุณต้องการจัดหมวดหมู่ใด

หมวดหมู่สิ่งที่ต้องรวมตัวอย่าง
lessonกฎเฉพาะเพื่อป้องกันการเกิดซ้ำที่ควรทำเช่นนี้ในครั้งต่อไป”ส่วนหัวการรีเซ็ตอัตราเป็นคำตอบที่ถูกต้องเท่านั้น”
ideaแนวคิด/แนวความคิดที่คุณอยากจะนำไปใช้/ทำให้เป็นจริงในอนาคต“แปลง RAG ส่วนบุคคลเป็น MCP และเชื่อมต่อกับ Copilot”
knowledgeข้อกำหนดทางเทคนิค/ข้อกำหนด API/ข้อเท็จจริงเกี่ยวกับวัตถุประสงค์”nomic-embed-text มี 768 มิติ”
profileค่านิยม/ความเชื่อ/แรงจูงใจ/ความหลงใหล“จัดลำดับความสำคัญความสามารถในการอ่านของมนุษย์มากกว่าการเพิ่มประสิทธิภาพเครื่องจักร”
conclusionการตัดสินมาถึงโดยการอภิปรายและการพิจารณา”Qiita = ฉบับสรุป Astro = ฉบับสมบูรณ์”
noneไม่มีข้อใดข้างต้น (บันทึกการทำงาน, คำขอโทษ, คู่มือขั้นตอนการปฏิบัติงาน)“ขออภัย เราจะแก้ไขให้ถูกต้อง”

none ได้รับการจัดทำขึ้นอย่างเป็นอิสระเพื่อเป็นมาตรการตอบโต้สำหรับ “เหตุการณ์บทเรียนการขอโทษ” ซึ่งฉันจะเขียนเกี่ยวกับเรื่องนี้ในภายหลัง


3. การใช้งานที่ไร้เดียงสาและอุบัติเหตุทันที

ตอนแรกฉันโยนมันอย่างเลอะเทอะไปที่ LLM```หลาม พรอมต์ = f""" โปรดจำแนกข้อความด้านล่างเป็นบทเรียน / แนวคิด / ความรู้ / โปรไฟล์ / บทสรุป

ข้อความ: {ข้อความ}

หมวดหมู่: """ การตอบสนอง = ollama.chat(model=“llama3.2:3b”, ข้อความ=[…])


ตอนนี้มันใช้งานได้แล้ว ฉันทดสอบสินค้าประมาณ 30 รายการและได้รับ **การจัดประเภทเช่นนั้น** ฉันยินดีที่จะส่งต่อทุกอย่าง

เมื่อฉันตรวจสอบผลลัพธ์ ฉันพบจดหมายขอโทษจำนวนมากในไดเร็กทอรี **`lessons/`

```มาร์กดาวน์
## 22:43 [กลั่นอัตโนมัติ]

ขออภัย ระวังครั้งหน้าจะได้ไม่ทำผิดซ้ำอีก

**ข้อความต้นฉบับ (ข้อความที่ตัดตอนมา)**:
ขออภัย การดำเนินการก่อนหน้านี้ไม่ถูกต้อง

---

LLM อาจให้เหตุผล:

“อย่าทำผิดแบบเดิมอีก” “คราวหน้าฉันจะระวังให้มากขึ้น” = คำพูดที่ฟังดูเหมือนบทเรียน = บทเรียน!

แน่นอน อ่านแบบนั้น แต่นี่คือ จดหมายขอโทษ ทันทีหลังจากเกิดอุบัติเหตุ AI ไม่ใช่บทเรียนนั่นเอง บทเรียนอยู่ที่อื่นในประโยคเช่น “ส่วนหัวการรีเซ็ตอัตราเป็นคำตอบที่ถูกต้องเท่านั้น” ที่ฉันเขียนด้วยมือ

การจัดประเภทที่ไม่ถูกต้องอื่นๆ ที่พบบ่อย ได้แก่:

  • “กรุณาวางข้อมูลต่อไปนี้ตามที่อยู่ใน Gemini Ultra” → จัดเป็นแนวคิด (ตามคำแนะนำในการใช้งานจริง)
  • “ถูกต้อง” → จัดเป็นข้อสรุป (จริง ๆ แล้วตกลง)
  • ประโยคสั้นๆ เพียง 3 บรรทัด → บังคับจัดเป็นบทเรียน (จริงๆ แล้วไม่มีพื้นฐานในการตัดสิน)

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


4. มาตรการตอบโต้ — บอก LLM ว่าพวกเขาสามารถเลือก “ไม่มี”

เมื่อฉันแตกปัญหามันก็เป็นแบบนี้

4.1 LLM ไม่เต็มใจที่จะเลือก “ไม่เกี่ยวข้อง”

LLM มักไม่ได้รับการฝึกอบรมให้ตัดสินข้อมูลที่ไม่ใช่ตัวเลือกว่า “ไม่เกี่ยวข้อง” มีแนวโน้มที่จะบังคับตัวเลือกเดียวออกจากตัวเลือกที่กำหนด

มาตรการรับมือ: ระบุ none เป็นตัวเลือก + เขียน “ตัวอย่างที่คุณสามารถเลือกไม่มีได้” ในข้อความแจ้ง

CLASSIFY_PROMPT = """\
โปรดอ่านรายการหมายเหตุด้านล่างและจัดไว้ในหมวดหมู่ที่เหมาะสมที่สุดหมวดหมู่และเกณฑ์การคัดเลือก:
- บทเรียน: มีกฎเฉพาะเพื่อป้องกันการเกิดซ้ำ เช่น สิ่งที่คุณควรทำในครั้งต่อไป
- แนวคิด: มีการเขียนแนวคิดหรือแนวคิดที่คุณต้องการนำไปใช้หรือตระหนักในอนาคต
- ความรู้: มีการเขียนข้อเท็จจริงเชิงวัตถุประสงค์เกี่ยวกับข้อกำหนดทางเทคนิค ข้อกำหนด API และเครื่องมือ
- โปรไฟล์: อธิบายค่านิยม ความเชื่อ แรงจูงใจ และความชอบของผู้เขียน
- บทสรุป: มีการเขียนแหล่งที่มา ฉันทามติ และการออกแบบผ่านการอภิปรายและการพิจารณา
- ไม่มี: ไม่ตรงกับข้อใดเลยข้างต้น (บันทึกการทำงาน จดหมายขอโทษ ขั้นตอนการปฏิบัติงาน การแลกเปลี่ยนการสนทนา ฯลฯ)

ตัวอย่างการเลือกไม่มี:
- คำขอโทษและข้อตกลงเช่น "ฉันขอโทษ" และ "ถูกต้อง"
- คำแนะนำ/ขั้นตอนการใช้งาน เช่น "โปรดดำเนินการดังต่อไปนี้"
- คำอธิบายประวัติการทำงานง่ายๆ (บันทึกสิ่งที่ทำ)
- แฟรกเมนต์สั้นเกินกว่าจะอ่านกฎหรือข้อมูลเชิงลึกได้

รายการหมายเหตุ:
---
{ข้อความ}
---

กระบวนการคิด:
1. รายการนี้คือ "สนามกีฬา
2. พระเจ้าใช่ประเด็นคืออะไร
3. หากไม่รวม: เลือกไม่มี

เอาต์พุต (JSON เท่านั้น ไม่ต้องบล็อกโค้ดหรือข้อความเพิ่มเติม):
{{"reasoning": "หนึ่งประโยคว่าทำไมคุณถึงเลือกหมวดหมู่นั้น", "type": "lesson|idea|knowledge|profile|conclusion|none", "summary": "สรุปในประโยคเดียว (ว่างเปล่าหากไม่มี)"}}
"""

สามคะแนน:

  1. ระบุตัวอย่างการเลือก none 3 ถึง 4 ตัวอย่าง — แสดงตัวอย่างคำขอโทษ คำแนะนำ และประโยคสั้นๆ เฉพาะของ LLM
  2. อธิบายกระบวนการคิดของคุณ — ถามก่อนว่า “มีข้อมูลเชิงลึกใดบ้างที่ฉันสามารถใช้ได้ในครั้งต่อไป”
  3. reasoning รวมอยู่ใน JSON — ป้องกันการจำแนกประเภทได้ง่ายโดยให้ LLM เขียนเหตุผลในการตัดสินใจเอง

เพียงอย่างเดียวนี้สามารถลดการจำแนกประเภทที่ไม่ถูกต้องได้มากกว่า 80%

4.2 กรองล่วงหน้าก่อนส่งเข้า LLM

สำหรับรูปแบบที่ยังคงอยู่ ฉันได้เพิ่มตัวกรองล่วงหน้าในฝั่ง Python

def classify_entry (ข้อความ: str) -> dict:
    ปล้น = text.strip()

    # ตัวกรอง 1: หากแฟรกเมนต์สั้นเกินไป ไม่มีการถามคำถาม ไม่มีเลย
    ถ้า len (เปลื้องผ้า) <50:
        กลับ {"ประเภท": "ไม่มี", "สรุป": ""}# ตัวกรอง 2: รูปแบบการเปิดทั่วไปของการขอโทษ ข้อตกลง และการแนะนำขั้นตอน
    apology_patterns = ("ขออภัย", "ถูกต้อง", "อย่างที่คุณพูด", "ตามที่คุณชี้ให้เห็น", "ดำเนินการต่อด้านล่าง")
    หากมี (stripped.startswith(p) สำหรับ p ใน apology_patterns):
        กลับ {"ประเภท": "ไม่มี", "สรุป": ""}

    # เมื่อคุณมาถึงจุดนี้แล้ว ให้ส่งไปที่ LLM
    prompt = CLASSIFY_PROMPT.format (ข้อความ = ข้อความ [: 600])
    # ...

น้อยกว่า 50 ตัวอักษรและจุดเริ่มต้นของรูปแบบคำขอโทษ เล่นก่อนติดต่อ LLM ช่วยลดต้นทุนในการโทรหา Ollama และลดแหล่งที่มาหลักของการจัดประเภทที่ไม่ถูกต้อง

4.3 ใช้โหมด JSON + regex ทางเลือก

Ollama (และโมเดลที่ใช้ Llama อยู่เบื้องหลัง) มีความแตกต่างระหว่างแต่ละบุคคลตรงที่แม้ว่าคุณจะขอให้พวกเขา “ส่งออกเฉพาะ JSON” ทันที พวกเขาจะขึ้นต้นด้วย “ใช่ ฉันเข้าใจ” หรือล้อมรอบด้วยบล็อกโค้ด

วิธีแก้ไข: บังคับใช้โหมด JSON ด้วยตัวเลือก format="json" ของ Ollama

ตอบกลับ = ollama.chat(
    รุ่น=LLM_MODEL,
    ข้อความ=[{"role": "ผู้ใช้", "เนื้อหา": prompt}],
    options={"temperature": 0.1}, # ระงับความผันผวน
    format="json", # โหมด JSON: ส่งออก JSON ที่ถูกต้องเสมอ
)

ถึงกระนั้นก็ตาม บางครั้งมันก็ล้มเหลว ดังนั้นฉันจะรวมทางเลือกสำรองไว้ด้วย

raw = resp["ข้อความ"]["เนื้อหา"].strip()
ลอง:
    ผลลัพธ์ = json.loads (ดิบ)
ยกเว้น json.JSONDecodeError:
    # ทางเลือกสำรอง: วาล์วนิรภัยในกรณี format="json" ล้มเหลวในบางกรณี
    m = re.search(r"\{[^{}]+\}", raw, re.DOTALL)
    ถ้าไม่ใช่ม:
        กลับ {"ประเภท": "ไม่มี", "สรุป": ""}
    ผลลัพธ์ = json.loads(m.group())
````**อย่าคาดหวังความสมบูรณ์แบบ**. หากสมมติฐานคือสามารถล้มเหลวได้ ก็สามารถบันทึกได้ด้วยทางเลือกสำรอง ฉันรู้สึกว่านี่เป็นกฎทองเมื่อใช้ LLM ในชุดงานจริง

---

## 5. กระบวนการโปรโมต — เพิ่มลงในไฟล์หมวดหมู่ + ใส่ ChromaDB

เมื่อสรุปผลการจำแนกประเภทแล้ว ให้เพิ่มลงใน `data/<カテゴリ>/YYYY-MM-DD.md` ที่เกี่ยวข้อง

```หลาม
TYPE_DIRS = {
    "ความคิด": DATA_DIR / "ความคิด",
    "บทเรียน": DATA_DIR / "บทเรียน",
    "ความรู้": DATA_DIR / "ความรู้",
    "โปรไฟล์": DATA_DIR / "โปรไฟล์",
    "ข้อสรุป": DATA_DIR / "ข้อสรุป",
}

def Promo_entry (ประเภทรายการ, time_str, สรุป, ต้นฉบับ, source_date, dry_run):
    target_dir = TYPE_DIRS.get (ประเภทรายการ)
    ถ้าไม่ใช่ target_dir:
        return # none ไม่ได้สร้างไฟล์

    target_dir.mkdir (ผู้ปกครอง = True, มีอยู่_ok = True)
    target_file = target_dir / f"{source_date}.md"

    ถ้าไม่ใช่ target_file.exists():
        target_file.write_text(
            f"# {source_date} {LABEL_BY_TYPE[entry_type]} (การแยกข้อมูลอัตโนมัติ)\n\n",
            การเข้ารหัส = "utf-8"
        )

    บล็อก = ฉ"""
## {time_str} [กลั่นอัตโนมัติ]

{สรุป}

**ข้อความต้นฉบับ (ข้อความที่ตัดตอนมา)**:
{ต้นฉบับ[:400]}

---
"""
    ด้วย target_file.open("a", encoding="utf-8") เป็น f:
        f.write(บล็อก)

    # ป้อนข้อมูลไปยัง ChromaDB ในเวลาเดียวกัน
    ingest_file(str(target_file), entry_type, tags=f"{source_date},กลั่นอัตโนมัติ")

แนวคิดสามประการ:1. เลื่อนระดับเป็นไฟล์แยกต่างหากจากบันทึกต้นฉบับ — ปล่อยให้บันทึกต้นฉบับไม่ถูกแตะต้อง (เพื่อให้มนุษย์สามารถตรวจสอบได้ในภายหลัง) 2. บันทึกทั้งบทสรุป + ข้อความต้นฉบับที่ตัดตอนมา — แม้ว่า LLM จะทำผิดพลาดในการสรุป แต่ก็สามารถระบุได้โดยการดูจากข้อความต้นฉบับ 3. Inject into ChromaDB พร้อมๆ กับโปรโมชั่น — ใส่ auto-distilled ในแท็กเพื่อจำกัด “จำแนกอัตโนมัติ” ให้แคบลงในภายหลัง


6. การป้องกันการประมวลผลซ้ำ — ไฟล์สถานะ + การตรวจสอบเวลา

การกลั่นเป็น กระบวนการที่หนัก โดยจะสอบถาม Ollama ครั้งละหนึ่งรายการ ดังนั้นจึงต้องใช้เวลาหลายสิบวินาทีถึงหลายนาทีสำหรับโน้ต 100 รายการ

เนื่องจากการประมวลผลไฟล์ทั้งหมดซ้ำในแต่ละครั้งจะเป็นการสิ้นเปลือง เราจึงเพิ่มกลไกในการบันทึกไฟล์ที่ประมวลผลในสถานะ

STATE_FILE = DATA_DIR / ".distill_state.json"

def load_state() -> dict:
    ถ้า STATE_FILE.exists():
        กลับ json.loads(STATE_FILE.read_text(encoding="utf-8"))
    กลับ {"ประมวลผล": {}}

def save_state (สถานะ: dict):
    STATE_FILE.write_text(json.dumps(state, Sure_ascii=False, indent=2), encoding="utf-8")

{ファイル名: 処理時の mtime} ถูกบันทึกไว้ใน processed ครั้งถัดไปที่ดำเนินการจะถูกกำหนดดังนี้:

สำหรับ md_path ใน diary_files:
    file_key = md_path.name
    mtime = datetime.fromtimestamp(md_path.stat().st_mtime).isoformat()

    # ดำเนินการแล้วและไฟล์ไม่ได้รับการอัพเดต → ข้าม
    หากไม่ใช่ all_mode และ file_key ในการประมวลผลและประมวลผล [file_key] >= mtime:
        ดำเนินการต่อ

    # ใหม่หรืออัปเดต → กระบวนการ
    ...

สิ่งสำคัญคือต้องตรวจสอบไม่เพียงแต่ชื่อไฟล์เท่านั้น แต่ยังตรวจสอบเวลาทำงานด้วย หากมีการเพิ่มรายการบันทึกใหม่ลงในไฟล์เดียวกัน mtime จะได้รับการอัปเดตและจะถูกประมวลผลใหม่

คุณยังสามารถบังคับให้ประมวลผลใหม่ทั้งหมดได้โดยใช้แฟล็ก --all:``` ทุบตี rag distill # ยังไม่แปรรูปเท่านั้น rag distill —all # ประมวลผลใหม่ทั้งหมด (ละเว้นสถานะ) rag distill —dry-run # แสดงเฉพาะผลการจำแนกประเภท ห้ามบันทึก


---

## 7. ลองดู — นักวิจัยอะไรบ้าง

นี่คือความประทับใจของฉันหลังจากใช้งานมาหนึ่งเดือน

### 7.1 “บันทึกย่อ” เกือบหายไป

บันทึกย่อที่เคยทิ้งไว้ในขณะที่เขียนจะถูกจัดเรียงเป็นหมวดหมู่ที่มีความหมายโดยอัตโนมัติและสามารถค้นหาได้
จำนวน `data/lessons/` ค่อยๆ เพิ่มขึ้น และตอนนี้สามารถค้นหาข้ามเฉพาะบทเรียนที่ได้เรียนรู้เท่านั้น

### 7.2 ปรับปรุงคุณภาพการค้นหา RAG

หากคุณจำกัดการค้นหาให้แคบลงโดยใช้ `type=lesson` ระบบจะส่งคืนเฉพาะ ``กฎที่เรียนรู้จากความผิดพลาดในอดีต'' เท่านั้น สิ่งนี้ใช้ได้ดีเป็นบริบทในการส่งผ่านไปยัง Copilot/Claude Code แทนที่จะค้นหารายการทั้งหมดอย่างเลอะเทอะ สามารถส่งบริบทที่แม่นยำยิ่งขึ้นไปยัง AI ได้

### 7.3 ตอนนี้ฉันมีช่วงเวลาที่ฉันคิดว่า "โอ้ ฉันควรจะบันทึกสิ่งนี้ไว้"

ผลข้างเคียง เมื่อฉันเขียนบันทึก ฉันเริ่มคิดว่า ``หากสิ่งนี้ถูกจำแนกโดยอัตโนมัติ มันจะไปที่บทเรียน'' หรือ ``นี่คือความรู้'' **การรับรู้หมวดหมู่** พัฒนาขึ้นสำหรับผู้เขียนเช่นกัน ปฏิกิริยาลูกโซ่เกิดขึ้นซึ่งทำให้คุณภาพการบันทึกดีขึ้น

---

## 8. ข้อควรทราบ/ข้อจำกัด

### 8.1 การตัดสิน LLM ไม่สมบูรณ์แบบ

หากคุณไม่ตรวจสอบ `--dry-run` บ่อยๆ **บางครั้งการจำแนกประเภทแปลกๆ อาจปะปนกัน** จำเป็นต้องดูที่ `data/lessons/` และลบรายการ `none` ที่คุณคิดว่าผิดออกด้วยตนเองทุกๆ หกเดือน

### 8.2 หมายเหตุเดียวกันอาจจัดอยู่ในหลายหมวดหมู่

"บทเรียนรีเซ็ตอัตราของ Qiita 429" เป็นทั้งบทเรียนและความรู้ การใช้งานปัจจุบันใช้ **1 รายการและ 1 หมวดหมู่** แต่การจัดหมวดหมู่แบบหลายป้ายกำกับอาจมีความเหมาะสมมากกว่า คะแนนสำหรับการปรับปรุงในอนาคต

### 8.3 การเปลี่ยนโมเดล LLM จะเปลี่ยนผลลัพธ์

ฉันใช้ `microai/suzume-llama3` และสังเกตเห็นว่าแนวโน้มการจัดหมวดหมู่เปลี่ยนไปเมื่อเปลี่ยนไปใช้โมเดลอื่น จำเป็นต้องมีการปรับแต่งสำหรับแต่ละรุ่น ก่อนเปลี่ยนควรตรวจสอบคุณภาพด้วยตัวอย่าง

### 8.4 การใช้ทรัพยากร LLM ท้องถิ่น

เนื่องจากสันนิษฐานว่า Ollama กำลังทำงานอยู่ หากคุณกำลังทำงานอย่างอื่นบนแล็ปท็อป คุณจะรู้สึกเหมือนกำลังใช้หน่วยความจำและ CPU อย่างช้าๆ หากคุณต้องการเรียกใช้งานทั้งหมดพร้อมกันเป็นชุด ก็สมเหตุสมผลที่จะเรียกใช้งานก่อนเข้านอน

---## 9. สรุป

- ทุกคนประสบปัญหา ``ฉันเขียนบันทึก แต่ฉันไม่สามารถจัดหมวดหมู่ได้'' เมื่อใช้งาน RAG ส่วนตัว สามารถแก้ไขได้ด้วย **การจำแนก LLM อัตโนมัติ**
- หากการดำเนินการนั้นไร้เดียงสา เกิดอุบัติเหตุโดยที่ `` ฉันขอโทษ '' ถือเป็นบทเรียน** **`none` หมวดหมู่ที่ชัดเจน** + **พร้อมท์กระบวนการคิดฝัง** + **ระงับด้วยตัวกรองล่วงหน้า**
- รับเอาต์พุต LLM อย่างปลอดภัยใน **โหมด JSON + regex สำรอง** ออกแบบโดยไม่คาดหวังความสมบูรณ์แบบและอาจเกิดความล้มเหลวได้
- ป้องกันการประมวลผลซ้ำด้วย **ไฟล์สถานะ + การตรวจสอบเวลา** พื้นฐานของการจัดการแบตช์ LLM จำนวนมากอย่างชาญฉลาด
- หลังจากใช้งานเป็นเวลาหนึ่งเดือน ทั้งคุณภาพของบันทึกและคุณภาพการค้นหาจะดีขึ้น **แม้แต่จิตสำนึกของผู้เขียนก็เปลี่ยนไป** ก็เป็นผลข้างเคียงที่ดี

บทความที่เกี่ยวข้อง:
- [ป้อนประวัติการสนทนาของ Copilot Chat และ Claude Code ลงใน ChromaDB และค้นหา "ตัวตนในอดีต" ของคุณ](/blog/ai-chat-transcript-ingestion) — ก่อนกลั่น จะมีกลไกในการสะสมบันทึกย่อและประวัติการสนทนาใน RAG
- [กลไกเพื่อป้องกันไม่ให้ Copilot ทำผิดพลาดซ้ำสองครั้ง — ออกแบบให้มี "หน่วยความจำของการสนทนา" ด้วย RAG + MCP] (/blog/copilot-memory-rag-mcp) — การใช้งานเซิร์ฟเวอร์ MCP โดยที่ Copilot อ้างอิงบทเรียนที่แยกออกมาโดยการกลั่นแบบเรียลไทม์

บันทึกที่คุณเขียนต่อไปจะกลายเป็นบทเรียนที่จะช่วยคุณในวันพรุ่งนี้ **ผมรู้สึกว่านั่นคือมูลค่าที่แท้จริงของท่อกลั่นครับ**

ส่งข้อความได้ตามสบาย

กรุณาส่งข้อความ หากมีคำปรึกษาด้านเทคนิค ความคิดเห็น หรือคำถาม