เปิดบริษัทซอฟต์แวร์ของตัวเอง แต่ไม่ต้องจ้างพนักงานสักคน ทีมที่มี Lead แบ่งงาน มีลูปแก้งาน และเด้งกลับมาถามเราเมื่อโจทย์ไม่ชัด คือของจริงที่ทำได้วันนี้แค่ไหน
สมมติคุณเปิดบริษัทพัฒนาซอฟต์แวร์ของตัวเองขึ้นมา เริ่มจากศูนย์ ยังไม่มีพนักงานสักคน มีแค่โจทย์งานกองอยู่ตรงหน้า กับตัวคุณคนเดียวที่ต้องทำทุกอย่าง ทั้งคิดสเปก เขียนโค้ด ตรวจงานตัวเอง ส่งงานเอง
ทำไปสักพักก็เริ่มรู้ตัวว่านี่ไม่ใช่ทางที่ยั่งยืน คุณอยากมีทีม คนที่รับสเปกจากคุณแล้วแตกงานเป็น คนที่ลงมือเขียนจริง กับคนที่คอยตรวจก่อนงานจะถึงมือคุณ ทำงานประสานกันเองได้ในระดับหนึ่ง โดยที่คุณแค่คอยตัดสินใจเรื่องที่สำคัญจริง ๆ
ฟังดูเหมือนต้องรอเปิดรับสมัครงาน สัมภาษณ์ อบรม จ่ายเงินเดือนอีกหลายเดือนกว่าจะได้ทีมแบบนั้นจริง แต่ถ้าบอกว่าตั้งทีมแบบนี้ได้ตั้งแต่วันนี้เลย โดยไม่ต้องจ้างใครสักคนล่ะ
เฉลยเลยแล้วกันครับ "พนักงาน" ที่ว่านั้นคือ Claude นี่แหละ ไม่ใช่คนจริง ๆ สิ่งที่ผมทำไปเมื่อกี้ไม่ใช่แค่จินตนาการลอย ๆ แต่ลองเอาโจทย์เขียนโค้ดจริงไปให้ "ทีม Claude" ทำดูจริง แล้วมันก็ทำได้จริง ทั้ง reject กันเอง แก้กันเอง จนงานผ่าน (รายละเอียดเต็ม ๆ อยู่ท้ายบทความ) ก่อนไปถึงตรงนั้น ขอแกะศัพท์ที่จะเจอถี่ ๆ ตลอดบทความนี้กันก่อน
ถ้าสั่งงาน Claude ตัวเดียวตรง ๆ มันก็เขียนโค้ดได้ ตรวจโค้ดตัวเองได้ในระดับหนึ่ง แต่นั่นเหมือนจ้างฟรีแลนซ์คนเดียวทำทุกขั้นตอน ตั้งแต่วางแผน เขียน จนถึงตรวจงานตัวเอง จุดอ่อนคือ คนตรวจกับคนทำเป็นคนเดียวกัน อคติเดิมที่ทำให้เขียนพลาดตอนแรก ก็มักจะเป็นอคติเดียวกับตอนตรวจทานเองด้วย มองไม่เห็นจุดบอดของตัวเอง
การแบ่งเป็นทีม (Lead คนหนึ่งตั้งเกณฑ์ dev คนหนึ่งลงมือ QA อีกคนตรวจ) คือการตัดบทบาทออกจากกัน ให้แต่ละ agent โฟกัสอยู่กับงานของตัวเอง และที่สำคัญกว่านั้นคือ QA ไม่ได้เห็น context เดียวกับตอนที่ dev กำลังปวดหัวเขียนโค้ด มันมาไล่โค้ดด้วยสายตาที่สดกว่า จับจุดที่ dev มองข้ามได้ง่ายกว่า
Claude Code ไม่ได้มีปุ่มเดียวชื่อ "สร้างทีม" แต่มี 3 วิธีที่ทำเรื่องนี้ได้ ต่างกันที่ agent แต่ละตัวคุยกันเองได้แค่ไหน และเราคุมความแน่นอนของผลลัพธ์ได้มากน้อยแค่ไหน
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 ก่อน
ไม่มีเพดานจำนวนตัวตายตัว แต่เอกสารทางการแนะนำว่าเริ่มที่ 3–5 ตัวก่อน เพราะยิ่งทีมใหญ่ ภาระในการประสานงานกันเองก็ยิ่งกินผลประโยชน์ที่ควรได้จากการขนานงาน
agent() (เรียก agent หนึ่งตัว รอผลกลับ),
parallel() (รันหลายงานพร้อมกันแล้วรอครบทุกตัว) และ pipeline() (ส่งต่องานเป็นทอด ๆ ไม่ต้องรอครบ)
ควบคุมได้เป๊ะที่สุดเพราะเราเป็นคนเขียนลำดับเอง แต่มีเพดาน agent รันพร้อมกันสูงสุด 16 ตัว และรวมทั้ง workflow ไม่เกิน 1,000 ตัวต่อการรันหนึ่งครั้ง
ตัวอย่าง "Lead–dev–QA" ในบทความนี้ใช้ Agent Teams เพราะอยากได้บรรยากาศ "ทีมคุยกันเอง" จริง ๆ เห็น QA ส่งข้อความตีกลับหา dev สด ๆ ในแผง agent ไม่ใช่แค่ log สรุปตอนจบ
ไม่ว่าจะเลือกวิธีไหนใน 3 ข้อบน สิ่งที่ต้องทำเหมือนกันคือเขียน "บทบาท" ให้แต่ละ agent รู้ว่าตัวเองเป็นใคร ทำหน้าที่อะไร ใช้เครื่องมืออะไรได้บ้าง เหมือนใบกำหนดตำแหน่งงาน (job description) ที่เขียนครั้งเดียว แล้วหยิบมาใช้ซ้ำได้ทุกครั้งที่เรียก agent ตัวนั้น ไม่ต้องอธิบายบทบาทใหม่ทุกรอบ
เก็บเป็นไฟล์ Markdown ในโฟลเดอร์ .claude/agents/ ระบุ name กับ description เป็นอย่างน้อย
(สองช่องนี้จำเป็น ที่เหลือใส่เพิ่มได้) ส่วน tools จำกัดว่าใช้เครื่องมืออะไรได้บ้าง ไม่ใส่ก็ได้ (จะสืบทอดเครื่องมือทั้งหมดจาก session หลัก)
และ model เลือกได้ว่าจะรันด้วยโมเดลไหน ตัวอย่างไฟล์บทบาทของ QA ในบทความนี้หน้าตาแบบนี้
---
name: qa
description: ตรวจโค้ดเทียบเกณฑ์รับงานที่ Lead ตั้งไว้ ไล่ลอจิกด้วยมือ อนุมัติหรือตีกลับพร้อมเหตุผล
model: sonnet
tools: Read, Grep, Bash
---
คุณคือ QA reviewer เข้มงวด ไล่ execute โค้ดในหัวทีละ input ที่ Lead ระบุไว้
approve เฉพาะเมื่อทุกเกณฑ์ผ่านจริงเท่านั้น ถ้าตีกลับ ต้องระบุ input ที่พังและเหตุผลให้ชัด โน้ต
ช่อง tools ในตัวอย่างจำกัดให้ QA อ่านโค้ดกับรันคำสั่งตรวจได้อย่างเดียว แก้ไฟล์เองไม่ได้ เป็นการบังคับให้บทบาทนี้ทำหน้าที่แค่ "ตรวจ" ไม่เผลอไปช่วยแก้โค้ดเอง ซึ่งจะไปเบลอเส้นแบ่งบทบาทกับ dev
ก่อนลงมือ ขอแยกให้ชัดว่าการตั้งทีมแบบนี้ทำได้ สองทาง ที่ค่าใช้จ่ายต่างกันคนละเรื่อง
บทความนี้จะเล่าให้เห็นทั้งคู่ แต่ลงมือรันจริงแค่ทางเดียว โจทย์ที่ให้ทีมทำคือฟังก์ชัน
formatThousands(n) คือใส่ comma คั่นหลักพันให้ตัวเลข รองรับทั้งจำนวนลบและทศนิยม
ทางแรก: แบบเสียตัง คือยิง Claude API ตรง ๆ เขียนสคริปต์เรียก SDK เอง
แล้วเอาเนื้อไฟล์บทบาท (.claude/agents/<role>.md) ไปใส่เป็น system prompt ของแต่ละ agent
แกนกลางเหลือแค่ฟังก์ชันเดียวที่เรียก agent หนึ่งตัวหนึ่งครั้ง:
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic(); // อ่าน ANTHROPIC_API_KEY จาก env
async function agent(system, prompt) {
const res = await client.messages.create({
model: 'claude-opus-4-8',
max_tokens: 4096,
system, // ← เนื้อไฟล์ .claude/agents/<role>.md
messages: [{ role: 'user', content: prompt }],
});
return res.content[0].text;
} วิธีนี้ clone ไปรันได้ทุกเครื่อง แต่ ทุกครั้งที่ agent พูดหนึ่งที คือจ่ายเงินต่อ token ทีมนึงวางแผน เขียน ตรวจ ตีกลับ แก้ วนกันหลายสิบเทิร์น มิเตอร์ค่า API ก็เดินตลอด และต้องไปสมัครขอ API key มาก่อนถึงจะเริ่มได้
ทางที่สอง: แบบไม่เสียเพิ่ม คือ Agent Teams ใน Claude Code อันนี้รันในซับที่เราจ่ายอยู่แล้ว ไม่ต้องมี key แยก แถมได้เห็นทีมคุยกันสด ๆ ในแผง agent บทความนี้เลยเลือกรันทางนี้ให้ดู เปิดฟีเจอร์ (ยัง experimental) ด้วยตัวแปรระบบก่อน แล้วให้ session หลักสวมบทเป็น lead:
# .claude/settings.json: { "env": { "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1" } }
claude --agent lead จากนั้นสั่งงานด้วยภาษาคนตรง ๆ ให้ lead ตั้งเกณฑ์แล้วเรียกลูกทีมมาทำ:
โจทย์: เขียน formatThousands(n) ใส่ comma คั่นหลักพัน รองรับจำนวนลบและทศนิยม เป็น pure function
ตั้ง acceptance criteria แล้ว spawn teammate สองตัว: ตัวหนึ่งใช้ agent type "dev" อีกตัวใช้ "qa"
ให้ dev เขียนโค้ด, qa ตรวจตามเกณฑ์แล้วส่งข้อความตีกลับถ้าไม่ผ่าน วนจน qa อนุมัติ
lead จะทำงานเป็นลำดับ: ตั้งเกณฑ์ → spawn dev กับ qa เป็น teammate → สร้าง task ให้ทำเป็นทอด
dev เขียน → qa ตรวจ → ถ้าไม่ผ่าน qa ส่งข้อความตีกลับให้ dev แก้ วนจนผ่าน → lead สรุปส่งมอบ
ทั้งหมดเห็นสด ๆ ในแผง agent
รอบแรก dev เขียนแบบร่างเร็ว ยังไม่กันเคสทศนิยมไว้ โค้ดที่ได้ใช้ regex ตัดหลักพันตรง ๆ กับตัวเลขทั้งก้อน รวมถึงส่วนทศนิยมด้วย ผลคือพัง
QA reject รอบ 1 ระบุ input ที่พังชัดเจน:
formatThousands(1234.5678) คืนค่า "1,234.5,678" ทั้งที่ควรได้ "1,234.5678" เพราะ regex ไปหั่นส่วนทศนิยมด้วยทั้งที่ไม่ควรแตะ
พิสูจน์ว่านี่ไม่ใช่ QA มโนไปเอง ลองรันจริงดูก็เจอบั๊กเดียวกันเป๊ะ
node -e 'console.log(String(1234.5678).replace(/\B(?=(\d{3})+(?!\d))/g, ","))'
# → 1,234.5,678 (ตรงกับที่ QA รายงาน) รอบ 2 dev แก้โดยแยกส่วนจำนวนเต็มกับทศนิยมออกจากกันก่อนใส่ comma แล้ว QA อนุมัติผ่าน
export function formatThousands(n) {
const negative = n < 0;
const [intPart, fracPart] = Math.abs(n).toString().split(".");
const grouped = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
const body = fracPart === undefined ? grouped : `${grouped}.${fracPart}`;
return negative ? `-${body}` : body;
} ลองรันเองได้
ทั้งหมดนี้ไม่ใช่แค่เล่าให้ฟัง ผมทำเป็น repo ที่ clone ไปเปิดใน Claude Code แล้วรันเองได้จริงไว้ที่
ChimengSoso/claude-agent-team-demo
ข้างในมีแค่ไฟล์บทบาท Lead–dev–QA ใน .claude/agents/ กับ .claude/settings.json ที่เปิดฟีเจอร์ Agent Teams ไว้ให้แล้ว
ไม่ต้องมี API key ไม่ต้อง npm install เปิดโฟลเดอร์ด้วย claude --agent lead แล้วสั่งงานตามตัวอย่างด้านบนได้เลย
.claude/agents/ ป้อนได้ทั้งสองทาง ต่างกันที่ปลายทาง คือยิง API ตรงจ่ายต่อ token ทุกครั้งที่ทีมพูด ส่วน Agent Teams รันในซับที่จ่ายอยู่แล้ว บทความนี้จึงเลือกทดลองทางขวาเคสข้างบนคือลูป แนวนอน คือ dev กับ QA แก้กันเองจนผ่าน โดยที่ผมไม่ต้องเข้าไปยุ่งเลยสักครั้ง แต่มีอีกทิศหนึ่งที่สำคัญไม่แพ้กัน คือลูป แนวตั้ง คือตอนที่ทีมเด้งกลับมาถามมนุษย์โดยตรง
ตอนแรกผมลองให้โจทย์กำกวมกว่านี้ แค่ "ใส่ comma หน่อย" ไม่บอกละเอียดว่าต้องรองรับติดลบหรือทศนิยมไหม QA เอะใจว่าตัวเองไม่รู้จะตั้งเกณฑ์ตรวจตรงไหน เพราะความกำกวมไม่ได้อยู่ที่โค้ด แต่อยู่ที่ requirement ตั้งแต่ต้น เลยส่งเรื่องกลับไปหา Lead และ Lead ก็ถามผม 3 คำถามตรง ๆ ก่อนจะล็อกสเปกแล้วค่อยส่งงานต่อ
ประเด็นสำคัญคือ requirement ที่กำกวมจะถูกตีความเพี้ยนไปเรื่อย ๆ เป็นทอด ๆ ถ้าปล่อยให้ไหลจาก Lead → dev → QA โดยไม่มีจุดตัดวงจร แต่ละ agent จะเดาเอาเองคนละแบบ แล้วสุดท้ายผลลัพธ์ที่ได้ก็ไม่มีใครรู้ว่าตรงกับที่ผมต้องการจริง ๆ หรือเปล่า
agent ที่ดีคือ agent ที่ปฏิเสธจะเดา แล้วถามกลับ ดีกว่าเดาผิดแล้วส่งต่อความผิดพลาดนั้นไปทั้งสาย
ข้อดีของ Agent Teams คือไม่ต้องทำเครื่องมืออะไรเพิ่มเพื่อ "ดูทีมคุยกัน" Claude Code มีให้ในตัว
ทุก teammate โผล่เป็นแถวในแผง agent (agent panel) ใต้ช่องพิมพ์ กดลูกศรเลือกตัวไหนแล้วกด Enter
จะเปิด transcript ของตัวนั้นให้ไล่อ่านสด ๆ เห็น QA ร่างเหตุผลที่จะตีกลับ เห็น dev รับ feedback ไปแก้ ครบทุกเทิร์น
และพิมพ์ส่งข้อความหา teammate ตัวนั้นตรง ๆ ได้ด้วยถ้าอยากแทรก
เบื้องหลังการคุยกันคือ mailbox (กล่องข้อความของแต่ละ agent เก็บเป็นไฟล์ JSON) กับ task list ร่วม ที่ทุกตัวเห็นตรงกันว่างานไหนใครถือ เสร็จหรือยัง teammate ส่งข้อความหากันเองได้โดยตรง ไม่ต้องเด้งผ่าน lead ทุกครั้ง ต่างจาก sub-agent ที่รายงานกลับตัวหลักได้อย่างเดียว
ถ้าอยากเห็นทุกตัวพร้อมกันคนละจอ เปิดโหมด split-pane ได้ (ต้องมี tmux หรือ iTerm2 บน Windows Terminal กับ VS Code integrated terminal ยังไม่รองรับ split-pane ใช้แบบ in-process เลือกดูทีละตัวแทน)
บทบาท agent ที่เขียนไว้ใน .claude/agents/ การเปิดฟีเจอร์ใน .claude/settings.json
และคู่มือโปรเจกต์ใน CLAUDE.md ทั้งหมดนี้เก็บเป็นไฟล์ในโปรเจกต์ ทุก session ถัดไปที่เปิดโปรเจกต์เดียวกันจะอ่านเจอเอง
ไม่ต้องอธิบายบทบาทซ้ำทุกครั้ง และเพราะมันเป็นไฟล์ ก็ commit ขึ้น git แชร์ให้ทั้งทีมใช้ชุดเดียวกันได้
โน้ต
ข้อจำกัดที่ควรรู้ไว้: ไฟล์ตั้งค่าแชร์ผ่าน git ได้ก็จริง แต่ "ทีมที่กำลังรัน" ไม่ได้ตามไปด้วย Agent Teams ยัง resume ทีมเดิมไม่ได้ (ออกจาก session แล้วเปิดใหม่ ต้อง spawn teammate กันใหม่หมด) และมีได้ทีมเดียวต่อ session
ตั้งบริษัทซอฟต์แวร์ที่มี Lead-dev-QA เป็น Claude ล้วน ๆ ทำได้จริงวันนี้ ผ่าน Agent Teams, Workflows หรือ sub-agents แล้วแต่ว่าอยากได้ความยืดหยุ่นหรือความแน่นอนมากกว่ากัน แต่หัวใจที่ทำให้ทีมแบบนี้ต่างจาก AI ตัวเดียวตรวจงานตัวเองจริง ๆ ไม่ใช่จำนวน agent ที่มี แต่คือลูป feedback ที่ยอมเด้งกลับไปถามเมื่อไม่แน่ใจ ทั้งในแนวนอนระหว่าง agent ด้วยกัน และในแนวตั้งกลับมาหาเรา
เรียบเรียงและอธิบายใหม่ด้วยคำตัวเอง โดยตรวจสอบข้อเท็จจริงกับแหล่งปฐมภูมิด้านล่าง