Skip to main content

การทำดัชนีฐานความรู้

ภาพรวม

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

  1. โหลดแถว knowledge_document ตาม documentId โดยข้ามไปหากไม่พบหรือถูกลบไปแล้ว
  2. parseFile ดึงไฟล์จาก URL แล้วสกัดข้อความตามชนิดของไฟล์
    • PDF ใช้ extractPDFText (ledongthuc/pdf)
    • DOCX ใช้ extractDOCXText ซึ่งอ่าน zip แล้ว parse XML
    • text และชนิดอื่น ๆ ใช้เนื้อหาตรง ๆ
  3. ChunkingService ตัดข้อความออกเป็น chunk ตามขนาดและ overlap ที่กำหนดไว้
  4. เรียก embedding API เพื่อแปลงแต่ละ chunk เป็น vector
  5. เขียนลงตาราง knowledge_chunk (เนื้อหา, vector และ metadata) พร้อม index เข้า Meilisearch
  6. 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.go
    • Service.IndexDocument(), DeleteDocument(), ReindexAll()
    • indexDocumentBody(), parseFile(), classifyFileType(), fetchFile()
    • extractPDFText(), extractDOCXText(), updateStats()
    • struct Payload ที่มีฟิลด์ Action, DocumentID, KnowledgeBaseID, LineOaID, OrganizationID
  • internal/knowledgeindex/chunking.goChunkingService สำหรับตัดข้อความเป็น chunk
  • internal/knowledgeindex/consumer.goConsumer.HandleIndexJob ทำหน้าที่ dispatch ตาม action
  • internal/meilix/meilix.go — Meilisearch client สำหรับ index, delete และ search
  • internal/embedx/embedx.go — เรียก embedding API
  • cmd/worker/main.gorunKnowledgeWorker() ซึ่งเป็น entry ของ profile knowledge-worker
  • Queue: knowledge_index (profile knowledge-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