64 คะแนน โดย GN⁺ 2026-03-17 | 10 ความคิดเห็น | แชร์ทาง WhatsApp
  • แชร์วิธีการที่เป็นรูปธรรมในการพัฒนาซอฟต์แวร์ด้วย LLM โดยใช้เวิร์กโฟลว์มัลติเอเจนต์แบบ สถาปนิก-นักพัฒนา-ผู้รีวิว เพื่อดูแลโปรเจ็กต์ระดับหลายหมื่นบรรทัดให้มีอัตราบั๊กต่ำ
  • เดิมทีสนใจ การสร้างอะไรบางอย่าง มากกว่าการเขียนโปรแกรมเอง และเมื่อ LLM เขียนโค้ดได้ดีขึ้น ก็ทำให้โฟกัสกับการสร้างได้เต็มที่
  • ทักษะวิศวกรรมอย่าง การออกแบบสถาปัตยกรรมระบบและการตัดสินใจเลือกสิ่งที่ถูกต้อง สำคัญกว่าความสามารถในการเขียนโค้ดมาก
  • ใช้หลายโมเดลผสมกันเพื่อยกระดับคุณภาพการรีวิวโค้ด และแยกใช้ จุดแข็งกับจุดอ่อนของแต่ละโมเดลตามบทบาท
  • เปิดเผยเซสชันการเพิ่มฟีเจอร์อีเมลจริงทั้งหมด พร้อมบันทึกอย่างละเอียดถึง กระบวนการร่วมมือระหว่างมนุษย์ที่เป็นผู้นำกับ LLM ตั้งแต่การตัดสินใจด้านสถาปัตยกรรมไปจนถึง QA

ข้อดีของการสร้างด้วย LLM

  • เคยคิดว่าตัวเองชอบการเขียนโปรแกรม แต่จริงๆ แล้วชอบ การสร้างสิ่งต่างๆ มากกว่า และเมื่อ LLM เขียนโปรแกรมได้เก่งขึ้น ก็สามารถสร้างของได้อย่างต่อเนื่องไม่หยุด
  • ช่วงที่ Codex 5.2 ออกใหม่ๆ และล่าสุดมาถึง Opus 4.6 ก็สามารถเขียนซอฟต์แวร์ได้ด้วย อัตราข้อบกพร่องที่ต่ำมาก ซึ่งอาจต่ำกว่าการเขียนโค้ดด้วยมือเองอย่างมีนัยสำคัญ
  • ก่อนหน้านี้พอทำงานไป 2~3 วัน โค้ดมักจะเข้าสู่สภาพที่ดูแลต่อไม่ได้ แต่ตอนนี้สามารถทำงานต่อเนื่องเป็นสัปดาห์และขยาย โค้ดที่ใช้งานได้จริงหลายหมื่นบรรทัด อย่างมั่นคง
  • ไม่ใช่ว่าทักษะวิศวกรรมหมดความสำคัญ แต่ ย้ายตำแหน่งไป: จากความสามารถในการเขียนโค้ดให้ถูกต้อง ไปสู่การตัดสินใจที่ทำให้ระบบมีสถาปัตยกรรมที่ถูกต้องและใช้งานได้จริง
  • ในโปรเจ็กต์ที่รู้เทคโนโลยีพื้นฐานดีอยู่แล้ว (เช่น แบ็กเอนด์) แม้มี SLoC หลายหมื่นบรรทัดก็ยังไม่มีปัญหา แต่กับเทคโนโลยีที่ยังไม่คุ้นเคย (เช่น แอปมือถือ) โค้ดก็ยังพังเละได้จาก การสะสมของการตัดสินใจที่ผิด
  • ในยุคแรกของ LLM (หลัง davinci) จำเป็นต้องตรวจ ทุกบรรทัดของโค้ด ต่อมาจึงลดลงเหลือระดับ ฟังก์ชัน และปัจจุบันมีแนวโน้มว่าแค่ตรวจในระดับ สถาปัตยกรรมทั้งหมด ก็พอ ปีหน้าอาจไม่จำเป็นแม้กระทั่งสิ่งนี้

โปรเจ็กต์ที่สร้างด้วยวิธีนี้

  • Stavrobot: ผู้ช่วยส่วนตัว LLM ที่เน้นความปลอดภัย ทำงานอย่างการจัดการปฏิทิน ตรวจสอบเวลาว่าง ค้นคว้า ขยายความสามารถตัวเองด้วยการเขียนโค้ด แจ้งเตือน และจัดการงานบ้านแบบอัตโนมัติ คุณค่าหลักไม่ใช่ฟีเจอร์เดียวที่โดดเด่น แต่คือการ ขจัดความรำคาญเล็กๆ น้อยๆ หลายพันอย่าง
  • Middle: อุปกรณ์จี้ขนาดเล็ก สำหรับอัด voice memo แล้วแปลงเป็นข้อความส่งผ่าน webhook จุดสำคัญคือพกติดตัวได้ตลอดและใช้งานได้แทบไม่มีแรงเสียดทาน
  • Sleight of Hand: โปรเจ็กต์ศิลปะนาฬิกาแขวนผนังที่เดินติ๊กไม่สม่ำเสมอในระดับวินาที แต่ยังแม่นยำเสมอในระดับนาที มีหลายโหมด เช่น ติ๊กแบบแปรผัน 500ms~1500ms หยุดแบบสุ่มหลังจากเร่งหรือชะลอความเร็วที่สังเกตได้ยาก หรือเร่งเป็นสองเท่าแล้วรอ 30 วินาที
  • Pine Town: แคนวาสมัลติเพลเยอร์แบบไร้ขีดจำกัด ที่แต่ละคนได้ที่ดินเล็กๆ ของตัวเองไว้สำหรับวาดภาพ เป็น โปรเจ็กต์ทุ่งหญ้าเชิงโต้ตอบ
  • โปรเจ็กต์ทั้งหมดนี้สร้างด้วย LLM และแม้ส่วนใหญ่จะไม่เคยอ่านโค้ดด้วยตัวเอง แต่ก็ เข้าใจสถาปัตยกรรมและการทำงานภายในของแต่ละโปรเจ็กต์เป็นอย่างดี

เครื่องมือ Harness

  • ตอนนี้ใช้ OpenCode เป็น harness และก็เคยมีประสบการณ์ที่ดีกับ Pi เช่นกัน
  • ข้อกำหนดจำเป็นของ harness มีสองข้อ:
    • ต้องใช้โมเดลหลากหลายจากหลายบริษัทได้: harness แบบ first-party ส่วนใหญ่ (Claude Code, Codex CLI, Gemini CLI) รองรับเฉพาะโมเดลของตัวเอง จึงไม่ตรงเงื่อนไขนี้
    • ต้องให้ custom agent เรียกหากันเองได้อย่างอิสระ

ทำไมต้องใช้หลายโมเดล

  • มองโมเดลแต่ละตัวเหมือนเป็นคนคนหนึ่งได้ และแม้จะรีเซ็ต context ก็ยังมีแนวโน้ม รักษาความเห็น จุดแข็ง และจุดอ่อนเดิมไว้
  • หากให้โมเดลรีวิวโค้ดที่ตัวเองเขียน มักมีแนวโน้มเห็นด้วยกับตัวเองจนแทบไม่มีประโยชน์ แต่ถ้าให้ อีกโมเดลหนึ่งมารีวิว คุณภาพจะดีขึ้นมาก
  • ณ ตอนนี้ Codex 5.4 ละเอียดและเข้มงวด จึงเหมาะกับการรีวิว, Opus 4.6 มักสอดคล้องกับการตัดสินใจที่ผู้เขียนเองจะเลือก, และ Gemini 3 Flash บางครั้งก็เสนอวิธีแก้ที่โมเดลอื่นพลาดไป
  • เพื่อให้ได้ผลลัพธ์ดีที่สุด จำเป็นต้อง ผสมใช้ทุกโมเดล

เวิร์กโฟลว์: สถาปนิก → นักพัฒนา → ผู้รีวิว

  • เวิร์กโฟลว์ประกอบด้วย สถาปนิก นักพัฒนา และผู้รีวิว 1~3 คน โดยทั้งหมดถูกตั้งค่าเป็น OpenCode agent (ไฟล์สกิล)
  • เหตุผล 3 ข้อที่ใช้หลายเอเจนต์:
    • ใช้โมเดลราคาแพง (Opus) กับ การวางแผน และใช้โมเดลราคาถูกกว่า (Sonnet) กับ การเขียนโค้ด เพื่อประหยัดโทเค็น
    • การ รีวิวด้วยโมเดลที่ต่างกัน ช่วยจับปัญหาคนละแบบ
    • สามารถ แยกสิทธิ์ตามบทบาท ได้ (เช่น อ่านอย่างเดียว vs เขียนได้)
  • การใช้สองเอเจนต์ที่เป็นโมเดลเดียวกันและมีสิทธิ์เท่ากัน ก็เหมือนคนคนเดียวสลับใส่หมวกคนละใบ จึงไม่มีความหมายมากนัก
  • ไฟล์สกิลนั้น เขียนด้วยมือเองทั้งหมด ถ้าให้ LLM เขียนสกิลให้ ก็เหมือนให้ใครสักคนเขียนว่า “จะเป็นวิศวกรที่ยอดเยี่ยมได้อย่างไร” แล้วส่งคู่มือนั้นกลับมาให้พร้อมบอกว่า “เอาล่ะ ตอนนี้จงเก่งซะ”

บทบาทสถาปนิก

  • สถาปนิก (ปัจจุบันคือ Claude Opus 4.6) เป็น เอเจนต์เพียงตัวเดียวที่คุยโดยตรง และควรเป็นโมเดลที่ทรงพลังที่สุด
  • จะเริ่มจากการเสนอเป้าหมายของฟีเจอร์หรือบั๊กที่เฉพาะเจาะจงมาก แล้วคุยกันได้นานถึง 30 นาที จนกว่าจะตกลงเป้าหมาย ข้อจำกัด และ trade-off ได้ชัดเจน
  • ผลลัพธ์ที่ได้คือ แผนระดับค่อนข้างต่ำ ลงไปถึงระดับไฟล์และฟังก์ชันแต่ละตัว
  • นี่ไม่ใช่แค่การ prompt ตรงๆ แต่เป็นกระบวนการ ร่วมกันก่อรูปแผน ด้วยความช่วยเหลือของ LLM เมื่อ LLM ผิดหรือไม่ตรงกับวิธีที่ต้องการ ก็จะมีการแก้ไขอย่างมาก และนี่คือส่วนสำคัญที่ทำให้โปรเจ็กต์ “เป็นของตัวเอง”
  • ตั้งค่าไว้ว่า ห้ามเริ่มลงมือ implement จนกว่าจะพูดคำว่า "approved" อย่างชัดเจน เพราะบางโมเดลมีแนวโน้มรีบเริ่มทำทันทีเมื่อคิดว่าตัวเองเข้าใจแล้ว
  • หลังอนุมัติแล้ว สถาปนิกจะแบ่งงานเป็น task และ บันทึกอย่างละเอียดไว้ในไฟล์แผน ก่อนเรียกนักพัฒนา

บทบาทนักพัฒนา

  • นักพัฒนาสามารถใช้โมเดลที่อ่อนกว่าแต่ คุ้มค่าโทเค็นกว่า ได้ (Sonnet 4.6)
  • เพราะแผนถูกกำหนดมาให้เหลือดุลยพินิจน้อยที่สุด บทบาทนี้จึงเป็นการ ลงมือ implement การเปลี่ยนแปลงตามแผนอย่างเคร่งครัด
  • เมื่อ implement เสร็จแล้วก็จะเรียกผู้รีวิว

บทบาทผู้รีวิว

  • ผู้รีวิวแต่ละคนจะตรวจแผนและ diff พร้อมวิจารณ์ อย่างอิสระจากกัน
  • อย่างน้อยจะใช้ Codex เสมอ บางครั้งเพิ่ม Gemini และในโปรเจ็กต์สำคัญก็เพิ่ม Opus ด้วย
  • ฟีดแบ็กจะส่งกลับไปยังนักพัฒนา และถ้าเกิด ความเห็นไม่ตรงกันระหว่างผู้รีวิว ก็จะเอสคาเลตกลับไปหาสถาปนิก
  • Opus เก่งในการเลือกฟีดแบ็กที่ถูกต้อง และบางครั้งก็ เพิกเฉยต่อฟีดแบ็กที่จุกจิกเกินไป ซึ่งมีโอกาสก่อปัญหาจริงต่ำเมื่อเทียบกับภาระในการแก้

แนวทางโดยรวมและรูปแบบความล้มเหลว

  • วิธีนี้ทำให้สามารถ เข้าใจการตัดสินใจทั้งหมดตั้งแต่ระดับสูงกว่าฟังก์ชันขึ้นไป และนำความรู้นั้นไปใช้กับงานต่อเนื่องได้
  • เมื่อ LLM มี จุดบอด ที่มองข้ามองค์ประกอบบางอย่างใน codebase การชี้ว่า “ต้องใช้ Y” จะทำให้ LLM รับรู้การมีอยู่ของ Y และเปลี่ยนไปใช้แนวทางที่ดีกว่า
  • ถ้าไม่คุ้นเคยกับเทคโนโลยีนั้นมากพอ ก็จะจับการตัดสินใจผิดของ LLM ไม่ได้ และ การตัดสินใจผิดจะซ้อนทับกัน จนสุดท้ายไปถึงจุดที่แก้ไม่ออก
  • รูปแบบความล้มเหลวที่พบบ่อยคือเมื่อบอกซ้ำๆ ว่า “โค้ดใช้งานไม่ได้” LLM จะตอบว่า “เข้าใจแล้ว! จะแก้ให้” แล้ว กลับทำให้แย่ลงกว่าเดิม
  • ดังนั้นแม้จะยังไม่คุ้นกับเทคโนโลยีนั้น ก็ยังควรพยายาม ทำความเข้าใจให้มากที่สุดตั้งแต่ขั้นวางแผน

เซสชันจริง: เพิ่มการรองรับอีเมลให้ Stavrobot

  • มีการเผยแพร่ข้อความเต็มของเซสชันจริงพร้อมคำอธิบายประกอบ โดยตัดการเรียกใช้เครื่องมือและส่วนที่เยิ่นเย้อออก แต่ คงบทสนทนาและกระบวนการตัดสินใจไว้ตามเดิม
  • บทสนทนาเริ่มต้น: เสนอเป้าหมายระดับสูง (“อยากเพิ่มการรองรับอีเมลให้บอตนี้”) → LLM อ่านโค้ดและเข้าใจแพตเทิร์นปัจจุบัน (inbound webhook → enqueueMessage → ประมวลผลด้วย LLM → ตอบกลับ) จากนั้นจึงตั้งคำถามด้านการออกแบบ
    • วิธี inbound (IMAP polling, webhook, SMTP server), วิธี outbound, จะรองรับสองทางหรือไม่, สถาปัตยกรรม (container แยก vs in-process), การจัดการอีเมล HTML, การติดตามเธรด, ไฟล์แนบ ฯลฯ
  • การตัดสินใจด้านดีไซน์: ใช้ Cloudflare Email Worker webhook สำหรับ inbound, ใช้ SMTP client สำหรับ outbound, รองรับบทสนทนาแบบสองทางเต็มรูปแบบ, ประมวลผลแบบ in-process, แปลงเป็น Markdown, มองอีเมลเป็นรายการอิสระ, รองรับไฟล์แนบ
  • ข้อเสนอการออกแบบรายละเอียดจาก LLM: เสนอข้อกังวล 7 ข้อและแนวทางที่เจาะจง เช่น MIME parsing (ใช้ mailparser), การยืนยันตัวตนของ webhook (shared secret), ความจำเป็นของ subject สำหรับ outbound, การจัดการอีเมลที่มีแต่ HTML, อัตลักษณ์ของที่อยู่ From, การจัดการอีเมลที่ถูก forward, ไฟล์แนบของ outbound
    • เสนอให้ทำ payload ของ Worker ให้เรียบง่ายเป็น { from, to, raw } แล้วค่อย parse ฝั่งเซิร์ฟเวอร์
    • สรุปโครงสร้าง Config, flow ของ inbound/outbound, รายการไฟล์ที่ต้องแก้ และรายการ explicit non-goal (YAGNI)
  • การขัดเกลาแผน: มนุษย์ชี้ว่ามีจุดตกหล่นอย่างการอัปเดต README.md และ config.example.toml รวมถึงการลบการตรวจสอบ E.164 ออกจากหน้ารายการ allowlist อีเมล → LLM จึงรวมสิ่งเหล่านี้เข้าแผน
  • แบ่งเป็น 6 งานย่อย: Config/Dependency, allowlist, การตรวจสอบ allowlist ฝั่ง UI/แบ็กเอนด์, inbound email, outbound email, README/test
  • การปรับปรุงเพิ่มเติม: เสนอไอเดียให้ฟิลด์ SMTP เป็น optional เพื่อให้ inbound email ใช้งานได้แม้ไม่มีการตั้งค่า SMTP → แล้วก็ implement ตามนั้น
  • บั๊กที่พบใน QA: อีเมลของเจ้าของไม่ได้ถูกลงทะเบียน จึงทำให้ข้อความถูกทิ้ง → สาเหตุคือ seedOwnerInterlocutor ไม่ได้รวมช่องทางอีเมล → จึงแก้ไข
  • ข้อเสนอเพื่อปรับปรุงโค้ด: รีแฟกเตอร์จาก if block แบบฮาร์ดโค้ดแยกตามช่องทาง ไปเป็นการ วนลูปรายการช่องทางที่ใช้ร่วมกัน หลังถกกันเรื่องกรณีพิเศษการแปลงค่าตัวเลขของ Telegram จึงตัดสินใจใช้ลูปเฉพาะใน seedOwnerInterlocutor และคง getOwnerIdentities ไว้ดังเดิมเพราะความต่างของประเภทข้อมูลเป็นประเด็นสำคัญ
  • allowlist อีเมลแบบ wildcard: เพิ่มการรองรับ wildcard ระดับโดเมน ในรูปแบบ *@example.com เพราะจำเป็นกับ use case จริงที่ใช้อีเมลแบบใช้ครั้งเดียว
    • ประเด็นด้านความปลอดภัย: เพื่อป้องกันการโจมตีแบบ "me@mydomain.com"@evildomain.com จึงแปลง * เป็น [^@]* เพื่อ ไม่ให้ข้ามขอบเขตของ @
    • รองรับ partial wildcard อย่าง myusername+*@gmail.com ด้วย
    • มนุษย์ชี้ว่าหากใช้ regular expression ต้อง escape อักขระอื่นทั้งหมด ของที่อยู่อีเมลด้วย
  • ยืนยันว่า wildcard ใช้งานได้ทั้งในฟิลด์เจ้าของและ allowlist โดยใช้ helper function matchesEmailEntry ร่วมกัน
  • ใช้เวลาทั้งหมดในการทำฟีเจอร์นี้ ประมาณ 1 ชั่วโมง

บทส่งท้าย

  • ไม่ใช่เซ็ตอัปที่หวือหวามาก แต่ใช้งานได้ดีมาก และพอใจกับ ความน่าเชื่อถือ ของกระบวนการ
  • รัน Stavrobot แบบ 24/7 มาเกือบหนึ่งเดือนแล้ว และ เสถียรมาก

10 ความคิดเห็น

 
kurthong 2026-03-17

เหมือนกับเมื่อราว 20 ปีก่อนที่กระแสเว็บเอดิเตอร์หรือบล็อกสำเร็จรูปทำให้มีโฮมเพจหรือโพสต์จำนวนมากที่ไม่มีใครอ่านเกิดขึ้นเป็นจำนวนมาก ในยุค AI ตอนนี้ก็มีลักษณะคล้ายกัน แต่การสร้างแอปแบบคัสตอมและแบ่งปันกระบวนการหรือรูทีนเหล่านั้น ผมคิดว่าเป็นทรัพย์สินที่ยอดเยี่ยมและมีคุณค่าอย่างมาก แน่นอนว่าส่วนตัวผมมองว่ายุคนี้ไม่ใช่การสร้างแอปหรือบริการที่ทำเงินด้วย AI แต่คือการสร้างเครื่องมือคัสตอมที่ตัวเองต้องการได้อย่างง่ายดายเพื่อเพิ่มผลิตภาพ

 
zetbouaka 2026-03-18
  • ถ้าให้โมเดลรีวิวโค้ดที่ตัวเองเขียน มันมักมีแนวโน้มจะเห็นด้วยกับตัวเองจนแทบไม่มีความหมาย แต่ถ้าให้โมเดลอื่นเป็นคนรีวิว คุณภาพจะดีขึ้นอย่างมาก

จริง ๆ แล้วมนุษย์ก็คงเป็นแบบนั้นเหมือนกัน เหตุผลที่มนุษย์ควรแสวงหาความหลากหลายก็คงเพราะแบบนี้ไม่ใช่หรือ...

 
newbie1004 2026-03-17

เพราะเป็นโมเดลภาษา จึงเหมาะที่ให้โมเดลราคาแพงเป็นคนวางแผน

 
tested 2026-03-17

> โมเดลราคาแพง (Opus) ใช้สำหรับการวางแผน ส่วนโมเดลราคาถูก (Sonnet) ใช้สำหรับเขียนโค้ด เพื่อประหยัดโทเค็น

หลายคนก็มักใช้ Sonnet สำหรับวางแผน แล้วใช้ Opus สำหรับลงมือเขียนโค้ดจริง แต่ที่นี่กลับกันนะ

 
wegaia 2026-03-18

ผมก็ให้ opus กับ codex โต้ตอบกันไปมาสำหรับการวางแผนอยู่เหมือนกัน
ให้ opus เขียนโค้ด แล้วก็ให้ opus อีกตัวกับ codex รีวิวโค้ดอีกที
ที่รู้สึกระหว่างทำก็คือ ไม่ว่าจะ AI หรือคนก็ตาม ดูเหมือนจะเก่งเรื่องคอยจับผิดคนอื่นกันจริง ๆ..

 
remin1994 2026-03-17

https://code.claude.com/docs/ko/model-config#opusplan-model-settings

ผมก็ตั้งค่าโมเดลของ Claude เป็น opusplan แล้วใช้อยู่เหมือนกัน

 
pencil6962 2026-03-17

ในการตั้งค่าพื้นฐานของ Oh my opencode นั้น opus จะเป็นคนวางแผน ส่วนการลงมือพัฒนา จะให้โมเดลที่เบากว่าเป็นผู้ทำ

 
princox 2026-03-17

รอบตัวผมเห็นเขาวางแผน/ออกแบบด้วย Sonnet แล้วก็เขียนโค้ดด้วย GLM-5 กันน่ะครับ..

 
developerohn 2026-03-17

ผมเองก็วางแผนให้ Sonnet ทำหน้าที่วางแผน และให้ Opus ลงมือเขียนโค้ดอยู่เหมือนกัน แต่วิธีของผู้เขียนอาจจะมีประสิทธิภาพมากกว่าก็ได้

 
bigseoul 2026-03-17

ผมก็วางแผนด้วย Opus ให้ Codex high ช่วยรีวิว แล้วให้ sonet หรือ codex medium ทำโค้ดจริงครับ