การทำดัชนีฐานความรู้
ภาพรวม
Knowledge base คือชุดเอกสารที่ลูกค้าอัปโหลดไว้ให้ AI ใช้ตอบคำถาม (RAG) รองรับทั้งไฟล์ PDF, DOCX และข้อความธรรมดา
งานนี้เป็น worker profile เฉพาะ (SVC=knowledge-worker) ที่ทำหน้าที่แปลงเอกสารเป็น chunk
สร้าง embedding แล้วเก็บลงทั้ง PostgreSQL (ตาราง knowledge_chunk) และ Meilisearch เพื่อให้ค้นหาได้
เหตุผลที่แยกออกมาเป็น profile ของตัวเอง คือเป็นงานที่ใช้ทรัพยากรสูง (ดาวน์โหลดไฟล์ + parse + เรียก embedding API) จึงไม่ควรไปแย่ง resource กับ consumer ที่ต้องตอบผู้ใช้แบบ realtime
Business Flow
Handler จะแตกการทำงานตามค่า payload.action
index_document
- โหลดแถว
knowledge_documentตามdocumentIdโดยข้ามไปหากไม่พบหรือถูกลบไปแล้ว parseFileดึงไฟล์จาก URL แล้วสกัดข้อความตามชนิดของไฟล์- PDF ใช้
extractPDFText(ledongthuc/pdf) - DOCX ใช้
extractDOCXTextซึ่งอ่าน zip แล้ว parse XML - text และชนิดอื่น ๆ ใช้เนื้อหาตรง ๆ
- PDF ใช้
ChunkingServiceตัดข้อความออกเป็น chunk ตามขนาดและ overlap ที่กำหนดไว้- เรียก embedding API เพื่อแปลงแต่ละ chunk เป็น vector
- เขียนลงตาราง
knowledge_chunk(เนื้อหา, vector และ metadata) พร้อม index เข้า Meilisearch updateStatsอัปเดตจำนวน document และ chunk บนตารางknowledge_base
delete_document
ลบ chunk ของเอกสารนั้นออกจากทั้ง PostgreSQL และ Meilisearch แล้วอัปเดตสถิติ
reindex_all
ไล่ทุกเอกสารใน knowledge base นั้นแล้วทำ index ใหม่ทั้งชุด ใช้ในกรณีที่มีการเปลี่ยน config ของ chunking หรือ embedding
กรณีอื่น
- action ที่ไม่รู้จักจะ log warning แล้ว return nil (ack)
- payload ที่ decode ไม่ได้จะคืน
mq.Permanentเพื่อเข้า DLQ
ไฟล์และฟังก์ชันหลัก
internal/knowledgeindex/service.goService.IndexDocument(),DeleteDocument(),ReindexAll()indexDocumentBody(),parseFile(),classifyFileType(),fetchFile()extractPDFText(),extractDOCXText(),updateStats()- struct
Payloadที่มีฟิลด์Action,DocumentID,KnowledgeBaseID,LineOaID,OrganizationID
internal/knowledgeindex/chunking.go—ChunkingServiceสำหรับตัดข้อความเป็น chunkinternal/knowledgeindex/consumer.go—Consumer.HandleIndexJobทำหน้าที่ dispatch ตามactioninternal/meilix/meilix.go— Meilisearch client สำหรับ index, delete และ searchinternal/embedx/embedx.go— เรียก embedding APIcmd/worker/main.go—runKnowledgeWorker()ซึ่งเป็น entry ของ profileknowledge-worker- Queue:
knowledge_index(profileknowledge-worker)
จุดเชื่อมต่อกับ Service อื่น
- รับ job จาก: cms-api-go โดเมน knowledge base ทั้งการอัปโหลด การลบเอกสาร และการสั่ง reindex
- ตารางที่เกี่ยวข้อง:
knowledge_document(metadata และ file url),knowledge_chunk(เนื้อหาและ vector) และknowledge_base(สถิติ) - Meilisearch (
MEILISEARCH_HOST,MEILISEARCH_API_KEY) — index สำหรับ full-text และ hybrid search - Embedding API (
EMBEDDING_API_URL) — แปลงข้อความเป็น vector - HTTP ภายนอก — ดาวน์โหลดไฟล์เอกสารจาก URL ซึ่งเป็น S3 แบบ public หรือ presigned
- ผู้บริโภคผลลัพธ์: การจำแนกเจตนาข้อความด้วย AI ในโหมด
ai_knowledgeที่ค้น chunk มาให้ LLM ใช้ตอบ - งานนี้ไม่มีการเรียก LINE API