10 คะแนน โดย GN⁺ 4 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เปลี่ยนจากวิธีที่คอยพรอมป์ต์ coding agent โดยตรงในทุกเทิร์น ไปสู่รูปแบบการทำงานที่ ออกแบบระบบที่พรอมป์ต์เอเจนต์แทนเรา
  • ลูป คือ เป้าหมายแบบเรียกซ้ำ ที่เมื่อกำหนดวัตถุประสงค์แล้ว AI จะวนทำซ้ำจนกว่างานจะเสร็จ โดยประกอบด้วยองค์ประกอบราวห้าส่วน
  • องค์ประกอบทั้งห้าคือ Automations, Worktrees, Skills, Plugins·connectors, Sub-agents ซึ่งปัจจุบันทั้ง Claude Code และ Codex ต่างก็มีครบทั้งห้า
  • องค์ประกอบที่หกคือ หน่วยความจำ ซึ่งอาจเป็นไฟล์ markdown หรือบอร์ด Linear ที่เก็บสถานะไว้นอกบทสนทนาเดียว เพื่อชดเชยข้อจำกัดของโมเดลที่ลืมทุกครั้งเมื่อเริ่มรันใหม่
  • ทั้งหมดยังอยู่ในช่วงเริ่มต้น และต้องระวัง ต้นทุนโทเค็น ให้มาก การตรวจสอบและความเข้าใจยังคงเป็นหน้าที่ของมนุษย์ (build the loop, stay the engineer)

ความหมายของ Loop Engineering และที่มาของแนวคิด

  • Loop engineering คือการ แทนที่คนที่พรอมป์ต์เอเจนต์ด้วยระบบที่เราสร้างขึ้นเอง โดยเราเป็นผู้ออกแบบระบบที่ทำหน้าที่นั้นแทน
    • ลูปคือ เป้าหมายแบบเรียกซ้ำ (recursive goal) ที่เมื่อกำหนดวัตถุประสงค์แล้ว AI จะวนไปเรื่อย ๆ จนกว่างานจะเสร็จ
    • นี่อาจเป็นรูปแบบการทำงานแห่งอนาคตกับ coding agent แต่ยังอยู่ในระยะเริ่มต้น และต้องระวัง ต้นทุนโทเค็น อย่างมาก (รูปแบบการใช้งานจะแตกต่างกันมากตามว่าเป็นคนที่ token rich หรือ token poor)
  • คำพูดที่ถูกอ้างถึง
    • Peter Steinberger: "เลิกพรอมป์ต์ coding agent ตรง ๆ แล้วมา ออกแบบลูป ที่พรอมป์ต์เอเจนต์แทน"
    • Boris Cherny (หัวหน้าฝ่าย Claude Code ของ Anthropic): "ตอนนี้ผมไม่ได้พรอมป์ต์ Claude โดยตรงแล้ว แต่รัน ลูปที่พรอมป์ต์ Claude และกำหนดว่าจะให้ทำอะไร งานของผมคือการเขียนลูป"
  • ตลอดราว 2 ปีที่ผ่านมา แนวทางคือให้พรอมป์ต์ที่ดีและคอนเท็กซ์ที่มากพอ แล้วคุยกันทีละเทิร์นในลักษณะ ที่เรายังถือเอเจนต์ไว้ในมือเหมือนเครื่องมือโดยตรง แต่วิธีนั้นกำลังจะสิ้นสุดลง
  • ตอนนี้คือการสร้าง ระบบเล็ก ๆ ที่คอยค้นหางาน กระจายงาน ตรวจสอบ บันทึกสิ่งที่เสร็จแล้ว และตัดสินใจว่างานถัดไปคืออะไร จากนั้นให้ระบบนั้นไปสะกิดเอเจนต์อีกที
    • แนวคิดนี้อยู่เหนือบทความก่อนหน้าเรื่อง agent harness engineering (สภาพแวดล้อมที่เอเจนต์หนึ่งตัวทำงานอยู่) และ factory model (ระบบสำหรับสร้างซอฟต์แวร์)
    • เป็น harness ที่รันด้วยตัวจับเวลา สร้าง helper ขนาดเล็ก และคอยป้อนงานให้ตัวเอง
  • เรื่องนี้ไม่ใช่ปัญหาของเครื่องมืออีกต่อไป — เมื่อ 1 ปีก่อน ถ้าอยากได้ลูปต้องเขียนและดูแล bash ก้อนใหญ่เอง แต่ตอนนี้องค์ประกอบต่าง ๆ ถูกฝังมาในผลิตภัณฑ์แล้ว
    • รายการของ Steinberger แทบตรงกับแอป Codex แบบเป๊ะ และแทบเหมือนกับ Claude Code เช่นกัน ดังนั้นแทนที่จะเถียงกันว่าเครื่องมือไหนดีกว่า ควร ออกแบบลูปที่ทำงานได้บนทั้งสองฝั่ง

องค์ประกอบทั้งห้าของลูปและหน่วยความจำ

  • ลูปต้องมีห้าอย่าง และมีที่เพิ่มมาอีกหนึ่งแห่งไว้จำสถานะ
    • Automations — ทำงานตามตารางเวลาเพื่อค้นหาและคัดแยก (triage) ด้วยตัวเอง
    • Worktrees — ทำให้เอเจนต์สองตัวที่ทำงานขนานกันไม่ชนกัน
    • Skills — บันทึกความรู้เกี่ยวกับโปรเจกต์ที่เอเจนต์ไม่ต้องเดาเอาเอง
    • Plugins·connectors — เชื่อมเอเจนต์เข้ากับเครื่องมือที่ใช้อยู่แล้ว
    • Sub-agents — ให้ฝั่งหนึ่งคิดแนวทาง และอีกฝั่งหนึ่งตรวจสอบ
  • อย่างที่หกคือ หน่วยความจำ เช่นไฟล์ markdown หรือบอร์ด Linear ที่อยู่นอกบทสนทนาเดียว และเก็บสิ่งที่ทำเสร็จแล้วรวมถึงสิ่งที่จะทำต่อ
    • มันดูง่ายเกินไป แต่เป็นกลเม็ดเดียวกันที่เอเจนต์ระยะยาวทุกตัวพึ่งพา (บทความก่อนหน้าเรื่อง long-running agents)
    • โมเดลจะลืมทุกอย่างระหว่างการรันแต่ละครั้ง ดังนั้นหน่วยความจำต้องอยู่บนดิสก์ ไม่ใช่อยู่ในคอนเท็กซ์ — เอเจนต์อาจลืม แต่ repo ไม่ลืม
  • ตอนนี้ทั้งสองผลิตภัณฑ์มีครบทั้งห้าส่วนแล้ว ต่างกันแค่ชื่อ แต่ความสามารถเหมือนกัน

Automations — จังหวะการเต้นของหัวใจของลูป

  • Automations คือสิ่งที่ทำให้ลูปไม่ใช่แค่การรันครั้งเดียว แต่เป็น ลูปจริง ๆ
    • ในแอป Codex สามารถสร้างได้จากแท็บ Automations โดยเลือกโปรเจกต์ พรอมป์ต์ที่จะให้รัน รอบเวลา และจะใช้ local checkout หรือ background worktree
    • การรันที่พบอะไรบางอย่างจะถูกส่งไปยัง Triage inbox ส่วนการรันที่ไม่พบอะไรเลยจะถูกเก็บถาวรเองโดยอัตโนมัติ
    • OpenAI ใช้สิ่งนี้ภายในองค์กรกับงานน่าเบื่อ เช่น triage issue รายวัน สรุปความล้มเหลวของ CI เขียน commit briefing และไล่ล่าบั๊กที่เพิ่งถูกเพิ่มเข้ามาในสัปดาห์ก่อน
    • ระบบอัตโนมัติสามารถ เรียกใช้ skill ได้ จึงไม่ต้องแปะกำแพงข้อความคำสั่งยาว ๆ แต่ใช้การเรียก $skill-name เพื่อทำให้งานซ้ำ ๆ ดูแลง่ายขึ้น
  • Claude Code ไปถึงจุดเดียวกันด้วย scheduling และ hooks
    • ใช้ /loop เพื่อรันพรอมป์ต์หรือคำสั่งเป็นช่วง ๆ ตั้งเวลาแบบ cron ได้ และยิงคำสั่งเชลล์ผ่าน hooks ในจังหวะเฉพาะของ lifecycle ของเอเจนต์
    • ถ้าต้องการให้มันรันต่อแม้ปิดโน้ตบุ๊กไปแล้ว ก็สามารถย้ายทั้งหมดไปที่ GitHub Actions ได้
  • ยังมี primitive อีกตัวภายในเซสชันที่เป็นแก่นสำคัญของบทความนี้
    • /loop จะรันซ้ำตามรอบเวลาที่กำหนด
    • /goal จะทำต่อไปจนกว่าเงื่อนไขที่เราเขียนไว้จะเป็นจริง และหลังจบแต่ละเทิร์นจะมี โมเดลเล็กอีกตัวแยกต่างหากมาตรวจว่าทำเสร็จหรือยัง เพื่อไม่ให้เอเจนต์ที่เขียนโค้ดเป็นคนตรวจงานตัวเอง
      • ตัวอย่างเช่น กำหนดเงื่อนไขว่า "ทุกเทสต์ใน test/auth ต้องผ่าน และ lint ต้อง clean" แล้วเราก็ลุกไปทำอย่างอื่นได้
    • Codex ก็มี /goal แบบเดียวกัน ทำงานต่อเนื่องโดยส่งต่อทีละเทิร์นจนกว่า เงื่อนไขหยุดที่ตรวจสอบได้ จะเป็นจริง และรองรับ pause, resume, clear

Worktrees — ให้การทำงานขนานไม่กลายเป็นความโกลาหล

  • ทันทีที่รันเอเจนต์มากกว่าหนึ่งตัว ไฟล์ก็เริ่มชนกัน และนี่คือจุดที่ทุกอย่างพังได้
    • การที่เอเจนต์สองตัวเขียนไฟล์เดียวกันก็ปวดหัวพอ ๆ กับวิศวกรสองคน commit ลงบรรทัดเดียวกันโดยไม่คุยกัน
    • git worktree แก้ปัญหานี้ได้ — มันแชร์ประวัติ repo เดียวกัน แต่แต่ละตัวมีไดเรกทอรีทำงานแยกบน branch ของตัวเอง จึงทำให้การแก้ไขของเอเจนต์ฝั่งหนึ่งไม่ไปโดน checkout ของอีกฝั่ง
  • Codex รองรับ worktree ในตัว จึงให้หลายเธรดแตะ repo เดียวกันพร้อมกันได้โดยไม่ชนกัน
  • Claude Code ก็ให้การแยกแบบเดียวกันผ่าน git worktree, แฟลก --worktree ที่เปิดเซสชันด้วย checkout ของตัวเอง และการตั้งค่า isolation: worktree สำหรับ subagent (แต่ละ helper จะได้ checkout ใหม่ที่ล้างทิ้งเองเมื่อทำงานเสร็จ)
  • worktree ช่วยตัดปัญหาการชนกันเชิงกลไกออกไป แต่ ตัวคุณยังเป็นคอขวดอยู่ดี — จำนวนที่รันได้จริงไม่ได้ขึ้นกับเครื่องมือ แต่ขึ้นกับแบนด์วิดท์ในการรีวิวของคุณเอง (บทความก่อนหน้าเรื่อง the orchestration tax)

Skills — เพื่อไม่ต้องอธิบายโปรเจกต์ใหม่ทุกครั้ง

  • skill คือวิธีหยุดการต้องอธิบายคอนเท็กซ์ของโปรเจกต์เดิมซ้ำ ๆ ในทุกเซสชันเหมือนปลาทองความจำสั้น
    • ทั้งสองเครื่องมือใช้ฟอร์แมตเดียวกัน — โฟลเดอร์ที่มี SKILL.md สำหรับเก็บคำสั่งและเมตะดาตา พร้อมสคริปต์ เอกสารอ้างอิง หรือแอสเซ็ตเพิ่มเติมแบบเลือกได้
    • Codex เรียกใช้ได้ด้วย $ หรือ /skills หรือจะให้มันรันเองเมื่อพบว่างานตรงกับคำอธิบายของ skill ก็ได้ ดังนั้นแทนที่จะเขียนให้อัจฉริยะ ควรเขียนแบบ สั้น ตรง และน่าเบื่อ จะดีกว่า
    • Claude Code ก็ทำงานแบบเดียวกัน (บทความก่อนหน้าเรื่อง agent skills)
  • skill คือที่ที่ เจตนา (intent) ไม่กลายเป็นต้นทุนที่ต้องจ่ายซ้ำ
    • เอเจนต์เริ่มทุกเซสชันจากสภาพเย็น และจะเติมช่องว่างของเจตนาด้วยการเดาอย่างมั่นใจ (บทความก่อนหน้าเรื่อง the intent debt)
    • skill คือการเขียนเจตนานั้นไว้ข้างนอก — เช่น convention, ขั้นตอน build, หรือข้อจำกัดประเภท "เพราะเหตุการณ์ครั้งนั้น เราไม่ทำแบบนี้" เขียนไว้ครั้งเดียว แล้วเอเจนต์จะอ่านทุกครั้งที่รัน
    • ถ้าไม่มี skill ลูปจะต้องสรุปความเข้าใจทั้งโปรเจกต์ใหม่จากศูนย์ในทุกวัฏจักร แต่ถ้ามี มันจะ สะสมและทบต้นเหมือนดอกเบี้ย
  • skill คือฟอร์แมตสำหรับการเขียน ส่วน plugin คือวิธีการแจกจ่าย — ถ้าต้องการแชร์ข้ามหลาย repo หรือแพ็กเป็นชุด ก็ค่อยทำเป็น plugin (Codex และ Claude Code เหมือนกันทั้งคู่)

Plugins·connectors — ให้ลูปแตะต้องเครื่องมือจริงได้

  • ลูปที่มองเห็นแค่ไฟล์ระบบอย่างเดียวคือลูปขนาดเล็ก
    • connector ที่อิง MCP ทำให้เอเจนต์อ่าน issue tracker, query ฐานข้อมูล, เรียก staging API, หรือส่งข้อความใน Slack ได้
    • ทั้ง Codex และ Claude Code ต่างพูดภาษา MCP ดังนั้น connector ที่ทำให้ฝั่งหนึ่งมักจะใช้กับอีกฝั่งได้เลย
    • plugin จะรวม connector กับ skill ไว้ด้วยกัน เพื่อให้เพื่อนร่วมทีมติดตั้งได้ทีเดียว โดยไม่ต้องสร้างทั้งหมดขึ้นใหม่จากความจำ
  • นี่คือความต่างระหว่างเอเจนต์ที่บอกว่า "มีแพตช์แก้ตรงนี้นะ" กับ ลูปที่เปิด PR เชื่อมตั๋ว Linear และส่ง ping เข้าแชนเนลเมื่อ CI เป็นสีเขียว
    • connector คือเหตุผลที่ลูปไม่ใช่แค่พูดถึงความเป็นไปได้ แต่สามารถ ลงมือกระทำในสภาพแวดล้อมจริง ได้

Sub-agents — แยกคนทำออกจากคนตรวจ

  • โครงสร้างที่มีประโยชน์ที่สุดในลูปอย่างไม่ต้องสงสัยคือ การแยกฝั่งที่เขียนโค้ดออกจากฝั่งที่ตรวจสอบ
    • โมเดลที่เขียนโค้ดเองมักใจดีกับการให้คะแนนการบ้านตัวเองเกินไป
    • เอเจนต์ตัวที่สองซึ่งมีคำสั่งต่างออกไป และบางครั้งใช้คนละโมเดล จะจับสิ่งที่ตัวแรกปล่อยผ่านเพราะมันโน้มน้าวตัวเองไปแล้วได้
  • Codex จะสร้าง subagent เมื่อร้องขอเท่านั้น จากนั้นรันพร้อมกันและรวมผลลัพธ์เป็นคำตอบเดียว
    • สามารถกำหนดเอเจนต์ของตัวเองด้วย ไฟล์ TOML ใน .codex/agents/ (name, description, instructions และมี model กับ reasoning effort เป็นตัวเลือก)
    • ตัวอย่างเช่น reviewer ด้านความปลอดภัยอาจใช้โมเดลที่แรงและตั้ง high effort ส่วน explorer อาจใช้โมเดลเร็วแบบ read-only
  • Claude Code ก็ทำแบบเดียวกันผ่าน subagents ใน .claude/agents/ และ agent teams ที่ส่งงานถึงกัน
    • การแบ่งงานที่พบได้บ่อยในทั้งสองเครื่องมือคือ เอเจนต์หนึ่งสำรวจ เอเจนต์หนึ่งลงมือทำ และอีกเอเจนต์หนึ่งตรวจเทียบกับสเปก (บทความก่อนหน้าเรื่อง the code agent orchestra และ adversarial code review)
  • เพราะลูปจะทำงานตอนที่เราไม่ได้มองอยู่ จึงต้องมี ผู้ตรวจสอบที่เชื่อถือได้ (verifier) เพื่อให้เรากล้าลุกออกจากที่นั่ง
    • subagent แต่ละตัวใช้โมเดลและการเรียกเครื่องมือของตัวเอง จึง กินโทเค็นเพิ่มขึ้น และควรใช้ในจุดที่การมีความเห็นที่สองคุ้มค่า
    • สิ่งนี้เองคือสิ่งที่ /goal ของ Claude Code ทำอยู่ภายใน — ใช้โมเดลใหม่มาตัดสินความสำเร็จแทนฝั่งที่ลงมือทำ เป็นการนำการแยก maker/checker มาใช้กับเงื่อนไขหยุดด้วย

ลูปหนึ่งชุดหน้าตาเป็นอย่างไร

  • เมื่อนำทั้งหมดมารวมกัน เธรดเดียวจะกลายเป็นแผงควบคุมขนาดเล็ก และนี่คือรูปแบบหนึ่งที่ใช้ซ้ำได้
    • automation รันใน repo ทุกเช้า โดยพรอมป์ต์ของมันจะเรียกใช้ triage skill เพื่ออ่านความล้มเหลวของ CI เมื่อวาน issue ที่ยังเปิดอยู่ และ commit ล่าสุด แล้วบันทึกผลลงไฟล์ markdown หรือบอร์ด Linear
    • สำหรับแต่ละรายการที่คุ้มค่าจะทำต่อ เธรดจะเปิด worktree ที่แยกจากกัน แล้วมอบหมายให้ sub-agent ร่างการแก้ไข จากนั้น sub-agent ตัวที่สองจะรีวิวร่างนั้นเทียบกับ project skill และเทสต์ที่มีอยู่
    • connector ทำให้ลูปเปิด PR และอัปเดตตั๋วได้ ส่วนสิ่งที่ลูปจัดการไม่ไหวจะเข้าไปอยู่ใน triage inbox
    • state file คือกระดูกสันหลังของทั้งหมด — มันจำได้ว่าเคยลองอะไรไปแล้ว อะไรผ่านแล้ว และอะไรยังเปิดค้างอยู่ เพื่อให้การรันในเช้าวันถัดไปต่อจากจุดที่วันนี้หยุดไว้ได้
  • ประเด็นสำคัญคือ ไม่มีขั้นตอนไหนในนั้นที่ต้องพรอมป์ต์ทีละอย่าง แต่เป็นการ ออกแบบไว้ครั้งเดียว — ไม่ว่าจะเป็น Codex หรือ Claude Code องค์ประกอบก็เหมือนกัน ลูปจึงเหมือนกัน

สิ่งที่ลูปยังทำแทนไม่ได้

  • ลูปเปลี่ยนลักษณะของงาน แต่ไม่ได้ลบมนุษย์ออกไป และยิ่งลูปดีขึ้น ก็ยิ่งมีปัญหาสามอย่างที่คมชัดขึ้น
  • การตรวจสอบยังเป็นหน้าที่ของคุณอยู่ดี
    • ลูปที่รันแบบไม่มีคนเฝ้า ก็คือลูปที่ทำพลาดแบบไม่มีคนเฝ้าได้เช่นกัน
    • เหตุผลที่ต้องแยก verifier sub-agent ออกจาก maker ก็เพื่อทำให้คำว่า "เสร็จแล้ว" ของลูปมีความหมาย แต่ถึงอย่างนั้นคำว่า "done" ก็ยังเป็น คำกล่าวอ้าง ไม่ใช่ข้อพิสูจน์ (บทความก่อนหน้าเรื่อง code review in the age of AI — งานคือการส่งมอบโค้ดที่ยืนยันแล้วว่าใช้งานได้)
  • ความเข้าใจจะเสื่อมหากปล่อยทิ้งไว้
    • ยิ่งลูปช่วยให้ส่งมอบโค้ดที่เราไม่ได้เขียนเองได้เร็วขึ้น ช่องว่างระหว่างสิ่งที่มีอยู่กับสิ่งที่เราเข้าใจจริงก็ยิ่งกว้างขึ้น
    • นี่คือ comprehension debt และลูปที่ลื่นไหลจะขยายช่องว่างนั้นให้เร็วขึ้น ถ้าเราไม่อ่านสิ่งที่ลูปสร้างขึ้นมา
  • ท่าทีที่สบายเกินไปคือท่าทีที่อันตราย
    • เมื่อปล่อยให้ลูปรันเอง เราอาจหยุดมีความเห็นของตัวเองและรับสิ่งที่มันส่งกลับมาแบบตรง ๆ ได้ง่าย (cognitive surrender)
    • การออกแบบลูปเป็นยารักษาได้ถ้าทำด้วยวิจารณญาณ แต่เป็นตัวเร่งได้ถ้าทำเพื่อหลีกเลี่ยงการคิด — พฤติกรรมเดียวกัน แต่ผลลัพธ์ตรงข้ามกันสุดขั้ว

จงสร้างลูป แต่จงยังเป็นวิศวกร

  • สิ่งนี้ดูเหมือนตัวอย่างล่วงหน้าของวิธีที่งานจะพัฒนาไป แต่ถ้าไม่รีวิวโค้ดด้วยตัวเอง หรือพึ่งลูปอัตโนมัติอย่างเดียว ก็อาจติดอยู่ใน วงจรขาลงที่คุณภาพผลิตภัณฑ์ลดลงและจมลึกลงเรื่อย ๆ
  • ตั้งค่าลูปได้ แต่การ พรอมป์ต์เอเจนต์โดยตรงก็ยังมีประสิทธิภาพอยู่ หัวใจสำคัญคือการหาสมดุลที่เหมาะสม
  • ลูปเดียวกันอาจให้ผลตรงข้ามกันสุดขั้วในคนละคน — ในสองคนที่สร้างลูปเดียวกัน คนหนึ่งจะใช้มันเพื่อเร่งงานที่ตนเข้าใจลึกอยู่แล้ว ส่วนอีกคนจะใช้มันเพื่อหลีกเลี่ยงการทำความเข้าใจงาน
    • ลูปไม่รู้ความต่างนี้ แต่คุณรู้
  • นี่คือเหตุผลที่การออกแบบลูปไม่ง่ายกว่าการทำ prompt engineering และจริง ๆ แล้วยากกว่า — ประเด็นของ Cherny ไม่ใช่ว่างานง่ายขึ้น แต่คือ จุดที่เกิด leverage ได้ย้ายที่ไปแล้ว
  • สรุปคือ จงสร้างลูป แต่จงสร้างมัน ราวกับว่าคุณจะยังเป็นวิศวกร ไม่ใช่แค่คนกดปุ่มเริ่มต้น

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

 
shakespeares 3 시간 전

การตรวจสอบก็ยังคงเป็นหน้าที่ของตัวเอง

ความเข้าใจถ้าปล่อยทิ้งไว้ก็เสื่อมถอย

ท่าที่สบายคือท่าที่อันตราย

=> สุดท้ายแล้วจำเป็นต้องตรวจสอบด้วยตัวเอง และต้องมีการเขียนพรอมป์ต์เพื่อทำให้งานที่ทำซ้ำๆ น้อยลง