AWS Builder 工作坊

使用 Kiro 建置:他加祿語 學習 App 的提示優先產品設計工作坊

工作坊系列

對象: 熟悉 TypeScript、React、JSON 與基本測試的專業開發者
時間: 2 小時
主要 AWS AI 服務: Kiro
專案輸出: 一個以 React 靜態句子卡為基礎的 App,將產品提示轉成經審查的 schema、UI、測試與發布檢查清單。

工作坊摘要

他加祿語 Kiro 工作坊

本工作坊帶領開發者從原始產品提示出發,完成經測試的 他加祿語 句子卡應用程式。參與者使用 Kiro 定義產品意圖、整理需求、設計型別化卡片 schema、建置 React 呈現器並加入驗證。完成後,開發者將理解提示優先規劃如何把語言學習想法轉成可審查的實作任務與可靠發布檢查,提供更安全且一致的學習體驗。

開發者將建置的內容

開發者將建置一個 他加祿語 句子卡學習 App。此 App 儲存經整理的句子卡,並呈現自然 他加祿語、禮貌 他加祿語、友善 Filipino-English、活潑 Filipino-English、語氣、文化脈絡、文法、例句與發音。工作坊使用 Kiro 作為 AI 工程環境:開發者會建立 steering 文件、產生 spec、審查需求、將 spec 轉成實作任務、撰寫程式碼、產生測試,並以 hook 自動化品質檢查。

2 小時議程

時間 模組 開發者成果
0–10 分鐘 設定 Kiro 工作區 專案已開啟並產生 steering 文件
10–25 分鐘 產品合約 先定義句子卡 schema,再設計 UI
25–45 分鐘 Kiro spec 已建立需求、設計與任務
45–70 分鐘 資料模型與範例卡片 已實作型別化內容合約
70–95 分鐘 React 呈現器 以 mobile-first UX 呈現句子卡
95–110 分鐘 測試與 hook 已加入 schema 測試與 Kiro hook 指引
110–120 分鐘 審查與擴充 開發者知道如何安全擴充分類

先備條件

node --version   # 20+
npm --version

建議的本機結構:

他加祿語-prompt-first-app/
  .kiro/
    steering/
    specs/他加祿語-learning-app/
  src/
    data/
    components/
    lib/
    tests/
  package.json

步驟 1 — 建立 Kiro 工作區與 steering 檔案

Kiro 提示範例

為 AWS Manila Community Day 的 他加祿語 學習 App 建立基礎 steering 文件。
此 App 以教育用途為主、非商業,並且對初學者友善。
使用 TypeScript、React、Vite、Vitest 與 CSS modules。
App 必須分開 natural 他加祿語、polite 他加祿語、friendly Filipino-English 與 playful Filipino-English。
一律將 playful style 標示為 informal。
語言內容在 production 使用前必須經過 native speaker 審查。

系統設計決策

  1. 先建立持久脈絡,再進行產生: 先使用 steering 檔案,是因為 App 具有不應在每次 Kiro 對話中重複說明的領域規則。此領域不只是 UI 呈現,也包含文化尊重、禮貌標記、活潑語氣界線與審查要求。將這些規則寫入 .kiro/steering/product.md.kiro/steering/tech.md.kiro/steering/structure.md,可讓 Kiro 取得持久脈絡,使後續程式碼建議遵循相同的產品期待。
  2. 工作區本機治理: 將 steering 檔案保存在儲存庫中,而不是只依賴個人記憶。專業團隊需要可審查的 AI 指引,就像審查架構決策紀錄一樣。本機 steering 讓產品範圍、技術選擇與檔案慣例能在 pull request、onboarding、稽核與未來工作坊中清楚可見。
  3. 人工審查安全性: 此 App 教授語言與文化,因此產生的內容不能被視為權威。steering 層明確要求 native-speaker review、適合初學者的措辭,以及避免刻板印象。這項設計讓品質保證成為系統層級的關注點,而不只是最後的人工提醒。

程式碼範例 — .kiro/steering/product.md

# Product Overview

此工作區會建置一個教育用途的 他加祿語 學習 App,協助準備 AWS Manila Community Day。
此 App 協助初學者練習活動中的禮貌短句,涵蓋問候、方向、工作坊、志工、等待時間與道別。

## 產品規則

- 先顯示 natural 他加祿語,再顯示 playful Filipino-English。
- 與講者、主辦者、志工、場地人員、長輩或第一次見面的人說話時,顯示 polite 他加祿語。
- 適當時說明 `po`、`opo`、`kayo` 與 `ninyo` 是尊重標記。
- 將 playful Filipino-English 標示為 informal。
- 讓例句短到適合手機閱讀。
- production 發布前必須經過 native speaker 審查。

程式碼說明

  • 商業邏輯: 此檔案定義會影響每個產生功能的學習產品規則。它避免 App 變成一般翻譯器,並讓工作坊聚焦在活動情境可用的學習。
  • 程式碼邏輯: 雖然這是 Markdown,Kiro 會把它視為持久的專案脈絡。未來產生的程式碼、測試與文件都應遵守這些規則。
  • 預期結果: 當開發者要求 Kiro 建置元件或測試時,Kiro 應保持自然、禮貌、友善與活潑輸出彼此分離,並加入審查提醒。

步驟 2 — 將產品想法轉成 Kiro spec

Kiro 提示範例

建立名為 他加祿語-learning-app 的 spec。
功能:呈現已審查的句子卡,供 AWS Manila Community Day 準備使用。
產生 requirements、design 與 implementation tasks。
使用 EARS-style acceptance criteria。
第一版為靜態版本,而且只使用本機 JSON 資料。

系統設計決策

  1. 以 spec 驅動開發,而不是直接寫程式: 工作坊從 spec 開始,因為產品需要在使用者目標、資料欄位、UI 行為與測試之間保持可追溯性。直接 code-first 可能快速做出畫面,但很難驗證禮貌、語氣標籤、文法支援與行動裝置可讀性是否一致處理。spec 會成為實作的單一事實來源。
  2. 先完成靜態版本,再準備上雲: 第一版使用本機 JSON,因為核心風險是內容形狀,而不是基礎設施。靜態 App 讓開發者能在兩小時內驗證 schema、呈現、測試與審查流程。合約通過驗證後,同一份資料形狀可以移到 S3、DynamoDB 或 API,而不必重新設計學習卡片。
  3. 將驗收條件當作測試: EARS-style 陳述讓產品行為可測試。例如:「當卡片包含 playful Filipino-English 時,UI 應顯示 informal 標籤。」這會把文化與教育需求轉成實作約束,對專業開發者工作坊至關重要。

程式碼範例 — .kiro/specs/他加祿語-learning-app/requirements.md

# Requirements

## Requirement 1:句子卡呈現

User story:身為初學者,我想看到一個英文句子,以及 natural、polite、friendly 與 playful 變體,這樣我就能在活動中選擇正確語氣。

Acceptance criteria:

1. WHEN 句子卡被呈現 THEN 系統 SHALL 顯示 English input、natural 他加祿語、polite 他加祿語、friendly Filipino-English、playful Filipino-English 與 tone。
2. WHEN playful Filipino-English 被顯示 THEN 系統 SHALL 將它標示為 informal。
3. WHEN polite 他加祿語 被顯示 THEN 系統 SHALL 加入何時使用尊重說法的文化脈絡。

## Requirement 2:Mobile-first 學習

Acceptance criteria:

1. WHEN viewport 很窄 THEN 句子卡 SHALL 保持可讀且不需要水平捲動。
2. WHEN grammar notes 被呈現 THEN 系統 SHALL 使用短清單項目。
3. WHEN pronunciation 被呈現 THEN 它 SHALL 顯示在 他加祿語 片語附近。

程式碼說明

  • 商業邏輯: 需求描述學習者體驗,並定義 App 必須教會的內容。
  • 程式碼邏輯: 每個驗收條件都可以對應到元件屬性、DOM assertion 或無障礙檢查。
  • 預期結果: Kiro 可以產生任務與測試來驗證產品行為,而不只是檢查元件是否能編譯。

步驟 3 — 定義句子卡資料合約

Kiro 提示範例

為 他加祿語 句子卡產生 TypeScript 資料合約。
包含 English input、natural 他加祿語、polite 他加祿語、friendly Filipino-English、playful Filipino-English、tone、cultural context、grammar breakdown、examples、pronunciation、category 與 review status 欄位。
加入兩張來自 Community Day 情境的範例卡片。

系統設計決策

  1. 先有 schema,再擴充內容: 穩定的 TypeScript 型別能保護 App,避免 AI 產生內容不一致。一旦合約定義完成,每張句子卡都必須包含相同的必要欄位。這能避免 AI 輔助開發常見問題:每張產生的卡片標籤略有不同、缺少文法說明,或例句格式不一致。
  2. 把審查狀態視為一級資料: schema 中包含 reviewStatus,因為語言內容存在品質風險。開發者常把審查註記放在註解或試算表中,但應用程式需要知道內容是 draft、reviewed 還是 blocked。將審查狀態視為資料,可支援篩選、徽章、發布閘門與未來審核工作流程。
  3. 將多種語氣版本拆成獨立欄位: Natural 他加祿語、polite 他加祿語、friendly Filipino-English 與 playful Filipino-English 是獨立欄位,因為它們服務不同的學習目的。把它們混在一個文字區塊中,會削弱 UI 呈現、測試與學習者理解。欄位分離也能支援未來搜尋、標記與分析。

程式碼範例 — src/data/cards.ts

export type ReviewStatus = "draft" | "native-reviewed" | "blocked";

export interface GrammarItem {
  term: string;
  meaning: string;
}

export interface ExampleSentence {
  他加祿語: string;
  english: string;
}

export interface PronunciationGuide {
  full: string;
  stress: string;
  speakingTip: string;
}

export interface SentenceCard {
  id: string;
  category: "greetings" | "directions" | "workshops" | "volunteers" | "waiting";
  englishInput: string;
  naturalTagalog: string;
  politeTagalog: string;
  friendlyFilipinoEnglish: string;
  playfulFilipinoEnglish: string;
  tone: string;
  culturalContext: string;
  grammar: GrammarItem[];
  examples: ExampleSentence[];
  pronunciation: PronunciationGuide;
  reviewStatus: ReviewStatus;
}

export const cards: SentenceCard[] = [
  {
    id: "greeting-001",
    category: "greetings",
    englishInput: "你好,我正在學 他加祿語。",
    naturalTagalog: "Kumusta, nag-aaral ako ng 他加祿語.",
    politeTagalog: "Kumusta po, nag-aaral po ako ng 他加祿語.",
    friendlyFilipinoEnglish: "Hello po, learning 他加祿語 ako.",
    playfulFilipinoEnglish: "Kumusta, learning 他加祿語 na ako, all right.",
    tone: "友善、適合初學者、活動可用",
    culturalContext:
      "與志工、講者、主辦者、場地人員、長輩或第一次見面的人說話時,使用禮貌版本。",
    grammar: [
      { term: "Kumusta", meaning: "你好或你好嗎" },
      { term: "po", meaning: "禮貌標記" },
      { term: "nag-aaral", meaning: "正在讀書或學習" }
    ],
    examples: [
      { 他加祿語: "Kumusta po kayo?", english: "你好嗎?" },
      { 他加祿語: "Nag-aaral po ako.", english: "我正在學習。" },
      { 他加祿語: "Salamat po sa tulong.", english: "謝謝你的幫忙。" }
    ],
    pronunciation: {
      full: "koo-MOOS-tah poh, nag-ah-AH-ral poh AH-koh ngah tah-GAH-log",
      stress: "重音放在 MOOS、AH 與 GAH。",
      speakingTip: "輕柔地說 po,並讓問候保持溫暖。"
    },
    reviewStatus: "draft"
  },
  {
    id: "workshop-001",
    category: "workshops",
    englishInput: "我可以問一個問題嗎?",
    naturalTagalog: "Puwede ba akong magtanong?",
    politeTagalog: "Puwede po ba akong magtanong?",
    friendlyFilipinoEnglish: "Can I ask po?",
    playfulFilipinoEnglish: "Question time na ako, all right?",
    tone: "禮貌、實用、工作坊可用",
    culturalContext:
      "在場次中向講者、導師或主辦者提問前,使用禮貌版本。",
    grammar: [
      { term: "Puwede", meaning: "可以或能夠" },
      { term: "ba", meaning: "疑問標記" },
      { term: "magtanong", meaning: "提問" }
    ],
    examples: [
      { 他加祿語: "Puwede po ba akong umupo dito?", english: "我可以坐這裡嗎?" },
      { 他加祿語: "Puwede po bang pakiulit?", english: "可以請你再說一次嗎?" },
      { 他加祿語: "Puwede po bang sumali?", english: "我可以加入嗎?" }
    ],
    pronunciation: {
      full: "PWEH-deh poh bah AH-kong mag-tah-NONG",
      stress: "重音放在 PWEH、AH 與 NONG。",
      speakingTip: "讓問題聽起來溫和,而不是強硬要求。"
    },
    reviewStatus: "draft"
  }
];

程式碼說明

  • 商業邏輯: 此 schema 代表 App 對學習者的承諾:一個句子、多種語氣、文法、例句、發音與審查狀態。
  • 程式碼邏輯: TypeScript interface 會強制資料符合預期格式。 cards 陣列會提供呈現器強型別資料。
  • 預期結果: App 可以一致地呈現每張句子卡。如果開發者忘記必要欄位,就會出現型別錯誤。

步驟 4 — 建置 React 句子卡呈現器

Kiro 提示範例

建立名為 SentenceCardView 的 React 元件。
它接收 SentenceCard,並以可存取的標題與清單呈現每個欄位。
Playful Filipino-English 必須顯示 Informal 徽章。
審查狀態必須可見。

系統設計決策

  1. 每個合約對應一個元件: 呈現器接收一個 SentenceCard,且不直接擷取資料。這種分離讓 UI 可預測、可測試且可重複使用。開發者日後可以從本機 JSON、API 或靜態產生檔載入卡片,而不必變更呈現邏輯。
  2. 明確標示語氣: UI 會以 informal 徽章顯示 playful Filipino-English,因為學習者可能直接複製眼前內容。語氣標籤不是裝飾,而是安全與教育控制。元件應教導學習者:活潑語言不同於正式 他加祿語。
  3. 可存取的內容階層: 語言卡片可能變得資訊密集。語意化區段、標題、清單與可讀標籤,能讓 App 在行動裝置上可用,並對輔助科技友善。可存取性是系統設計的一部分,因為目標環境是使用多種裝置的公開社群活動。

程式碼範例 — src/components/SentenceCardView.tsx

import type { SentenceCard } from "../data/cards";
import "./SentenceCardView.css";

interface Props {
  card: SentenceCard;
}

export function SentenceCardView({ card }: Props) {
  return (
    <article className="sentence-card" aria-labelledby={`${card.id}-title`}>
      <header className="sentence-card__header">
        <p className="sentence-card__category">{card.category}</p>
        <h2 id={`${card.id}-title`}>{card.englishInput}</h2>
        <span className={`review review--${card.reviewStatus}`}>{card.reviewStatus}</span>
      </header>

      <section aria-label="他加祿語 variants" className="sentence-card__variants">
        <p><strong>Natural 他加祿語:</strong> <span lang="tl">{card.naturalTagalog}</span></p>
        <p><strong>Polite 他加祿語:</strong> <span lang="tl">{card.politeTagalog}</span></p>
        <p><strong>Friendly Filipino-English:</strong> {card.friendlyFilipinoEnglish}</p>
        <p>
          <strong>Playful Filipino-English:</strong> {card.playfulFilipinoEnglish}
          <span className="badge">Informal</span>
        </p>
      </section>

      <section aria-label="Learning notes">
        <p><strong>Tone:</strong> {card.tone}</p>
        <p><strong>Cultural context:</strong> {card.culturalContext}</p>
      </section>

      <section aria-labelledby={`${card.id}-grammar`}>
        <h3 id={`${card.id}-grammar`}>Grammar breakdown</h3>
        <ul>
          {card.grammar.map((item) => (
            <li key={item.term}><strong>{item.term}:</strong> {item.meaning}</li>
          ))}
        </ul>
      </section>

      <section aria-labelledby={`${card.id}-examples`}>
        <h3 id={`${card.id}-examples`}>Examples</h3>
        <ol>
          {card.examples.map((example) => (
            <li key={example.tagalog}>
              <span lang="tl">{example.tagalog}</span><br />
              <span>{example.english}</span>
            </li>
          ))}
        </ol>
      </section>

      <section aria-labelledby={`${card.id}-pronunciation`}>
        <h3 id={`${card.id}-pronunciation`}>Pronunciation</h3>
        <p>{card.pronunciation.full}</p>
        <p>{card.pronunciation.stress}</p>
        <p>{card.pronunciation.speakingTip}</p>
      </section>
    </article>
  );
}

程式碼說明

  • 商業邏輯: 此元件會將經審查的學習卡片轉成面向學習者的課程。
  • 程式碼邏輯: 它會從型別化卡片呈現結構化區段,將文法與例句映射為清單,為 他加祿語 文字加入 lang="tl",並將 informal 徽章套用到活潑輸出。
  • 預期結果: 開發者會看到包含所有必要學習欄位的完整卡片,學習者也能辨識哪個句子是自然、禮貌、友善或 informal。

步驟 5 — 加入響應式樣式

Kiro 提示範例

為 SentenceCardView 建立 mobile-first CSS。
使用易讀間距、高對比、可見的 informal 徽章,並確保小螢幕不需要水平捲動。

系統設計決策

  1. 因活動準備情境而採用 mobile-first: 學習者可能在通勤、排隊或坐在場次中使用 App。介面必須優先考量小螢幕可讀性,而不只是桌面呈現。
  2. 使用卡片而非表格: 表格版面會壓縮較長的語言欄位並降低可讀性。卡片能讓每個學習區段保有空間,尤其是文法與發音。這是產品決策,因為語言學習需要快速掃描與口說練習。
  3. 審查與語氣的視覺狀態: 徽章與審查標籤能幫助使用者快速理解信心水準與語氣。在學習產品中,視覺階層可降低認知負荷,並避免 informal 內容被誤認為建議的正式答案。

程式碼範例 — src/components/SentenceCardView.css

.sentence-card {
  border: 1px solid #d0d7de;
  border-radius: 16px;
  padding: 1rem;
  margin: 1rem 0;
  background: #ffffff;
  color: #1f2328;
  line-height: 1.6;
}

.sentence-card__header {
  display: grid;
  gap: 0.5rem;
}

.sentence-card__category {
  margin: 0;
  font-size: 0.85rem;
  color: #57606a;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.sentence-card__variants {
  border-left: 4px solid #ff9900;
  padding-left: 1rem;
}

.badge,
.review {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
}

.badge {
  background: #fff3cd;
  color: #7a4d00;
}

.review--draft {
  background: #eaeef2;
  color: #57606a;
}

.review--native-reviewed {
  background: #dafbe1;
  color: #116329;
}

.review--blocked {
  background: #ffebe9;
  color: #82071e;
}

@media (min-width: 760px) {
  .sentence-card {
    padding: 1.5rem;
  }

  .sentence-card__header {
    grid-template-columns: 1fr auto;
    align-items: start;
  }
}

程式碼說明

  • 商業邏輯: 樣式透過讓分類、語氣與審查狀態容易掃描,支援學習任務。
  • 程式碼邏輯: CSS 使用卡片容器、響應式 grid 標頭、變體左側強調線,以及 informal/review 狀態的徽章樣式。
  • 預期結果: UI 在行動裝置上保持可讀,在較大螢幕上則更寬敞。

步驟 6 — 呈現 App shell

Kiro 提示範例

建立 App.tsx,呈現 src/data/cards.ts 中的所有句子卡。
加入簡短免責聲明,說明產生內容需要 native speaker 審查。

系統設計決策

  1. 為工作坊可靠性採用靜態 shell: 在兩小時工作坊中,App 應能在沒有外部 API 或網路憑證的情況下執行。這能降低設定阻力,讓開發者專注於 Kiro 的 spec-to-code 工作流程。
  2. 在產品 UI 中放入免責聲明: 語言學習原型必須向使用者傳達審查狀態。將免責聲明放在 App shell 中,可讓限制在展示時可見,而不是藏在文件裡。
  3. 匯入資料而非硬編碼 JSX: shell 會映射 cards,證明 UI 是資料驅動。當更多內容被產生或審查時,App 可透過新增資料擴充,而不是複製 UI markup。

程式碼範例 — src/App.tsx

import { cards } from "./data/cards";
import { SentenceCardView } from "./components/SentenceCardView";

export default function App() {
  return (
    <main className="app-shell">
      <header>
        <h1>AWS Manila Community Day 他加祿語 學習卡</h1>
        <p>
          教育用途原型。Production 使用前,請與母語人士審查 他加祿語 翻譯、
          文法 notes 與文化 guidance。
        </p>
      </header>

      {cards.map((card) => (
        <SentenceCardView key={card.id} card={card} />
      ))}
    </main>
  );
}

程式碼說明

  • 商業邏輯: shell 會將 App 呈現為教育原型,並呈現所有可用的學習卡片。
  • 程式碼邏輯: React 會將型別化的 cards 陣列映射到可重複使用的 SentenceCardView 元件。
  • 預期結果: 執行 App 後會看到標題、審查免責聲明,以及每筆資料項目對應的一張 UI 卡片。

步驟 7 — 產生測試並使用 Kiro hook 進行品質檢查

Kiro 提示範例

為 SentenceCardView 產生 Vitest 測試。
驗證 natural 他加祿語、polite 他加祿語、informal 徽章、grammar notes、examples、pronunciation 與 review status 都能正確呈現。
接著建立一個 Kiro hook 想法:當 source files 儲存時執行測試。

系統設計決策

  1. 測試對應驗收條件: 測試不應只檢查 snapshot。它們應斷言必要學習欄位會出現,且活潑內容會標示為 informal。這能讓實作與 spec 保持一致,並在加入更多卡片或樣式時防止回歸。
  2. 以 hook 輔助紀律: Kiro hooks 很有價值,因為開發者在快速 AI 輔助建置時常忘記重複性的驗證步驟。file-save hook 或 pre-commit hook 可以提醒團隊執行測試、更新文件或驗證卡片 schema。
  3. 產生內容的品質閘門: AI 輔助的程式碼與內容應通過可重複的決定性檢查。測試提供穩定安全網,而人工審查處理語言細節。這種分層品質設計將機械正確性與文化正確性分開處理。

程式碼範例 — src/tests/SentenceCardView.test.tsx

import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { SentenceCardView } from "../components/SentenceCardView";
import { cards } from "../data/cards";

describe("SentenceCardView", () => {
  it("renders all required learning sections", () => {
    render(<SentenceCardView card={cards[0]} />);

    expect(screen.getByText(cards[0].englishInput)).toBeInTheDocument();
    expect(screen.getByText(cards[0].naturalTagalog)).toBeInTheDocument();
    expect(screen.getByText(cards[0].politeTagalog)).toBeInTheDocument();
    expect(screen.getByText(cards[0].friendlyFilipinoEnglish)).toBeInTheDocument();
    expect(screen.getByText(cards[0].playfulFilipinoEnglish)).toBeInTheDocument();
    expect(screen.getByText("Informal")).toBeInTheDocument();
    expect(screen.getByText("Grammar breakdown")).toBeInTheDocument();
    expect(screen.getByText("Examples")).toBeInTheDocument();
    expect(screen.getByText("Pronunciation")).toBeInTheDocument();
    expect(screen.getByText(cards[0].reviewStatus)).toBeInTheDocument();
  });
});

程式碼說明

  • 商業邏輯: 測試會確認每張句子卡都教授必要的學習面向。
  • 程式碼邏輯: Testing Library 會呈現元件,並搜尋第一張卡片中的預期文字。
  • 預期結果: 當 UI 呈現所有必要卡片欄位時測試會通過;如果欄位消失,測試會失敗。

Kiro hook sample — .kiro/hooks/run-tests-on-save.md

# Hook:儲存 source 時執行測試

Trigger:當 `src/` 底下的檔案被儲存。
Action:
1. 執行 `npm test -- --run`。
2. 如果測試失敗,摘要失敗測試並建議最小修正。
3. 如果卡片資料有變更,提醒開發者確認 reviewStatus 與 native-speaker review notes。

Hook 說明

  • 商業邏輯: hook 會在快速迭代期間保護教育合約。
  • 程式碼邏輯: 它會將來源檔案變更連結到測試執行與審查提醒。
  • 預期結果: 當 UI 或資料變更破壞學習需求時,開發者會立即收到回饋。

步驟 8 — 最終 Kiro 審查與擴充任務

Kiro 提示範例

依照 spec 審查實作。
找出缺少的 requirements、薄弱測試、不清楚標籤與 mobile-readability 風險。
建議接下來五個任務,用來加入 directions、volunteer thanks、waiting time 與 goodbye 分類。

系統設計決策

  1. 先審查,再擴大: 在前兩張卡片正確之前,App 不應產生數十個分類。專業工作流程會在擴充內容前,先驗證合約、元件、測試與審查流程。
  2. 讓 Kiro 擔任審查者,而不只是產生器: Kiro 可以說明 spec 與程式碼之間的落差、提出下一步任務並產生文件。這能幫助開發者把 AI 當成工程協作者,而不是 code-completion 捷徑。
  3. 逐步擴充分類: 新分類應重用相同的 schema 與元件。這能保持架構簡單並避免功能偏移。產品透過資料與測試擴充,而不是透過新的 one-off 頁面擴充。

完成檢查清單

  • .kiro/steering/product.md 記錄產品規則。
  • .kiro/specs/他加祿語-learning-app/requirements.md 已存在。
  • TypeScript SentenceCard 合約已存在。
  • 至少兩張卡片可正確呈現。
  • Playful Filipino-English 顯示 informal 徽章。
  • 審查狀態出現在 UI 中。
  • 元件測試通過。
  • 已有用於測試自動化的 Kiro hook 指引。

工作坊後的選用 AWS 擴充

  • 將靜態建置託管在 AWS Amplify Hosting 或 Amazon S3。
  • 加入 Amazon CloudFront 進行全球交付。
  • 將經審查的卡片儲存在 Amazon S3 JSON。
  • 日後使用 Amazon Bedrock 進行受控的 draft-card 產生,並在發布前進行人工審查。

額外動手開發實驗

以下實驗會以更具體的開發者操作加深工作坊內容。它們是為想練習把 Kiro 當作工程工作流程工具,而不只是 chat assistant 的專業開發者所設計。這些實驗刻意使用 Kiro steering、spec、agentic chat、hooks、任務執行、測試產生、文件產生、審查支援與 MCP-ready 整合模式。

動手實驗 A — 使用 Kiro agentic chat 初始化儲存庫

開發者操作

  1. 在 Kiro 中開啟專案資料夾。
  2. 要求 Kiro 檢查空白工作區並提出最小結構。
  3. 要求 Kiro 產生初始檔案,然後在接受變更前審查 diff。
  4. Kiro 建立檔案後,手動執行本機 App 或產生器命令。

Kiro 提示範例

檢查此工作區並建立最小實作計畫。
如果既有 steering 與 spec 檔案存在,請使用它們。
不要產生不必要的基礎設施。
只建立第一個 vertical slice 所需的檔案。
提出變更後,說明每個檔案以及它存在的原因。

系統設計決策

  1. 從工作區檢查開始: Kiro 應先理解既有內容,再產生檔案。這能避免重複資料夾、相衝突的相依套件與意外重新設計。在專業工作坊中,這就像開發者加入既有程式碼庫的流程:檢查、理解,然後變更。工作區檢查也讓 Kiro 能在實作前連結 steering 檔案、spec 與原始碼。
  2. 產生 vertical slice: 第一個實作應證明從資料到可見結果的最小完整路徑。vertical slice 比建置許多彼此斷開的工具更好,因為它會同時驗證產品合約、呈現器、測試設定與開發者工作流程。這能提供參與者快速回饋並避免過度工程化。
  3. 接受前審查 diff: Kiro 可以快速產生有用程式碼,但專業開發者仍擁有程式碼庫責任。審查 diff 能強化責任感、抓出不想要的假設,並教導參與者把 Kiro 當作工程助理協作,而不是盲目委派。

程式碼範例 — React 工作坊變體的 package.json

{
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "test": "vitest --environment jsdom",
    "test:run": "vitest --environment jsdom --run",
    "lint:data": "node scripts/validate-cards.mjs"
  },
  "dependencies": {
    "@vitejs/plugin-react": "latest",
    "vite": "latest",
    "typescript": "latest",
    "react": "latest",
    "react-dom": "latest"
  },
  "devDependencies": {
    "vitest": "latest",
    "@testing-library/react": "latest",
    "@testing-library/jest-dom": "latest",
    "jsdom": "latest"
  }
}

程式碼說明

  • 商業邏輯: 這些 scripts 定義開發者回饋循環:執行 App、建置 production 輸出、執行測試,並驗證學習卡片資料。
  • 程式碼邏輯: dev 會啟動 Vite,build 會編譯 TypeScript 並打包 App,test 會執行元件測試,lint:data 會執行自訂卡片驗證器。
  • 預期結果: 開發者可以在整個工作坊中使用相同的命令詞彙,Kiro 也能在產生 hooks 與任務計畫時引用這些 scripts。

動手實驗 B — 產生並精煉 Kiro steering 檔案

開發者操作

  1. 在 Kiro 中產生基礎 steering 檔案。
  2. 手動編輯 product、tech 與 structure steering 檔案。
  3. 要求 Kiro 摘要 steering 檔案將如何影響未來實作。
  4. 為語言內容審查建立一個額外 steering 檔案。

Kiro 提示範例

為此工作區產生基礎 steering 文件。
接著加入 language-review steering 檔案。
此 App 教授活動準備用的 他加祿語,因此實作必須讓 review status 可見、標示 informal 內容,並避免將產生的語言內容呈現為 final。
說明每個 steering 檔案將如何引導未來程式碼產生。

系統設計決策

  1. 分離產品、技術與內容規則: 產品規則說明學習者成果,技術規則限制實作選擇,內容規則保護教育品質。拆分這些關注點可讓 steering 更容易審查與更新。這也能幫助 Kiro 在產生元件、測試、hook 或文件頁面時擷取正確脈絡。
  2. 讓審查政策持久化: native-speaker review 要求必須超越單一 chat 訊息。如果它只寫在暫時對話中,未來產生的卡片可能會省略審查狀態或誇大正確性。持久 steering 檔案會讓政策成為工作區運作模型的一部分。
  3. 使用 steering 對齊團隊: 在開發者工作坊中,參與者可能產生專案變體。steering 檔案讓這些變體收斂到相同標準。當多位開發者並行要求 Kiro 產生程式碼且仍需要一致輸出時,這特別有用。

程式碼範例 — .kiro/steering/language-review.md

# 語言審查標準

所有 他加祿語 學習內容在母語人士審查前,都是教育用途 draft content。
UI 必須在學習者看得到的位置顯示 review status。
不要只把 review state 藏在 comments、logs 或 documentation 中。

## 必要欄位

- `reviewStatus`: draft, native-reviewed, or blocked
- `reviewNotes`: 給 reviewer 的簡短 note
- `lastReviewedAt`: ISO date string or null
- `reviewedBy`: reviewer name 或 null

## 產生規則

- Natural 他加祿語 顯示在 playful Filipino-English 之前。
- Playful Filipino-English 必須標示為 informal。
- Polite 他加祿語 必須說明何時使用尊重說法較安全。
- 未經審查前,不得宣稱具備最終語言權威。

程式碼說明

  • 商業邏輯: 此檔案定義語言品質與學習者透明度的治理方式。
  • 程式碼邏輯: Kiro 可在產生型別、UI 標籤、驗證 scripts 與測試時,將此 Markdown 作為持久工作區脈絡。
  • 預期結果: 未來產生的功能會包含可見的審查 metadata,且不會將 draft 內容視為 final。

動手實驗 C — 使用 Kiro spec 建立需求、設計與任務追蹤

開發者操作

  1. 要求 Kiro 為下一個功能建立 spec。
  2. 在接受設計前審查 requirements。
  3. 要求 Kiro 將已接受的設計轉換為實作任務。
  4. 一次執行一個任務,並在每個任務後審查 diff。

Kiro 提示範例

為具備審查意識的句子卡功能建立 spec。
Requirements 必須包含可見 review status、playful Filipino-English 的 informal label、pronunciation display、grammar notes 與 mobile readability。
完成 requirements 後,建立 design 與排序過的 implementation tasks。
在 tasks 被審查前不要實作。

系統設計決策

  1. 先有 requirements,再實作: Specs 會迫使團隊在程式碼存在前先同意行為。這很有價值,因為 AI 輔助實作可能產生看似合理但未審查的行為。Requirements 定義產品必須做什麼,以及後續測試應驗證什麼。
  2. 先有設計,再有任務: 設計區段會說明元件邊界、資料流、驗證點與可存取性期待。沒有設計時,任務可能變成檔案清單,而不是架構。當 Kiro 擁有設計意圖,而不只是功能請求時,效果會更好。
  3. 逐項執行任務: 一次實作一個任務能保持 diff 小,並教導開發者審查 AI 輸出。這也讓失敗更容易隔離。如果元件測試在某個任務後失敗,原因會比一大批產生變更後更清楚。

程式碼範例 — .kiro/specs/review-aware-card/requirements.md

# Requirements

## Requirement 1:可見的審查狀態

Acceptance criteria:

1. WHEN 句子卡被呈現 THEN 系統 SHALL 顯示 `reviewStatus`。
2. WHEN `reviewStatus` 是 `draft` THEN 系統 SHALL 顯示面向學習者的草稿提示。
3. WHEN `reviewStatus` 是 `blocked` THEN 系統 SHALL 不建議使用該卡片練習。

## Requirement 2:語氣安全

Acceptance criteria:

1. WHEN playful Filipino-English 被呈現 THEN 系統 SHALL 顯示 Informal 徽章。
2. WHEN polite 他加祿語 被呈現 THEN 系統 SHALL 顯示何時使用禮貌說法較安全。

程式碼說明

  • 商業邏輯: requirements 會保護學習者,避免將 draft 或 informal 語言誤認為 final 建議說法。
  • 程式碼邏輯: 每個驗收條件都可成為元件 assertion、資料驗證器規則或發布檢查。
  • 預期結果: Kiro 可以產生直接對應審查與語氣需求的實作任務與測試。

動手實驗 D — 為產生或整理過的卡片資料加入 schema 驗證

開發者操作

  1. 為句子卡資料建立 validator script。
  2. 手動執行它。
  3. 要求 Kiro 加入缺少的驗證規則。
  4. 將 validator 串接到 test 或 build command。

Kiro 提示範例

為句子卡建立資料驗證 script。
驗證必要欄位、reviewStatus 值、非空 pronunciation、至少三個 grammar items,以及 playful Filipino-English 的 informal label 覆蓋情況。
此 script 應以清楚訊息失敗,並可在 npm scripts 中使用。

系統設計決策

  1. 將資料驗證與 UI 分開: UI 測試能證明呈現結果,但不能保證整份資料集完整。專用 validator 可在 App 呈現前,先找出所有卡片中缺少的欄位。當 Kiro 或開發者快速新增大量卡片時,這特別重要。
  2. 以可行動訊息失敗: validator 應清楚告訴開發者是哪張卡片、哪個欄位失敗。清楚的失敗訊息能降低工作坊阻力,並培養良好發布習慣。模糊失敗會迫使開發者手動檢查資料,拖慢學習。
  3. 讓驗證可被 script 執行: validator 必須能透過 command、hook 或 CI job 執行。可 script 化會把品質規則變成可重複的工程實務,也讓 Kiro 在建立 hooks 或 release tasks 時能引用相同 command。

程式碼範例 — scripts/validate-cards.mjs

import { readFileSync } from "node:fs";

const raw = readFileSync("src/data/cards.json", "utf8");
const cards = JSON.parse(raw);

const allowedReviewStatus = new Set(["draft", "native-reviewed", "blocked"]);
const failures = [];

for (const card of cards) {
  const prefix = `Card ${card.id ?? "<missing id>"}`;

  for (const field of ["id", "englishInput", "naturalTagalog", "politeTagalog", "playfulFilipinoEnglish", "pronunciation", "reviewStatus"]) {
    if (!card[field]) failures.push(`${prefix}: missing ${field}`);
  }

  if (!allowedReviewStatus.has(card.reviewStatus)) {
    failures.push(`${prefix}: invalid reviewStatus ${card.reviewStatus}`);
  }

  if (!Array.isArray(card.grammar) || card.grammar.length < 3) {
    failures.push(`${prefix}: expected at least three grammar items`);
  }

  if (card.playfulFilipinoEnglish && card.playfulLabel !== "Informal") {
    failures.push(`${prefix}: playful Filipino-English must use playfulLabel = Informal`);
  }
}

if (failures.length > 0) {
  console.error(failures.join("\n"));
  process.exit(1);
}

console.log(`Validated ${cards.length} cards successfully.`);

程式碼說明

  • 商業邏輯: validator 會在發布前對每張卡片強制執行教育合約。
  • 程式碼邏輯: 它會載入 JSON、檢查必要欄位、驗證允許的 review states、確認 grammar 覆蓋率,並在錯誤時讓流程失敗。
  • 預期結果: 執行 npm run lint:data 時,有效資料會印出成功訊息;無效資料會印出清楚的卡片層級錯誤。

動手實驗 E — 使用 Kiro hooks 提供自動化品質回饋

開發者操作

  1. .kiro/hooks/ 中建立 hook guidance。
  2. 要求 Kiro 精煉 hook triggers 與 actions。
  3. 儲存資料或元件檔案,觀察建議的驗證工作流程。
  4. 調整 hook,讓它只執行相關檢查。

Kiro 提示範例

為此工作區建立 Kiro hook guidance。
當 source data 變更時,驗證 cards。
當 React components 變更時,執行 component tests。
當 build scripts 變更時,執行 production build。
每個 hook 都應摘要失敗內容,並建議最小且安全的修正。

系統設計決策

  1. 依脈絡執行檢查: 每次檔案變更都執行所有檢查會浪費時間。Hook 應將檔案類型對應到相關驗證:資料變更觸發 data validation、元件變更觸發 tests、build scripts 變更觸發 release checks。這能提供快速回饋,而不會讓開發者負擔過重。
  2. 自動化教練: 在工作坊中,hooks 不只是自動化,也會教導工作流程紀律。當 hook 說明失敗卡片或缺少標籤時,開發者會學到此專案中品質代表什麼。Kiro 會成為 reviewer 與 coach。
  3. 小而安全的修正: AI 產生的修正建議應該最小化。當一張卡片缺少 pronunciation 時,hook 不應重寫整個 App。小修正能保留開發者控制權,並讓 diffs 可審查。

程式碼範例 — .kiro/hooks/workspace-quality.md

# Hook:工作區品質檢查

## 資料變更
Trigger:`src/data/` 底下的檔案
Action:
1. 執行 `npm run lint:data`。
2. 如果驗證失敗,列出 card IDs 與缺少欄位。
3. 建議最小 JSON 修正。

## 元件變更
Trigger:`src/components/` 底下的檔案
Action:
1. 執行 `npm run test:run`。
2. 摘要失敗的 assertions。
3. 建議最小元件或測試更新。

## 建置變更
Trigger:`package.json`、`vite.config.ts` 或 `scripts/` 底下的檔案
Action:
1. 執行 `npm run build`。
2. 摘要 TypeScript 或 bundling errors。
3. 建議最小安全修正。

程式碼說明

  • 商業邏輯: 此 hook 會在開發者快速迭代時維持學習產品可靠。
  • 程式碼邏輯: 此 Markdown 定義 Kiro 可在工作區內作為自動化指引使用的 trigger/action 行為。
  • 預期結果: 開發者編輯資料、元件或建置設定時,會收到針對性的驗證回饋。

動手實驗 F — 加入 Kiro 輔助測試產生與審查

開發者操作

  1. 要求 Kiro 根據 spec acceptance criteria 產生測試。
  2. 審查 tests 是否具有有意義的 assertions。
  3. 執行測試並要求 Kiro 說明失敗原因。
  4. 為 blocked content 加入一個 negative test。

Kiro 提示範例

根據已接受的 requirements 產生測試。
不要建立只有 snapshot 的測試。
測試可見 review status、blocked card behavior、informal badge、grammar section、pronunciation section 與 polite guidance。
寫完測試後,說明每個測試涵蓋哪一項 requirement。

系統設計決策

  1. 從 requirements 產生測試: 測試應證明 requirements 已被實作,而不只是目前 HTML 符合 snapshot。Kiro 可以將 acceptance criteria 對應到 assertions,協助開發者讓測試與產品行為保持一致。
  2. Negative tests 很重要: blocked card 不應被建議用於練習。只測 happy paths 會漏掉安全行為。在 draft 或 blocked content 不得被推廣的教育 App 中,negative tests 特別重要。
  3. 說明覆蓋範圍: 要求 Kiro 說明每個測試涵蓋哪項 requirement,會讓 test suite 更容易審查,也會教參與者如何評估 AI-generated tests,而不是自動認為它們足夠。

程式碼範例 — src/tests/card-policy.test.ts

import { describe, expect, it } from "vitest";

type Card = {
  id: string;
  reviewStatus: "draft" | "native-reviewed" | "blocked";
};

function isPracticeRecommended(card: Card) {
  return card.reviewStatus !== "blocked";
}

describe("card review policy", () => {
  it("does not recommend blocked cards for practice", () => {
    const card = { id: "blocked-001", reviewStatus: "blocked" } satisfies Card;
    expect(isPracticeRecommended(card)).toBe(false);
  });

  it("allows draft cards to appear with visible draft status", () => {
    const card = { id: "draft-001", reviewStatus: "draft" } satisfies Card;
    expect(isPracticeRecommended(card)).toBe(true);
  });
});

程式碼說明

  • 商業邏輯: Blocked content 不得被推薦;draft content 只有在 UI 其他地方清楚顯示其狀態時才可出現。
  • 程式碼邏輯: helper 只會對 blocked 回傳 false。測試會驗證 blocked 與 draft 行為。
  • 預期結果: 如果未來變更推薦了 blocked cards,test suite 會抓出政策回歸。

動手實驗 G — 使用 MCP-ready 脈絡規劃且不增加 runtime 複雜度

開發者操作

  1. 要求 Kiro 提出 MCP server 使用案例,但不要實作。
  2. 決定未來版本中哪些外部脈絡會有幫助。
  3. 撰寫 integration note,保持目前工作坊 local-first。
  4. 為未來 MCP integration 加入 backlog item。

Kiro 提示範例

為此 App 的未來版本建議 MCP-ready integration 選項。
考慮 design files、content review sheets、issue trackers 與 deployment metadata。
現在不要實作 integrations。
建立 backlog note,說明此工作坊的 local-first 範圍與未來 MCP opportunities。

系統設計決策

  1. 規劃 integrations,但不偏離工作坊: MCP 可以連接外部工具與脈絡,但兩小時建置應保持 local-first。規劃未來 integration 可展示能力,同時不增加設定複雜度。
  2. 將 runtime App 與工程脈絡分開: 面向學習者的 App 不需要直接存取設計工具或 issue trackers。這些 integrations 對開發工作流程、審查與規劃有用。保持分離可保護 App 的簡潔度。
  3. 把 backlog 當作架構記憶: 撰寫未來 integration notes 可避免想法遺失,同時讓目前實作保持聚焦。這也展示 Kiro 如何協助團隊記錄工程策略。

程式碼範例 — docs/mcp-backlog.md

# MCP-ready Backlog

此工作坊保持 local-first。兩小時建置不需要 MCP server。

未來 MCP opportunities:

1. 連接 design context,讓 Kiro 能將元件對齊已核准的 UI patterns。
2. 連接 content review sheets,讓 Kiro 能讀取 native-speaker review status。
3. 連接 issue tracker context,讓 Kiro 能將 bugs 對應到 specs 與 tasks。
4. 連接 deployment metadata,讓 Kiro 能摘要 release readiness。

Decision:讓 runtime App 與 engineering integrations 保持獨立。

程式碼說明

  • 商業邏輯: 此 note 捕捉未來工作流程改善,同時保留工作坊的實務範圍。
  • 程式碼邏輯: 此 Markdown 檔案是 Kiro 與開發者日後可參考的架構文件。
  • 預期結果: 參與者可理解 MCP-ready planning,而工作坊期間不需要外部服務。

動手實驗 H — 要求 Kiro 進行最終架構審查

開發者操作

  1. 要求 Kiro 將實作與 steering、specs 比對。
  2. 要求找出風險、缺少的測試與不清楚的內容審查狀態。
  3. 要求 Kiro 產生最終開發者交接 note。
  4. 將審查結果轉成 backlog tasks。

Kiro 提示範例

對此工作區執行最終架構審查。
將實作與 steering files、specs 進行比對。
找出 review status visibility、informal labeling、mobile readability、tests、data validation 與 release automation 的落差。
以 severity、evidence 與 recommended fix 格式回傳 findings。
接著建立開發者交接 note。

系統設計決策

  1. 讓 Kiro 擔任 reviewer: 最終審查會使用 Kiro 的 codebase context 檢查意圖與實作是否一致。這不同於要求 Kiro 產生更多程式碼;它會教開發者用 AI 進行架構審查、測試審查與發布信心檢查。
  2. 以 evidence 為基礎的 findings: Findings 應包含 evidence,而不是模糊建議。Evidence 可能是缺少測試檔、元件沒有徽章,或 validator 忽略 review notes。Evidence 讓審查更可行且公平。
  3. 用交接 note 維持延續性: 工作坊常以可運作程式碼結束,但文件薄弱。handoff note 會說明建置了什麼、如何執行、已知未完成項目,以及下一步應做什麼。這能讓成果在課程後仍然有用。

程式碼範例 — docs/developer-handoff.md

# Developer Handoff

## 本工作坊完成項目

- 產品、技術、結構與語言審查用的 Kiro steering files。
- 句子卡或產生器工作流程的 Kiro spec。
- 型別化卡片模型或 Python 內容合約。
- UI renderer 或 static HTML renderer。
- 驗證與測試 commands。
- 品質檢查用的 hook guidance。

## 執行 commands

npm run dev
npm run test:run
npm run lint:data
npm run build

已知限制

  • 語言內容在 native speaker 審查前皆為 draft。
  • runtime generation 有意排除在第一個工作坊建置範圍外。
  • MCP integrations 只記錄為未來 backlog,尚未實作。

下一步任務

  1. 加入更多已審查卡片。
  2. 加入 blocked-card UI 行為。
  3. 加入部署到 AWS Amplify Hosting 或 Amazon S3。
  4. 使用相同本機 commands 加入 CI validation。

程式碼說明

  • 商業邏輯: handoff 保留工作坊的學習與工程成果。
  • 程式碼邏輯: Markdown 以 Kiro 與開發者可重用的格式記錄已建置成果、commands、限制與下一步任務。
  • 預期結果: 另一位開發者可以開啟儲存庫、理解目前狀態,並安全接續工作。

參考架構備註

  • 本工作坊使用的 Kiro 能力:agentic chat、spec-driven development、steering files、hooks、MCP-ready external context、privacy-aware workspace guidance、implementation tasks、documentation generation 與 test generation。
  • 產品範圍:用於 AWS Manila Community Day 準備的教育原型。語言內容在 production 使用前,必須由 native 他加祿語 speakers 審查。
  • Runtime 範圍:以本機開發者工作站優先。工作坊後的選用 AWS 部署可使用 Amazon S3 static website hosting 或 AWS Amplify Hosting。