เมื่อเอเจนต์รับงานที่ซับซ้อนมากขึ้น พวกเขาจะพบกับปัญหาสองอย่าง:
- การทำงานให้เสร็จสมบูรณ์ในระดับขนาดใหญ่ได้อย่างน่าเชื่อถือ
- การจัดการบริบทของตัวเอง
เราได้ทดลองวิธีรับมือกับความท้าทายเหล่านี้ในรูปแบบที่เราเรียกว่า dynamic subagents นั่นคือ แทนที่จะออกคำสั่ง subagent ผ่านการเรียกใช้เครื่องมือทั่วไป เอเจนต์จะเขียนสคริปต์สั้นๆ ที่ขับเคลื่อนการทำงานของ subagent ซึ่งหมายความว่าโมเดลสามารถพึ่งพารูปแบบโค้ดที่มันเขียนได้ดี (เช่น การวนซ้ำ การแยกสาขา หรือการทำงานพร้อมกัน) เพื่อเขียนตรรกะการจัดระบบที่เหมาะสมกับงาน
ทำไมต้อง dynamic subagents?
Deep Agents รองรับ subagents อยู่แล้ว พวกมันแยกบริบท ปล่อยให้เอเจนต์หลักมอบหมายงานแต่ละหน่วย และเก็บผลลัพธ์ระหว่างกลางไว้นอกหน้าต่างบริบทหลัก แล้วทำไมเราถึงต้องการ dynamic subagents?
กับ subagents ปกติ พวกมันจะถูกเรียกทีละตัว โดยโมเดลหลักเรียกใช้โดยตรง ซึ่งใช้ได้ในระดับเล็ก แต่จะพังเมื่อคุณต้องสร้าง subagents หลายร้อยตัว หรือเมื่อตรรกะการจัดระบบมีเงื่อนไขหรือหลายเฟส
Dynamic subagents แก้ปัญหานี้ด้วย การจัดระบบเชิงโปรแกรม แทนที่จะเรียกใช้เครื่องมือทีละขั้น เอเจนต์จะเขียนสคริปต์สั้นๆ ที่จัดระบบและเรียก subagents แล้วรันในอินเทอร์พรีเตอร์ที่มีน้ำหนักเบา
ตัวอย่างที่ชัดเจน: หนึ่ง subagent ต่อหนึ่งหน้าในเอกสาร 300 หน้า แทนที่จะเรียกใช้เครื่องมือ subagent 300 ครั้ง เอเจนต์จะเขียนลูป:
1const results = await Promise.all(pages.map(page =>2 task({ description: `สรุปหน้า ${page.number}`, subagentType: "summarizer" })3));
สิ่งนี้ปลดล็อกสองสิ่งที่การจัดระบบแบบเรียกใช้เครื่องมือไม่สามารถทำได้อย่างน่าเชื่อถือ:
การครอบคลุมที่แน่นอนในระดับขนาดใหญ่ หากไม่มีโครงสร้าง เอเจนต์จะใช้ดุลยพินิจเกี่ยวกับขอบเขต โดยตรวจสอบ 75 จาก 500 รายการแล้วบอกว่าเสร็จแล้ว แต่ลูปแบบ dispatch ไม่ทำแบบนั้น การครอบคลุมกลายเป็นหลักประกันเชิงโครงสร้าง ไม่ใช่ปัญหาของวิศวกรรม prompt
การจัดระบบที่ซับซ้อนและเชื่อถือได้ การเขียนการจัดระบบเป็นโค้ดนั้นเชื่อถือได้มากกว่าการให้โมเดลสร้างใหม่เป็นลำดับของการเรียกใช้เครื่องมือ โดยเฉพาะอย่างยิ่งสำหรับแฟนเอาท์รวมท่อหลายเฟส หรือการแยกสาขาตามเงื่อนไข
นี่คือแนวคิดเดียวกันกับ workflows ใน Claude Code และ Recursive Language Models (RLMs): โมเดลเขียนโค้ด และโค้ดนั้นจัดส่งเอเจนต์เพิ่มเติม
เริ่มต้นใช้งาน
Dynamic subagents ต้องการสองสิ่ง: subagents สำหรับกระจายงาน และ code interpreter: รันไทม์ที่ปลอดภัยและเบา ซึ่งโมเดลจะเขียนและรันโค้ดการจัดระบบ Deep Agents มี code interpreter แบบเลือกใช้ได้ที่ใช้ QuickJS หากต้องการใช้ ให้ติดตั้งแพ็กเกจ QuickJS middleware จากนั้นส่ง CodeInterpreterMiddleware ผ่านอาร์กิวเมนต์ middleware ใน create_deep_agent
1pip install -U "deepagents[quickjs]"
1from deepagents import create_deep_agent2from langchain_quickjs import CodeInterpreterMiddleware34agent = create_deep_agent(5 model="openai:gpt-5.5",6 middleware=[CodeInterpreterMiddleware()],7)
Deep Agents มาพร้อมกับ subagent ทั่วไปในตัว ดังนั้นจึงมีโปรไฟล์ subagent ทั่วไปหนึ่งตัวที่สามารถใช้ใน workflows ได้ สำหรับ workflows เฉพาะทาง ให้กำหนดค่า custom subagents พร้อมชื่อ คำอธิบาย และ system prompts ของตัวเอง: ชื่อและคำอธิบายคือวิธีที่เอเจนต์รู้ว่าควรใช้บทบาทใด
เพื่อเรียกใช้ dynamic subagents ให้ prompt เอเจนต์ของคุณด้วยคำว่า "workflow" ดังนี้:
1result = await agent.ainvoke({2 "messages": [{"role": "user", "content": "รันเวิร์กโฟลว์ที่ตรวจสอบทุกไฟล์ใน src/routes/ และสรุปความเสี่ยงหลัก"}]3})
ใช้งานกับโค้ดดิ้งเอเจนต์
วิธีที่เร็วที่สุดในการลอง dynamic subagents คือการใช้ dcode ซึ่งเป็นโค้ดดิ้งเอเจนต์บนเทอร์มินัลของเราที่สร้างขึ้นโดยใช้ Deep Agent มันมาพร้อมกับ code interpreter ที่เปิดใช้งานแล้ว ดังนั้นไม่ต้องเชื่อมต่ออะไรเลย — dynamic subagents ทำงานได้ทันที
ติดตั้ง
1curl -LsSf https://langch.in/dcode | bash
รัน
1dcode
เพื่อเรียกใช้ dynamic subagents เพียงแค่ขอ "workflow" แทนที่จะทำงานด้วยตัวเอง หรือพยายามจัดการแฟนเอาท์ของ subagent ด้วยเครื่องมือ task ดั้งเดิม เอเจนต์จะเขียนสคริปต์การจัดระบบที่เรียกใช้ task() ส่วนกลางในตัวและรันใน code interpreter ตัวอย่างเช่น: “รัน workflow เพื่อตรวจสอบทุกไฟล์ใน src/ ว่ามี SQL injection หรือไม่”
เมื่อ subagents ถูกสร้างขึ้น dcode จะแสดงพวกมันแบบสดในแผง dynamic subagents ที่จัดกลุ่มเป็นเฟสตามการกระจายงาน

คุณสามารถลองวิธีนี้ได้เร็วที่สุดด้วย dcode แต่คุณยังสามารถใช้ในเครื่องมือที่คุณเลือกผ่าน ACP (เช่น Zed) ได้ด้วย
วิธีการทำงาน
เอเจนต์ได้รับ eval tool มันเขียน JavaScript ที่รันอย่างปลอดภัยภายใน interpreter เมื่อมีการกำหนดค่า subagents interpreter จะเปิดเผย task() ส่วนกลางในตัวที่จัดส่งพวกมันจากโค้ด ขึ้นอยู่กับงานที่ทำ โมเดลจะเขียนโค้ดที่แตกต่างกัน — ลูป, การแยกสาขา, Promise.all — และ interpreter จะรันมันอย่างแน่นอน

task() รับ description, subagentType และ responseSchema ที่เป็นตัวเลือก — เมื่อระบุ ผลลัพธ์จะเป็นอ็อบเจกต์ที่พิมพ์แล้ว พร้อมที่จะกรองหรือส่งต่อไปยังขั้นตอนถัดไป
1const result = await task({2 description: "ตรวจสอบ src/auth/login.ts เพื่อหาปัญหาความปลอดภัย",3 subagentType: "reviewer",4 responseSchema: {5 type: "object",6 properties: {7 severity: { type: "string", enum: ["high", "medium", "low"] },8 issues: { type: "array", items: { type: "string" } },9 },10 },11});1213const critical = result.severity === "high" ? result.issues : [];14critical; // โมเดลเห็นบรรทัดสุดท้าย
สำหรับรายละเอียดเพิ่มเติม โปรดดู Programmatic subagents และ Interpreters ในเอกสารประกอบ
รูปแบบการจัดระบบทั่วไป
dynamic workflows ของ Anthropic ทำให้รูปแบบการจัดระบบสำหรับการทำงานของเอเจนต์แบบขนานเป็นที่นิยม พวกมันไม่ใช่ฟีเจอร์ที่คุณเปิดใช้งาน แต่เป็นรูปทรงที่เกิดขึ้นตามธรรมชาติจากงาน และเอเจนต์จะปรับเปลี่ยนไปตามรูปแบบที่แตกต่างกันเมื่องานเปลี่ยนไป ตารางด้านล่างจับคู่แต่ละรูปทรงกับประเภทของงานที่เหมาะสม

ด้านล่างนี้เราจะลงลึกว่าแต่ละรูปแบบทำงานอย่างไรใน Deep Agents พร้อมตัวอย่างการติดตามแบบสด นอกจากนี้เรายังได้ทำวิดีโออธิบายรูปแบบทั้งหกนี้ ซึ่งคุณสามารถดูได้ ที่นี่
จำแนกและดำเนินการ
ไอเท็มจะถูกจำแนกก่อน จากนั้นแต่ละไอเท็มจะถูกจัดการโดย subagent เฉพาะทางตามการจำแนกของมัน ซึ่งช่วยให้คุณประมวลผลอินพุตที่หลากหลายซึ่งแต่ละไอเท็มต้องการความเชี่ยวชาญที่แตกต่างกัน

กรณีการใช้งาน: การคัดแยกตั๋วสนับสนุน บันทึกข้อผิดพลาด ข้อเสนอแนะจากผู้ใช้ หรือชุดไอเท็มใดๆ ที่ต้องการการจัดการที่แตกต่างกันตามประเภทของมัน
ตัวอย่าง: การคัดแยกงานค้างของตั๋วสนับสนุน เอเจนต์อ่านตั๋วและจำแนกแต่ละรายการเป็น bug, feature request หรือคำถาม bugs ไปยัง bug-investigator, feature requests ไปยัง feature-analyst และคำถามไปยัง support-responder ผลลัพธ์คือสรุปที่จัดกลุ่มตามหมวดหมู่
ดูตัวอย่างการติดตามได้ ที่นี่
แฟนเอาท์และสังเคราะห์
เอเจนต์กระจายงานประเภทเดียวกันไปยังหลายไอเท็มแบบขนาน จากนั้นรวมผลลัพธ์

กรณีการใช้งาน: การตรวจสอบโค้ดในไดเรกทอรี การวิเคราะห์เอกสารชุดหนึ่ง การประมวลผลไฟล์บันทึก การตรวจสอบแบบเดียวกันในหลายบริการ
ตัวอย่าง: การตรวจสอบความปลอดภัยแบบต่อไฟล์ในซอร์สทรี เอเจนต์ค้นหาไฟล์ TypeScript ทุกไฟล์ภายใต้ src/ และจัดส่ง security-reviewer หนึ่งตัวต่อไฟล์แบบขนาน จากนั้นรวมผลลัพธ์เป็นรายงานเดียวที่จัดลำดับความสำคัญพร้อมระดับความรุนแรงและบรรทัดที่ต้องเปลี่ยนแปลง
ดูตัวอย่างการติดตามได้ ที่นี่
การตรวจสอบแบบเป็นปฏิปักษ์
รูปแบบสองรอบ รอบแรกสร้างผลการค้นพบ รอบที่สองส่งแต่ละผลการค้นพบไปยังผู้ตรวจสอบอิสระ และเฉพาะผลการค้นพบที่ผ่านการยืนยันเท่านั้นที่จะถูกเก็บไว้ ซึ่งช่วยลดผลบวกลวงเมื่อความมั่นใจสำคัญกว่าความเร็ว

กรณีการใช้งาน: การตรวจสอบความปลอดภัยที่ผลบวกลวงมีค่าใช้จ่ายสูง การตรวจสอบการปฏิบัติตามข้อกำหนด การตรวจสอบใดๆ ที่ต้องการความมั่นใจสูงในผลการค้นพบ
ตัวอย่าง: การตรวจสอบความปลอดภัยที่ผลบวกลวงไม่สามารถยอมรับได้ ผู้ตรวจสอบสุ่มแหเพื่อหาช่องโหว่ที่อาจเกิดขึ้น จากนั้นแต่ละผลการค้นพบจะถูกส่งไปยังผู้ตรวจสอบอิสระที่อ่านโค้ดใหม่และส่งคืนคำตัดสิน CONFIRMED หรือ REFUTED เฉพาะผลการค้นพบที่ถูกยืนยันเท่านั้นที่จะอยู่ในรายงานสุดท้าย
ดูตัวอย่างการติดตามได้ ที่นี่
สร้างและกรอง
subagents หลายตัวสร้างวิธีแก้ปัญหาอิสระสำหรับปัญหาเดียวกัน เอเจนต์เปรียบเทียบ ให้คะแนน และกรองผลลัพธ์ในโค้ด โดยเก็บเฉพาะสิ่งที่ดีที่สุด

กรณีการใช้งาน: ข้อเสนอทางสถาปัตยกรรม กลยุทธ์การปรับโครงสร้าง รูปแบบเนื้อหา งานใดๆ ที่การสำรวจหลายตัวเลือกก่อนตัดสินใจให้ผลลัพธ์ที่ดีกว่า
ตัวอย่าง: การออกแบบ rate-limiter ใหม่ที่แข่งขันกัน จัดอันดับ เอเจนต์มีสถาปนิกเพื่อสร้างการออกแบบใหม่อิสระหลายแบบของ rate-limiter.ts แต่ละแบบเขียนในไฟล์ของตัวเองเพื่อไม่ให้เขียนทับกัน จากนั้นให้คะแนนตามความถูกต้องภายใต้ burst, การรองรับหลายอินสแตนซ์ และความซับซ้อน แบบที่แข็งแกร่งที่สุดชนะ พร้อมเหตุผลว่าทำไม
ดูตัวอย่างการติดตามได้ ที่นี่
ทัวร์นาเมนต์
รูปแบบต่างๆ ถูกเปรียบเทียบแบบตัวต่อตัวโดย subagent ผู้ตัดสิน โดยผู้ชนะจะผ่านเข้ารอบคัดออก

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

กรณีการใช้งาน: การค้นหาอย่างละเอียด การตรวจจับโค้ดที่ตายแล้ว การตรวจสอบ dependencies การกวาดใดๆ ที่คุณต้องการความสมบูรณ์แทนจำนวนผลลัพธ์ที่แน่นอน
ตัวอย่าง: การกวาดความปลอดภัยแบบรอบ เอเจนต์รันรอบสแกน ตรวจสอบสิ่งที่พบในโค้ด และเริ่มรอบอื่นก็ต่อเมื่อรอบก่อนหน้าพบปัญหาใหม่ มันหยุดเมื่อรอบไม่พบอะไรใหม่ มันรายงานผลการค้นพบที่รวบรวมและจำนวนรอบที่ใช้
ดูตัวอย่างการติดตามได้ ที่นี่
บทสรุป
Dynamic subagents เป็นวิธีการให้เอเจนต์มีความเป็นอิสระและความน่าเชื่อถือเพิ่มขึ้น โค้ดจัดการการครอบคลุมและบริบทระหว่างกลาง และโมเดลยังคงทำงานที่ต้องใช้ดุลยพินิจ รูปแบบข้างต้นเป็นจุดเริ่มต้น ในทางปฏิบัติ เอเจนต์จะประกอบและผสมผสานตามที่งานต้องการ
นี่คือแนวคิด Recursive Language Model ในรูปแบบที่ง่ายที่สุด เอเจนต์ที่เขียนโค้ด และโค้ดนั้นจัดส่งเอเจนต์เพิ่มเติม มันคือเอเจนต์ที่เรียกตัวเองแบบวนซ้ำ และไม่ได้ถูกจำกัดด้วยหน้าต่างบริบทหรือถูกบังคับให้อยู่ในเวิร์กโฟลว์ตายตัว เอเจนต์สามารถแบ่งปัญหาลงไปได้เท่าที่ต้องการ และประกอบชิ้นส่วนกลับเข้าใหม่ในรูปแบบที่เหมาะสม รูปแบบการจัดระบบที่เน้นไว้ข้างต้นเป็นเพียงภาพแรกเริ่มของสิ่งที่เป็นไปได้ แต่เพดานจะเพิ่มสูงขึ้นเรื่อยๆ เมื่อโมเดลมีความสามารถในการเขียนโค้ดดีขึ้น
Dynamic subagents คือวิธีที่ Deep Agents มอบสิ่งนี้ให้คุณได้ในวันนี้ เริ่มต้นโดยเพิ่ม code interpreter ให้กับเอเจนต์ของคุณ หรือใช้ dcode ซึ่ง dynamic subagents ทำงานได้ทันที
กิตติกรรมประกาศ
ร่วมเขียนโดย @colifran_ และ @huntlovell ขอบคุณ @hwchase17, @masondrxy และ @chester_curme สำหรับการตรวจสอบอย่างละเอียด





