DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Claude Codeでダークローンチを設計する:トラフィックシャドウイング・段階的ロールアウト

はじめに

「新機能を本番でいきなり全ユーザーに公開するのが怖い」——ダークローンチ(Dark Launch)で本番トラフィックをシャドウイングし、実データで新機能を検証してから段階的に展開する設計をClaude Codeに生成させる。


CLAUDE.mdに設計ルールを書く

## ダークローンチ設計ルール

### 段階的ロールアウト
- 0% → 1% → 5% → 10% → 25% → 50% → 100% の段階で展開
- 各段階で1時間以上観察してエラー率・レイテンシーを確認
- 問題検出時は即座に0%に戻す(フラグOFF)
- ユーザーIDのhashで決定的に割り振り(同じユーザーは常に同じ体験)

### シャドウイング
- 本番は旧実装、バックグラウンドで新実装も実行
- 新旧の差異・エラー・レイテンシーをRedisに記録
- 差異サンプルを100件まで保存して調査可能に
Enter fullscreen mode Exit fullscreen mode

生成される実装(抜粋)

// ロールアウト判定(ユーザーIDハッシュで決定的)
isUserInRollout(userId: string, userEmail: string, config: RolloutConfig): boolean {
  if (config.disabledUserIds?.includes(userId)) return false;
  if (config.enabledForInternal && userEmail.endsWith('@company.com')) return true;
  const hash = djb2Hash(userId);
  return (hash % 100) < config.percentage; // 決定的に割り振り
}

// シャドウイング(本番は旧実装、バックグラウンドで新実装)
async runWithShadowing<T>(featureKey, oldFn, newFn, requestId): Promise<T> {
  const oldResult = await oldFn(); // 本番: ブロッキング

  setImmediate(async () => {
    let newResult, newError;
    try { newResult = await newFn(); }
    catch (err) { newError = err.message; }

    const hasDiff = newError !== undefined || !deepEqual(oldResult, newResult);
    await redis.incr(`shadow:${featureKey}:total`);
    if (hasDiff) {
      await redis.incr(`shadow:${featureKey}:diff`);
      await redis.lpush(`shadow:${featureKey}:samples`, JSON.stringify({ requestId, newError }));
      await redis.ltrim(`shadow:${featureKey}:samples`, 0, 99);
    }
  });

  return oldResult; // 本番レスポンスは旧実装
}

// 管理API
router.put('/admin/dark-launch/:key', requireAdmin, async (req, res) => {
  await rolloutManager.setConfig({ featureKey: req.params.key, percentage: req.body.percentage });
  res.json({ success: true }); // パーセンテージを変えるだけでロールアウト制御
});
Enter fullscreen mode Exit fullscreen mode

まとめ

  1. CLAUDE.md に段階ロールアウト(0→1→5→10→25→50→100%)・ユーザーIDハッシュで決定的割り振り・即時ロールバック方針を明記
  2. シャドウイング で本番トラフィックを旧実装で処理しつつ新実装をsetImmediateで並行実行——ユーザー体験に影響なく新実装を検証
  3. 差異率トラッキング でRedisのtotal/diff比率を1日ウィンドウで監視——差異サンプルを100件まで保存して差異の内容を調査
  4. 管理APIで%を操作 ——問題発見時はpercentage:0に設定するだけで即座にロールバック完了

デプロイ設計のレビューは **Code Review Pack(¥980)* の /code-review で確認できます。*

prompt-works.jp

みょうが (@myougatheaxo) — ウーパールーパーのVTuber。

Top comments (0)