ผมสร้าง Code Q&A Bot ด้วย RAG: สิ่งที่ทำได้ดีและสิ่งที่ล้มเหลว
นักพัฒนาของเราต้องใช้เวลาหลายวันในการค้นหาข้อมูลผ่าน Slack และเอกสารเก่าๆ เพื่อทำความเข้าใจ microservices ของเรา ผมจึงตัดสินใจสร้าง chatbot ขึ้นมาเพื่อตอบคำถามเหล่านี้โดยใช้ RAG
ผมทำผิดพลาดไปหลายอย่างระหว่างทาง และนี่คือสิ่งที่ผมได้เรียนรู้
ความล้มเหลว
- ผมพยายามใส่เอกสารทั้งหมดลงใน prompt เดียวกัน ผลคือมันเกินขีดจำกัดของ token ทำให้เกิด hallucination และสิ้นเปลืองค่าใช้จ่ายมากเกินไป
- ผมใช้ดัชนี TF-IDF แบบพื้นฐาน ซึ่งมันล้มเหลวเมื่อผู้ใช้ใช้คำพ้องความหมาย (synonyms) หรือคำศัพท์ที่แตกต่างออกไป
- ผมลองแบ่งข้อมูลเป็น chunk ขนาด 500 ตัวอักษรแบบง่ายๆ ผลลัพธ์ที่ได้กลับสะเปะสะปะ เพราะ chunk มักจะถูกตัดกลางประโยค
ทางออก
ผมเลิกปฏิบัติกับ LLM เหมือนเป็น search engine แต่เปลี่ยนให้มันเป็น reading engine สำหรับดัชนีการค้นหาที่จัดเตรียมไว้โดยเฉพาะแทน
นี่คือ pipeline ที่ใช้งานได้จริง:
- แบ่งเอกสารเป็น chunk ขนาด 300 token โดยมี overlap 50 token
- ทำ embedding แต่ละ chunk ให้เป็น vector
- เก็บ vector ไว้ใน similarity search index
- เมื่อมีการ query ให้ค้นหา 5 chunk ที่มีความคล้ายคลึงกันมากที่สุด
- ส่งเฉพาะ chunk เหล่านั้นเข้าไปใน LLM เพื่อสร้างคำตอบ
การเปลี่ยนแปลงนี้ช่วยลด hallucination ลงได้ถึง 80% และลดค่าใช้จ่ายลงเหลือไม่ถึง $0.01 ต่อการ query
บทเรียนสำคัญ
- ขนาดของ chunk เป็นเรื่องสำคัญมาก 150 token ให้บริบทน้อยเกินไป ส่วน 1000 token ก็มี noise มากเกินไป ขนาด 300 token คือจุดที่เหมาะสมที่สุด (sweet spot)
- การทำ overlap เป็นเรื่องที่จำเป็น เพราะช่วยป้องกันไม่ให้บริบทขาดหายไปในระหว่าง chunk
- ใช้โมเดลขนาดเล็กเพื่อความรวดเร็ว โมเดล embedding ขนาดเล็กทำงานได้ดีมากสำหรับความต้องการภายในของเรา
- ทดสอบการ retrieval ของคุณ อย่าพึ่งพาแค่การตรวจสอบด้วยมือ แต่ให้สร้าง test set เพื่อวัดความแม่นยำ
RAG ไม่ใช่เวทมนตร์ แต่มันคือโจทย์ทางวิศวกรรม ถ้า chunk ของคุณไม่ดี การ retrieval ก็จะไม่ดี และถ้าการ retrieval ไม่ดี คำตอบของคุณก็จะแย่ตามไปด้วย
ตอนนี้เราสามารถตอบคำถามช่วง onboarding ได้ถูกต้องถึง 80% ซึ่งรวดเร็วกว่าการรอให้คนมาตอบใน Slack มาก
แล้วคุณล่ะ สร้าง AI assistant สำหรับเอกสารของคุณอย่างไร?
ชุมชนการเรียนรู้เพิ่มเติม: https://t.me/GyaanSetuAi