
Knowledge Graph × RAG คือสถาปัตยกรรมการสืบค้นและสร้างข้อมูลขั้นสูงที่รวมความสัมพันธ์เชิงโครงสร้างของ Knowledge Graph เข้ากับ Vector Search เพื่อรองรับการตอบคำถามแบบ Multi-hop ที่ซับซ้อนซึ่ง RAG แบบเดิมไม่สามารถทำได้
คำถามแบบต่อเนื่อง เช่น "A เกี่ยวข้องกับ B, B เป็นเจ้าของ C และ C ตรงตามเงื่อนไขของ D หรือไม่?" ไม่สามารถตอบได้อย่างแม่นยำด้วยความคล้ายคลึงของเวกเตอร์เพียงอย่างเดียว การใช้โครงสร้างกราฟจะช่วยให้สามารถรวบรวมบริบทที่จำเป็นโดยการไล่เรียงความสัมพันธ์ระหว่าง Entity ต่างๆ ได้
คู่มือนี้จัดทำขึ้นสำหรับวิศวกรที่มีความรู้พื้นฐานเกี่ยวกับระบบ RAG โดยจะอธิบายขั้นตอนการนำไปใช้งานอย่างละเอียด ตั้งแต่การสร้าง Graph DB, การออกแบบ Hybrid Search Pipeline ไปจนถึงการปรับแต่ง Input สำหรับ LLM โดยมีเป้าหมายสูงสุดเพื่อเพิ่มความแม่นยำในการตอบคำถามที่ซับซ้อนให้สูงขึ้นอย่างมีนัยสำคัญ
บทสรุป: การค้นหาด้วยเวกเตอร์ (Vector Search) เพียงอย่างเดียวไม่สามารถติดตามความสัมพันธ์แบบหลายขั้นตอนได้ ทำให้มีกรณีที่ไม่สามารถตอบโจทย์คำถามทางธุรกิจที่ซับซ้อนได้เพิ่มมากขึ้น
เราจะมาสรุปข้อจำกัดของ RAG แบบดั้งเดิมและปัญหาที่สามารถแก้ไขได้ด้วยการผสานรวมเข้ากับ Knowledge Graph รวมถึงทำความเข้าใจไปพร้อมกันว่าเหตุใด GraphRAG จึงได้รับความสนใจในขณะนี้ โดยเริ่มจากภูมิหลังความเป็นมาครับ
เมื่อเริ่มนำ Vector Search RAG มาใช้ หลายทีมมักคิดว่า "การเพิ่มจำนวนมิติของ Embedding จะช่วยเพิ่มความแม่นยำ" แต่ในความเป็นจริง มีรายงานจำนวนมากระบุว่า ความสามารถในการจับความเชื่อมโยงเชิงโครงสร้างของข้อมูล ส่งผลต่อคุณภาพของคำตอบมากกว่าจำนวนมิติของโมเดลเสียอีก
กลไกของ Vector Search คือการฉาย (Project) Query และเอกสารลงในพื้นที่ Embedding เดียวกัน แล้วค้นหาจุดที่ใกล้เคียงกันด้วยวิธีอย่าง Cosine Similarity แม้วิธีนี้จะมีประสิทธิภาพสูงในการ "ดึงเอกสารที่มีความหมายใกล้เคียงกัน" แต่ก็มีจุดอ่อนเชิงโครงสร้างสำหรับคำถามประเภทต่อไปนี้:
ผลที่ตามมาคือ แม้ Vector Search RAG จะสามารถส่งคืน "เศษเสี้ยวของข้อความที่น่าจะเกี่ยวข้อง" ได้ แต่ก็ไม่สามารถรักษาหรือค้นหาความสัมพันธ์ระหว่าง Entity ได้อย่างชัดเจน ข้อจำกัดนี้จะเห็นได้ชัดโดยเฉพาะในโดเมนที่มีความสัมพันธ์ระหว่าง Entity ซับซ้อน เช่น ฐานความรู้ภายในองค์กร (Internal Knowledge Base) หรือแคตตาล็อกผลิตภัณฑ์
การอนุมานแบบหลายขั้นตอน (Multi-hop reasoning) คือรูปแบบการอนุมานที่ไม่สามารถหาคำตอบได้ด้วยขั้นตอนการค้นหาเพียงขั้นตอนเดียว แต่ต้องอาศัยการสืบค้นความสัมพันธ์หลายอย่างต่อเนื่องกันจึงจะพบคำตอบ ตัวอย่างเช่น คำถามประเภท "กลุ่มผลิตภัณฑ์ของบริษัทที่ CEO ของบริษัทแม่ของบริษัท A เคยทำงานอยู่" เป็นตัวอย่างที่ชัดเจนของเรื่องนี้
โครงสร้างกราฟ (Graph structure) ช่วยแก้ปัญหานี้ด้วยกลไกดังต่อไปนี้:
การตัดสินใจเลือกใช้ให้เหมาะสมกับลักษณะของคำถามนั้นมีความสำคัญ ในกรณีที่เป็นการสอบถามข้อเท็จจริงแบบง่าย (เช่น "นิยามของ X คืออะไร") การค้นหาด้วยเวกเตอร์เพียงอย่างเดียวก็เพียงพอแล้ว แต่ในกรณีที่เป็นคำถามเกี่ยวกับความสัมพันธ์ที่ครอบคลุมหลายเอนทิตี (เช่น "จงอธิบาย Z โดยผ่านจุดร่วมของ X และ Y") การท่องไปในกราฟ (Graph traversal) ถือเป็นสิ่งที่ขาดไม่ได้
ในสถานการณ์การทำงานจริง โครงสร้างกราฟจะแสดงความได้เปรียบอย่างชัดเจน เช่น การไล่ตามแผนผังความสัมพันธ์ของผลิตภัณฑ์เพื่อระบุสาเหตุรากเหง้าของปัญหา หรือการทำแผนผังองค์กรให้อยู่ในรูปแบบกราฟเพื่อทำให้เห็นภาพเส้นทางการตัดสินใจ ในขณะที่การค้นหาด้วยเวกเตอร์ทำหน้าที่จับ "ความใกล้เคียงเชิงความหมาย" โครงสร้างกราฟจะทำหน้าที่จับ "ห่วงโซ่ของความสัมพันธ์" ซึ่งทั้งสองอย่างนี้มีบทบาทที่ส่งเสริมซึ่งกันและกัน
"ทำไมเราถึงไม่สามารถดึงข้อมูลที่เกี่ยวข้องออกมาได้ ทั้งที่มีเอกสารภายในบริษัทอยู่หลายพันฉบับ" — นักพัฒนาหลายคนคงเคยประสบกับความรู้สึกเช่นนี้ GraphRAG จึงกำลังได้รับความสนใจในฐานะสถาปัตยกรรมที่ตอบโจทย์ความท้าทายนี้โดยตรง
งานวิจัยเรื่อง "GraphRAG: Unlocking LLM discovery on narrative private data" ที่เผยแพร่โดย Microsoft Research ได้แสดงให้เห็นว่า การนำโครงสร้างกราฟ (Graph structure) มาผนวกเข้ากับ RAG ช่วยเพิ่มความแม่นยำในการสรุปภาพรวมและการตอบคำถามแบบข้ามเอกสาร ซึ่งเป็นสิ่งที่วิธีแบบเดิมทำได้ยาก โดยคลังข้อมูล (Repository) ดังกล่าวมีการอัปเดตอย่างต่อเนื่องภายใต้สัญญาอนุญาต MIT และได้เข้าสู่ขั้นตอนการใช้งานจริงแล้ว
กรณีการใช้งาน (Use case) ที่ GraphRAG แสดงประสิทธิภาพได้อย่างโดดเด่น มีดังนี้:
ทั้งหมดนี้คือจุดร่วมของปัญหาที่ว่า "มีเอกสารแต่ละฉบับอยู่แล้ว แต่ไม่สามารถตอบคำถามเกี่ยวกับความสัมพันธ์ข้ามเอกสารได้" ซึ่งสะท้อนให้เห็นถึงคุณค่าของ GraphRAG ได้อย่างชัดเจน
บทสรุป: การกำหนดเงื่อนไขเบื้องต้น (ไลบรารี, DB, คุณภาพข้อมูล) ให้ชัดเจนก่อนเริ่มการพัฒนา จะช่วยลดการแก้ไขงานในขั้นตอนหลังได้เป็นอย่างมาก
ยิ่งไปป์ไลน์มีองค์ประกอบมากเท่าใด การขาดการเตรียมการล่วงหน้าก็จะส่งผลโดยตรงต่อการต้องย้อนกลับมาแก้ไขงานในภายหลัง การบูรณาการ Knowledge Graph และ RAG ก็เช่นเดียวกัน หากใช้วิธี "ลองทำไปก่อนแล้วค่อยปรับแก้" มักจะนำไปสู่การทำงานที่มีต้นทุนสูงในภายหลัง เช่น การปรับโครงสร้างข้อมูลใหม่ หรือการย้ายฐานข้อมูล (DB Migration)
เนื้อหาต่อจากนี้จะสรุป 3 ประเด็นสำคัญที่ควรตัดสินใจให้ชัดเจนก่อนเริ่ม เพื่อให้การพัฒนาเป็นไปอย่างราบรื่น ได้แก่ การเลือกไลบรารี, เกณฑ์การเลือก DB และข้อกำหนดในการเตรียมข้อมูลล่วงหน้า
เมื่อเกี่ยวข้องกับการรวมกราฟ (Graph Integration) ไลบรารีเชนทั่วไปเพียงอย่างเดียวอาจไม่เพียงพอสำหรับการจัดการการรัน Cypher และการทำ Node Embedding ในการใช้งาน Knowledge Graph ร่วมกับ RAG หากคุณคำนึงถึง 3 เลเยอร์ ได้แก่ "การจัดการกราฟ (Graph Operation)", "การค้นหาเวกเตอร์ (Vector Search)" และ "การประสานงาน LLM (LLM Orchestration)" ตั้งแต่เริ่มต้น จะช่วยลดการเปลี่ยนแปลงการออกแบบในภายหลังได้
เลเยอร์การจัดการกราฟ (Graph Operation Layer)
neo4j (Python driver): สำหรับการรัน Cypher query และการเชื่อมต่อกับ Graph DBlangchain-community Neo4j integration: ทำหน้าที่เป็นตัวเชื่อมในการนำการค้นหากราฟไปรวมเข้ากับ LLM chainเลเยอร์การค้นหาเวกเตอร์ (Vector Search Layer)
sentence-transformers หรือ Embedding API: สำหรับสร้าง Embedding ของโหนดหรือ Chunkfaiss-cpu หรือ chromadb: สำหรับ Vector store แบบน้ำหนักเบาในสภาพแวดล้อม Localเลเยอร์การประสานงาน LLM (LLM Orchestration Layer)
langchain / llama-index: สำหรับการรวมผลลัพธ์การค้นหา, การสร้าง Prompt และการทำ Pipeline ของการสร้างคำตอบในขั้นตอนการตรวจสอบ (Validation) การใช้ Stack ที่ทำงานแบบ Local ได้ทั้งหมด (เช่น NetworkX + FAISS) ก็เพียงพอแล้ว แต่หากมองถึงการใช้งานจริง (Production) การทำ PoC ด้วยการผสมผสานระหว่าง Neo4j และ Managed Vector DB ตั้งแต่แรก จะช่วยลดต้นทุนในการย้ายระบบได้
การเลือกใช้ Graph DB และ Vector DB ขึ้นอยู่กับขนาดของข้อมูลและรูปแบบการสืบค้น (Query pattern) หากเป็นโปรโตไทป์ขนาดเล็ก การใช้เครื่องมือที่มีน้ำหนักเบาก็เพียงพอ แต่หากคำนึงถึงการใช้งานจริงในระดับโปรดักชัน จำเป็นต้องเลือกโดยให้ความสำคัญกับความสามารถในการขยายระบบ (Scalability) และความง่ายในการบูรณาการ (Integration)
จุดพิจารณาในการเลือก Graph DB
จุดพิจารณาในการเลือก Vector DB
จุดตัดสินใจ
หากกรณีการใช้งานหลักคือการอนุมานความสัมพันธ์แบบหลายลำดับ (Multi-hop reasoning) การออกแบบโดยใช้ Neo4j เป็นแกนหลักและผนวก Vector search เข้าไปเป็นฟังก์ชันเสริมจะเป็นโครงสร้างที่เสถียรกว่า
「กราฟที่พยายามสร้างขึ้นกลับใช้งานไม่ได้เลยตั้งแต่ต้นเพราะข้อมูลสกปรก」เป็นประสบการณ์ที่มักพบเห็นได้บ่อยในการนำ GraphRAG ไปใช้งานจริง เนื่องจากคุณภาพของ Knowledge Graph ขึ้นตรงกับคุณภาพของข้อมูลที่ป้อนเข้าไป การออกแบบขั้นตอนการประมวลผลล่วงหน้า (Pre-processing) จึงจำเป็นต้องกำหนดให้ชัดเจนก่อนเริ่มขั้นตอนการสร้าง
ข้อกำหนดด้านคุณภาพข้อมูลที่ควรตรวจสอบ
ขั้นตอนหลักที่ควรดำเนินการในไปป์ไลน์การประมวลผลล่วงหน้า
บทสรุป: การสร้าง Knowledge Graph จะดำเนินการผ่าน 3 ขั้นตอน ได้แก่ "การสกัด Entity (Entity Extraction) → การกำหนดความสัมพันธ์ (Relationship Definition) → การจัดเก็บลงใน Graph DB"
การตัดสินใจในการออกแบบแต่ละขั้นตอนจะส่งผลโดยตรงต่อความแม่นยำในการสืบค้นในลำดับถัดไป เรามาตรวจสอบไปทีละขั้นตอนกันครับ
ในการทำ Entity Extraction หลายคนมักเข้าใจผิดว่า "ยิ่งสกัดข้อมูลออกมาได้มากเท่าไร ความแม่นยำก็จะยิ่งสูงขึ้น" แต่ในความเป็นจริงแล้ว การออกแบบโดยจำกัดขอบเขต (Scope) ให้แคบลงจะช่วยเพิ่มคุณภาพของกราฟและความแม่นยำในการค้นหาได้ดีกว่า
หลักการพื้นฐานในการกำหนดความละเอียด (Granularity) ของ Entity คือการคิดย้อนกลับจากประเภทของ Query ที่ต้องการตอบ ตัวอย่างเช่น หากมีโจทย์ว่า "ต้องการตอบคำถามโดยเชื่อมโยงข้อมูลระหว่างข้อกำหนดทางเทคนิคและแผนกที่รับผิดชอบของผลิตภัณฑ์หนึ่งๆ" การออกแบบที่เหมาะสมคือการกำหนดให้ ผลิตภัณฑ์ (Product)・ข้อกำหนด (Specification)・แผนก (Department)・ผู้รับผิดชอบ (Person in charge) เป็น Core Entity 4 ประเภท และเก็บข้อมูลส่วนที่เหลือไว้เป็น Attribute
สำหรับการกำหนดความสัมพันธ์ (Relationship Definition) ควรจัดเตรียมประเด็นต่อไปนี้ไว้ล่วงหน้า:
(A)-[:DEPENDS_ON]->(B) เพื่อให้ทิศทางการอนุมานชัดเจนในทางปฏิบัติ การใช้วิธีแบบทำซ้ำ (Iterative approach) จะได้ผลดีที่สุด โดยไม่ต้องพยายามทำให้ Schema สมบูรณ์แบบตั้งแต่ต้น แต่ให้เริ่มจากการจำกัด Use case ไว้ที่ 3-5 กรณีเพื่อกำหนด MVP Schema แล้วจึงขยายผลหลังจากผ่านการตรวจสอบแล้ว การควบคุมให้ประเภทของ Entity ไม่เกิน 10 ประเภท และประเภทของความสัมพันธ์ไม่เกิน 15 ประเภท จะช่วยป้องกันไม่ให้กราฟขยายตัวจนใหญ่เกินความจำเป็น
ก่อนที่จะเข้าสู่ขั้นตอนการสกัดข้อมูลอัตโนมัติด้วย LLM ซึ่งจะอธิบายในหัวข้อถัดไป การจัดทำเอกสาร Schema Definition นี้ไว้ จะช่วยให้การออกแบบ Prompt สำหรับการสกัดข้อมูลและเกณฑ์การประเมินคุณภาพมีความชัดเจนยิ่งขึ้น
การสร้างกราฟโดยใช้ LLM มีขั้นตอนพื้นฐานคือการแบ่งเอกสารออกเป็นส่วนๆ (Chunking) จากนั้นจึงส่งพรอมต์เพื่อสั่งให้ดึงข้อมูลเอนทิตี (Entity Extraction) และความสัมพันธ์ (Relation Extraction) ออกมาจากแต่ละส่วนพร้อมกัน
สรุปขั้นตอน
(ประธาน, กริยา, กรรม)"สำหรับการตัดสินใจในการออกแบบพรอมต์ หากเป็นโดเมนที่มีคำศัพท์เฉพาะทางจำนวนมากและมีความเสี่ยงที่จะดึงข้อมูลผิดพลาดสูง วิธีการแบบ Few-shot โดยการกำหนดสคีมาไว้ล่วงหน้าและฝังลงในพรอมต์จะมีประสิทธิภาพมากกว่า ในทางกลับกัน หากโดเมนมีความกว้างขวางและยากต่อการกำหนดนิยามล่วงหน้า การใช้วิธี Zero-shot เพื่อให้ดึงประเภทเอนทิตีได้อย่างอิสระ แล้วนำมาจัดกลุ่ม (Clustering) ในขั้นตอนหลัง จะช่วยให้รองรับการทำงานได้อย่างยืดหยุ่นกว่า
หลังจากเสร็จสิ้นการสกัดเอนทิตี (Entity Extraction) และการกำหนดความสัมพันธ์แล้ว หลายหน้างานมักจะเกิดความสับสนว่า "ควรตัดสินใจเลือกใช้ Node Label หรือ Relation Type อย่างไรดี"
ในการนำข้อมูลเข้าสู่ Neo4j การกำหนดการออกแบบ Schema ให้ชัดเจนตั้งแต่ต้นจะส่งผลต่อความแม่นยำในการสืบค้นในขั้นตอนถัดไป โดยมีจุดสำคัญในการออกแบบดังนี้:
Person, Organization, Concept ฯลฯ) เป็น Label และเก็บ Chunk ID ของข้อความต้นฉบับหรือ Embedding Vector ไว้ใน PropertyWORKS_AT, RELATED_TO ฯลฯ) และควรหลีกเลี่ยงการใช้คำทั่วไปอย่าง CONNECTEDsource (URI ของเอกสารต้นฉบับ), chunk_id, และ embedding (อาเรย์ของ Float) เพื่อให้สามารถอ้างอิงได้ในการทำ Hybrid Search ในขั้นตอนถัดไปสำหรับการนำข้อมูลเข้า ยังสามารถใช้เครื่องมือ LLM Knowledge Graph Builder ที่ Neo4j เปิดให้ใช้งานได้ ซึ่งจะช่วยลดต้นทุนในการสร้างระบบเริ่มต้น โดยเครื่องมือนี้จะจัดเตรียมไปป์ไลน์ที่ครอบคลุมตั้งแต่การทำ Chunking เอกสาร, การสร้าง Embedding, การสกัดเอนทิตี/ความสัมพันธ์, การจัดเก็บลงกราฟ ไปจนถึงการสรุปผลแบบ Community
ตัวอย่างการนำข้อมูลเข้าด้วย Cypher มีดังนี้:
1// การสร้างเอนทิตี (Node) ใช้ MERGE เพื่อป้องกันข้อมูลซ้ำ
2MERGE (p:Person {name: "Yamada Taro"})
3 ON CREATE SET p.source = "doc_001", p.chunk_id = "c_012";
4MERGE (o:Organization {name: "ABC Co., Ltd."})
5 ON CREATE SET o.source = "doc_001";
6
7// การสร้างความสัมพันธ์ (Edge)
8MATCH (p:Person {name: "Yamada Taro"}), (o:Organization {name: "ABC Co., Ltd."})
9MERGE (p)-[:WORKS_AT]->(o);การใช้ MERGE จะช่วยป้องกันการสร้าง Node ที่มีชื่อซ้ำกันและทำให้สามารถนำข้อมูลเข้าได้อย่างเป็นเอกภาพ (Idempotent) หากต้องการนำข้อมูลเข้าจำนวนมาก การใช้ UNWIND เพื่อประมวลผลอาเรย์ของ Triple พร้อมกันจะช่วยให้มีประสิทธิภาพมากขึ้น
บทสรุป: การเชื่อมโยง Knowledge Graph เข้ากับ Vector Index ช่วยให้สามารถใช้ประโยชน์จากการค้นหาความคล้ายคลึงเชิงความหมาย (Semantic Similarity Search) และการสำรวจความสัมพันธ์เชิงโครงสร้าง (Structural Relationship Exploration) ได้พร้อมกัน
เมื่อสร้างกราฟเสร็จสิ้น หัวใจสำคัญถัดไปคือการสร้าง Node Embedding และการออกแบบ Hybrid Search Pipeline นอกจากนี้ ตรรกะการกำหนดเส้นทาง (Routing Logic) เพื่อเลือกระหว่างการค้นหาแบบเวกเตอร์ (Vector Search) และการท่องไปในกราฟ (Graph Traversal) ตามประเภทของคำค้นหา (Query) ก็มีความสำคัญเช่นกัน
การทำ Node Embedding ให้ผลลัพธ์ความแม่นยำในการค้นหาที่เสถียรกว่าการทำ Embedding เอกสารทั้งฉบับรวมกัน เนื่องจากเป็นการสร้างโดยเน้นความละเอียดในระดับโหนด (Node-level granularity) ในขณะที่การทำ Document Embedding มักมีบริบทที่ปะปนกันหลายอย่าง ทำให้ยากต่อการจับคู่ความหมายกับโหนดในกราฟ
ขั้นตอนการสร้าง Node Embedding
การจัดเก็บใน Vector Store
หากออกแบบการจับคู่นี้ไว้อย่างรอบคอบ จะช่วยให้การทำ Hybrid Search ในขั้นตอนถัดไปสามารถนำผลลัพธ์จากฝั่งกราฟและฝั่งเวกเตอร์มาเปรียบเทียบกันได้ง่ายขึ้น
การค้นหาแบบเวกเตอร์ (Vector Search) และการค้นหาแบบกราฟ (Graph Search) ต่างมีจุดเด่นในด้านที่แตกต่างกัน การออกแบบ "ไปป์ไลน์การค้นหาแบบไฮบริด" (Hybrid Search Pipeline) ที่รันทั้งสองวิธีควบคู่กันไปและรวมผลลัพธ์เข้าด้วยกัน จะช่วยเติมเต็มบริบทที่อาจตกหล่นไปหากใช้วิธีใดวิธีหนึ่งเพียงอย่างเดียว
โครงสร้างพื้นฐานของไปป์ไลน์ประกอบด้วย 3 ขั้นตอน ดังนี้:
ในการถ่วงน้ำหนักคะแนน มุมมองเรื่องเงื่อนไขการแบ่งประเภทมีความสำคัญมาก ตัวอย่างเช่น สำหรับคำค้นหาประเภทนิยามหรือแนวคิด เช่น "คืออะไร" ควรให้คะแนนการค้นหาแบบเวกเตอร์สูงกว่า แต่สำหรับคำค้นหาประเภทความสัมพันธ์หรือเหตุปัจจัย เช่น "A ส่งผลต่อ C ผ่าน B อย่างไร" ควรให้ความสำคัญกับผลลัพธ์จากการทำ Graph Traversal มากกว่า การกำหนดเกณฑ์การตัดสินใจเหล่านี้ให้ชัดเจนในขณะที่ทำการ Implement จะช่วยให้เชื่อมโยงกับตรรกะการ Routing ในขั้นตอนถัดไปได้ง่ายขึ้น
ข้อควรระวังในการ Implement มีดังนี้:
「ควรส่งคิวรีนี้ไปที่การค้นหาแบบเวกเตอร์ (Vector Search) หรือการค้นหาแบบกราฟ (Graph Search) ดี?」——เมื่อเริ่มลงมือพัฒนา คุณจะพบกับช่วงเวลาที่ต้องตัดสินใจเรื่องนี้อย่างหลีกเลี่ยงไม่ได้
Query Routing คือตรรกะในการวิเคราะห์คิวรีของผู้ใช้ที่ได้รับมา แล้วจัดสรรไปยังเส้นทางการค้นหาที่เหมาะสมที่สุด หากส่งคิวรีทั้งหมดไปทั้งสองเส้นทาง จะทำให้เกิดความหน่วง (Latency) และค่าใช้จ่ายด้านโทเค็นของ LLM เพิ่มขึ้นโดยไม่จำเป็น ดังนั้นการแยกเส้นทางอย่างเหมาะสมจึงเป็นสิ่งที่ขาดไม่ได้
แกนหลักในการตัดสินใจเลือกเส้นทาง (Routing)
การจำแนกคุณลักษณะของคิวรีด้วย 2 แกนต่อไปนี้เป็นวิธีที่ใช้งานได้จริง:
รูปแบบการนำไปใช้งาน (Implementation Patterns)
การนำตรรกะ Routing ไปใช้งานมี 2 แนวทางหลัก:
graph / vector / hybrid วิธีนี้มีความแม่นยำสูง แต่การจำแนกประเภทเองจะทำให้เกิดความหน่วงในการทำงานจริง การออกแบบแบบ 2 ชั้นที่จัดการรูปแบบที่ชัดเจนด้วย Rule-based ก่อน แล้วค่อย Fallback เฉพาะคิวรีที่กำกวมให้ LLM จำแนก จะช่วยสร้างสมดุลระหว่างความแม่นยำและต้นทุนได้ดีที่สุด ส่วนคิวรีที่ตัดสินใจไม่ได้ ให้กำหนดเป็น hybrid เพื่อส่งไปยังทั้งสองเส้นทางแล้วรวมผลลัพธ์เข้าด้วยกัน จะช่วยป้องกันการตกหล่นของข้อมูลได้
บทสรุป: การนำบริบทที่รวบรวมได้จากการทำ Graph Traversal มาจัดโครงสร้างก่อนส่งให้ LLM จะช่วยเพิ่มความแม่นยำในการตอบคำถามที่ซับซ้อนได้อย่างมาก
วิธีการบูรณาการผลลัพธ์จากการสืบค้นแบบกราฟ (Graph Search) และแบบเวกเตอร์ (Vector Search) เพื่อส่งต่อไปยัง LLM นั้นเป็นปัจจัยสำคัญที่กำหนดคุณภาพของคำตอบ ในส่วนนี้จะอธิบายขั้นตอนการนำไปใช้งานจริง ตั้งแต่การรวบรวมบริบท การออกแบบ Prompt ไปจนถึงการปรับแต่งข้อมูลนำเข้า (Input Optimization) ตามลำดับ
ในการรวบรวมบริบท (Context) เรามักจะดึงข้อมูลเพียงโหนดที่อยู่ห่างออกไป 1 ฮอป (hop) เท่านั้น แต่การสืบค้นลึกลงไปถึง 2-3 ฮอปจะช่วยให้สามารถนำความสัมพันธ์ที่ต่อเนื่องกันซึ่งการค้นหาด้วยเวกเตอร์ (Vector Search) แบบปกติไม่สามารถตรวจพบได้ มาใช้ในการตอบคำถามได้
ขั้นตอนพื้นฐานของการทำ Traversal มีดังนี้:
MATCH (n)-[r*1..3]->(m) เพื่อป้องกันการขยายผลแบบไม่สิ้นสุดAUTHORED_BY, BELONGS_TO, REFERENCES)ตัวอย่าง Cypher Query มีดังนี้:
1// สืบค้นความสัมพันธ์ที่เกี่ยวข้องจากโหนดเริ่มต้นที่ได้จาก Vector Search สูงสุด 3 ฮอป
2MATCH path = (start:Entity {id: $seedId})-[:AUTHORED_BY|BELONGS_TO|REFERENCES*1..3]->(related)
3RETURN related, relationships(path) AS rels, length(path) AS hops
4ORDER BY hops ASC
5LIMIT 20;การใช้ *1..3 เพื่อจำกัดความลึกสูงสุดไว้ที่ 3 ฮอป และการเรียงลำดับตาม hops จากน้อยไปมาก จะช่วยให้สามารถนำโหนดที่อยู่ใกล้จุดเริ่มต้น (ซึ่งมีความเกี่ยวข้องสูง) เข้าสู่บริบทได้ก่อนเป็นอันดับแรก
การนำบริบทที่รวบรวมได้จากการทำ Graph Traversal ไปวางลงใน Prompt โดยตรง มักจะทำให้ LLM ไม่สามารถตัดสินลำดับความสำคัญของข้อมูลได้ ส่งผลให้คุณภาพของคำตอบลดลง การเตรียมเทมเพลตที่มีโครงสร้างเพื่อจัดระเบียบผลลัพธ์ที่ได้ก่อนส่งต่อจึงเป็นเรื่องสำคัญ
โดยทั่วไปแล้ว Prompt Template มักจะประกอบด้วย 3 ส่วนหลัก ดังนี้:
การเรียงลำดับตามนี้จะช่วยให้ LLM อ่านข้อมูลความสัมพันธ์เชิงโครงสร้างก่อน แล้วจึงอ้างอิงข้อมูลเชิงข้อความเพื่อเป็นหลักฐานประกอบในภายหลัง
นอกจากนี้ จำเป็นต้องปรับใช้ให้เหมาะสมกับปริมาณของบริบท หากผลลัพธ์จากการทำ Graph มีจำนวนมาก ควรแปลงข้อมูล Relation ให้เป็นรายการแบบ Bullet point เพื่อสรุปใจความ และหากผลลัพธ์จาก Vector Search มีน้อย ควรนำข้อมูล Property จากฝั่ง Graph มาขยายความเพิ่มเติมเพื่อเป็นข้อความเสริม
ตัวอย่างของเทมเพลตมีดังนี้:
แม้ว่าการทำ Graph Traversal และ Vector Search จะช่วยรวบรวม Context ได้จำนวนมาก แต่หากไม่มีการปรับแต่ง "ว่าจะส่งอะไรให้ LLM และในลำดับใด" คุณภาพของคำตอบก็อาจไม่ดีขึ้นอย่างที่คาดหวัง — วิศวกรหลายคนคงเคยประสบปัญหานี้มาก่อน
หากนำ Context ที่รวบรวมได้มาต่อกันแล้วส่งเข้า Prompt โดยตรง มีรายงานว่า LLM จะประมวลผล Input ที่มี Noise มากไม่ได้อย่างสมบูรณ์ และอาจพลาดความสัมพันธ์ที่สำคัญไป ควรคำนึงถึงประเด็นต่อไปนี้ในการปรับแต่ง Input:
## เอกสารที่เกี่ยวข้อง / ## ความสัมพันธ์ของ Entity)เพื่อยกระดับคุณภาพคำตอบให้ดียิ่งขึ้น การใช้ Chain-of-Thought (CoT) Prompting มีประสิทธิภาพมาก การเพิ่มคำสั่งเช่น "ให้ระบุ Entity ที่เกี่ยวข้องก่อน จากนั้นแสดง Reasoning Step แล้วจึงให้คำตอบสุดท้าย" มีแนวโน้มช่วยเพิ่มความแม่นยำของการอนุมานแบบ Multi-hop
นอกจากนี้ การนำ รูปแบบคำตอบพร้อม Citation มาใช้ โดยรวม Graph Path และ Source Node ที่ใช้ในการตอบไว้ใน Output ด้วย จะช่วยให้การตรวจจับ Hallucination และการตรวจสอบความน่าเชื่อถือทำได้ง่ายขึ้น
บทสรุป: การทำความเข้าใจรูปแบบความผิดพลาดที่มักถูกมองข้ามไว้ล่วงหน้า จะช่วยลดการทำงานซ้ำซ้อน (rework) ลงได้อย่างมาก
การขยายตัวของกราฟ (Graph Bloat) และความขัดแย้งของผลลัพธ์ในการค้นหาแบบ Vector Graph เป็นปัญหาสำคัญสองประการที่มักจะปรากฏให้เห็นชัดเจนโดยเฉพาะในสภาพแวดล้อมการใช้งานจริง (Production) ต่อไปนี้คือคำอธิบายถึงสาเหตุและแนวทางแก้ไขของแต่ละปัญหา
กราฟที่บวมโตเกินขนาดเกิดขึ้นจากการสกัด Entity อย่างไม่เลือกสรร เมื่อจำนวน Node และ Relation เพิ่มขึ้นอย่างไม่มีทิศทาง พื้นที่การค้นหาของ Graph Traversal จะขยายตัว ทำให้ Context ที่มีความเกี่ยวข้องต่ำปะปนเข้ามาเป็นจำนวนมาก และส่งผลให้คุณภาพของคำตอบลดลง
รูปแบบที่มักก่อให้เกิดกราฟบวมโตได้ง่าย ได้แก่ การสกัด Entity ที่มีความทั่วไปเกินไปอย่างไม่เลือกสรร เช่น "บริษัท" "บุคคล" หรือ "วันที่" จนทำให้จำนวน Node พุ่งสูงถึงหลักแสน นอกจากนี้ยังมีปัญหาการลงทะเบียน Node ซ้ำซ้อนจากการสะกดที่แตกต่างกัน เช่น "บริษัท A จำกัด" "บริษัท A" และ "A" ถูกบันทึกเป็น Node แยกกัน รวมถึงกรณีที่ Node เก่าซึ่งบรรจุข้อมูลจากเหตุการณ์ชั่วคราวหรือข้อมูลที่อัปเดตบ่อยครั้งยังคงค้างอยู่ในระบบ
เมื่อกราฟบวมโตขึ้น ไม่เพียงแต่ต้นทุนการรัน Cypher Query จะเพิ่มสูงขึ้นเท่านั้น แต่การค้นหาเพื่อนบ้านจาก Seed Node ที่ได้จาก Vector Search ยังดึงดูด Node ที่ไม่เกี่ยวข้องเข้ามาเป็นจำนวนมากอีกด้วย ผลลัพธ์คือ Context ที่ส่งให้ LLM เต็มไปด้วย Noise ทำให้ความสอดคล้องของคำตอบเสียหาย
เพื่อหลีกเลี่ยงปัญหานี้ หลักการพื้นฐานคือการจำกัดประเภท Entity ในขั้นตอนการออกแบบ Schema ให้เหลือเฉพาะที่จำเป็นสำหรับ Domain นั้น ๆ และหลีกเลี่ยงการใช้ประเภททั่วไปให้มากที่สุด นอกจากนี้ยังสำคัญอย่างยิ่งที่จะต้องฝัง Pipeline สำหรับ Entity Resolution ซึ่งทำหน้าที่รวม Entity ที่สะกดต่างกันเข้าด้วยกันตั้งแต่ขั้นตอนการสร้างระบบ สำหรับ Node ที่ต้องการความสดใหม่ของข้อมูล ควรกำหนดนโยบาย TTL (Time-To-Live) และทำการ Pruning อย่างสม่ำเสมอ อีกทั้งการนำ Community Detection มาใช้เพื่อจำกัดขอบเขตการค้นหาให้อยู่ในหน่วย Subgraph ที่มีความหนาแน่นสูง ก็ช่วยลดการปะปนของ Noise ได้เช่นกัน
การรันทั้ง Vector Search และ Graph Search พร้อมกันอาจทำให้แต่ละวิธีส่งคืนเอกสารหรือโหนดที่แตกต่างกัน ซึ่งอาจนำไปสู่การปนเปื้อนของข้อมูลที่ขัดแย้งกันใน Prompt สุดท้าย ตัวอย่างเช่น หากมีคำถามว่า "ผลิตภัณฑ์หลักของบริษัท A คืออะไร" แล้ว Vector Search ส่งคืนข่าวประชาสัมพันธ์เก่า ในขณะที่ Graph Search ส่งคืนโหนดผลิตภัณฑ์ล่าสุด LLM อาจไม่สามารถตัดสินใจได้ว่าควรให้ความสำคัญกับข้อมูลใด และมีแนวโน้มที่จะสร้างบทสรุปที่ผิดพลาดได้
สถานการณ์ที่เกิดความขัดแย้งนี้สามารถแบ่งออกเป็น 3 ประเภทหลัก ประการแรกคือ ความไม่สอดคล้องกันของความสดใหม่ของข้อมูล (Freshness Mismatch) ซึ่งเกิดจากความถี่ในการอัปเดต Vector Index ต่ำกว่า Graph ทำให้มีข้อมูลเก่าปะปนเข้ามา ประการที่สองคือ ความไม่สอดคล้องกันของระดับความละเอียด (Granularity Mismatch) เนื่องจาก Vector Search ส่งคืนผลลัพธ์เป็นหน่วย Chunk ในขณะที่ Graph Search ส่งคืนเป็นหน่วย Entity ทำให้ระดับความนามธรรมไม่ตรงกัน ประการที่สามคือ ความไม่เข้ากันของคะแนน (Score Incompatibility) เนื่องจาก Cosine Similarity และน้ำหนักของเส้นทางในกราฟไม่สามารถนำมาเปรียบเทียบกันโดยตรงได้ ทำให้การรวมอันดับ (Ranking Integration) เป็นเรื่องยาก
แนวทางพื้นฐานในการรับมือคือการกำหนด "ลำดับความสำคัญของความน่าเชื่อถือ" ให้ชัดเจนก่อนที่จะรวมผลลัพธ์เข้าด้วยกัน การนำระบบ Query Routing มาใช้เพื่อกำหนดเงื่อนไข เช่น ให้ความสำคัญกับผลลัพธ์จาก Graph Search ในคำถามที่เกี่ยวกับชื่อเฉพาะ ตัวเลข หรือความสัมพันธ์ระหว่าง Entity และให้ความสำคัญกับ Vector Search ในคำถามที่เน้นความคล้ายคลึงทางความหมายหรือความเข้าใจบริบท จะช่วยลดความขัดแย้งลงได้อย่างมาก
นอกจากนี้ เมื่อส่งผลลัพธ์จากทั้งสองวิธีไปยัง LLM การใช้ Prompt Template ที่มีการระบุแหล่งที่มา เช่น "ข้อมูลจากกราฟ" และ "ข้อมูลจากเวกเตอร์" จะให้ผลลัพธ์ที่มีประสิทธิภาพ การระบุแหล่งที่มาอย่างชัดเจนจะช่วยให้ LLM สามารถตรวจพบความขัดแย้งและเพิ่มคำอธิบายประกอบในคำตอบได้ง่ายขึ้น
บทสรุป: Knowledge Graph × RAG คือสถาปัตยกรรมที่รวมเอา "การค้นหาแบบเวกเตอร์" (Vector Search) ซึ่งจับ "ความใกล้เคียงทางความหมาย" เข้ากับ "โครงสร้างกราฟ" (Graph Structure) ซึ่งจับ "สายสัมพันธ์" เพื่อตอบคำถามที่ซับซ้อนแบบหลายขั้นตอน (Multi-hop)
ในคู่มือฉบับนี้ เราได้อธิบายตามลำดับตั้งแต่การจัดเตรียมเงื่อนไขเบื้องต้น การสร้าง Knowledge Graph การบูรณาการเข้ากับ Vector Index การสร้างคำตอบสำหรับคำถามที่ซับซ้อน ไปจนถึงรูปแบบความล้มเหลวที่มักพบได้บ่อยในการใช้งานจริง โดยสรุปประเด็นสำคัญได้ 3 ข้อดังนี้:
สำหรับการนำไปใช้งานจริง แนวทางที่เป็นไปได้มากที่สุดคือการเริ่มทดสอบในระดับเล็ก (PoC) เพื่อยืนยันผลลัพธ์ก่อนที่จะขยายไปสู่ขนาดข้อมูลจริง หากคุณกำลังประสบปัญหาในการออกแบบหรือสร้างโครงสร้างพื้นฐาน RAG เพื่อใช้ประโยชน์จากความรู้ภายในองค์กรที่มีความซับซ้อนอย่างครอบคลุม สามารถติดต่อสอบถามบริการสนับสนุนการสร้าง RAG ของเราได้ทันที
นี่คือคำถามที่พบบ่อยเกี่ยวกับการนำ Knowledge Graph × RAG ไปใช้งาน
Q1. ควรเลือกใช้ Knowledge Graph × RAG กับ RAG ปกติอย่างไร?
สำหรับการสอบถามข้อเท็จจริงเพียงอย่างเดียว เช่น "〇〇 คืออะไร" การใช้ Vector RAG ปกติก็เพียงพอแล้ว แต่ Knowledge Graph × RAG จะแสดงประสิทธิภาพได้ดีในกรณีที่เป็นคำถามที่ต้องอาศัยการสืบค้นความสัมพันธ์ระหว่าง Entity แบบต่อเนื่อง เช่น "ความสัมพันธ์ระหว่าง A กับ B" หรือ "คำถามที่ครอบคลุมหลายเงื่อนไข" แนวทางที่เหมาะสมคือเริ่มจากการใช้งาน RAG ปกติก่อน แล้วค่อยพิจารณาบูรณาการกราฟเมื่อพบว่าความแม่นยำในการสืบค้นความสัมพันธ์ยังไม่เพียงพอ
Q2. จำเป็นต้องใช้ทั้ง Graph DB และ Vector DB หรือไม่? สามารถรวมไว้ในที่เดียวได้ไหม?
โดยหลักการแล้วควรใช้ควบคู่กัน เนื่องจาก Graph DB ถนัดด้านการสำรวจความสัมพันธ์ ส่วน Vector DB ถนัดด้านการค้นหาความใกล้เคียงเชิงความหมาย อย่างไรก็ตาม ยังมีทางเลือกในการรวมไว้ในฐานข้อมูลเดียว เช่น การใช้โครงสร้างที่อิงกับ RDB อย่าง pgvector หรือการใช้ฟังก์ชัน Vector Index ของ Graph DB หากต้องการลดภาระในการดูแลระบบ สามารถเริ่มจากแบบบูรณาการก่อน แล้วค่อยแยกออกเมื่อความต้องการด้านประสิทธิภาพสูงขึ้น
Q3. สามารถเพิ่ม Knowledge Graph เข้าไปในระบบ RAG ที่มีอยู่เดิมได้หรือไม่?
สามารถทำได้ โดยคุณสามารถคง Pipeline การค้นหาแบบ Vector เดิมไว้ แล้วเพิ่มการค้นหาแบบกราฟเป็นช่องทางการดึงข้อมูลแบบขนาน จากนั้นใช้ชั้น Hybrid Search ในการรวมผลลัพธ์ ซึ่งจะช่วยให้สามารถเปลี่ยนผ่านได้อย่างเป็นขั้นตอน ไม่จำเป็นต้องแปลงเอกสารทั้งหมดเป็นกราฟตั้งแต่เริ่มต้น แต่ควรเริ่มจากการทำกราฟในบางโดเมนที่มีการสืบค้นความสัมพันธ์บ่อยๆ จะเป็นแนวทางที่เหมาะสมกว่า
Chi
ศึกษาเอกวิทยาการสารสนเทศที่มหาวิทยาลัยแห่งชาติลาว และระหว่างศึกษาได้มีส่วนร่วมในการพัฒนาซอฟต์แวร์ทางสถิติ สั่งสมพื้นฐานด้านการวิเคราะห์ข้อมูลและการเขียนโปรแกรมอย่างเป็นรูปธรรม ตั้งแต่ปี 2021 ได้ก้าวเข้าสู่เส้นทางการพัฒนา Web และแอปพลิเคชัน และตั้งแต่ปี 2023 เริ่มสั่งสมประสบการณ์การพัฒนาอย่างจริงจังทั้งในด้าน Frontend และ Backend ในบริษัทปัจจุบันรับผิดชอบการออกแบบและพัฒนาบริการ Web ที่ใช้ AI โดยมีส่วนร่วมในโครงการที่นำการประมวลผลภาษาธรรมชาติ (NLP) การเรียนรู้ของเครื่อง (Machine Learning) และ Generative AI รวมถึงโมเดลภาษาขนาดใหญ่ (LLM) มาผสานรวมกับระบบงานจริง มีความกระตือรือร้นในการติดตามเทคโนโลยีล่าสุดอยู่เสมอ และให้ความสำคัญกับความรวดเร็วในการดำเนินงานตั้งแต่การพิสูจน์แนวคิดทางเทคนิคไปจนถึงการนำไปใช้งานจริง