คู่มือลงมือทำ ทีละขั้น จนเห็นผลจริง
เลือกหัวข้อที่สนใจ แล้วกางขั้นตอนเพื่อทำตามไปพร้อมกัน ทุกคำสั่งทดสอบมาแล้ว
ติดตั้ง Ollama แล้วดึงโมเดล Qwen มารันในเครื่องของคุณเอง ไม่ต้องพึ่งคลาวด์ ควบคุมข้อมูลได้เต็มที่ และใช้งานแบบออฟไลน์ได้จริง
- 1
ติดตั้ง Ollama
ดาวน์โหลดตัวติดตั้งจาก ollama.com แล้วรันให้เรียบร้อย จากนั้นเช็กว่าติดตั้งสำเร็จด้วยคำสั่งตรวจเวอร์ชัน บน macOS และ Linux ใช้บรรทัดเดียวก็พอ
curl -fsSL https://ollama.com/install.sh | sh ollama --version - 2
ดึงโมเดล Qwen
เริ่มจากรุ่นเล็กที่รันได้บนเครื่องทั่วไปก่อน เช่น Qwen2.5 ขนาด 7B ถ้าการ์ดจอแรงค่อยขยับขึ้นรุ่นใหญ่ คำสั่ง pull จะโหลดน้ำหนักโมเดลมาเก็บไว้ในเครื่อง
ollama pull qwen2.5:7b # เครื่องสเปกสูงลองรุ่นใหญ่ขึ้น ollama pull qwen2.5:14b - 3
เริ่มคุยกับโมเดล
สั่ง run แล้วพิมพ์คุยได้เลยในเทอร์มินัล โมเดลจะตอบจากเครื่องคุณล้วน ๆ ออฟไลน์ก็ใช้ได้ พิมพ์ /bye เพื่อออกจากการสนทนา
ollama run qwen2.5:7b >>> ช่วยสรุปแนวคิด RAG ให้หน่อย - 4
เรียกผ่าน API ในโปรเจกต์
Ollama เปิด REST API ที่พอร์ต 11434 ให้อัตโนมัติ เรียกใช้จากโค้ดได้ทันที เหมาะกับการต่อเข้าแอปหรือสคริปต์ของคุณเอง
curl http://localhost:11434/api/generate -d '{ "model": "qwen2.5:7b", "prompt": "อธิบาย vector database สั้น ๆ", "stream": false }' - 5
ปรับแต่งด้วย Modelfile
อยากให้โมเดลมีบุคลิกหรือคำสั่งระบบประจำตัว สร้าง Modelfile กำหนด SYSTEM prompt แล้ว build เป็นโมเดลเวอร์ชันของคุณเอง นำไปใช้ซ้ำได้
FROM qwen2.5:7b SYSTEM "คุณเป็นผู้ช่วยที่ตอบเป็นภาษาไทยกระชับ" PARAMETER temperature 0.6
รวมแพตเทิร์นที่ใช้บ่อยเวลาต่อ AI เข้ากับแอป Next.js ตั้งแต่การสตรีมคำตอบ ไปจนถึงการเก็บคีย์ให้ปลอดภัยและจัดการสถานะ
- 1
แยกฝั่งเซิร์ฟเวอร์ให้ชัด
เก็บการเรียกโมเดลและคีย์ลับไว้ในฝั่งเซิร์ฟเวอร์เสมอ อย่าให้คีย์หลุดไปฝั่งเบราว์เซอร์ ใช้ Server Action หรือ Route Handler เป็นด่านหน้า
// app/api/chat/route.ts export async function POST(req: Request) { const { prompt } = await req.json(); // เรียกโมเดลด้วยคีย์ที่อยู่ใน process.env เท่านั้น } - 2
สตรีมคำตอบทีละโทเคน
อย่าให้ผู้ใช้รอจนจบ ส่งคำตอบแบบสตรีมเพื่อให้ตัวอักษรทยอยขึ้น ประสบการณ์ดีขึ้นชัดเจน ใช้ ReadableStream ส่งกลับได้เลย
return new Response(stream, { headers: { "Content-Type": "text/event-stream" }, }); - 3
จัดการสถานะโหลด
ปุ่มส่งต้องโชว์สถานะกำลังทำงาน คงป้ายเดิมไว้ พร้อมตัวหมุน และเปิดให้กดได้จนกว่าคำขอจะเริ่มจริง เพื่อไม่ให้ผู้ใช้สับสน
- 4
แคชคำตอบที่ซ้ำ
คำถามยอดฮิตที่ตอบเหมือนเดิมทุกครั้ง เก็บผลลัพธ์ไว้ลดทั้งค่าใช้จ่ายและเวลา ใช้ระบบแคชในตัวของ Next.js หรือเก็บลงฐานข้อมูลก็ได้
ทำให้โมเดลตอบจากข้อมูลของคุณได้ ด้วยการแปลงเอกสารเป็นเวกเตอร์ ค้นหาส่วนที่เกี่ยวข้อง แล้วป้อนเป็นบริบทก่อนถามโมเดล
- 1
ตัดเอกสารเป็นชิ้น
แบ่งเอกสารยาวเป็นชิ้นย่อยขนาดพอดี ประมาณ 300 ถึง 800 โทเคน พร้อมเหลื่อมกันเล็กน้อย เพื่อไม่ให้บริบทขาดตอนเวลาค้นหา
- 2
สร้าง embedding
แปลงแต่ละชิ้นเป็นเวกเตอร์ด้วยโมเดล embedding รันผ่าน Ollama ในเครื่องก็ได้ แล้วเก็บลง vector database เพื่อค้นหาด้วยความใกล้เคียง
ollama pull nomic-embed-text # แล้วเรียก /api/embeddings เพื่อแปลงข้อความเป็นเวกเตอร์ - 3
ค้นหาส่วนที่เกี่ยวข้อง
เมื่อมีคำถามเข้ามา แปลงคำถามเป็นเวกเตอร์เช่นกัน แล้วดึงชิ้นที่ใกล้ที่สุดมาไม่กี่ชิ้น เป็นบริบทที่ตรงประเด็นที่สุด
- 4
ประกอบ prompt แล้วถาม
ใส่บริบทที่ค้นเจอไว้หน้าคำถาม สั่งให้โมเดลตอบโดยอ้างอิงเฉพาะข้อมูลที่ให้ ลดอาการแต่งเรื่องและทำให้ตรวจสอบที่มาได้
const prompt = `ใช้บริบทต่อไปนี้ตอบคำถาม บริบท: ${context} คำถาม: ${question}`;
เขียนคำสั่งให้โมเดลเข้าใจตรงที่ต้องการ ด้วยหลักไม่กี่ข้อ ระบุบทบาท ให้ตัวอย่าง กำหนดรูปแบบผลลัพธ์ และบอกขอบเขตให้ชัด
- 1
ระบุบทบาทและเป้าหมาย
บอกชัดว่าให้โมเดลสวมบทบาทอะไร และผลลัพธ์ที่ต้องการหน้าตาเป็นอย่างไร ยิ่งเฉพาะเจาะจง คำตอบยิ่งตรง
- 2
ให้ตัวอย่าง
แนบตัวอย่างอินพุตและเอาต์พุตที่ถูกต้องสักหนึ่งถึงสองชุด โมเดลจะเลียนแบบรูปแบบได้แม่นขึ้นมาก
- 3
กำหนดรูปแบบผลลัพธ์
อยากได้ JSON หรือหัวข้อ บอกโครงสร้างไปเลย จะนำไปใช้ต่อในโค้ดได้ง่ายและไม่ต้องมานั่งแกะ
ตอบเป็น JSON: { "หัวข้อ": string, "สรุป": string } - 4
บอกสิ่งที่ไม่ต้องการ
ระบุขอบเขตและข้อห้าม เช่น ห้ามเดาถ้าไม่รู้ ให้ตอบว่าไม่ทราบ ช่วยลดคำตอบที่มั่วและทำให้เชื่อถือได้มากขึ้น
เปรียบเทียบตัวเลือกยอดนิยมสำหรับเก็บเวกเตอร์ ตั้งแต่ตัวที่รันในเครื่องไปจนถึงบริการคลาวด์ พร้อมเกณฑ์ตัดสินใจที่ใช้ได้จริง
- 1
เริ่มจากขนาดข้อมูล
ถ้าข้อมูลหลักพันถึงหลักหมื่นชิ้น ตัวเล็กที่ฝังในแอปก็เพียงพอ ไม่ต้องตั้งเซิร์ฟเวอร์แยกให้ยุ่งยาก
- 2
ดูที่การ deploy
อยากคุมทุกอย่างเองเลือกตัวที่ self-host ได้ อยากเริ่มเร็วไม่ดูแลเซิร์ฟเวอร์เลือกบริการคลาวด์ ชั่งน้ำหนักระหว่างความสะดวกกับการควบคุม
- 3
เช็กฟีเจอร์กรองข้อมูล
หลายงานต้องค้นเวกเตอร์พร้อมกรองด้วยเงื่อนไข เช่น เฉพาะเอกสารของผู้ใช้คนนี้ ตรวจว่าตัวที่เลือกรองรับ metadata filter ดีพอ
การ fine-tune ไม่ใช่คำตอบของทุกปัญหา เรียนรู้ว่าเมื่อไหร่ prompt หรือ RAG เพียงพอ และเมื่อไหร่การปรับโมเดลจริงคุ้มค่า
- 1
ลอง prompt ให้สุดก่อน
ปัญหาส่วนใหญ่แก้ได้ด้วยการเขียน prompt ที่ดีและให้ตัวอย่าง ก่อนจะลงทุนเวลาและทรัพยากรกับการ fine-tune ลองทางนี้ให้เต็มที่
- 2
พิจารณา RAG ถ้าเป็นเรื่องความรู้
ถ้าต้องการให้โมเดลรู้ข้อมูลเฉพาะของคุณ RAG มักเหมาะกว่า เพราะอัปเดตข้อมูลได้ง่ายโดยไม่ต้องเทรนใหม่
- 3
Fine-tune เมื่อต้องการสไตล์หรือรูปแบบเฉพาะ
ถ้าต้องการให้โมเดลตอบด้วยน้ำเสียงหรือฟอร์แมตเฉพาะตัวอย่างสม่ำเสมอ การ fine-tune ด้วยตัวอย่างจำนวนมากจึงเริ่มคุ้ม