Agile Retrospective
Retrospective Agile Scrum Sprint Review Action Items Continuous Improvement Facilitation Start Stop Continue Mad Sad Glad 4Ls Sailboat Remote Team
| เทคนิค | ความยาก | เหมาะกับ | ใช้เวลา | ผู้เข้าร่วม |
|---|---|---|---|---|
| Start Stop Continue | ง่าย | ทีมใหม่ | 45 นาที | 3-10 คน |
| Mad Sad Glad | ง่าย | ทีมที่มีปัญหา | 60 นาที | 3-10 คน |
| 4Ls | ปานกลาง | ทีมทั่วไป | 60 นาที | 3-12 คน |
| Sailboat | ปานกลาง | ทีมที่มีเป้าหมาย | 90 นาที | 5-15 คน |
| Timeline | ยาก | Sprint ยาว | 90 นาที | 5-15 คน |
Retrospective Framework
# === Retrospective Automation ===
# Python — Retro Board Management
# from dataclasses import dataclass, field
# from datetime import datetime
# from typing import List
# import json
#
# @dataclass
# class StickyNote:
# author: str
# text: str
# category: str # start, stop, continue
# votes: int = 0
# created_at: str = ""
#
# @dataclass
# class RetroBoard:
# sprint: str
# date: str
# technique: str
# notes: List[StickyNote] = field(default_factory=list)
# action_items: List[dict] = field(default_factory=list)
#
# def add_note(self, author, text, category):
# note = StickyNote(author, text, category,
# created_at=datetime.now().isoformat())
# self.notes.append(note)
#
# def vote(self, note_index):
# self.notes[note_index].votes += 1
#
# def top_items(self, n=5):
# return sorted(self.notes, key=lambda x: x.votes, reverse=True)[:n]
#
# def add_action(self, action, owner, deadline):
# self.action_items.append({
# "action": action,
# "owner": owner,
# "deadline": deadline,
# "status": "pending"
# })
#
# def export_json(self):
# return json.dumps({
# "sprint": self.sprint,
# "date": self.date,
# "technique": self.technique,
# "notes": [vars(n) for n in self.notes],
# "action_items": self.action_items
# }, indent=2, ensure_ascii=False)
from dataclasses import dataclass
@dataclass
class RetroItem:
category: str
text: str
votes: int
priority: str
items_example = [
RetroItem("Start", "เขียน Unit Test ก่อน Code (TDD)", 8, "High"),
RetroItem("Start", "Daily Standup ไม่เกิน 15 นาที", 6, "High"),
RetroItem("Stop", "Merge โดยไม่ผ่าน Code Review", 9, "High"),
RetroItem("Stop", "ประชุมที่ไม่มี Agenda", 7, "High"),
RetroItem("Continue", "Pair Programming วันละ 2 ชั่วโมง", 5, "Medium"),
RetroItem("Continue", "Sprint Demo ทุกศุกร์", 4, "Medium"),
RetroItem("Improve", "CI/CD Pipeline ช้า รอ 20 นาที", 10, "Critical"),
RetroItem("Improve", "Documentation ไม่อัพเดท", 6, "High"),
]
print("=== Sprint 24 Retrospective ===")
print(" Technique: Start-Stop-Continue\n")
for item in sorted(items_example, key=lambda x: x.votes, reverse=True):
print(f" [{item.category}] {item.text}")
print(f" Votes: {item.votes} | Priority: {item.priority}")
Facilitation Guide
# === Retro Facilitation ===
# Meeting Agenda (60 minutes)
# Phase 1: Set the Stage (5 min)
# - Check-in: "ให้คะแนน Sprint นี้ 1-5"
# - Review previous action items
#
# Phase 2: Gather Data (15 min)
# - Silent writing: ทุกู้คืนเขียน Sticky Notes
# - Categories: Start / Stop / Continue
# - Timer: 10 minutes writing
#
# Phase 3: Generate Insights (20 min)
# - Group similar items
# - Dot Voting: 3 dots per person
# - Discuss top voted items
#
# Phase 4: Decide Actions (15 min)
# - Pick top 2-3 items
# - Create SMART action items
# - Assign owners and deadlines
#
# Phase 5: Close (5 min)
# - Summarize action items
# - Rate the retro: "Retro นี้มีประโยชน์แค่ไหน 1-5"
@dataclass
class ActionItem:
action: str
owner: str
deadline: str
metric: str
status: str
actions = [
ActionItem("ลด CI/CD Pipeline เหลือ 10 นาที", "DevOps Lead", "Sprint 25", "Pipeline < 10min", "In Progress"),
ActionItem("บังคับ Code Review ก่อน Merge", "Tech Lead", "Sprint 25", "100% PR reviewed", "Done"),
ActionItem("อัพเดท API Documentation", "Backend Team", "Sprint 26", "All endpoints documented", "Pending"),
ActionItem("ตั้ง Daily Standup Timer 15 นาที", "Scrum Master", "Sprint 25", "Avg < 15min", "Done"),
]
print("\n=== Action Items ===")
for a in actions:
print(f" [{a.status}] {a.action}")
print(f" Owner: {a.owner} | Deadline: {a.deadline}")
print(f" Metric: {a.metric}")
# Facilitation Tips
tips = [
"Safety Check: เริ่มด้วย Anonymous Safety Check 1-5",
"Silent Writing: ให้เวลาเขียนก่อน ไม่พูดทับ",
"Dot Voting: ทุกู้คืนมีสิทธิ์เท่ากัน 3 dots",
"Timebox: จับเวลาทุก Phase ไม่ให้ยืด",
"Rotate Technique: สลับเทคนิคทุก Sprint",
"Follow-up: Review Action Items ต้น Sprint ถัดไป",
"Celebrate: ชื่นชมสิ่งที่ทำได้ดี ไม่ใช่แค่ปัญหา",
]
print(f"\n\nFacilitation Tips:")
for i, t in enumerate(tips, 1):
print(f" {i}. {t}")
Remote Retro Tools
# === Online Retro Tools ===
@dataclass
class RetroTool:
name: str
pricing: str
features: str
max_users: str
best_for: str
tools = [
RetroTool("Miro", "Free / $8/mo", "Whiteboard Templates Timer", "Unlimited", "Visual Teams"),
RetroTool("EasyRetro", "Free / $25/mo", "Board Voting Actions", "3 free boards", "Simple Retro"),
RetroTool("FunRetro", "Free / $25/mo", "Board Voting Export", "3 free boards", "Quick Setup"),
RetroTool("Retrium", "$29/user/mo", "Guided Retro Analytics", "Unlimited", "Enterprise"),
RetroTool("Metro Retro", "Free / $6/mo", "Templates Games Timer", "Unlimited free", "Fun Retros"),
RetroTool("Parabol", "Free / $6/mo", "Standup Retro Poker", "Unlimited free", "All-in-one"),
]
print("Remote Retro Tools:")
for t in tools:
print(f" [{t.name}] {t.pricing}")
print(f" Features: {t.features}")
print(f" Users: {t.max_users} | Best for: {t.best_for}")
# Retro Metrics Over Time
sprint_metrics = {
"Sprint 20": {"happiness": 3.2, "actions_completed": "1/3", "velocity": 28},
"Sprint 21": {"happiness": 3.5, "actions_completed": "2/3", "velocity": 30},
"Sprint 22": {"happiness": 3.8, "actions_completed": "3/3", "velocity": 32},
"Sprint 23": {"happiness": 4.0, "actions_completed": "2/3", "velocity": 35},
"Sprint 24": {"happiness": 4.2, "actions_completed": "3/3", "velocity": 38},
}
print(f"\n\nTeam Health Over Sprints:")
for sprint, m in sprint_metrics.items():
bar = "#" * int(m["happiness"] * 4)
print(f" {sprint}: Happiness {m['happiness']}/5 {bar}")
print(f" Actions: {m['actions_completed']} | Velocity: {m['velocity']} pts")
เคล็ดลับ
- Safety: สร้างบรรยากาศปลอดภัย ไม่ตำหนิ
- SMART: Action Items ต้อง SMART วัดได้
- 2-3 Actions: เลือกแค่ 2-3 ข้อ ไม่เยอะเกิน
- Follow-up: ติดตาม Action Items ทุก Sprint
- Rotate: สลับเทคนิค ไม่ให้น่าเบื่อ
การนำความรู้ไปประยุกต์ใช้งานจริง
แหล่งเรียนรู้ที่แนะนำ ได้แก่ Official Documentation ที่อัพเดทล่าสุดเสมอ Online Course จาก Coursera Udemy edX ช่อง YouTube คุณภาพทั้งไทยและอังกฤษ และ Community อย่าง Discord Reddit Stack Overflow ที่ช่วยแลกเปลี่ยนประสบการณ์กับนักพัฒนาทั่วโลก
Retrospective คืออะไร
ประชุมทบทวน Sprint อะไรดี อะไรปรับปรุง 1-2 ชั่วโมง Scrum Master Facilitator Action Items Continuous Improvement Sprint ถัดไป
มีเทคนิค Retrospective อะไรบ้าง
Start Stop Continue Mad Sad Glad 4Ls Sailboat Timeline Dot Voting Fishbone สลับทุก Sprint ไม่น่าเบื่อ
Action Items ที่ดีเป็นอย่างไร
SMART Specific Measurable Achievable Relevant Time-bound 2-3 ข้อ มีคนรับผิดชอบ ติดตามผล Sprint ถัดไป
Retrospective Remote Team ทำอย่างไร
Miro EasyRetro FunRetro Retrium Metro Retro Sticky Note Timer Video Call Breakout Room Anonymous Async เขียนก่อน Discuss ทีหลัง
สรุป
Retrospective Agile Scrum Sprint Action Items SMART Continuous Improvement Start Stop Continue Sailboat 4Ls Facilitation Remote Tools Miro EasyRetro Team Health
