【設計はKiro、実装はClaude】組み合わせたらかなり良かった

に公開

Claude Code、確かに実装は強いんですけど、設計となると思ったようなアウトプットは簡単には出てこない…。

正直、要件定義や設計のスキルを持っていないと難しいのではないかと思っています。

そこで、設計に強いと噂の Kiro を導入して、Claude Code × Kiro を実践してみたところ想像以上に良かったのでまとめます。

Claude Codeを使って感じた課題

コーディングに関しては優秀ですが、ゼロからプロダクトを立ち上げる際の要件定義や設計には、やや頼りなさを感じる場面もありました。

特に、要件がまだ曖昧な状態だったり設計方針が固まっていない段階では、期待したアウトプットを得るには知識とプロンプトやルール作成などの工夫が必要でした。

Kiroの登場

Kiroは、CursorやWindsurfのような AI駆動の開発支援環境(Agentic IDE) です。

中でも特徴的なのは、「仕様駆動開発(Spec-driven Development)」というスタイルでAIによるコーディングを実現している点です。

特に注目すべき機能が、Kiro独自のSpecs

これにより、開発者の頭の中にあるあいまいなアイディアや要望を、構造化された形で容易に言語化・設計化することが可能になったことがポイントです。

https://kiro.dev/

素晴らしい設計力:Specsとは

Specs は、「考えていること」を「言語化する」あいだにあるギャップを埋めることをコンセプトとした機能です。

コードを書く前の「こういう機能がほしい」「こんなことができたらいい」という、まだ設計にも実装にもなっていない“ぼんやりした断片”を具体化し、設計として意味を持つ構造に変えていくワークフローを提供してくれています。

具体的に、Specsでは、次の3つのステップを経てシステムを開発していきます。

  1. Requirements:要件定義
  2. Design:設計
  3. Task list:タスク整理

1. Requirements:要件定義

要件定義フェーズでは、EARS記法(Easy Approach to Requirements Syntax) に沿ってユーザーストーリーと受け入れ基準を requirements.md に記述します。

実際にやってみましょう。
要件定義の作成

作成されたrequirements.mdがこちらです:

# 要件定義書

## 概要

職務経歴書を効率的に作成するためのWebアプリケーションです。ユーザーが必要な情報を入力し、複数のフォーマットから選択してプレビューし、最終的にPDFとしてエクスポートできる機能を提供します。AIを活用して入力支援や内容の最適化も行います。

## 要件

### 要件1

**ユーザーストーリー:** 求職者として、基本情報を簡単に入力できるようにしたい。そうすることで、職務経歴書作成の最初のステップを効率的に完了できる。

#### 受入基準

1. WHEN ユーザーが基本情報入力画面にアクセスした時 THEN システムは氏名、連絡先、住所、生年月日の入力フィールドを表示する
2. WHEN ユーザーが必須項目を未入力のまま次に進もうとした時 THEN システムはエラーメッセージを表示し、該当フィールドをハイライトする
3. WHEN ユーザーがメールアドレスを入力した時 THEN システムは有効なメールアドレス形式かどうかを検証する

### 要件2

**ユーザーストーリー:** 求職者として、職歴情報を詳細に入力できるようにしたい。そうすることで、自分の経験を正確に職務経歴書に反映できる。

#### 受入基準

1. WHEN ユーザーが職歴入力画面にアクセスした時 THEN システムは会社名、部署、役職、在籍期間、業務内容の入力フィールドを表示する
2. WHEN ユーザーが複数の職歴を追加したい時 THEN システムは「職歴を追加」ボタンで新しい職歴入力フォームを動的に追加する
3. WHEN ユーザーが在籍期間を入力した時 THEN システムは開始日が終了日より前であることを検証する
4. WHEN ユーザーが業務内容を入力した時 THEN システムはAIによる文章改善提案を表示する

~~~ 以下略 ~~~

このように要件をまとめることによって、以下のメリットがあります。

  • 明確性:要件があいまいにならず、誰が見ても理解しやすい
  • テスト可能性:そのままテストケースに落とし込める
  • トレーサビリティ:個別の要件を実装やテストにひも付けて追跡できる
  • 網羅性:条件と期待動作を明示的に書くことで、漏れや曖昧さが減る

プロンプトやルールで工夫をしなくても、一定のクオリティの要件定義書が出来上がるのは嬉しいですね。

0→1をスムーズに進められるだけでなく、開発プロセスが効率的になり、チーム開発においても認識のズレを減らすことができそうです。

2. Design:設計

設計フェーズでは、要件定義フェーズで明確になった要件をもとに、技術的なアーキテクチャやシーケンス図、実装上の考慮事項などをdesign.mdにまとめます。

先ほどの要件をもとに作成したdesign.mdがこちらです。

ツッコミどころはままありますが、実装フェーズに移行できる十分な粒度を備えているように見えるので、出力されたフォーマットに沿って詰めていけば完成度の高い設計書が完成しそうです。

# 設計文書

## 概要

職務経歴書作成AIツールは、React.jsベースのSPA(Single Page Application)として実装します。ユーザーフレンドリーなインターフェースでデータ入力を行い、複数のテンプレートから選択してプレビューし、高品質なPDFを生成する機能を提供します。

## アーキテクチャ

### システム構成

```` ```mermaid
graph TB
    A[ユーザー] --> B[React Frontend]
    B --> C[State Management - Zustand]
    B --> D[PDF Generation - jsPDF/html2canvas]
    B --> E[Local Storage]
    B --> F[AI Service - OpenAI API]
    
    subgraph "Frontend Components"
        G[入力フォーム]
        H[プレビュー]
        I[テンプレート選択]
        J[PDF出力]
    end
    
    B --> G
    B --> H
    B --> I
    B --> J
```` ```

### 技術スタック

- **フロントエンド**: React 18 + TypeScript
- **状態管理**: Zustand(軽量で使いやすい状態管理)
- **スタイリング**: Tailwind CSS(レスポンシブデザイン対応)
- **PDF生成**: jsPDF + html2canvas(クライアントサイドPDF生成)
- **フォーム管理**: React Hook Form(バリデーション付き)
- **AI統合**: OpenAI API(文章改善提案)
- **データ永続化**: LocalStorage(ブラウザローカル保存)##
 コンポーネントとインターフェース

### 主要コンポーネント構成

```` ```
src/
├── components/
│   ├── forms/
│   │   ├── BasicInfoForm.tsx
│   │   ├── WorkExperienceForm.tsx
│   │   ├── EducationForm.tsx
│   │   └── SkillsForm.tsx
│   ├── templates/
│   │   ├── TemplateSelector.tsx
│   │   ├── ClassicTemplate.tsx
│   │   ├── ModernTemplate.tsx
│   │   └── MinimalTemplate.tsx
│   ├── preview/
│   │   ├── ResumePreview.tsx
│   │   └── PrintPreview.tsx
│   ├── ai/
│   │   ├── AIAssistant.tsx
│   │   └── TextImprovement.tsx
│   └── export/
│       └── PDFExporter.tsx
├── stores/
│   ├── resumeStore.ts
│   └── uiStore.ts
├── types/
│   └── resume.ts
├── utils/
│   ├── validation.ts
│   ├── pdfGenerator.ts
│   └── aiService.ts
└── hooks/
    ├── useResumeData.ts
    ├── useAutoSave.ts
    └── useAIAssistant.ts
```` ```

### コンポーネントインターフェース

#### ResumeStore(状態管理)
```` ```typescript
interface ResumeStore {
  // データ
  basicInfo: BasicInfo;
  workExperience: WorkExperience[];
  education: Education[];
  skills: Skill[];
  
  // UI状態
  currentStep: number;
  selectedTemplate: TemplateType;
  isPreviewMode: boolean;
  
  // アクション
  updateBasicInfo: (info: Partial<BasicInfo>) => void;
  addWorkExperience: (experience: WorkExperience) => void;
  updateWorkExperience: (id: string, experience: Partial<WorkExperience>) => void;
  deleteWorkExperience: (id: string) => void;
  setSelectedTemplate: (template: TemplateType) => void;
  exportToPDF: () => Promise<void>;
}
```` ```

#### AIService
```` ```typescript
interface AIService {
  improveText: (text: string, context: string) => Promise<string>;
  generateSuggestions: (jobTitle: string, experience: string) => Promise<string[]>;
  validateContent: (content: string) => Promise<ValidationResult>;
}
```` ```## デー
タモデル

### 基本情報(BasicInfo)
```typescript
interface BasicInfo {
  id: string;
  fullName: string;
  email: string;
  phone: string;
  address: string;
  dateOfBirth?: string;
  profileImage?: string;
  summary?: string;
}
```` ```

### 職歴(WorkExperience)
```` ```typescript
interface WorkExperience {
  id: string;
  companyName: string;
  department?: string;
  position: string;
  startDate: string;
  endDate?: string; // 現在も在籍の場合はnull
  isCurrentJob: boolean;
  responsibilities: string[];
  achievements: string[];
  technologies?: string[];
}
```` ```

### 学歴(Education)
```` ```typescript
interface Education {
  id: string;
  schoolName: string;
  degree: string;
  fieldOfStudy: string;
  graduationDate: string;
  gpa?: number;
  honors?: string[];
}
```` ```

### スキル・資格(Skill)
```` ```typescript
interface Skill {
  id: string;
  name: string;
  category: 'technical' | 'language' | 'certification' | 'soft';
  level?: 'beginner' | 'intermediate' | 'advanced' | 'expert';
  certificationDate?: string;
  expirationDate?: string;
}
```` ```

### テンプレート(Template)
```` ```typescript
interface Template {
  id: string;
  name: string;
  description: string;
  previewImage: string;
  styles: TemplateStyles;
}

interface TemplateStyles {
  layout: 'single-column' | 'two-column';
  colorScheme: 'classic' | 'modern' | 'minimal';
  fontFamily: string;
  fontSize: {
    heading: string;
    body: string;
    small: string;
  };
  spacing: {
    section: string;
    item: string;
  };
}
```` ```
## エラーハンドリング

### バリデーション戦略
1. **リアルタイムバリデーション**: フォーム入力時の即座な検証
2. **サブミット時バリデーション**: フォーム送信時の包括的な検証
3. **データ整合性チェック**: 日付の論理的整合性など

### エラー表示
```` ```typescript
interface ValidationError {
  field: string;
  message: string;
  type: 'required' | 'format' | 'logic' | 'length';
}

interface ErrorState {
  hasErrors: boolean;
  errors: ValidationError[];
  showErrors: boolean;
}
```` ```

### PDF生成エラー対応
- ブラウザ互換性チェック
- メモリ不足時の分割処理
- 生成失敗時のリトライ機能
- フォールバック印刷機能

## テスト戦略

### 単体テスト
- **コンポーネントテスト**: React Testing Library使用
- **ユーティリティ関数テスト**: Jest使用
- **状態管理テスト**: Zustandストアのテスト

### 統合テスト
- **フォーム入力フロー**: ユーザー操作の一連の流れ
- **PDF生成プロセス**: データ入力からPDF出力まで
- **テンプレート切り替え**: データ保持とレイアウト変更

### E2Eテスト
- **完全な職務経歴書作成フロー**: 入力からPDF出力まで
- **データ永続化**: ページリロード後のデータ復元
- **レスポンシブデザイン**: 異なる画面サイズでの動作

### テストケース例
```` ```typescript
describe('Resume Builder', () => {
  test('基本情報入力と保存', () => {
    // テストケース実装
  });
  
  test('職歴追加と編集', () => {
    // テストケース実装
  });
  
  test('テンプレート切り替え', () => {
    // テストケース実装
  });
  
  test('PDF生成', () => {
    // テストケース実装
  });
});
```` ```
## セキュリティ考慮事項

### データ保護
- **ローカルストレージ暗号化**: 機密情報の暗号化保存
- **XSS対策**: ユーザー入力のサニタイゼーション
- **CSP設定**: Content Security Policyの適用

### AI API連携
- **API キー管理**: 環境変数での安全な管理
- **レート制限**: API呼び出し頻度の制御
- **データ最小化**: 必要最小限のデータのみ送信

## パフォーマンス最適化

### フロントエンド最適化
- **コード分割**: React.lazy()による動的インポート
- **メモ化**: React.memo()とuseMemo()の活用
- **仮想化**: 大量データ表示時の仮想スクロール

### PDF生成最適化
- **段階的レンダリング**: セクション別の分割処理
- **画像最適化**: 適切な解像度とフォーマット
- **メモリ管理**: 大きなPDF生成時のメモリ効率化

## 国際化対応

### 多言語サポート
- **i18n実装**: react-i18nextライブラリ使用
- **日本語対応**: 日本の職務経歴書フォーマット
- **文字エンコーディング**: UTF-8での適切な文字表示

3. Task:タスク整理

タスク整理フェーズでは詳細な実装計画をtasks.mdにまとめます。

要件定義(requirements.md)と設計(design.md)が固まっていれば、あとは Claude Code に任せても高品質なアウトプットが期待できます(私調べ)が、以下にあてはまる方にはKiroによるタスク整理の活用をおすすめします。

  • 開発をミニマムに進めたい
  • 詳細なタスク内容を把握しておきたい

実際に、要件定義書requirements.md、設計書design.mdをもとに作成したtasks.mdがこちらです:
実装計画

Kiroのタスク整理の特徴としては、以下の2点が挙げられます:

  • どこまで実装するかのスコープを詳細に管理しやすい
  • 「Start task」ボタンで、各タスクの実行タイミングをコントロールできる

コードをざっくり把握しておきたい私にとってはありがたい機能ですが、これに関しては好みによるところが大きい気がします。

残念な実装力

「このままKiroだけで開発を完結すれば良いのでは?」と感じる方もいるかもしれません。

しかし実際には、実装フェーズに入るとかなりのもたつきを感じるのが現状です。

せっかくSpecsで、「これが実現できればプロトタイプとしては満足」くらいの実装計画を立てたとしても、実装フェーズでの待ち時間が長すぎて正直やっていられません。

そこで、Kiroの設計力とClaude Codeの実装力を組み合わせるという“いいとこ取り”な解に至りました。

Claude Code と Kiro のいいとこ取りをしよう

改めてそれぞれの強みと弱みを整理しましょう。

項目 Kiro Claude Code
要件定義
設計
タスク整理
実装

もちろん今後、AWS(Kiro)もAnthropic(Claude Code)もそれぞれの弱点を補強してくるとは思いますが、現時点ではフェーズごとの得意・不得意がはっきりしていると感じています。

だからこそ、Kiroで設計し、Claude Codeで実装するという分担が有効でしょう。

それぞれの特性を活かして、効率的に高品質な開発を実現していきましょう。

とはいえ、IDEを変えたくない

とはいえ、Claude Codeのようなコマンドツールと違い、IDEそのものを切り替えることはハードルが高い方もいると思います。

そんな方のために、Kiro風に仕様書駆動開発を実践する方法をまとめた記事を紹介しておきます。

https://zenn.dev/sosukesuzuki/articles/593903287631e9
https://qiita.com/nokonoko_1203/items/8bafb6033409aadccd9f

まとめ

KiroのSpecsはAWSによって調整された要件定義・設計のやり方で出力されます。

よって、特に設計スキルが浅い方やスピード重視でプロトタイプを作りたい方にとっては、KiroとClaude Codeを組み合わせることで簡単に一定以上のクオリティを出せるというのは素晴らしいなと思いました。

また、Specsで作成したドキュメントを読むだけでも得られる学びは多く、設計の引き出しを増やすという意味でも有益でした。

ぜひ一度、試してみてください〜

参考記事

https://zenn.dev/galirage/articles/aws-ai-native-kiro
https://zenn.dev/ubie_dev/articles/kiro-claude-code

Discussion