ใช้หลาย AI model เป็นทีมที่มี role และป้ายราคา: route งานไปหา model ที่ถูกที่สุดที่ทำได้ดี
ผมเลิกใช้ model แพงตัวเดียวทำทุกอย่างมานานแล้ว แล้วหันมามอง LLM lineup เป็น "ทีมที่มี role + ป้ายราคาต่อ token" — บทความนี้คือกฎเจ็บๆ ที่ได้จากการ route งานจริง: อย่า delegate งานจิ๋ว, fan-out ต้อง diversify, และ proof-tier ทุก claim
อ่าน ~8 นาที
Thesis: มอง LLM lineup เป็นทีม ไม่ใช่ปุ่มวิเศษปุ่มเดียว
ช่วงแรกที่ผมใช้ AI ช่วย dev ผมทำผิดแบบคลาสสิก คือเปิด model ที่แพงและเก่งที่สุดตัวเดียว แล้วโยนทุกอย่างเข้าไป ตั้งแต่ตัดสินใจ architecture ยัน "ช่วยเปลี่ยนชื่อตัวแปรให้หน่อย" ผลคือบิลค่า token บวมโดยไม่จำเป็น เพราะงาน 80% ที่ผมโยนเข้าไปนั้น model ราคาถูกกว่า 10-20 เท่าก็ทำได้ดีพอๆ กัน
จุดเปลี่ยนคือตอนที่ผมเริ่มมอง lineup ของ model ทั้งหมด (ตัว premium สำหรับ reasoning, ตัวกลางสำหรับ implement, ตัวถูกสำหรับ summarize/bulk) เป็น ทีมที่มี role และมีป้ายราคาต่อ token ติดหัวแต่ละคน แล้วตั้งกฎง่ายๆ ว่า: route งานไปหา model ที่ถูกที่สุดที่ยังทำงานนั้นได้ดี ปล่อยให้ตัว premium ทำเฉพาะ decision จริงๆ — architecture, security review, final sign-off — ไม่ใช่แรงงาน copy-paste
หลักคิดนี้ transferable กับทุก provider เพราะราคาต่อ 1M token ต่างกันเป็นสิบเท่าเสมอ ยกตัวอย่างช่วงราคาคร่าวๆ (per 1M input): model summarize ราคาถูกอยู่หลัก $0.1x, ตัว implement กลางๆ หลัก $1, ส่วน model reasoning ระดับ flagship อยู่หลัก $10+ ความต่าง 100 เท่าระหว่างหัวและท้าย table คือเหตุผลทั้งหมดว่าทำไม routing ถึงคุ้ม
กฎที่ 1: Fixed per-session tax ทำให้ "อย่า delegate งานจิ๋ว"
นี่คือบทเรียนที่ counter-intuitive ที่สุด และเป็นอันที่คนพลาดกันเยอะ หลายคนพออ่านหลักการข้างบนก็สรุปว่า "งั้น delegate ทุกอย่างไป model ถูก" — ซึ่งผิด สำหรับงานเล็ก
เหตุผลคือทุกครั้งที่คุณเรียก agent ตัวอื่นมาทำงาน มันมี ภาษีคงที่ (fixed tax) ที่ตัดไม่ได้: tool schema, system prompt, handoff context ที่ต้องส่งเข้าไปให้มันเข้าใจงาน ภาษีนี้กินไปหลายพันถึงหลักหมื่น token ก่อนที่มันจะพิมพ์คำตอบตัวแรกด้วยซ้ำ
ผมเลยตั้ง break-even rule ไว้ชัดๆ:
งาน < 3 ไฟล์ AND < ~100 บรรทัด diff AND เป็น single-shot Q&A
→ ทำเองใน model ปัจจุบันเลย (แม้จะเป็นตัวแพง)
เพราะค่า handoff + system prompt ของ agent ถูก > ค่าที่ประหยัดได้
งานหลายไฟล์ / refactor ยาว / อ่าน log เป็นพันบรรทัด
→ ค่อย delegate ไป model ถูก คุ้มแน่นอน
วิธีคิดคือ: การ delegate คุ้มก็ต่อเมื่อ ปริมาณงานจริง ใหญ่พอจะกลบภาษีคงที่ ถ้างานจิ๋วกว่าภาษี การส่งต่อคือการจ่ายแพงขึ้นเพื่อให้ได้คุณภาพเท่าเดิมหรือแย่กว่า จำไว้ว่า "cheapest model" ไม่เท่ากับ "cheapest total cost" เสมอไป
กฎที่ 2: Fan-out review ต้อง diversify สองแกน
เวลาต้องการ review หนักๆ (เช่นก่อน merge โค้ดที่แตะ auth หรือเรื่องเงิน) ผมใช้เทคนิค fan-out คือกระจายโค้ดชิ้นเดียวให้หลาย model ช่วยกันมองพร้อมกัน แล้วเอาผลมา synthesize แต่มันมี pitfall สองอันที่ทำให้ fan-out ไร้ค่าถ้าไม่ระวัง
Pitfall แรก: ถาม model เดิมซ้ำหลายรอบ — ถ้าคุณถาม model เดียวกันด้วยคำถามเดียวกัน 5 ครั้ง คุณไม่ได้ 5 ความเห็น คุณได้ความเห็นเดิม 5 ครั้ง blind spot ของมันก็ blind เหมือนเดิมทุกครั้ง fan-out ที่มีค่าจริงต้อง diversify สองแกน:
- แกน lens (มุมมอง): ตัวหนึ่งดู correctness, ตัวหนึ่งดู security/auth, ตัวหนึ่งดู durability/race condition — สั่งให้แต่ละตัวมองคนละมุม
- แกน model family (ค่าย): ให้ lens ต่างกันไปอยู่คนละ model family กัน เพราะ model จากค่ายเดียวกันมักถูก train บนวิธีคิดคล้ายๆ กัน มันจะพลาดจุดเดียวกันพร้อมกัน
Pitfall ที่สอง: ให้ worker แต่ละตัวไปไล่อ่าน repo เอง — ถ้า orchestrator ปล่อยให้ worker 6 ตัวต่างคนต่าง read ไฟล์เดียวกัน input cost จะโตแบบ quadratic (จำนวน worker × ขนาดไฟล์) วิธีที่ถูกคือ orchestrator อ่านไฟล์ครั้งเดียว แล้ว paste excerpt ที่จำเป็นเข้าไปใน prompt ของแต่ละ worker — worker ไม่ต้องเห็น repo ทั้งก้อน เห็นแค่ชิ้นที่มันต้อง review
# แนวคิด orchestrator (pseudo)
excerpt = read_once("src/auth/session.ts") # อ่านครั้งเดียว
review_a = ask(model="family-X", lens="correctness", code=excerpt)
review_b = ask(model="family-Y", lens="security", code=excerpt)
review_c = ask(model="family-Z", lens="durability", code=excerpt)
# จุดขายของ cross-model: ใช้ "ความเห็นตรงกัน" เป็น false-positive filter
# ถ้า 3 ค่ายเห็นตรงกันว่าตรงนี้บั๊ก → น่าเชื่อสูง
# ถ้าตัวเดียวโวยคนเดียว → น่าจะ noise ค่อยไปตรวจมือ
ผลพลอยได้ที่ผมชอบมากคือ cross-model agreement กลายเป็น false-positive filter ในตัว ถ้า model จาก 3 ค่ายเห็นตรงกันว่าบรรทัดนี้มีปัญหา ความน่าเชื่อสูงมาก แต่ถ้ามีตัวเดียวโวย มักเป็น noise ที่ไปเช็คมือทีหลังได้
กฎที่ 3: Cross-family review จับบั๊กที่ same-family มองไม่เห็น
ขยายความจากกฎที่แล้ว: บั๊กประเภท durability กับ race condition เป็นตัวอย่างชัดที่ model ค่ายเดียวกันมักพลาดพร้อมกัน เพราะ pattern การมองปัญหา concurrency ของมันถูกหล่อมาคล้ายกัน การบังคับให้ reviewer มาจากคนละ family จึงไม่ใช่แค่ "เผื่อไว้" แต่เป็นการเพิ่มโอกาสจับ class ของบั๊กที่ family เดิมมี blind spot ร่วมกัน
ประเด็น engineering ที่สำคัญคือ: อย่าเชื่อ self-declaration อย่าให้ระบบมัน "บอกเอง" ว่า reviewer ตัวนี้มาจากคนละค่าย ให้ enforce จาก invocation record จริง — คือ log ว่า request นี้ยิงไป endpoint/model id ไหนจริงๆ แล้วตรวจว่า family ไม่ซ้ำกับคนเขียนโค้ด ระบบ orchestration ที่ผมวางไว้จะ reject ถ้า reviewer family ตรงกับ author family เพราะการันตีจาก metadata ที่ตรวจย้อนได้ ไม่ใช่จากคำพูดของ model
กฎที่ 4: Proof-or-it's-not-done — tag proof-tier ทุก claim
AI agent มีนิสัยเสียอย่างหนึ่งที่อันตรายมาก: มันชอบพูดว่า "should work", "tests should pass", "looks good" โดยไม่ได้รันอะไรจริงเลย ผมเลยตั้งกฎเหล็กว่า งานจะ done ได้ก็ต่อเมื่อรันจริง + จับ output จริง + output พิสูจน์พฤติกรรมที่อ้าง
วิธีบังคับให้มันซื่อสัตย์คือให้ tag ทุก claim ด้วย proof-tier เป็น column แยก:
| Task | ผลลัพธ์ | Proof tier |
|-------------------------|----------|-------------------------------------|
| แก้ query filter | ผ่าน | runtime — รันจริงเห็น 13/13 pass |
| เพิ่ม type ให้ response | ผ่าน | compile — tsc/lint ผ่าน แต่ยังไม่รัน |
| refactor helper | ผ่าน | static — อ่าน diff เฉยๆ ยังไม่ทดสอบ |
| อ้างว่า deploy สำเร็จ | (ห้าม) | none — ยังไม่มีหลักฐาน ห้ามรายงาน done|
สี่ tier ที่ผมใช้: runtime (รันจริงเห็น output ถูก — เชื่อได้สุด), compile (tsc/lint/build ผ่าน), static (แค่อ่าน diff/grep), และ none (ไม่มีหลักฐาน — ห้ามนับเป็น done เด็ดขาด) กฎเสริมที่สำคัญ: ถ้าคุณ mutate state อะไร (เขียน DB, สร้างไฟล์, แก้ config) ต้อง verify ด้วยคำสั่งอิสระเสมอ — อย่าเชื่อ exit code ของคำสั่งที่ทำ mutation เอง ให้ยิง query อีกตัวไปอ่านผลลัพธ์ยืนยัน
และถ้า verify ไม่ได้จริงๆ (ไม่มี tooling, framework ไม่รองรับ) ให้ บอก gap ตรงๆ ว่าขาดอะไร แล้วเสนอทางเลือก — อย่า fake ให้ดูเหมือนผ่าน การรายงานว่า "static-only เพราะรัน runtime ไม่ได้ ต้องติดตั้ง X ก่อน" มีค่ากว่าการโกหกว่า pass มหาศาล
กฎที่ 5: Propose-first — อย่าจ่ายเงินเย็นๆ และอย่าสั่งงานคลุมเครือ
ทุก prompt ที่ยิงไป paid model คือการจ่ายเงิน ผมเลยมีกฎ propose-first: ก่อนจะ spawn งานที่มีค่าใช้จ่าย ให้เขียน scope + ประมาณ cost + เสนอ 2-3 option พร้อม trade-off ก่อน แล้วรอ OK ชัดๆ (ความเงียบ ≠ อนุมัติ) การมีขั้น propose ป้องกันไม่ให้ agent ไป burn เงินกับ direction ที่ผิดตั้งแต่ต้น
คู่กันคือกฎ elaborate-before-execute: ถ้า instruction สั้นและคลุมเครือ (เช่น "fix this", "ดูให้หน่อย" — pronoun ไม่มี antecedent, verb+noun ไม่มี scope) อย่าเพิ่งทำ ให้เอา model ราคาถูก ขยาย prompt นั้นให้ชัดก่อน (ค่าไม่กี่สตางค์) แล้วโชว์สิ่งที่ตีความได้ + ชี้ assumption 1-2 ข้อ ก่อนลงมือด้วย model แพง การจ่าย $0.001 เพื่อกันการทำงานผิดทิศด้วย model $15/1M คือ ROI ที่ดีที่สุดใน workflow นี้
อีกสองเสาที่ทำให้ทั้งระบบไม่บวม token:
- Shared context-pack เป็น external memory: เขียนสรุปโครง repo / decision สำคัญไว้ในไฟล์ compact ไฟล์เดียว แล้วให้ทุก agent อ้างจากไฟล์นั้น แทนที่จะให้แต่ละตัวไล่ re-read repo ใหม่ทุกครั้ง — memory ภายนอกกัน input โตซ้ำซ้อน
- Review ladder ตาม risk trigger: ไม่ใช่ทุก diff ต้อง review หนักเท่ากัน งานปกติใช้ unit test + lint ก็พอ แต่พอ diff ไปแตะ trigger เสี่ยง (เงิน, auth, RLS, migration, secrets) ค่อยดันขึ้นไป fan-out cross-family เต็มรูปแบบ — จ่าย review หนักเฉพาะจุดที่พังแล้วเจ็บ
สรุป: กฎที่เอาไปใช้ได้เลย
- มอง LLM lineup เป็นทีมมี role + ป้ายราคา — route งานไปหา model ถูกสุดที่ทำได้ดี ปล่อย premium ทำแค่ decision (architecture / security / final review)
- อย่า delegate งานจิ๋ว — fixed per-session tax (tool schema + system prompt) ตัดไม่ได้ งาน <3 ไฟล์ / ~100 บรรทัดทำเองในตัวปัจจุบันถูกกว่า "cheapest model" ≠ "cheapest total cost"
- Fan-out ต้อง diversify 2 แกน — lens ต่าง + model family ต่าง ไม่ใช่ถามตัวเดิมซ้ำ; orchestrator อ่านไฟล์ครั้งเดียวแล้ว paste excerpt กัน input โต quadratic; ใช้ cross-model agreement เป็น false-positive filter
- บังคับ cross-family จาก invocation record — ไม่ใช่ self-declare เพื่อจับ durability/race ที่ same-family มองไม่เห็นพร้อมกัน
- Proof-or-it's-not-done — tag ทุก claim เป็น runtime / compile / static / none; mutate ต้อง verify ด้วยคำสั่งอิสระ; verify ไม่ได้ให้บอก gap ตรงๆ ห้าม fake
- Propose-first ก่อนจ่ายเงิน + elaborate prompt สั้น/คลุมด้วย model ถูกก่อน + shared context-pack เป็น external memory + review ladder ยกระดับตาม risk trigger
สุดท้าย หัวใจของทั้งหมดไม่ใช่ "ใช้ AI ให้เยอะ" แต่คือ วินัยในการ route: จ่ายแพงเฉพาะตอนที่ตัดสินใจสำคัญ จ่ายถูกกับแรงงาน และพิสูจน์ทุกอย่างที่อ้างว่าทำเสร็จ วินัยนี้ทำให้บิลลดลงหลายเท่าโดยคุณภาพงานดีขึ้น เพราะแต่ละ model ได้ทำในสิ่งที่มันเก่งจริง




