เดือนที่แล้วผมนำพาเพื่อนร่วมงานที่เพิ่งย้ายตำแหน่งทำต้นแบบแชทบอทอัจฉริยะ ความต้องการง่ายมาก:ผู้ใช้ถาม โมเดลตอบ มีความจำบริบทนิดหน่อย พิมพ์แบบสตรีมมิ่งได้ ฟังดูเหมือนสองวันเสร็จ แต่ปรากฏว่าเขาเจอปัญหาทั้งการเขียน API Key แบบ hardcode ตรรกะการ retry และการเชื่อมต่อสตรีมมิ่ง ผมจึงรวบรวมกระบวนการทั้งหมดมาเป็นบทความนี้ ใช้เป็นบันทึกการสอนคนใหม่ได้
ขั้นตอนแรก:แยกความต้องการก่อน แล้วค่อยเลือกโมเดล
อย่าเพิ่งเขียนโค้ดตั้งแต่แรก ความต้องการด้านความสามารถของแชทบอทอัจฉริยะแบ่งได้ประมาณสามส่วน:การจดจำเจตนา ถามตอบความรู้ และการคุยเล่นหลายรอบ การจดจำเจตนาต้องเร็วและถูก ใช้ DeepSeek-V3 หรือ API ของ Qwen ก็เพียงพอแล้ว ส่วนถามตอบความรู้เกี่ยวข้องกับเอกสารภายในของคุณ ต้องใช้ RAG โมเดลต้องเข้าใจบริบทยาว ส่วนการคุยเล่นหลายรอบต้องการน้ำเสียงที่เหมาะสม Claude 4 Sonnet หรือ GPT-4o จะเสถียรกว่า
วิธีของผมคือใช้โมเดลทั่วไปตัวหนึ่งรันทั้ง pipeline ให้ผ่านก่อน แล้วค่อยแทนที่ทีละส่วน การ rout หลายโมเดลของ SiCore TokenWorks ช่วยให้ประหยัดเวลาในจังหวะนี้ โค้ดชุดเดียวกันแค่เปลี่ยนชื่อโมเดลก็เทียบผลลัพธ์ได้ ไม่ต้องแก้การ authenticate การเลือก API โมเดลขนาดใหญ่ไม่ใช่เลือกที่แรงที่สุด แต่เลือกที่ตรงกับงานที่สุด
ขั้นตอนที่สอง:จัดการ Key อย่าเขียนลงในโค้ด
การ hardcode Key ลงในซอร์สโค้ดเป็นความผิดพลาดที่มือใหม่เจอบ่อยที่สุด พอ commit ขึ้น git ก็เท่ากับเปิดเผย วิธีที่ถูกต้องคือใช้ environment variable ร่วมกับไฟล์ config แบ่งระดับ:ในเครื่องใช้ .env ส่วน test และ production ใช้ config center หรือบริการจัดการคีย์
การแยกสภาพแวดล้อมต้องจำสามข้อ:dev, test, production ใช้ Key คนละตัว;แต่ละ Key ตั้งวงเงินแยกกัน;Key ของ production ให้เฉพาะฝั่งเซิร์ฟเวอร์ ฝั่ง frontend เข้าถึงไม่ได้เด็ดขาด ในโปรเจกต์ของเราใช้ SiCore TokenWorks Key เดียวก็เรียก GPT-4o, Claude, DeepSeek, Qwen, ERNIE, Doubao และโมเดลหลักอื่นๆ ได้ ประหยัดเรื่องการดูแลระบบ authenticate หลายชุด การสลับ Key ตามสภาพแวดล้อมก็แค่เปลี่ยนตัวแปร
ขั้นตอนที่สาม:ห่อการเรียกและ retry เมื่อเกิดข้อผิดพลาด
โค้ดที่เรียก SDK ตรงๆ ไม่สามารถ maintain ได้ ต้องห่อหนึ่งชั้นเพื่อจัดการ timeout, rate limit และ retry อย่างเป็นระบบ แนวคิดคือ:ห่อการเรียกโมเดลเป็นฟังก์ชันเดียว พารามิเตอร์คือ messages กับชื่อโมเดล ภายในดักจับข้อผิดพลาดสามประเภท——network timeout, 429 rate limit และ 5xx ข้อผิดพลาดฝั่งเซิร์ฟเวอร์
กลยุทธ์ retry ใช้ exponential backoff รอ 1 วินาทีครั้งแรก 2 วินาทีครั้งที่สอง 4 วินาทีครั้งที่สาม สูงสุดสามครั้ง 429 ต้องจัดการเป็นพิเศษ ดู header retry-after ที่ส่งกลับมา อย่า retry ทุกข้อผิดพลาด ข้อผิดพลาดด้านพารามิเตอร์ retry ร้อยครั้งก็ไม่ช่วยอะไร คุณค่าของ model gateway อยู่ที่ชั้นนี้ รวม retry, การ degrade และ log ไว้ที่เดียว โค้ดธุรกิจแค่รับผลลัพธ์
ข้อเตือนเรื่องกับดัก:retry ต้อง idempotent ถ้าการเรียกมี side effect (เช่นเขียนฐานข้อมูล) ต้องยืนยันก่อนว่าครั้งก่อนล้มเหลวจริงหรือไม่
ขั้นตอนที่สี่:สตรีมมิ่ง output และการเชื่อมต่อ frontend
หัวใจของประสบการณ์แชทบอทคือ "เอฟเฟกต์เครื่องพิมพ์ดีด" ฝั่งเซิร์ฟเวอร์ใช้ SSE push token ทีละก้อนไปยัง frontend ฝั่ง frontend รับด้วย EventSource หรือ ReadableStream ของ fetch
จุดสำคัญฝั่ง backend:ตั้ง stream=True แยกวิเคราะห์ delta ที่ส่งกลับทีละก้อน เจอ [DONE] ก็จบ จุดสำคัญฝั่ง frontend:อย่า setState ทุกครั้งที่รับตัวอักษรหนึ่งตัว ให้สะสม 20 ถึง 50 มิลลิวินาทีแล้ว render เป็นชุด ไม่งั้นหน้าจะค้างเหมือนสไลด์
ยังมีกับดักอีกข้อ ระหว่างสตรีมมิ่งผู้ใช้อาจปิดหน้า ฝั่งเซิร์ฟเวอร์ต้องดักฟังเหตุการณ์การตัดการเชื่อมต่อ และยกเลิกคำขอ upstream ทันที ไม่งั้นก็เผา token เปล่าๆ ภายใต้การคิดค่าบริการตามปริมาณ การสูญเปล่าแบบนี้สะสมทีละน้อยก็มาก
ขั้นตอนที่ห้า:ตรวจสอบต้นทุนและการแจ้งเตือน
ก่อนเปิดใช้งานต้องทำ event tracking ทุกครั้งที่เรียก บันทึก:ชื่อโมเดล จำนวน token ขาเข้า จำนวน token ขาออก ระยะเวลา และ retry หรือไม่ ข้อมูลเหล่านี้สะสมหนึ่งสัปดาห์คุณถึงจะรู้ว่าเงินหมดไปตรงไหน
การแจ้งเตือนตั้งสองเส้น:ต้นทุนรายวันเกินขีดแจ้งเตือน และ token ของการเรียกครั้งเดียวผิดปกติแจ้งเตือน มีครั้งหนึ่งผู้ใช้วางเอกสารทั้งฉบับเข้ามา ครั้งเดียว input หลายหมื่น token ถ้าไม่มีการแจ้งเตือน บิลสิ้นเดือนจะดูไม่ดี
ประสบการณ์การประหยัดเงิน:งานความถี่สูงระดับง่ายอย่างการจดจำเจตนา เปลี่ยนไปใช้โมเดลจีนราคาถูก ต้นทุนลดได้หลายส่วน การจัดซื้อแบบรวม plus การจัดตารางพลังงานสีเขียว คือเหตุผลที่ราคาของแพลตฟอร์มรวมอย่าง SiCore TokenWorks ต่ำกว่าซื้อตรงจาก official เราเทียบแล้ว ในสถานการณ์ที่เรียกความถี่สูงความต่างชัดเจน
สรุปสั้นๆ:จุดยากของต้นแบบแชทบอทอัจฉริยะไม่ได้อยู่ที่โมเดล อยู่ที่รายละเอียดทางวิศวกรรม จัดการ Key ให้ดี เขียน retry ให้ถูก เชื่อมสตรีมมิ่งให้เสถียร และจับตาต้นทุนไว้ ที่เหลือก็แค่ปรับ prompt อยากเจาะลึกเรื่องการเชื่อมต่อหลายโมเดลแบบ unified และการ implement model routing ก็สามารถติดตามสายของ large model API gateway ต่อได้