mcpField
K
kaizen

kaizen

github.com/davila7開発33.0k219 回インストール今日更新
リポジトリ

kaizen について

Kaizenは、継続的改善、エラー予防、既存の標準、ジャストインタイム設計をコーディングやプロセスの判断に適用する開発スキルです。日々の作業指針に加え、体系的な問題分析用コマンドも備えています。

主な機能

  1. 01小さく検証可能な変更の推進
  2. 02設計によるエラー予防
  3. 03既存のプロジェクト規約の踏襲
  4. 04現在必要なものだけを実装
  5. 05体系的な問題分析コマンド

活用シーン

  1. 01コードの段階的な実装やリファクタリング
  2. 02アーキテクチャや設計判断の検討
  3. 03バリデーションとエラー処理の改善
  4. 04プロセス上の問題の体系的な分析

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/davila7/claude-code-templates --skill kaizen

インストール後、Claude Code で/kaizenを入力して読み込まれたか確認します。

詳細

Kaizen: 継続的改善

概要

小さな改善を継続的に積み重ねます。設計段階でエラーを防ぎ、実績のある方法に従い、必要なものだけを構築します。

中核原則: 大きな変更を一度に行うより、多くの小さな改善を重ねるほうが効果的です。修正ではなく、設計時点でエラーを防止します。

適用場面

常に適用する場面:

  • コードの実装とリファクタリング
  • アーキテクチャと設計上の判断
  • プロセスとワークフローの改善
  • エラー処理とバリデーション

考え方: 大規模な努力による完璧さではなく、段階的な前進と予防によって品質を高めます。

4 つの柱

1. 継続的改善 (Kaizen)

小さく頻繁な改善が積み重なって、大きな成果につながります。

原則

革命的な変更より漸進的な変更:

  • 品質を向上させる、最小限の実行可能な変更を行う
  • 一度に改善するのは 1 つだけにする
  • 次の変更に進む前に、各変更を検証する
  • 小さな成功を積み重ねて勢いをつける

コードは常に前より良くする:

  • 出会った小さな問題はその場で修正する
  • 作業中にスコープの範囲内でリファクタリングする
  • 古くなったコメントを更新する
  • 不要なコードを見つけたら削除する

反復的な洗練:

  • 最初のバージョン: 動くようにする
  • 2 回目: 分かりやすくする
  • 3 回目: 効率を高める
  • 3 つを同時に行おうとしない
```typescript // Iteration 1: Make it work const calculateTotal = (items: Item[]) => { let total = 0; for (let i = 0; i < items.length; i++) { total += items[i].price * items[i].quantity; } return total; };

// Iteration 2: Make it clear (refactor) const calculateTotal = (items: Item[]): number => { return items.reduce((total, item) => { return total + (item.price * item.quantity); }, 0); };

// Iteration 3: Make it robust (add validation) const calculateTotal = (items: Item[]): number => { if (!items?.length) return 0;

return items.reduce((total, item) => { if (item.price < 0 || item.quantity < 0) { throw new Error('Price and quantity must be non-negative'); } return total + (item.price * item.quantity); }, 0); };

各ステップが完了し、テスト済みで、正常に動作している
</Good>

<Bad>
```typescript
// Trying to do everything at once
const calculateTotal = (items: Item[]): number => {
  // Validate, optimize, add features, handle edge cases all together
  if (!items?.length) return 0;
  const validItems = items.filter(item => {
    if (item.price < 0) throw new Error('Negative price');
    if (item.quantity < 0) throw new Error('Negative quantity');
    return item.quantity > 0; // Also filtering zero quantities
  });
  // Plus caching, plus logging, plus currency conversion...
  return validItems.reduce(...); // Too many concerns at once
};

圧倒的で、エラーが起きやすく、検証しにくい

実践

機能を実装するとき:

  1. 動作する最もシンプルなバージョンから始める
  2. 改善を 1 つ追加する(エラー処理、バリデーションなど)
  3. テストして検証する
  4. 時間が許せば繰り返す
  5. すぐに完璧にしようとしない

リファクタリングするとき:

  • コードの臭いは一度に 1 つずつ直す
  • 改善ごとにコミットする
  • 全体を通してテストが通る状態を保つ
  • 「十分良い」と感じた時点で止める(収穫逓減)

コードをレビューするとき:

  • 書き直しではなく、段階的な改善を提案する
  • 優先順位をつける: 重大 → 重要 → あると良い
  • 影響の大きい変更を優先する
  • 完璧でなくても「以前より良い」なら受け入れる
2. ポカヨケ (エラー防止)

実行時ではなく、コンパイル時や設計時にエラーを防ぐシステムを設計します。

原則

エラーを不可能にする:

  • 型システムでミスを検出する
  • コンパイラで契約を強制する
  • 無効な状態を表現できないようにする
  • 本番環境より前の段階でエラーを捕捉する

安全性を考慮した設計:

  • 早期に、そして明確に失敗させる
  • 役立つエラーメッセージを提供する
  • 正しい経路を分かりやすくする
  • 誤った経路を使いにくくする

多層防御:

  1. 型システム (コンパイル時)
  2. バリデーション (実行時、早い段階)
  3. ガード (事前条件)
  4. エラー境界 (グレースフルデグラデーション)
型システムによるエラー防止
```typescript // Error: string status can be any value type OrderBad = { status: string; // Can be "pending", "PENDING", "pnding", anything! total: number; };

// Good: Only valid states possible type OrderStatus = 'pending' | 'processing' | 'shipped' | 'delivered'; type Order = { status: OrderStatus; total: number; };

// Better: States with associated data type Order = | { status: 'pending'; createdAt: Date } | { status: 'processing'; startedAt: Date; estimatedCompletion: Date } | { status: 'shipped'; trackingNumber: string; shippedAt: Date } | { status: 'delivered'; deliveredAt: Date; signature: string };

// Now impossible to have shipped without trackingNumber

型システムがエラーの種類ごと防ぐ
</Good>

<Good>
```typescript
// Make invalid states unrepresentable
type NonEmptyArray<T> = [T, ...T[]];

const firstItem = <T>(items: NonEmptyArray<T>): T => {
  return items[0]; // Always safe, never undefined!
};

// Caller must prove array is non-empty
const items: number[] = [1, 2, 3];
if (items.length > 0) {
  firstItem(items as NonEmptyArray<number>); // Safe
}

関数のシグネチャが安全性を保証する

バリデーションによるエラー防止
```typescript // Error: Validation after use const processPayment = (amount: number) => { const fee = amount * 0.03; // Used before validation! if (amount <= 0) throw new Error('Invalid amount'); // ... };

// Good: Validate immediately const processPayment = (amount: number) => { if (amount <= 0) { throw new Error('Payment amount must be positive'); } if (amount > 10000) { throw new Error('Payment exceeds maximum allowed'); }

const fee = amount * 0.03; // ... now safe to use };

// Better: Validation at boundary with branded type type PositiveNumber = number & { readonly __brand: 'PositiveNumber' };

const validatePositive = (n: number): PositiveNumber => { if (n <= 0) throw new Error('Must be positive'); return n as PositiveNumber; };

const processPayment = (amount: PositiveNumber) => { // amount is guaranteed positive, no need to check const fee = amount * 0.03; };

// Validate at system boundary const handlePaymentRequest = (req: Request) => { const amount = validatePositive(req.body.amount); // Validate once processPayment(amount); // Use everywhere safely };

境界で一度だけ検証すれば、それ以外の場所では安全
</Good>

#### ガードと事前条件

<Good>
```typescript
// Early returns prevent deeply nested code
const processUser = (user: User | null) => {
  if (!user) {
    logger.error('User not found');
    return;
  }

  if (!user.email) {
    logger.error('User email missing');
    return;
  }

  if (!user.isActive) {
    logger.info('User inactive, skipping');
    return;
  }

  // Main logic here, guaranteed user is valid and active
  sendEmail(user.email, 'Welcome!');
};

ガードによって前提条件が明示され、強制される

設定によるエラー防止
```typescript // Error: Optional config with unsafe defaults type ConfigBad = { apiKey?: string; timeout?: number; };

const client = new APIClient({ timeout: 5000 }); // apiKey missing!

// Good: Required config, fails early type Config = { apiKey: string; timeout: number; };

const loadConfig = (): Config => { const apiKey = process.env.API_KEY; if (!apiKey) { throw new Error('API_KEY environment variable required'); }

return { apiKey, timeout: 5000, }; };

// App fails at startup if config invalid, not during request const config = loadConfig(); const client = new APIClient(config);

本番環境ではなく、起動時に失敗させる
</Good>

#### 実践

**API を設計するとき:**
- 型を使って入力を制約する
- 無効な状態を表現できないようにする
- 例外を投げるのではなく Result<T, E> を返す
- 型で事前条件を文書化する

**エラーを処理するとき:**
- システムの境界でバリデーションを行う

- 事前条件にはガードを使う
- 明確なメッセージとともに早く失敗させる
- デバッグのためにコンテキストをログに残す

**設定するとき:**
- デフォルト値付きのオプションより、必須項目を優先する
- すべての設定を起動時に検証する
- 設定が無効なら、デプロイを失敗させる
- 部分的な設定を許可しない

### 3. 標準化された作業
確立されたパターンに従います。うまくいった方法を文書化します。良い習慣を実践しやすくします。
#### 原則

**巧妙さより一貫性:**
- 既存のコードベースのパターンに従う
- 解決済みの問題を作り直さない
- 新しいパターンは、明らかに優れている場合にのみ採用する
- 新しいパターンはチームの合意を得てから採用する

**ドキュメントはコードとともに:**
- README にはセットアップとアーキテクチャを書く
- AI のコーディング規約は CLAUDE.md に書く
- コメントには「何を」ではなく「なぜ」を書く
- 複雑なパターンには例を示す

**標準を自動化する:**
- リンターでスタイルを強制する
- 型チェックで契約を強制する
- テストで動作を検証する
- CI/CD で品質ゲートを強制する

#### パターンへの従い方

<Good>
```typescript
// Existing codebase pattern for API clients
class UserAPIClient {
  async getUser(id: string): Promise<User> {
    return this.fetch(`/users/${id}`);
  }
}

// New code follows the same pattern
class OrderAPIClient {
  async getOrder(id: string): Promise<Order> {
    return this.fetch(`/orders/${id}`);
  }
}

一貫性があるとコードベースが予測可能になる

```typescript // Existing pattern uses classes class UserAPIClient { /* ... */ }

// New code introduces different pattern without discussion const getOrder = async (id: string): Promise => { // Breaking consistency "because I prefer functions" };

一貫性の欠如は混乱を生む
</Bad>

#### エラーハンドリングのパターン

<Good>
```typescript
// Project standard: Result type for recoverable errors
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };

// All services follow this pattern
const fetchUser = async (id: string): Promise<Result<User, Error>> => {
  try {
    const user = await db.users.findById(id);
    if (!user) {
      return { ok: false, error: new Error('User not found') };
    }
    return { ok: true, value: user };
  } catch (err) {
    return { ok: false, error: err as Error };
  }
};

// Callers use consistent pattern
const result = await fetchUser('123');
if (!result.ok) {
  logger.error('Failed to fetch user', result.error);
  return;
}
const user = result.value; // Type-safe!

コードベース全体で標準的なパターンを使う

ドキュメントの標準
```typescript /** * Retries an async operation with exponential backoff. * * Why: Network requests fail temporarily; retrying improves reliability * When to use: External API calls, database operations * When not to use: User input validation, internal function calls * * @example * const result = await retry( * () => fetch('https://api.example.com/data'), * { maxAttempts: 3, baseDelay: 1000 } * ); */ const retry = async ( operation: () => Promise, options: RetryOptions ): Promise => { // Implementation... }; ``` なぜ、いつ、どのように行うかを文書化する
実践

新しいパターンを追加する前に:

  • 同様の問題がコードベース内で解決済みかを検索する
  • プロジェクトの規約について CLAUDE.md を確認する
  • パターンから外れる場合はチームと相談する
  • 新しいパターンを導入したらドキュメントを更新する

コードを書くとき:

  • 既存のファイル構成に合わせる
  • 同じ命名規則を使う
  • 同じエラーハンドリングの方法に従う
  • 同じ場所からインポートする

レビューするとき:

  • 既存のコードとの一貫性を確認する
  • コードベース内の例を示す
  • 標準に合わせるよう提案する
  • 新しい標準が生まれたら CLAUDE.md を更新する
4. Just-In-Time (JIT)

今必要なものだけを作る。多すぎず、少なすぎず。早すぎる最適化や過剰な設計を避けます。

原則

YAGNI (You Aren't Gonna Need It):

  • 現在の要件に必要な機能だけを実装する
  • 「念のため」の機能は作らない
  • 「将来必要になるかもしれない」コードは書かない
  • 推測に基づく部分は削除する

最も単純で動く解決策:

  • まずは単純な解決策から始める
  • 必要になったときにだけ複雑さを加える
  • 要件が変わったらリファクタリングする
  • 将来の必要性を先回りして考えない

計測してから最適化する:

  • 早すぎる最適化をしない
  • 最適化の前にプロファイリングする
  • 変更の影響を計測する
  • 「十分に良い」性能で満足する
実際のYAGNI
```typescript // Current requirement: Log errors to console const logError = (error: Error) => { console.error(error.message); }; ``` 単純で、現在のニーズを満たしている ```typescript // Over-engineered for "future needs" interface LogTransport { write(level: LogLevel, message: string, meta?: LogMetadata): Promise; }

class ConsoleTransport implements LogTransport { /... / } class FileTransport implements LogTransport { / ... / } class RemoteTransport implements LogTransport { / .../ }

class Logger { private transports: LogTransport[] = []; private queue: LogEntry[] = []; private rateLimiter: RateLimiter; private formatter: LogFormatter;

// 200 lines of code for "maybe we'll need it" }

const logError = (error: Error) => { Logger.getInstance().log('error', error.message); };

架空の将来要件のために作り込んでいる
</Bad>

**複雑さを加えるべきとき:**
- 現在の要件がそれを必要とするとき
- 使用を通じて問題点が明らかになったとき
- 計測によって性能問題が確認されたとき
- 複数のユースケースが出てきたとき

<Good>
```typescript
// Start simple
const formatCurrency = (amount: number): string => {
  return `$${amount.toFixed(2)}`;
};

// Requirement evolves: support multiple currencies
const formatCurrency = (amount: number, currency: string): string => {
  const symbols = { USD: '$', EUR: '€', GBP: '£' };
  return `${symbols[currency]}${amount.toFixed(2)}`;
};

// Requirement evolves: support localization
const formatCurrency = (amount: number, locale: string): string => {
  return new Intl.NumberFormat(locale, {\n    style: 'currency',
    currency: locale === 'en-US' ? 'USD' : 'EUR',
  }).format(amount);
};

必要になったときにだけ複雑さを加えている

早すぎる抽象化
```typescript // One use case, but building generic framework abstract class BaseCRUDService { abstract getAll(): Promise; abstract getById(id: string): Promise; abstract create(data: Partial): Promise; abstract update(id: string, data: Partial): Promise; abstract delete(id: string): Promise; }

class GenericRepository { /300 lines / } class QueryBuilder { / 200 lines/ } // ... building entire ORM for single table

不確かな将来のための大げさな抽象化
</Bad>

<Good>
```typescript
// Simple functions for current needs
const getUsers = async (): Promise<User[]> => {
  return db.query('SELECT * FROM users');
};

const getUserById = async (id: string): Promise<User | null> => {
  return db.query('SELECT * FROM users WHERE id = $1', [id]);
};

// When pattern emerges across multiple entities, then abstract

パターンが3件以上のケースで実証されたときにだけ抽象化する

性能の最適化
```typescript // Current: Simple approach const filterActiveUsers = (users: User[]): User[] => { return users.filter(user => user.isActive); };

// Benchmark shows: 50ms for 1000 users (acceptable) // ✓ Ship it, no optimization needed

// Later: After profiling shows this is bottleneck // Then optimize with indexed lookup or caching

推測ではなく計測に基づいて最適化している
</Good>

<Bad>
```typescript
// Premature optimization
const filterActiveUsers = (users: User[]): User[] => {
  // "This might be slow, so let's cache and index"
  const cache = new WeakMap();
  const indexed = buildBTreeIndex(users, 'isActive');
  // 100 lines of optimization code
  // Adds complexity, harder to maintain
  // No evidence it was needed
};\

計測されていない問題に対する複雑な解決策

実践

実装するとき:

  • 目の前の問題を解決する
  • 素直なアプローチを使う
  • 「もし〜だったら」という発想に流されない
  • 推測に基づくコードは削除する

最適化するとき:

  • 先にプロファイリングし、その後に最適化する
  • 前後で計測する
  • 最適化が必要な理由を文書化する
  • 単純な版をテストとして残しておく

抽象化するとき:

  • 類似のケースが3件以上そろうまで待つ(Rule of Three)
  • 抽象化はできるだけ単純にする
  • 誤った抽象化よりも重複を選ぶ
  • パターンが明確になったらリファクタリングする

コマンドとの連携

Kaizen スキルは作業の進め方を導きます。コマンドは構造化された分析を提供します:

  • /why: 根本原因分析(5 Whys)
  • /cause-and-effect: 多要因分析(特性要因図)
  • /plan-do-check-act: 反復的な改善サイクル
  • /analyse-problem: 包括的なドキュメント作成(A3)
  • /analyse: 適切な手法の選択(現地現物/VSM/ムダ)

構造化された問題解決にはコマンドを使い、日々の開発にはスキルを適用してください。

レッドフラッグ

継続的改善に違反する例:

  • 「あとでリファクタリングしよう」(実際にはやられない)
  • 見つけたときより悪い状態でコードを残す
  • 段階的に進めず、一気に書き直す(ビッグバン書き換え)

ポカヨケに違反する例:

  • 「ユーザーが気をつければいい」
  • 使用後に検証し、使用前には検証しない
  • 検証のないオプション設定

標準作業に違反する例:

  • 「自分のやり方でやりたい」
  • 既存のパターンを確認しない
  • プロジェクトの規約を無視する

ジャスト・イン・タイムに違反する例:

  • 「いつか必要になるかもしれない」
  • 使う前にフレームワークを作り込む
  • 計測せずに最適化する

覚えておくこと

カイゼンとは:

  • 小さな改善を継続的に積み重ねること
  • 設計によってエラーを未然に防ぐこと
  • 実証済みのパターンに従うこと
  • 必要なものだけを作ること

カイゼンではないもの:

  • 最初から完璧を目指すこと
  • 大規模なリファクタリングプロジェクト
  • 巧妙な抽象化
  • 早すぎる最適化

マインドセット: 今日は十分に良く、明日はより良く。これを繰り返す。

コメント