ทำความเข้าใจ Spec-Driven Development: Kiro, spec-kit และ Tessl
บทความนี้เป็น บทแปลภาษาไทยอย่างไม่เป็นทางการ ของ “Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl” โดย Birgitta Böckeler เผยแพร่ครั้งแรกบน martinfowler.com เมื่อ 15 ตุลาคม 2025 (ในซีรีส์ Exploring Generative AI)
แปลและเรียบเรียงเพื่อการศึกษา — ไดอะแกรมเชิงแนวคิดวาดใหม่เป็นภาษาไทย ส่วนภาพหน้าจอของเครื่องมือมี link ไปยังต้นฉบับ และศัพท์เทคนิคคงไว้เป็นภาษาอังกฤษตามต้นฉบับ ลิขสิทธิ์ของเนื้อหาต้นฉบับเป็นของผู้เขียน
ผู้เขียนพยายามทำความเข้าใจ buzzword ที่มาแรงล่าสุดในวงการ AI coding นั่นคือการพัฒนาแบบขับเคลื่อนด้วย spec (Spec-Driven Development — SDD) โดยลองใช้เครื่องมือสามตัวที่นิยามตัวเองว่าเป็นเครื่องมือ SDD เพื่อแกะดูว่าตอนนี้มันหมายความว่าอย่างไรกันแน่
เช่นเดียวกับศัพท์ใหม่ ๆ อีกหลายคำในวงการที่เปลี่ยนแปลงอย่างรวดเร็ว นิยามของ “spec-driven development” (SDD) ยังไม่ลงตัว นี่คือสิ่งที่ผู้เขียนพอจะสรุปได้จากวิธีที่เห็นคนใช้คำนี้มาจนถึงตอนนี้
กล่าวคือ spec-driven development หมายถึงการเขียน “spec” ก่อนที่จะลงมือเขียน code กับ AI (“documentation first”) โดย spec จะกลายเป็นแหล่งความจริง (source of truth) ทั้งสำหรับคนและสำหรับ AI
GitHub: “ในโลกใบใหม่นี้ การดูแลซอฟต์แวร์ก็คือการทำให้ spec ค่อย ๆ พัฒนาต่อไป […] ภาษากลางของการพัฒนาขยับขึ้นไปอยู่ในระดับที่สูงขึ้น ส่วน code กลายเป็นแนวทางช่วงปลายทาง (last-mile)”
Tessl: “แนวทางการพัฒนาที่ spec ไม่ใช่ code เป็นชิ้นงานหลัก (primary artifact) spec อธิบายเจตนาด้วยภาษาที่มีโครงสร้างและทดสอบได้ แล้ว agent ก็สร้าง code ให้ตรงกับ spec นั้น”
หลังจากได้ดูวิธีที่คนใช้คำนี้ และดูเครื่องมือบางตัวที่อ้างว่าตัวเองทำ SDD ผู้เขียนรู้สึกว่าในความเป็นจริงแล้ว มันมีระดับของการนำไปใช้งานหลายระดับด้วยกัน:
- Spec-first (เขียน spec ให้ดีก่อนเริ่มงาน): เขียน spec ที่คิดมาอย่างรอบคอบขึ้นมาก่อน แล้วจึงนำไปใช้ใน workflow การพัฒนาแบบ AI-assisted สำหรับงานที่อยู่ตรงหน้า
- Spec-anchored (คง spec ไว้ใช้ดูแล/พัฒนาต่อ): เก็บ spec ไว้แม้งานจะเสร็จไปแล้ว เพื่อนำมาใช้ในการพัฒนาต่อยอดและดูแลรักษา feature นั้น ๆ ต่อไป
- Spec-as-source (ใช้ spec เป็นต้นฉบับ คนแก้แค่ spec ไม่แตะ code): spec คือ file ต้นฉบับหลักที่อยู่กับ project ในระยะยาว และคนจะแก้ที่ spec เท่านั้น คนจะไม่แตะ code เลย
แนวทางและนิยามของ SDD ทุกอันที่ผู้เขียนเจอล้วนเป็น spec-first แต่ไม่ใช่ทุกอันที่มุ่งจะเป็น spec-anchored หรือ spec-as-source และบ่อยครั้งก็ปล่อยไว้คลุมเครือหรือเปิดกว้างไปเลยว่ากลยุทธ์ในการดูแล spec ในระยะยาวควรเป็นอย่างไร
| ระดับของ SDD | ตอนสร้าง feature (Creation) | ตอนพัฒนาและดูแลต่อ (Evolution & maintenance) |
|---|---|---|
| spec-first | spec นำไปสู่ code ทั้ง AI และคนช่วยกันแก้ทั้ง spec และ code | ทิ้ง spec เดิม แล้วเขียน spec ใหม่อธิบายเฉพาะส่วนที่จะเปลี่ยน |
| spec-anchored | เหมือน spec-first | เก็บ spec ไว้ แล้วกลับมาแก้ spec เดิมตอนพัฒนาต่อ |
| spec-as-source | เหมือน spec-anchored | คนแก้แค่ spec ไม่แตะ code ที่ถูก generate ขึ้นมา |
ภาพ 1 — สามระดับของ SDD สร้างต่อยอดกันเป็นชั้น ๆ (inheritance): spec-anchored รวมทุกอย่างของ spec-first และ spec-as-source รวมทุกอย่างของ spec-anchored ความต่างอยู่ที่ “ตอนดูแลต่อ” ว่าจะทิ้ง spec, เก็บไว้แก้, หรือให้ spec เป็นต้นฉบับที่คนแก้เพียงอย่างเดียว · ดูภาพต้นฉบับ ↗
spec คืออะไร?
หัวข้อที่มีชื่อว่า “spec คืออะไร?”แน่นอนว่าคำถามสำคัญในแง่ของนิยามก็คือ spec คืออะไร? ดูเหมือนจะยังไม่มีนิยามที่เป็นสากล นิยามที่สอดคล้องกันมากที่สุดเท่าที่ผู้เขียนเคยเห็นก็คือการเปรียบเทียบ spec เข้ากับ PRD (Product Requirements Document — เอกสารกำหนดความต้องการของผลิตภัณฑ์)
ตอนนี้คำนี้ถูกใช้ในความหมายที่หลากหลายจนกว้างเกินไป นี่คือความพยายามของผู้เขียนในการนิยามว่า spec คืออะไร:
spec คือชิ้นงานที่มีโครงสร้างและเน้นที่พฤติกรรม (behavior-oriented) — หรือชุดของชิ้นงานที่เกี่ยวข้องกัน — ซึ่งเขียนด้วยภาษาคน (natural language) เพื่อแสดงออกถึง function การทำงานของซอฟต์แวร์ และทำหน้าที่เป็นแนวทางให้กับ AI coding agent
โดย spec-driven development แต่ละแบบจะมีวิธีของตัวเองในการนิยามว่าโครงสร้างของ spec ควรเป็นอย่างไร ลงรายละเอียดมากแค่ไหน และจะจัดระเบียบชิ้นงานเหล่านี้ภายใน project อย่างไร
ผู้เขียนคิดว่ามีความแตกต่างที่เป็นประโยชน์ระหว่าง spec กับเอกสาร context ทั่ว ๆ ไปของ codebase โดย context ทั่วไปนั้นหมายถึงสิ่งอย่าง file rules หรือคำอธิบายระดับสูงของตัวผลิตภัณฑ์และ codebase
เครื่องมือบางตัวเรียก context นี้ว่า memory bank (คลังความจำของ project) ผู้เขียนจึงจะใช้คำนี้ในที่นี้
file เหล่านี้เกี่ยวข้องกับทุก ๆ session AI coding ใน codebase ขณะที่ spec จะเกี่ยวข้องเฉพาะกับงานที่สร้างหรือเปลี่ยนแปลง function การทำงานนั้น ๆ จริง ๆ เท่านั้น
flowchart TB
subgraph MB["Memory Bank"]
a1["AGENTS.md"]
a2["project.md"]
a3["architecture.md"]
end
subgraph SP["Specs"]
s1["Story-324.md"]
s2["product-search.md"]
subgraph FX["feature-x/"]
f1["data-model.md"]
f2["plan.md"]
end
end
ภาพ 2 — ภาพรวม file context ของ agent แบ่งเป็นสองกลุ่ม: memory bank ใช้ได้กับทุก session ใน codebase ส่วน specs เกี่ยวข้องเฉพาะกับงานหรือ feature ที่กำลังสร้าง/แก้เท่านั้น · ดูภาพต้นฉบับ ↗
ความท้าทายในการประเมินเครื่องมือ SDD
หัวข้อที่มีชื่อว่า “ความท้าทายในการประเมินเครื่องมือ SDD”กลายเป็นว่าการประเมินเครื่องมือและแนวทางแบบ SDD ให้ใกล้เคียงกับการใช้งานจริงนั้นกินเวลาพอสมควรทีเดียว คือต้องลองใช้กับปัญหาขนาดต่าง ๆ ทั้ง project ใหม่ (greenfield) และ codebase เดิมที่มีอยู่แล้ว (brownfield) และต้องลงเวลาจริง ๆ ในการรีวิวและปรับแก้ชิ้นงานระหว่างทาง ไม่ใช่แค่กวาดตามองผ่าน ๆ
เพราะอย่างที่ block post ของ GitHub เกี่ยวกับ spec-kit บอกไว้ว่า: “ที่สำคัญคือ บทบาทของคุณไม่ใช่แค่คอยกำกับทิศทาง แต่คือการตรวจสอบ ในแต่ละเฟส คุณต้องไตร่ตรองและขัดเกลา”
สำหรับเครื่องมือสองในสามตัวที่ผู้เขียนลอง ยังดูเหมือนจะต้องใช้แรงมากเป็นพิเศษในการนำมันไปใช้กับ codebase ที่มีอยู่แล้ว ทำให้ยิ่งยากขึ้นไปอีกที่จะประเมินว่ามันมีประโยชน์แค่ไหนกับ codebase แบบ brownfield
จนกว่าผู้เขียนจะได้ยินรายงานการใช้งานจากคนที่ใช้มันต่อเนื่องเป็นระยะเวลาหนึ่งบน codebase “จริง” ผู้เขียนก็ยังมีคำถามค้างคาอีกมากว่ามันใช้งานได้จริงในชีวิตจริงอย่างไร
เอาล่ะ — เรามาเข้าเรื่องเครื่องมือทั้งสามตัวกันเลย ผู้เขียนจะเล่าก่อนว่าแต่ละตัวทำงานอย่างไร (หรือพูดให้ถูกคือ ที่ผู้เขียนคิดว่ามันทำงานอย่างไร) และจะเก็บข้อสังเกตกับคำถามไว้ตอนท้าย
ทั้งนี้โปรดทราบว่าเครื่องมือเหล่านี้พัฒนาตัวเองเร็วมาก ดังนั้นมันอาจจะเปลี่ยนไปแล้วก็ได้จากตอนที่ผู้เขียนใช้เมื่อเดือนกันยายน
Kiro เป็นตัวที่เรียบง่ายที่สุด (หรือเบาที่สุด) ในสามตัวที่ผู้เขียนลอง มันดูเป็นแบบ spec-first เสียส่วนใหญ่ ตัวอย่างทั้งหมดที่ผู้เขียนเจอล้วนใช้มันกับงานหนึ่งงาน หรือกับ user story หนึ่งอัน โดยไม่มีการพูดถึงว่าจะใช้เอกสาร requirements แบบ spec-anchored ในระยะยาวข้ามหลาย ๆ งานได้อย่างไร
workflow: Requirements → Design → Tasks
แต่ละขั้นใน workflow จะแทนด้วยเอกสาร markdown หนึ่งฉบับ และ Kiro จะคอยนำทางคุณผ่าน 3 ขั้นนี้ภายในตัว distribution ที่อิงกับ VS Code ของมัน
Requirements: จัดเป็นรายการของ requirement โดยแต่ละ requirement แทน “User Story” หนึ่งอัน (ในรูปแบบ “As a…”) พร้อม acceptance criteria (ในรูปแบบ “GIVEN… WHEN… THEN…”)
📷 ภาพ 3 — เอกสาร Requirements ของ Kiro: แต่ละ requirement คือ “User Story” (รูปแบบ “As a…”) พร้อม acceptance criteria (รูปแบบ “GIVEN… WHEN… THEN…”) · ดูภาพหน้าจอต้นฉบับ ↗
Design: ในความพยายามของผู้เขียน เอกสาร design ประกอบด้วยส่วนต่าง ๆ ที่เห็นในภาพหน้าจอด้านล่าง ผู้เขียนยังมีผลลัพธ์เก็บไว้แค่จากความพยายามครั้งเดียว เลยไม่แน่ใจว่านี่เป็นโครงสร้างที่คงที่ หรือมันเปลี่ยนไปตามแต่ละงาน
📷 ภาพ 4 — เอกสาร Design ของ Kiro: มีไดอะแกรมสถาปัตยกรรมของคอมโพเนนต์ ตามด้วยหัวข้อที่พับเก็บไว้ — Data Flow, Data Models, Error Handling, Testing Strategy, Implementation Approach, Migration Strategy · ดูภาพหน้าจอต้นฉบับ ↗
Tasks: รายการของ task ที่โยงกลับไปยังหมายเลข requirement พร้อมส่วนประกอบ UI เพิ่มเติมสำหรับรัน task ทีละอันและรีวิวการเปลี่ยนแปลงในแต่ละ task
📷 ภาพ 5 — เอกสาร Tasks ของ Kiro: แต่ละ task มีปุ่ม “Task in progress” และ “View changes” เป็นรายการ TODO และจบด้วยเลขอ้างอิงกลับไปยัง requirement (1.1, 1.2, 1.3) · ดูภาพหน้าจอต้นฉบับ ↗
Kiro ก็มีแนวคิดของ memory bank เช่นกัน พวกเขาเรียกมันว่า “steering” เนื้อหาของมันยืดหยุ่นได้ และ workflow ของพวกเขาก็ดูเหมือนจะไม่ได้พึ่งพาว่าต้องมี file ใด file หนึ่งอยู่โดยเฉพาะ (ผู้เขียนลองใช้ Kiro ไปก่อนแล้วถึงเพิ่งมาค้นพบส่วน steering นี้ทีหลัง)
topology เริ่มต้นที่ Kiro สร้างขึ้นเมื่อคุณสั่งให้มันสร้างเอกสาร steering คือ product.md, structure.md, tech.md
flowchart TB
subgraph MB["Memory Bank (steering/)"]
p["product.md"]
t["tech.md"]
s["structure.md"]
end
subgraph SP["Specs: category-label-enhancement/"]
r["requirements.md"]
d["design.md"]
ta["tasks.md"]
end
ภาพ 6 — topology ของ Kiro: memory bank อยู่ใน folder steering/ ส่วน spec ของ feature ทดสอบ (category-label-enhancement/) มี3 file ตามขั้น requirements → design → tasks · ดูภาพต้นฉบับ ↗
Spec-kit
หัวข้อที่มีชื่อว่า “Spec-kit”Spec-kit คือ SDD version ของ GitHub มันถูกแจกจ่ายมาในรูปของ CLI ที่สามารถสร้างการตั้งค่า workspace ให้กับ coding assistant ยอดนิยมได้หลากหลายตัว เมื่อตั้งค่าโครงสร้างนี้เรียบร้อยแล้ว คุณจะโต้ตอบกับ spec-kit ผ่าน slash command ใน coding assistant ของคุณ
เนื่องจากชิ้นงานทั้งหมดของมันถูกวางไว้ใน workspace ของคุณโดยตรง มันจึงเป็นตัวที่ปรับแต่งได้มากที่สุดในสามตัวที่กล่าวถึงในที่นี้
📷 ภาพ 7 — โครง file ที่ spec-kit สร้างใน VS Code: ทางซ้ายมี file คำสั่งใน
.github/promptsและ folder.specify(มี memory, scripts, templates) ทางขวา GitHub Copilot กำลังพิมพ์คำสั่ง/specify· ดูภาพหน้าจอต้นฉบับ ↗
workflow: Constitution → Specify → Plan → Tasks
แนวคิด memory bank ของ spec-kit เป็นสิ่งที่ต้องมีก่อนจึงจะใช้แนวทาง spec-driven ได้ พวกเขาเรียกมันว่า constitution (ธรรมนูญ)
constitution มีไว้เพื่อบรรจุหลักการระดับสูงที่ “เปลี่ยนแปลงไม่ได้” และควรนำมาใช้เสมอกับทุก ๆ การเปลี่ยนแปลง โดยพื้นฐานแล้วมันก็คือ file rules ที่ทรงพลังมาก ๆ ซึ่ง workflow เรียกใช้อย่างหนัก
ในแต่ละขั้นของ workflow (specify, plan, tasks) spec-kit จะสร้างชุดของ file และ prompt ขึ้นมาด้วยความช่วยเหลือของ bash script และ template บางส่วน
จากนั้น workflow ก็จะใช้ checklist ภายใน file เหล่านั้นอย่างหนัก เพื่อติดตามจุดที่ต้องให้ผู้ใช้ชี้แจง การละเมิด constitution งาน research ฯลฯ มันก็เหมือนเป็น “definition of done” ของแต่ละขั้นใน workflow (แต่ AI เป็นคนตีความ ดังนั้นจึงไม่มีอะไรการันตี 100% ว่ามันจะถูกทำตาม)
📷 ภาพ 8 — ช่วงท้าย file
spec.mdของ spec-kit: เต็มไปด้วย checklist หลายชุด ทั้งคุณภาพเนื้อหา ความครบของ requirement และสถานะการทำงาน · ดูภาพหน้าจอต้นฉบับ ↗
ด้านล่างนี้คือภาพรวมเพื่อแสดงให้เห็น topology ของ file ที่ผู้เขียนเห็นใน spec-kit สังเกตว่า spec หนึ่งอันประกอบด้วย file จำนวนมาก
flowchart TB
subgraph MB["Memory Bank"]
c["constitution.md"]
end
subgraph TPL["Templates"]
pt["plan-template.md"]
st["spec-template.md"]
tt["tasks-template.md"]
end
subgraph SP["Specs: specs/001-when-a-user/ (~8 files)"]
f1["spec.md"]
f2["plan.md"]
f3["tasks.md"]
f4["data-model.md"]
f5["research.md"]
f6["api.md"]
f7["component.md"]
end
ภาพ 9 — topology ของ spec-kit: memory bank คือ constitution.md มีกล่อง templates เพิ่มเข้ามา และ spec หนึ่งชุด (specs/001-when-a-user/) ประกอบด้วย file ราว 8 file — สังเกตว่า 1 spec กระจายเป็นหลาย file · ดูภาพต้นฉบับ ↗
เมื่อมองเผิน ๆ ดูเหมือน GitHub จะมุ่งไปสู่แนวทางแบบ spec-anchored (“นี่คือเหตุผลที่เรากำลังคิดทบทวนเรื่อง spec กันใหม่ — ไม่ใช่ในฐานะเอกสารที่อยู่นิ่งกับที่ แต่ในฐานะชิ้นงานที่มีชีวิต รันได้ และพัฒนาไปพร้อมกับ project spec จะกลายเป็นแหล่งความจริงร่วมกัน เมื่ออะไรบางอย่างดูไม่สมเหตุสมผล คุณก็ย้อนกลับไปที่ spec เมื่อ project ซับซ้อนขึ้น คุณก็ขัดเกลามัน เมื่อรู้สึกว่างานใหญ่เกินไป คุณก็แตกย่อยมันออก”)
อย่างไรก็ตาม spec-kit สร้าง branch ขึ้นมาใหม่สำหรับทุก spec ที่ถูกสร้าง ซึ่งดูเหมือนจะบ่งชี้ว่าพวกเขามอง spec เป็นชิ้นงานที่มีชีวิตตลอดอายุของคำขอเปลี่ยนแปลง (change request) หนึ่งครั้ง ไม่ใช่ตลอดอายุของ feature การพูดคุยในชุมชนนี้ ก็กำลังพูดถึงความสับสนตรงนี้
มันทำให้ผู้เขียนคิดว่า spec-kit ยังเป็นแบบที่ผู้เขียนเรียกว่า spec-first เพียงอย่างเดียวอยู่ ไม่ใช่ spec-anchored ในระยะยาว
Tessl Framework
หัวข้อที่มีชื่อว่า “Tessl Framework”(ยังอยู่ในช่วง private beta)
เช่นเดียวกับ spec-kit Tessl Framework ถูกแจกจ่ายมาในรูปของ CLI ที่สามารถสร้างโครงสร้าง workspace และ config ทั้งหมดให้กับ coding assistant หลากหลายตัว นอกจากนี้ CLI ยังทำหน้าที่เป็น MCP server ได้ด้วย
📷 ภาพ 10 — file ที่ Tessl สร้างใน Cursor: ทางซ้ายมี folder
.tessl/frameworkทางขวาคือค่าตั้ง MCP ที่สั่งรันคำสั่งtesslในโหมด MCP · ดูภาพหน้าจอต้นฉบับ ↗
Tessl เป็นเครื่องมือตัวเดียวในสามตัวนี้ที่มุ่งสู่แนวทางแบบ spec-anchored อย่างชัดเจน และยังลองสำรวจ SDD ในระดับ spec-as-source อีกด้วย spec ของ Tessl สามารถทำหน้าที่เป็นชิ้นงานหลักที่ถูกดูแลและแก้ไข โดยตัว code เองยังมีคอมเมนต์กำกับไว้ด้านบนว่า // GENERATED FROM SPEC - DO NOT EDIT
ปัจจุบันนี้เป็นการ map แบบ 1:1 ระหว่าง file spec กับ file code กล่าวคือ spec หนึ่งอันแปลงไปเป็น file 1 file ใน codebase
แต่ Tessl ยังอยู่ในช่วง beta และพวกเขากำลังทดลองทำ version ต่าง ๆ ของแนวทางนี้ ดังนั้นผู้เขียนพอจะนึกออกว่าแนวทางนี้อาจถูกนำไปใช้ในระดับที่ spec หนึ่งอัน map ไปยัง component ของ code ที่มีหลาย file ก็ได้
คงต้องรอดูว่าตัว alpha product จะรองรับอะไรบ้าง (ทีม Tessl เองก็มองว่า framework ของพวกเขาเป็นเรื่องของอนาคตมากกว่า เมื่อเทียบกับผลิตภัณฑ์สาธารณะที่มีอยู่ตอนนี้อย่าง Tessl Registry)
นี่คือตัวอย่างของ spec ที่ผู้เขียนให้ Tessl CLI ทำ reverse engineer (tessl document --code ...js) จาก file JavaScript ใน codebase ที่มีอยู่แล้ว:
📷 ภาพ 11 — file spec ของ Tessl: ตัวอย่าง spec ที่ผู้เขียนให้ reverse engineer ออกมาจาก file JavaScript เดิม · ดูภาพหน้าจอต้นฉบับ ↗
แท็กอย่าง @generate หรือ @test ดูเหมือนจะเป็นตัวบอก Tessl ว่าจะให้สร้างอะไร
ส่วน API แสดงให้เห็นแนวคิดของการนิยาม interface เอาไว้ใน spec อย่างน้อยก็ตัวที่ถูกเปิดให้ส่วนอื่น ๆ ของ codebase เข้าถึง ซึ่งน่าจะเพื่อให้แน่ใจว่าส่วนที่สำคัญกว่าเหล่านี้ของ component ที่ถูกสร้างขึ้นมาอยู่ภายใต้การควบคุมของผู้ดูแลอย่างเต็มที่
การรัน tessl build สำหรับ spec นี้จะสร้าง file code JavaScript ที่สอดคล้องกันขึ้นมา
การวาง spec สำหรับ spec-as-source ไว้ที่ระดับนามธรรมที่ค่อนข้างต่ำ คือต่อ1 file code น่าจะช่วยลดจำนวนขั้นตอนและการตีความที่ LLM ต้องทำลง และจึงลดโอกาสเกิดข้อผิดพลาด
แต่ถึงจะอยู่ที่ระดับนามธรรมต่ำขนาดนี้ ผู้เขียนก็ยังได้เห็นความไม่แน่นอน (non-determinism) เกิดขึ้นจริง ตอนที่สร้าง code จาก spec เดียวกันหลาย ๆ ครั้ง
การวนปรับ spec ให้เฉพาะเจาะจงขึ้นเรื่อย ๆ เพื่อเพิ่มความสามารถในการสร้าง code ให้ออกมาซ้ำเดิมได้ เป็นแบบฝึกหัดที่น่าสนใจ กระบวนการนั้นทำให้ผู้เขียนนึกถึงกับดักและความท้าทายบางอย่างของการเขียน specification ที่ชัดเจนไม่กำกวมและครบถ้วน
flowchart TB
subgraph MB["Memory Bank"]
fw[".tessl/framework/ (4 files)"]
k["KNOWLEDGE.md"]
ag["AGENTS.md"]
end
subgraph SP["Specs"]
sp1["dynamic-data-renderer.spec.md"]
end
subgraph CD["Code"]
cd1["dynamic-data-renderer.js"]
end
sp1 <-->|"synced"| cd1
ภาพ 12 — topology ของ Tessl: memory bank คือ folder .tessl/framework (4 file) บวก KNOWLEDGE.md และ AGENTS.md มีกล่อง Code เพิ่มเข้ามา และลูกศรสองทางระหว่าง spec กับ code สื่อว่าทั้งคู่ถูก sync เข้าหากัน · ดูภาพต้นฉบับ ↗
ข้อสังเกตและคำถาม
หัวข้อที่มีชื่อว่า “ข้อสังเกตและคำถาม”เครื่องมือทั้งสามตัวนี้ต่างนิยามตัวเองว่าเป็นการนำ spec-driven development ไปใช้งาน แต่มันก็แตกต่างกันมากทีเดียว ดังนั้นนี่คือสิ่งแรกที่ต้องจำไว้เวลาพูดถึง SDD: มันไม่ใช่สิ่งเดียวกันหมด
workflow เดียวพอใช้ได้กับทุกขนาดงานไหม?
หัวข้อที่มีชื่อว่า “workflow เดียวพอใช้ได้กับทุกขนาดงานไหม?”Kiro และ spec-kit ต่างก็ให้ workflow ที่มีแนวทางตายตัวมาตัวละหนึ่งกระบวนการ แต่ผู้เขียนค่อนข้างมั่นใจว่าทั้งคู่ไม่เหมาะกับปัญหา coding ในชีวิตจริงส่วนใหญ่ โดยเฉพาะอย่างยิ่ง ผู้เขียนยังไม่ค่อยเห็นภาพชัดว่ามันจะรองรับปัญหาขนาดต่าง ๆ ได้มากพอจนนำไปใช้ได้ทั่วไปอย่างไร
ตอนที่ผู้เขียนให้ Kiro แก้ bug เล็ก ๆ (เป็น bug ตัวเดียวกับที่ผู้เขียนเคยใช้ลอง Codex มาก่อน) มันก็เห็นได้ชัดอย่างรวดเร็วว่า workflow นี้เหมือนขี่ช้างจับตั๊กแตน
เอกสาร requirements เปลี่ยน bug เล็ก ๆ นี้ให้กลายเป็น “user story” 4 อัน พร้อม acceptance criteria รวมกัน 16 ข้อ
รวมถึงอัญมณีล้ำค่า (ในเชิงประชด) อย่าง “User story: ในฐานะนักพัฒนา ฉันอยากให้ function transformation จัดการกับ edge case ได้อย่างราบรื่น เพื่อให้ระบบยังคงทนทานเมื่อมีรูปแบบ category ใหม่ ๆ เข้ามา”
ผู้เขียนเจอความท้าทายคล้าย ๆ กันตอนใช้ spec-kit คือไม่ค่อยแน่ใจว่าควรใช้มันกับปัญหาขนาดไหน tutorial ที่มีให้มักจะอิงกับการสร้าง application ขึ้นมาใหม่ทั้งหมด เพราะนั่นง่ายที่สุดสำหรับการทำ tutorial
หนึ่งใน use case ที่ผู้เขียนลองในที่สุดคือ feature ที่น่าจะเป็น story ขนาด 3-5 point ในทีมเดิมทีมหนึ่งของผู้เขียน feature นี้พึ่งพา code ที่มีอยู่แล้วเป็นจำนวนมาก โดยมันควรจะสร้าง modal ภาพรวมที่สรุปข้อมูลก้อนหนึ่งจาก dashboard ที่มีอยู่
ด้วยจำนวนขั้นตอนที่ spec-kit ทำ และจำนวน file markdown ที่มันสร้างมาให้ผู้เขียนรีวิว ตรงนี้ก็ให้ความรู้สึกว่าเกินจำเป็นอีกครั้งเมื่อเทียบกับขนาดของปัญหา มันเป็นปัญหาที่ใหญ่กว่าตัวที่ผู้เขียนใช้กับ Kiro แต่ก็มี workflow ที่ซับซ้อนละเอียดกว่ามากเช่นกัน
ผู้เขียนไม่เคยทำการ implement ให้เสร็จสมบูรณ์เลยด้วยซ้ำ แต่ผู้เขียนคิดว่าในเวลาเท่ากันกับที่ใช้ไปกับการรันและรีวิวผลลัพธ์ของ spec-kit ผู้เขียนน่าจะ implement feature นี้ได้ด้วยการเขียน code แบบ AI-assisted “ธรรมดา ๆ” และคงรู้สึกว่าตัวเองควบคุมได้มากกว่ามาก
เครื่องมือ SDD ที่ได้ผลจริง อย่างน้อยที่สุดก็ต้องให้ความยืดหยุ่นสำหรับ workflow หลักสักสองสามแบบที่ต่างกัน เพื่อรองรับการเปลี่ยนแปลงหลายขนาดและหลายประเภท
รีวิว markdown แทนที่จะรีวิว code?
หัวข้อที่มีชื่อว่า “รีวิว markdown แทนที่จะรีวิว code?”อย่างที่เพิ่งกล่าวไป และอย่างที่คุณเห็นในคำอธิบายเครื่องมือด้านบน spec-kit สร้าง file markdown ออกมาให้ผู้เขียนรีวิวเยอะมาก file เหล่านั้นซ้ำซ้อนกันเอง และซ้ำซ้อนกับ code ที่มีอยู่แล้วด้วย บาง file มี code อยู่ในตัวแล้ว โดยรวมแล้วมันเยิ่นเย้อและน่าเบื่อที่จะรีวิวมาก
ใน Kiro นั้นง่ายกว่าหน่อย เพราะคุณได้แค่ 3 file และ model ความคิด (mental model) แบบ “requirements > design > tasks” ก็เข้าใจได้ง่ายตามสัญชาตญาณมากกว่า อย่างไรก็ตาม อย่างที่กล่าวไป Kiro เองก็ทำเกินกว่าเหตุไปมากกับ bug เล็ก ๆ ที่ผู้เขียนขอให้แก้
พูดตามตรง ผู้เขียนอยากรีวิว code มากกว่ารีวิว file markdown พวกนี้ทั้งหมด เครื่องมือ SDD ที่ได้ผลจริงจะต้องให้ประสบการณ์การรีวิว spec ที่ดีมาก ๆ
ความรู้สึกว่าควบคุมได้นั้นลวงตาหรือไม่?
หัวข้อที่มีชื่อว่า “ความรู้สึกว่าควบคุมได้นั้นลวงตาหรือไม่?”ทั้ง ๆ ที่มี file template prompt workflow และ checklist ทั้งหมดนี้ ผู้เขียนก็ยังเห็น agent สุดท้ายแล้วไม่ทำตามคำสั่งทั้งหมดอยู่บ่อย ๆ
ใช่ ตอนนี้ context window ใหญ่ขึ้นแล้ว ซึ่งก็มักถูกยกขึ้นมาเป็นหนึ่งในปัจจัยที่ทำให้ spec-driven development เป็นไปได้ แต่การที่ window ใหญ่ขึ้น ไม่ได้แปลว่า AI จะหยิบเอาทุกอย่างที่อยู่ในนั้นไปใช้ได้อย่างถูกต้อง
ตัวอย่างเช่น: spec-kit มีขั้น research อยู่ที่ไหนสักแห่งระหว่างการวางแผน (planning) และมันก็ทำ research เกี่ยวกับ code ที่มีอยู่และสิ่งที่อยู่ตรงนั้นแล้วเยอะมาก ซึ่งดีมาก เพราะผู้เขียนขอให้มันเพิ่ม feature ที่ต่อยอดจาก code ที่มีอยู่
แต่สุดท้าย agent กลับเพิกเฉยต่อบันทึกที่ระบุว่าสิ่งเหล่านี้เป็นคำอธิบายของ class ที่มีอยู่แล้ว มันดันเอาไปตีความเป็น specification ใหม่และสร้างมันขึ้นมาใหม่ทั้งหมดอีกครั้ง ทำให้เกิดของซ้ำซ้อนขึ้นมา
แต่ผู้เขียนไม่ได้เห็นแค่ตัวอย่างของการเพิกเฉยต่อคำสั่ง ผู้เขียนยังเห็น agent ทำเลยเถิดเกินเลย เพราะมันกระตือรือร้นทำตามคำสั่งมากเกินไปด้วย (เช่น ทำตามมาตราหนึ่งใน constitution)
ประสบการณ์ที่ผ่านมาแสดงให้เห็นว่า วิธีที่ดีที่สุดในการคงการควบคุมสิ่งที่เรากำลังสร้างไว้ คือการทำทีละก้าวเล็ก ๆ แบบ iterative ดังนั้นผู้เขียนจึงค่อนข้างกังขาว่าการออกแบบ spec ล่วงหน้าจำนวนมากจะเป็นความคิดที่ดีจริงหรือ โดยเฉพาะเมื่อมันเยิ่นเย้อเกินไป
เครื่องมือ SDD ที่ได้ผลจริงจะต้องรองรับแนวทางแบบ iterative แต่ work package เล็ก ๆ ก็ดูเหมือนจะสวนทางกับแนวคิดของ SDD เกือบจะโดยสิ้นเชิง
จะแยก functional spec ออกจาก technical spec ให้ได้ผลอย่างไร?
หัวข้อที่มีชื่อว่า “จะแยก functional spec ออกจาก technical spec ให้ได้ผลอย่างไร?”เป็นแนวคิดที่พบได้ทั่วไปใน SDD ที่จะตั้งใจแยกระหว่าง functional spec กับการ implement เชิงเทคนิคออกจากกัน ผู้เขียนเดาว่าความมุ่งหวังเบื้องหลังคือ ในที่สุดเราจะให้ AI เติมส่วนของการแก้ปัญหาและรายละเอียดทั้งหมดเข้ามาเอง และสลับไปใช้ tech stack ต่าง ๆ ได้ด้วย spec อันเดียวกัน
ในความเป็นจริง ตอนที่ผู้เขียนลองใช้ spec-kit ผู้เขียนสับสนบ่อย ๆ ว่าเมื่อไรควรอยู่ที่ระดับ functional และเมื่อไรถึงเวลาที่จะเพิ่มรายละเอียดเชิงเทคนิค ทั้ง tutorial และเอกสารเองก็ไม่ค่อยสอดคล้องกันในเรื่องนี้ ดูเหมือนจะมีการตีความที่ต่างกันว่า “purely functional” จริง ๆ แล้วหมายความว่าอย่างไร
และเมื่อผู้เขียนนึกย้อนกลับไปถึง user story มากมายเหลือเกินที่ผู้เขียนได้อ่านมาตลอดอาชีพ ซึ่งแยก requirement ออกจาก implementation ได้ไม่ดีนัก ผู้เขียนก็ไม่คิดว่าพวกเราในฐานะวิชาชีพมีประวัติที่ดีในการทำเรื่องนี้เลย
ใครคือผู้ใช้กลุ่มเป้าหมาย?
หัวข้อที่มีชื่อว่า “ใครคือผู้ใช้กลุ่มเป้าหมาย?”เดโมและ tutorial มากมายของเครื่องมือ spec-driven development รวมถึงสิ่งต่าง ๆ อย่างการนิยามเป้าหมายของผลิตภัณฑ์และ feature รวมไปถึงการใช้คำอย่าง “user story” ด้วยซ้ำ
แนวคิดตรงนี้อาจจะเป็นการใช้ AI เป็นตัวช่วยให้นักพัฒนาข้ามไปเรียนรู้ทักษะอื่น (cross-skilling) และให้นักพัฒนามีส่วนร่วมในการวิเคราะห์ requirement มากขึ้น? หรือให้นักพัฒนาจับคู่ทำงาน (pair) กับคนสาย product เวลาทำ workflow นี้?
แต่ก็ไม่มีการทำให้ชัดเจนเลยสักอย่าง มันถูกนำเสนอราวกับเป็นเรื่องที่รู้กันอยู่แล้วว่านักพัฒนาจะเป็นคนวิเคราะห์ทั้งหมดนี้เอง
ซึ่งถ้าเป็นเช่นนั้น ผู้เขียนก็จะถามตัวเองอีกครั้งว่า SDD มีไว้สำหรับปัญหาขนาดและประเภทไหน?
คงไม่ใช่สำหรับ feature ขนาดใหญ่ที่ยังคลุมเครืออยู่มาก เพราะแน่นอนว่านั่นต้องการทักษะเฉพาะทางด้าน product และ requirement มากกว่านี้ บวกกับขั้นตอนอื่น ๆ อีกมากมายอย่างการทำ research และการให้ผู้มีส่วนได้ส่วนเสียเข้ามาเกี่ยวข้องด้วยไม่ใช่หรือ?
| ปัญหายังไม่ชัด | ปัญหาชัดเจน | |
|---|---|---|
| ปัญหาใหญ่ | ❓ | ❓ |
| ปัญหาเล็ก | ❓ | ❓ |
ภาพ 13 — แล้ว SDD ควรอยู่ช่องไหนของเมทริกซ์นี้? (แกนนอน = ความชัดเจนของปัญหา, แกนตั้ง = ขนาดของปัญหา) แต่ละช่องมีแต่เครื่องหมายคำถาม — นี่คือคำถามที่ผู้เขียนทิ้งไว้ให้คิด · ดูภาพต้นฉบับ ↗
Spec-anchored และ spec-as-source: เรากำลังเรียนรู้จากอดีตอยู่หรือเปล่า?
หัวข้อที่มีชื่อว่า “Spec-anchored และ spec-as-source: เรากำลังเรียนรู้จากอดีตอยู่หรือเปล่า?”ในขณะที่หลายคนเปรียบเทียบ SDD กับ TDD หรือ BDD ผู้เขียนคิดว่าอีกหนึ่งความเชื่อมโยงสำคัญที่ควรพิจารณา โดยเฉพาะสำหรับ spec-as-source คือ MDD (การพัฒนาแบบขับเคลื่อนด้วย model)
ผู้เขียนเคยทำงานใน project ไม่กี่อันช่วงต้นอาชีพที่ใช้ MDD อย่างหนัก และมันก็ทำให้ผู้เขียนนึกถึง MDD อยู่ตลอดเวลาตอนที่ลองใช้ Tessl Framework
model ใน MDD โดยพื้นฐานแล้วก็คือ spec นั่นเอง เพียงแต่ไม่ได้อยู่ในรูปภาษาคน แต่แสดงออกด้วย UML แบบกำหนดเอง หรือ DSL (Domain-Specific Language — ภาษาที่ออกแบบมาเฉพาะ domain) แบบข้อความ เป็นต้น เราสร้าง code generator แบบกำหนดเองขึ้นมาเพื่อแปลง spec เหล่านั้นให้เป็น code
Screen "Write Message" instantiates InputScreen { field recipient -> Domain.Contact.name field body -> Domain.Message.text inherits BaseComposeScreen // นำ pattern จากสกรีนอื่นมาใช้ซ้ำ on submit -> navigate("Inbox") // ตรรกะการนำทาง (navigation)}ภาพ 14 — ตัวอย่างภาษา DSL สำหรับเขียน spec แบบ MDD (วาดใหม่จากความทรงจำของผู้เขียน) ภาษาแบบนี้ “แยกวิเคราะห์ได้” (parseable) จึงสร้างเครื่องมือช่วยตรวจให้ spec ถูกต้อง ครบถ้วน และสอดคล้องกันได้ — ข้อดีที่กำลังหายไปเมื่อเปลี่ยนมาใช้ LLM · ดูภาพต้นฉบับ ↗
ในที่สุด MDD ก็ไม่เคยได้รับความนิยมแพร่หลายสำหรับ application เชิงธุรกิจ มันอยู่ที่ระดับนามธรรมที่ก้ำกึ่งไม่ลงตัว และสร้างทั้งภาระงานและข้อจำกัดที่มากเกินจำเป็น
แต่ LLM ช่วยกำจัดภาระงานและข้อจำกัดบางส่วนของ MDD ออกไป จึงเกิดความหวังใหม่ว่าในที่สุดเราจะมุ่งไปที่การเขียน spec แล้วสร้าง code ออกมาจากมันได้เสียที ด้วย LLM เราไม่ถูกจำกัดด้วยภาษา spec ที่ต้องนิยามไว้ล่วงหน้าและ parse ได้อีกต่อไป และเราก็ไม่ต้องสร้าง code generator ที่ซับซ้อนละเอียดอีกแล้ว
ราคาที่ต้องจ่ายสำหรับสิ่งนั้นแน่นอนว่าคือ non-determinism ของ LLM และโครงสร้างที่ parse ได้นั้นก็มีข้อดีที่ตอนนี้เรากำลังจะสูญเสียไปด้วย: เราเคยมีเครื่องมือมากมายคอยช่วยผู้เขียน spec ให้เขียน spec ที่ถูกต้องตามรูปแบบ ครบถ้วน และสอดคล้องกันได้
ผู้เขียนสงสัยว่า spec-as-source หรือแม้แต่ spec-anchoring อาจจะลงเอยด้วยการได้ข้อเสียของทั้ง MDD และ LLM มาทั้งคู่: ทั้งความไม่ยืดหยุ่น และ ความไม่แน่นอน
ขอพูดให้ชัด ผู้เขียนไม่ได้คิดถึงประสบการณ์ MDD ในอดีตด้วยความโหยหา แล้วบอกว่า “เราน่าจะเอามันกลับมาใช้ซะเลย” แต่เราควรย้อนดูความพยายามสร้าง code จาก spec (code-from-spec) ในอดีตเพื่อเรียนรู้จากมัน ในตอนที่เรากำลังสำรวจ spec-driven กันในวันนี้
ในการใช้ AI-assisted coding ส่วนตัวของผู้เขียนเอง ผู้เขียนก็มักใช้เวลาไปกับการเรียบเรียง spec บางรูปแบบขึ้นมาอย่างพิถีพิถันก่อนเพื่อส่งให้ coding agent เช่นกัน ดังนั้นหลักการทั่วไปของ spec-first นั้นมีคุณค่าอย่างแน่นอนในหลาย ๆ สถานการณ์
และแนวทางต่าง ๆ ในการจัดโครงสร้าง spec ก็เป็นสิ่งที่ผู้คนต้องการกันมาก มันอยู่ในกลุ่มคำถามที่ผู้เขียนได้ยินบ่อยที่สุดจากผู้ปฏิบัติงานในตอนนี้: “ผมควรจัดโครงสร้าง memory bank อย่างไร?”, “ผมจะเขียน specification และเอกสาร design ที่ดีสำหรับ AI ได้อย่างไร?”
แต่คำว่า “spec-driven development” ก็ยังไม่ถูกนิยามไว้ดีนัก และมันก็เกิดการจางของความหมาย (semantic diffusion) ไปแล้วด้วยซ้ำ ผู้เขียนถึงขั้นได้ยินคนใช้คำว่า “spec” ราวกับเป็นคำพ้องความหมายกับ “prompt ที่ละเอียด” เมื่อเร็ว ๆ นี้
ส่วนเครื่องมือที่ผู้เขียนได้ลองนั้น ผู้เขียนได้ list คำถามมากมายเกี่ยวกับประโยชน์ของมันในโลกจริงไว้ตรงนี้แล้ว
ผู้เขียนสงสัยว่าบางตัวอาจกำลังพยายามยัด workflow เดิมที่เรามีอยู่ให้เข้ากับ AI agent แบบตรงตัวเกินไปหรือเปล่า จนสุดท้ายกลับกลายเป็นการขยายปัญหาเดิมให้ใหญ่ขึ้น อย่างภาระงานรีวิวที่ล้นมือ (review overload) และปัญหา hallucination โดยเฉพาะกับแนวทางที่ละเอียดซับซ้อนกว่าซึ่งสร้าง file ออกมาเป็นจำนวนมาก
ผู้เขียนอดนึกถึงคำสมาสภาษาเยอรมัน “Verschlimmbesserung” (คำเยอรมัน หมายถึง “การทำให้แย่ลง ทั้งที่ตั้งใจจะทำให้ดีขึ้น”) ไม่ได้: เรากำลังทำบางอย่างให้แย่ลงในความพยายามที่จะทำให้มันดีขึ้นอยู่หรือเปล่า?
📄 อ่านต้นฉบับภาษาอังกฤษ: Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl — Birgitta Böckeler, martinfowler.com (15 ตุลาคม 2025)