ทำไม agent ต้องมีขอบเขต
ตลอดเส้นทางในเว็บนี้ เราปั้น domain ฟู้ดเดลิเวอรีก้อนเดียวกันมาตลอด — ค้น domain ทั้งทีมด้วย Event Storming ปั้น model Order ให้ถือกฎธุรกิจไว้ใน code พิสูจน์ว่ามันทำงานถูกด้วย test ทั้งพีระมิด แล้วในคอร์ส Bounded Contexts & Integration เราแยก Order ก้อนเดียวที่บวมเป็น god object ออกเป็น4 bounded context เพราะคำว่า “order” หมายถึงคนละอย่างในครัว ไรเดอร์ และบิลลิ่ง คอร์สนี้เดินต่อจากจุดเดิม แต่เปลี่ยนสนาม: ธุรกิจอยากได้ ผู้ช่วย AI มาช่วยทีมปฏิบัติการ — ตอบลูกค้า ติดตามออเดอร์ ดูแลงานหลังร้าน สัญชาตญาณแรกคือปั้น agent ตัวเดียวที่ทำได้ทุกอย่าง และนั่นคือกับดักเดิมในคราบใหม่
คอร์สนี้คือคอร์ส AI-engineering คอร์สแรกของแก่น มันไม่ได้สอน SDK ตัวไหนเป็นพิเศษ แต่เป็นการ สังเคราะห์: เอาเครื่องมือเชิงกลยุทธ์ของ DDD ที่คุณใช้คล่องแล้ว — bounded context, ubiquitous language, context map, ACL — มาเป็นวินัยในการออกแบบระบบ agent วิทยานิพนธ์ของทั้งคอร์สประโยคเดียว: AgentAgentระบบซอฟต์แวร์ที่รับเป้าหมายแล้ววางแผน-ตัดสินใจ-เรียกใช้ tool ได้เองหลายรอบ (agentic loop) โดยไม่ต้องมีมนุษย์กำกับทุกก้าว ต่างจากโปรแกรมทั่วไปที่รันตามลำดับคำสั่งตายตัว — ในคอร์สนี้มองแต่ละ agent เหมือน1 Bounded Context ที่ต้องมีขอบเขต ภาษา และหน้าที่ของตัวเองชัดเจนArchitecture หนึ่งตัวควรเป็น Bounded ContextBounded Contextขอบเขตที่ ubiquitous language และ model หนึ่งชุดมีความหมายคงเส้นคงวา นอกขอบเขตนี้คำเดียวกันอาจหมายถึงคนละอย่าง — เมื่อออกแบบระบบ agent ให้คิดว่าแต่ละ agent (หรือกลุ่ม agent ที่ทำงานร่วมกัน) ควรรับผิดชอบ Bounded Context เดียว ไม่ใช่ยัดทุกหน้าที่ไว้ใน agent เดียว หรือกระจาย agent ตามอำเภอใจStrategic Design หนึ่งอัน — และ version คมของมันคือ DDD คือวินัยที่บอกว่า อะไรควรอยู่ใน agent ที่มีขอบเขตดีตัวเดียว ส่วน Multi-agentMulti-agentระบบที่มี agent มากกว่าหนึ่งตัวทำงานร่วมกัน แต่ละตัวควรมี Bounded Context ของตัวเองชัดเจนและเชื่อมกันผ่าน context map/handoff ที่ออกแบบไว้ — ไม่ใช่คำตอบสำเร็จรูปสำหรับทุกปัญหา หลายงานทำด้วย agent เดียวหรือ workflow ธรรมดาก็เพียงพอและเชื่อถือได้กว่าArchitecture เป็นข้อยกเว้นที่มาทีหลังและต้องมีเหตุผล ไม่ใช่การแตก agent หนึ่งตัวต่อ1 subdomain แบบอัตโนมัติ
คอร์สนี้เป็น คอร์สออกแบบ ไม่ใช่ทัวร์ SDK — code ในคอร์สคือ ภาพร่าง ของ system prompt, ชุด tool และโทโพโลยี (Thai Mermaid + pseudo-config สั้นๆ) ไม่ใช่ app ที่รันได้จริง ตัวอย่างต่อยอดจาก domain เดิมที่ repo kaen-food-ordering (กำลังจัดทำ) โดยมองมันผ่านเลนส์ใหม่: ระบบ ops-copilot ที่ช่วยทีมปฏิบัติการของ platform
กับดัก agent เทวดาที่ทำได้ทุกอย่าง
หัวข้อที่มีชื่อว่า “กับดัก agent เทวดาที่ทำได้ทุกอย่าง”ตอนเริ่มต้น การมี agent ตัวเดียวที่ถือทุก tool ดูคุ้ม — มีที่เดียวให้คุย ไม่ต้องตัดสินใจว่าจะส่งงานให้ใคร แต่มันคือ “model เดียวครองทุกอย่าง” version agent เป๊ะๆ ทุกความสามารถที่ทีมอยากได้ไปกองรวมที่ system prompt เดียวและ tool list เดียว จน agent ตัวนั้นบวมจนไม่มีใครบอกได้ว่ามันควรทำหรือไม่ควรทำอะไร:
agent: ops-copilotsystem_prompt: | คุณคือผู้ช่วยของ platform ฟู้ดเดลิเวอรี ทำได้ทุกอย่าง: ตอบคำถามลูกค้า ติดตามสถานะออเดอร์ จัดคิวครัว คืนเงิน ปรับราคาเมนูร้าน จัดคิวไรเดอร์ ดึงรายงานยอดขาย แก้ข้อพิพาท ...tools: - search_customer_ticket # ภาษาฝั่งลูกค้า - issue_refund # ภาษาฝั่งการเงิน — ย้อนกลับไม่ได้! - reassign_rider # ภาษาฝั่งจัดส่ง - update_menu_price # ภาษาฝั่งร้าน - mark_kitchen_ticket # ภาษาฝั่งครัว - export_sales_report # ภาษาฝั่งวิเคราะห์ # ... อีกยี่สิบกว่า tool จากทุกฝ่ายปัญหาไม่ใช่แค่ tool list ยาว แต่คือ agent ที่พยายามพูดทุกภาษาพร้อมกัน สุดท้ายไม่แม่นสักภาษา issue_refund ที่ย้อนกลับไม่ได้นั่งอยู่ข้างๆ search_customer_ticket ที่แค่อ่านข้อมูล — คนละระดับความเสี่ยงกันโดยสิ้นเชิง แต่ถูกมอบให้ตัวตัดสินใจตัวเดียวกันภายใต้บริบทเดียวกัน ยิ่งงานหลากหลาย บริบทยิ่งพอกพูน และตรงนี้เองที่กลไกจริงของความพังเริ่มทำงาน
ขอบเขตสำคัญเพราะ context จะเน่า
หัวข้อที่มีชื่อว่า “ขอบเขตสำคัญเพราะ context จะเน่า”เหตุผลว่าทำไม agent เทวดาถึงพังไม่ใช่แค่เรื่องความเป็นระเบียบ แต่มีรากทางเทคนิคชื่อ Context RotContext Rotอาการที่คุณภาพการตอบของ agent เสื่อมลงเมื่อ context window ยาวขึ้นและสะสมสิ่งไม่เกี่ยวข้องมากขึ้นเรื่อย ๆ ระหว่างวน agentic loop หลายรอบ — เป็นเหตุผลเชิงเทคนิคข้อหนึ่งที่ agent ควรมีขอบเขตหน้าที่แคบ (เหมือน Bounded Context) แทนที่จะยัดทุกอย่างไว้ใน agent เดียวที่ context ยาวขึ้นเรื่อย ๆProcess — อาการที่คุณภาพการตอบเสื่อมลงเมื่อ context window ยาวขึ้นและสะสมสิ่งไม่เกี่ยวข้องมากขึ้นต่อเนื่อง กลไกอยู่ที่ตัว attention เอง: transformer ให้ทุก token มองทุก token ที่เหลือ ค่าใช้จ่ายของ attention จึงโตแบบ n² เมื่อจำนวน token เพิ่ม พูดอีกแบบคือ agent มี งบ attention ที่จำกัด และงบก้อนนั้นถูกเกลี่ยบางลงต่อเนื่อง ทุกครั้งที่คุณยัดของเข้า context ยิ่งอัดเข้าไปมาก ความสามารถในการดึงข้อเท็จจริงหนึ่งชิ้นที่สำคัญ ณ ตานี้ ก็ยิ่งจาง
ทีม Applied AI ของ Anthropic สรุปหลักนี้ไว้ชัดใน Effective context engineering for AI agents (Anthropic, Sep 2025) ว่าให้มอง context เป็น ทรัพยากรจำกัด ที่มี marginal return ลดลง ไม่ใช่ถังที่เติมได้ไม่อั้น (มีฉบับแปลไทยในเว็บนี้ที่บทความ Context Engineering ที่ได้ผลสำหรับ AI Agents) นี่คือดาบสองคมของ Agentic LoopAgentic Loopวงจรที่ agent ทำซ้ำจนกว่าจะบรรลุเป้าหมาย: รับ input → วางแผน/ตัดสินใจ → เรียก tool → สังเกตผลลัพธ์ → วนกลับไปตัดสินใจใหม่ — ต่างจากโปรแกรมทั่วไปที่รันเส้นทางเดียวจบ วงจรนี้เองที่ทำให้ agent ยืดหยุ่น แต่ก็เสี่ยง context rot ถ้าวนนานเกินไปโดยไม่มีขอบเขตProcess ด้วย — ทุกรอบที่ agent เรียก tool แล้วเอาผลกลับเข้า context บริบทจะยาวขึ้น agent เทวดาที่ทำงานข้ามฝ่ายจึงสะสม context จากทุกฝ่ายใน session เดียว พอถึงตาที่ต้องรักษากฎเดียวที่สำคัญ (เช่น “ห้ามคืนเงินเกินยอดที่จ่ายจริง”) กฎนั้นอาจถูกกลบอยู่ใต้ข้อความคิวครัวกับรายงานยอดขายที่ไม่เกี่ยวเลย ขอบเขตที่แคบจึงไม่ใช่เรื่องความสวยงาม แต่คือการ รักษางบ attention ให้เหลือพอสำหรับงานตรงหน้า
เริ่มจากสิ่งที่ง่ายที่สุด แล้วค่อยเพิ่มเมื่อจำเป็น
หัวข้อที่มีชื่อว่า “เริ่มจากสิ่งที่ง่ายที่สุด แล้วค่อยเพิ่มเมื่อจำเป็น”ถ้าขอบเขตแคบดีกว่า สัญชาตญาณถัดไปมักผิดพอๆ กับกับดักแรก: “งั้นก็แตกเป็น agent หลายตัวสิ” — ช้าก่อน คำแนะนำหลักจาก Building Effective Agents (Anthropic, Dec 2024) คือ เริ่มจากสิ่งที่ง่ายที่สุดที่แก้ปัญหาได้ แล้วเพิ่มความซับซ้อนเมื่อจำเป็น เท่านั้น หลายโจทย์ไม่ต้องการ agent เต็มรูปด้วยซ้ำ
ตรงนี้ต้องแยกให้ออกก่อนว่า workflow กับ agentWorkflow vs Agentความต่างสำคัญที่มักถูกมองข้าม: workflow คือ code ที่กำหนดลำดับขั้นตอนตายตัวไว้ล่วงหน้า (คาดเดาได้ ทดสอบง่าย) ส่วน agent คือระบบที่ตัดสินใจเส้นทางเองแบบไดนามิกผ่าน agentic loop (ยืดหยุ่นกว่าแต่คาดเดายากกว่า) — โจทย์ส่วนใหญ่ไม่ต้องการ agent เต็มรูปแบบ workflow ที่ออกแบบดีมักพอเพียงและเชื่อถือได้กว่าProcess เป็นคนละสิ่ง — workflow คือ code ที่กำหนดลำดับขั้นตอนไว้ล่วงหน้า (คาดเดาได้ ทดสอบง่าย ถูก) ส่วน agent คือระบบที่ตัดสินใจเส้นทางเองแบบไดนามิกผ่าน agentic loop (ยืดหยุ่นกว่าแต่แพงกว่า ช้ากว่า และคาดเดายากกว่า) การกระโดดขึ้น agent — และยิ่งกระโดดขึ้น multi-agent — คือการจ่ายค่าความยืดหยุ่นด้วย token, latency และความไม่แน่นอน มันไม่ใช่ “อัปเกรดฟรี” งานติดตามสถานะออเดอร์ที่มีขั้นตอนตายตัวอาจเป็น workflow ธรรมดาก็จบ ส่วนงานตอบลูกค้าปลายเปิดถึงจะคุ้มที่จะเป็น agent จริงๆ บทถัดไปจะทำบันไดการตัดสินใจนี้ให้เป็นขั้นชัดๆ —ขอปักหมุดแค่ทิศ: อย่าเริ่มที่ความซับซ้อนสูงสุด
ขอบเขตของ agent วางอยู่บนสองแกน
หัวข้อที่มีชื่อว่า “ขอบเขตของ agent วางอยู่บนสองแกน”เวลาลากเส้นแบ่ง agent เส้นนั้นไม่ได้มีมิติเดียว ขอบเขตของ agent วางอยู่บนสองแกนที่ คล้องจองกัน แต่ ไม่ทับกันเป๊ะเสมอไป:
- แกนภาษา/model — agent นี้พูดภาษาอะไร รู้จักคำศัพท์ชุดไหน ถือ tool อะไร รับผิดชอบเรื่องอะไร นี่คือแกนของ ubiquitous language ตรงๆ เป็นเส้นเดียวกับที่แบ่ง bounded context ใน domain
- แกนงบ token/ความไว้ใจ — บริบทของงานนี้ยาวแค่ไหน และเรามอบอำนาจให้ agent ทำอะไรได้เองบ้างก่อนต้องมีคนกั้น นี่คือแกนของ GuardrailGuardrailกติกาที่ควบคุมไม่ให้ agent ทำเกินขอบเขตหรือก่อความเสียหาย เช่น จำกัด tool ที่เรียกได้ ตรวจ output ก่อนส่งออก บังคับ human approval สำหรับการกระทำที่ย้อนกลับไม่ได้ — เป็นสิ่งที่รักษาขอบเขตของ Bounded Context ของ agent ให้ไม่ล้ำเส้นProcess และ Human-in-the-loopHuman-in-the-loopการออกแบบให้มนุษย์เข้ามาตรวจสอบหรืออนุมัติในจุดที่การกระทำของ agent มีความเสี่ยงสูงหรือย้อนกลับไม่ได้ เช่น ก่อนโอนเงินหรือลบข้อมูลจริง — เป็น guardrail ชนิดหนึ่งที่ยังจำเป็นแม้ agent จะฉลาดขึ้นเรื่อย ๆ เพราะบางการตัดสินใจไม่ควรปล่อยให้ agent ตัดสินใจเองทั้งหมดProcess
สองแกนนี้มัก คล้อง กัน — งานที่ภาษาแคบก็มักบริบทสั้นและความเสี่ยงต่ำ — แต่ไม่เสมอไป และจุดที่มันแยกกันคือจุดที่ design เนอร์มือใหม่พลาด: agent ตอบลูกค้ามี ภาษาแคบ (เคส/นโยบาย/ประวัติสนทนา) แต่ต้องแบก บริบทยาว (ประวัติแชตทั้งเส้น + คู่มือนโยบาย) ขณะที่การ “คืนเงิน” มี ภาษาแคบมาก (จำนวนเงินกับสถานะ) แต่ต้องการ ความไว้ใจสูงสุด เพราะย้อนกลับไม่ได้ จึงควรมีคนอนุมัติคั่น พอสองแกนไม่ทับกันแบบนี้ เราจึงยุบมันเป็นแกนเดียวไม่ได้ — และนี่คือเหตุผลที่ “1 agent ต่อ1 subdomain” เป็นสูตรที่หยาบเกินไป
วิสัยทัศน์ ops-copilot ของฟู้ดเดลิเวอรี
หัวข้อที่มีชื่อว่า “วิสัยทัศน์ ops-copilot ของฟู้ดเดลิเวอรี”เอาหลักข้างบนมาวางบน domain เดิม สมมติเราจะปั้น ops-copilot ให้ทีมปฏิบัติการ เส้นแบ่งที่เป็นธรรมชาติ ไม่ใช่ “ตำแหน่งงาน” แต่คือจุดที่ภาษาและระดับความไว้ใจเปลี่ยน — เห็นได้เป็น3 agent ที่เป็นตัวเลือกตั้งต้น:
- Customer-Support — พูดภาษาเคส/ลูกค้า/นโยบาย ถือ tool ค้นเคสและร่างคำตอบ ความไว้ใจต่ำ (การกระทำที่มีเงินเกี่ยวต้องผ่านคนก่อน)
- Order-Tracking — พูดภาษาออเดอร์/สถานะ/ETA ถือ tool อ่านสถานะอย่างเดียว ความเสี่ยงต่ำเพราะไม่เขียนอะไร
- Restaurant-Ops — พูดภาษาเมนู/คิว/สต๊อก ถือ tool จัดคิวครัวและปรับเมนู ความไว้ใจปานกลาง
แต่ละตัวคือ bounded context ที่มีภาษา, ชุด tool และระดับความไว้ใจของตัวเอง สังเกตว่าเรายังไม่ได้ฟันธงว่าต้องเป็น 3 agent จริง — บางตัวอาจเริ่มเป็น workflow ก่อน บางคู่อาจรวมได้ถ้าภาษาใกล้กันพอ การตัดสินใจนั้นเป็นเรื่องของบทถัดๆ ไป บทนี้แค่ตั้งภาพว่า ขอบเขตอยู่ตรงไหน ก่อนจะเถียงกันเรื่องจำนวนตัว
agent หนึ่งตัวคือ bounded context หนึ่งอัน
หัวข้อที่มีชื่อว่า “agent หนึ่งตัวคือ bounded context หนึ่งอัน”รวบทุกอย่างเป็นวิทยานิพนธ์เดียว: agent ที่ออกแบบดีคือ agent ที่มีขอบเขตชัดเหมือน bounded context — ภาษาหนึ่งชุด, tool ชุดหนึ่งที่พอดีกับหน้าที่, บริบทที่แคบพอจะรักษางบ attention และระดับความไว้ใจที่คู่ควรกับความเสี่ยงของงาน DDD ให้คำศัพท์ของ การยับยั้งชั่งใจ ที่วงการ agent กำลังค้นพบใหม่ด้วยตัวเอง — และหัวใจของมันคือการรู้ว่าอะไรควรอยู่ ข้างใน agent ตัวเดียว ก่อนจะไปคิดเรื่องหลายตัว
flowchart LR
subgraph OLD["❌ agent เทวดา: ตัวเดียวถือทุกอย่าง"]
GOD["ops-copilot<br/>tool จากทุกฝ่าย 25+ ตัว<br/>system prompt ครอบทุกงาน<br/>context โตทุกรอบจนงบ attention เน่า"]
end
subgraph NEW["✅ agent มีขอบเขต: หนึ่งตัว = 1 bounded context"]
CS["Customer-Support<br/>ภาษา ลูกค้า/เคส/นโยบาย<br/>tool ค้นเคส, ร่างคำตอบ<br/>trust ต่ำ (คืนเงินต้องมีคนอนุมัติ)"]
OT["Order-Tracking<br/>ภาษา ออเดอร์/สถานะ/ETA<br/>tool อ่านสถานะอย่างเดียว"]
RO["Restaurant-Ops<br/>ภาษา เมนู/คิว/สต๊อก<br/>tool จัดคิว, ปรับเมนู"]
end
OLD ==>|"แยกตามจุดที่ภาษาและความไว้ใจเปลี่ยน"| NEW
classDef god fill:#dc2626,stroke:#7f1d1d,color:#f8fafc;
classDef ctx fill:#c7d2fe,stroke:#3730a3,color:#1a1a1f;
class GOD god;
class CS,OT,RO ctx;
คำบรรยายภาพ: ฝั่งซ้ายคือกับดัก — ops-copilot ตัวเดียว (แดง) ที่แบก tool จากทุกฝ่ายและ system prompt ครอบทุกงาน จน context พอกพูนทุกรอบของ agentic loop และงบ attention เจือจางจนเกิด context rot ฝั่งขวาคือทางออก — ขอบเขตถูกลากตามจุดที่ภาษาและระดับความไว้ใจเปลี่ยน (น้ำเงิน) แต่ละ agent ถือเฉพาะภาษา, tool และ trust ของตัวเอง เส้นที่แบ่งไม่ใช่ “ตำแหน่งงาน” แต่คือเส้นเดียวกับที่แบ่ง bounded context ใน domain — และย้ำว่านี่คือ ภาพขอบเขต ไม่ใช่คำสั่งว่าต้องเป็น3 agent แยกกันจริงเสมอ
สิ่งที่จะทำต่อ
หัวข้อที่มีชื่อว่า “สิ่งที่จะทำต่อ”บทนี้วางแค่วิทยานิพนธ์ — agent ควรมีขอบเขต และขอบเขตนั้นคือ bounded context จากนี้ทั้งคอร์สคือการจับเครื่องมือเชิงกลยุทธ์ของ DDD มาเทียบกับงานออกแบบ agent ทีละชิ้น:
- Subdomain → ขอบเขตของ agent (บทที่ 2) — จำแนก subdomain (core/supporting/generic) แล้วเลือกขั้นบันได: generic ให้ซื้อหรือใช้ workflow, supporting ให้เป็น tool หรือ workflow, core ที่ปลายเปิดถึงจะเป็น ผู้สมัคร agent — ไม่ใช่ตอบ “ใช่ สร้าง agent” ทุกกล่อง
- Ubiquitous Language → system prompt + tools (บทที่ 3) — ภาษาของ context กลายเป็น system prompt ที่ “ระดับความสูงพอดี” กับชุด tool ที่ตั้งชื่อเป็น namespace ชัด
- Bounded Context → agent หนึ่งตัว (บทที่ 4) — รักษาบริบทด้วย compaction, agent memory ภายนอก และ guardrail (พร้อมยอมรับจุดที่ agent ไม่ เหมือน aggregate อย่างตรงไปตรงมา)
- Context Map → multi-agent (บทที่ 5) — วาดแผนที่ context ก่อน แล้วพิสูจน์ว่า multi-agent คุ้มด้วยเหตุผลที่มีชื่อสามข้อเท่านั้น ไม่ใช่แตกตามใจ
- Anti-Corruption Layer → tool integration (บทที่ 6) — tool คือชั้นแปลภาษาที่กั้นความรกของ backend ไม่ให้ไหลเข้ามาปน context ของ agent
- Handoff & Delegation (บทที่ 7) — agent คุยกันด้วย published language ที่มีสัญญาชัด แยก delegation (ผลกลับมาหาหัวหน้า) จาก handoff (โอนการควบคุมถาวร) ให้ขาด
- เมื่อไรไม่ควรใช้ agent + eval (บทที่ 8) — ประตูต้นทุน, งานแบบไหนที่ workflow หรือไม่ใช้ agent เลยชนะ และวิธีวัดผลด้วย eval ที่ดูปลายทางไม่ใช่เส้นทาง
ทุกบทกลับมาที่ domain ฟู้ดเดลิเวอรีเดิมเสมอ — ไม่มี domain ใหม่ มีแต่การมองมันผ่านเลนส์ agent และย้ำวินัยเดิมทุกบท: รู้ว่าอะไรควรอยู่ใน agent ตัวเดียวก่อน แล้วค่อยแตกเมื่อมีเหตุผลจริง
เจาะลึกแนวคิดในบทนี้ต่อได้ที่คลังอ้างอิง DevIQ และคอร์สที่เกี่ยวข้อง:
- Bounded Context — ขอบเขตที่ model หนึ่งชุดและภาษาหนึ่งชุดคงความหมายไว้ หัวใจที่ทั้งคอร์สนี้ยืมมาใช้กับ agent
- คอร์ส Bounded Contexts & Integration — ที่มาของกับดัก “model เดียวครองทุกอย่าง” กับการแยก
Orderเป็น4 context ที่บทนี้สะท้อนในคราบ agent
เช็กความเข้าใจ — บทที่ 1
ข้อ 1 / 3ทำไม agent เทวดาที่ถือ tool จากทุกฝ่ายถึงเสื่อมคุณภาพเมื่องานยาวขึ้น?